Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Sbalzarini Lab
S
Software
P
Parallel Computing
OpenFPM
openfpm_io
Commits
f6a17078
Commit
f6a17078
authored
Jun 26, 2015
by
incardon
Browse files
Added CSV and VTK writer
parent
d4b71c57
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/CSVWriter.hpp
0 → 100644
View file @
f6a17078
/*
* CSVWriter.hpp
*
* Created on: Dec 15, 2014
* Author: Pietro Incardona
*/
#ifndef CSVWRITER_HPP_
#define CSVWRITER_HPP_
#include <iostream>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <fstream>
#include "common.hpp"
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include "Point_test.hpp"
#include "csv_multiarray.hpp"
#include "util.hpp"
/*! \brief this class is a functor for "for_each" algorithm
*
* For each element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the properties of the object
*
* \tparam Tobj object
*
*/
template
<
typename
Tobj
>
struct
csv_prp
{
// String
std
::
stringstream
&
str
;
// Object to write
Tobj
&
obj
;
/*! \brief Constructor
*
* Create a vertex properties list
*
* \param str streamstring
* \param obj object to write
*
*/
csv_prp
(
std
::
stringstream
&
str
,
Tobj
&
obj
)
:
str
(
str
),
obj
(
obj
)
{
};
//! It call the functor for each member
template
<
typename
T
>
void
operator
()(
T
&
t
)
{
// This is the type of the csv column
typedef
typename
boost
::
fusion
::
result_of
::
at_c
<
typename
Tobj
::
type
,
T
::
value
>::
type
col_type
;
// Remove the reference from the column type
typedef
typename
boost
::
remove_reference
<
col_type
>::
type
col_rtype
;
csv_value_str
<
col_rtype
>
(
obj
.
template
get
<
T
::
value
>(),
str
);
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* For each element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the properties of the object
*
* \tparam T object
*
*/
template
<
typename
Tobj
,
bool
attr
>
struct
csv_col
{
std
::
stringstream
&
str
;
csv_col
(
std
::
stringstream
&
str
)
:
str
(
str
)
{
};
//! It call the functor for each member
template
<
typename
T
>
void
operator
()(
T
&
t
)
{
// This is the type of the csv column
typedef
typename
boost
::
fusion
::
result_of
::
at_c
<
typename
Tobj
::
type
,
T
::
value
>::
type
col_type
;
// Remove the reference from the column type
typedef
typename
boost
::
remove_reference
<
col_type
>::
type
col_rtype
;
csv_col_str
<
col_rtype
>
(
std
::
string
(
Tobj
::
attributes
::
name
[
T
::
value
]),
str
);
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the vertex
* properties
*
* Specialization when we do not have vertex attributes
*
* \tparam G graph type
*
*/
template
<
typename
Tobj
>
struct
csv_col
<
Tobj
,
false
>
{
std
::
stringstream
&
str
;
csv_col
(
std
::
stringstream
&
str
)
:
str
(
str
)
{
};
//! It call the functor for each member
template
<
typename
T
>
void
operator
()(
T
&
t
)
{
// This is the type of the csv column
typedef
typename
boost
::
fusion
::
result_of
::
at_c
<
typename
Tobj
::
type
,
T
::
value
>::
type
col_type
;
// Remove the reference from the column type
typedef
typename
boost
::
remove_reference
<
col_type
>::
type
col_rtype
;
std
::
stringstream
str2
;
str2
<<
"column_"
<<
T
::
value
;
csv_col_str
<
col_rtype
>
(
str2
.
str
(),
str
);
}
};
#define VECTOR 1
/*! \brief CSV Writer
*
* It write in CSV format vector of objects living into an N-dimensional space
*
* \tparam v_pos Positional vector
* \tparam v_prp Property vector
*
*/
template
<
typename
v_pos
,
typename
v_prp
,
unsigned
int
impl
=
VECTOR
>
class
CSVWriter
{
/*! \brief Get the colums name (also the positional name)
*
*/
std
::
string
get_csv_colums
()
{
std
::
stringstream
str
;
// write positional columns
for
(
int
i
=
0
;
i
<
v_pos
::
value_type
::
dims
;
i
++
)
{
if
(
i
==
0
)
str
<<
"x["
<<
i
<<
"]"
;
else
str
<<
","
<<
"x["
<<
i
<<
"]"
;
}
// write positional information
csv_col
<
typename
v_prp
::
value_type
,
has_attributes
<
typename
v_prp
::
value_type
>::
value
>
col
(
str
);
// Iterate through all the vertex and create the vertex list
boost
::
mpl
::
for_each
<
boost
::
mpl
::
range_c
<
int
,
0
,
v_prp
::
value_type
::
max_prop
>
>
(
col
);
str
<<
"
\n
"
;
return
str
.
str
();
}
/*! \brief Get the csv data section
*
* \param v_pos vector that contain the positional information
* \param v_prp vector that contain the property information
*
*/
std
::
string
get_csv_data
(
v_pos
&
vp
,
v_prp
&
vpr
)
{
std
::
stringstream
str
;
// The position and property vector size must match
if
(
vp
.
size
()
!=
vpr
.
size
())
{
std
::
cerr
<<
"Error: "
<<
__FILE__
<<
":"
<<
__LINE__
<<
" position vector and property vector must have the same size
\n
"
;
return
std
::
string
(
""
);
}
// Write the data
for
(
size_t
i
=
0
;
i
<
vp
.
size
()
;
i
++
)
{
for
(
size_t
j
=
0
;
j
<
v_pos
::
value_type
::
dims
;
j
++
)
{
if
(
j
==
0
)
str
<<
vp
.
template
get
<
0
>(
i
)[
j
];
else
str
<<
","
<<
vp
.
template
get
<
0
>(
i
)[
j
];
}
// Object to write
typename
v_prp
::
value_type
obj
=
vpr
.
get
(
i
);
csv_prp
<
typename
v_prp
::
value_type
>
c_prp
(
str
,
obj
);
// write the properties to the stream string
boost
::
mpl
::
for_each
<
boost
::
mpl
::
range_c
<
int
,
0
,
v_prp
::
value_type
::
max_prop
>
>
(
c_prp
);
str
<<
"
\n
"
;
}
return
str
.
str
();
}
public:
/*! \brief It write a CSV file
*
* \tparam prp which properties to output [default = -1 (all)]
*
* \param file path where to write
* \param v_pos positional vector
* \param v_prp properties vector
*
*/
bool
write
(
std
::
string
file
,
v_pos
&
v
,
v_prp
&
prp
)
{
// Header for csv (colums name)
std
::
string
csv_header
;
// Data point
std
::
string
point_data
;
// Get csv columns
csv_header
=
get_csv_colums
();
// For each property in the vertex type produce a point data
point_data
=
get_csv_data
(
v
,
prp
);
// write the file
std
::
ofstream
ofs
(
file
);
// Check if the file is open
if
(
ofs
.
is_open
()
==
false
)
{
std
::
cerr
<<
"Error cannot create the CSV file: "
+
file
;}
ofs
<<
csv_header
<<
point_data
;
// Close the file
ofs
.
close
();
// Completed succefully
return
true
;
}
};
#endif
/* CSVWRITER_HPP_ */
src/CSVWriter_unit_tests.hpp
0 → 100644
View file @
f6a17078
#ifndef CSVWRITER_UNIT_TESTS_HPP_
#define CSVWRITER_UNIT_TESTS_HPP_
#include "CSVWriter.hpp"
#include "Vector/vector_test_util.hpp"
BOOST_AUTO_TEST_SUITE
(
csv_writer_test
)
BOOST_AUTO_TEST_CASE
(
csv_writer_particles
)
{
// Allocate a property vector
auto
v_prp
=
allocate_openfpm
(
16
);
// Vector of position
openfpm
::
vector
<
Point
<
3
,
float
>>
v_pos
;
// create a positional vector
for
(
size_t
i
=
0
;
i
<
v_prp
.
size
()
;
i
++
)
{
Point
<
3
,
float
>
p
({
1.0
,
2.0
,
3.0
});
v_pos
.
add
(
p
);
}
// CSVWriter test
CSVWriter
<
openfpm
::
vector
<
Point
<
3
,
float
>>
,
openfpm
::
vector
<
Point_test
<
float
>>
>
csv_writer
;
// Write the CSV
csv_writer
.
write
(
"csv_out.csv"
,
v_pos
,
v_prp
);
bool
test
=
compare
(
"csv_out.csv"
,
"csv_out_test.csv"
);
BOOST_REQUIRE_EQUAL
(
true
,
test
);
}
BOOST_AUTO_TEST_SUITE_END
()
#endif
src/GraphMLWriter.hpp
View file @
f6a17078
#ifndef GRAPHML_WRITER_HPP
#define GRAPHML_WRITER_HPP
#include "map_graph.hpp"
#include "
Graph/
map_graph.hpp"
#include <iostream>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <fstream>
#include "common.hpp"
...
...
@@ -425,7 +423,7 @@ struct edge_node
void
end_node
()
{
// close a node
e_node
+=
"</
nod
e>
\n
"
;
e_node
+=
"</
edg
e>
\n
"
;
}
//! It call the functor for each member
...
...
@@ -478,7 +476,7 @@ class GraphMLWriter
std
::
string
get_vertex_properties_list
()
{
//! vertex property output string
std
::
string
v_out
(
"
<key id=
\"
d0
\"
for=
\"
node
\"
yfiles.type=
\"
nodegraphics
\"
/>
\n
"
);
std
::
string
v_out
(
""
);
// create a vertex property functor
vertex_prop
<
Graph
>
vp
(
v_out
);
...
...
@@ -633,7 +631,7 @@ public:
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd
\"
>
\n
"
;
// Graph header to define an header
graph_header
=
"<graph id=
\"
"
+
graph_name
+
"
\"
edgedefault=
\"
directed
\"
>
\n
"
;
graph_header
=
"<graph id=
\"
"
+
graph_name
+
"
\"
edgedefault=
\"
un
directed
\"
>
\n
"
;
// Graph header end
graph_header_end
=
"</graph>
\n
"
;
...
...
src/GraphMLWriter_unit_tests.hpp
View file @
f6a17078
...
...
@@ -13,6 +13,7 @@
#include "GraphMLWriter.hpp"
#include "VTKWriter.hpp"
#include "Graph/CartesianGraphFactory.hpp"
#include "util.hpp"
BOOST_AUTO_TEST_SUITE
(
graphml_writer_test
)
...
...
@@ -81,34 +82,35 @@ BOOST_AUTO_TEST_CASE( graphml_writer_use)
g_csr2
.
addEdge
(
2
,
0
);
g_csr2
.
addEdge
(
3
,
2
);
VTKWriter
<
Graph_CSR
<
ne_cp
,
ne_cp
>>
gv2
(
g_csr2
);
// Create a graph ML
GraphMLWriter
<
Graph_CSR
<
ne_cp
,
ne_cp
>>
gv2
(
g_csr2
);
gv2
.
write
(
"test_graph2.graphml"
);
gv2
.
write
(
"test_graph2.vtk"
);
// check that match
bool
test
=
compare
(
"test_graph2.graphml"
,
"test_graph2_test.graphml"
);
BOOST_REQUIRE_EQUAL
(
true
,
test
);
//! Create a graph
CartesianGraphFactory
<
3
,
Graph_CSR
<
ne_cp
,
ne_cp
>>
g_factory
;
// Cartesian grid
std
::
vector
<
size_t
>
sz
;
sz
.
push_back
(
GS_SIZE
);
sz
.
push_back
(
GS_SIZE
);
sz
.
push_back
(
GS_SIZE
);
size_t
sz
[]
=
{
GS_SIZE
,
GS_SIZE
,
GS_SIZE
};
// Box
Box
<
3
,
float
>
box
({
0.0
,
0.0
,
0.0
},{
1.0
,
1.0
,
1.0
});
Graph_CSR
<
ne_cp
,
ne_cp
>
g_csr
=
g_factory
.
construct
<
5
,
float
,
2
,
ne_cp
::
x
,
ne_cp
::
y
,
ne_cp
::
z
>
(
sz
,
box
);
// Create a graph ML
GraphMLWriter
<
Graph_CSR
<
ne_cp
,
ne_cp
>>
gw
(
g_csr
);
gw
.
write
(
"test_graph.graphml"
);
// std::cout << std::is_class<ne_cp::attributes>;
gw
.
write
(
"test_graph.gml"
);
VTKWriter
<
Graph_CSR
<
ne_cp
,
ne_cp
>>
gv
(
g_csr
);
gv
.
write
(
"test_graph.vtk"
);
// check that match
test
=
compare
(
"test_graph.graphml"
,
"test_graph_test.graphml"
);
BOOST_REQUIRE_EQUAL
(
true
,
test
);
}
BOOST_AUTO_TEST_SUITE_END
()
...
...
src/VTKWriter.hpp
0 → 100644
View file @
f6a17078
/*
* VTKWriter.hpp
*
* Created on: Dec 15, 2014
* Author: Pietro Incardona
*/
#ifndef VTKWRITER_HPP_
#define VTKWRITER_HPP_
#include "Graph/map_graph.hpp"
#include <iostream>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <fstream>
#include "common.hpp"
/*! \brief Get the type
*
* It convert T to a string identify the corrispondent type in VTK format
*
*/
template
<
typename
T
>
std
::
string
getType
()
{
// Create a property string based on the type of the property
if
(
typeid
(
T
)
==
typeid
(
float
))
return
"float"
;
else
if
(
typeid
(
T
)
==
typeid
(
double
))
return
"double"
;
else
if
(
typeid
(
T
)
==
typeid
(
char
))
return
"char"
;
else
if
(
typeid
(
T
)
==
typeid
(
unsigned
char
))
return
"unsigned_char"
;
else
if
(
typeid
(
T
)
==
typeid
(
short
))
return
"short"
;
else
if
(
typeid
(
T
)
==
typeid
(
unsigned
short
))
return
"unsigned_short"
;
else
if
(
typeid
(
T
)
==
typeid
(
int
))
return
"int"
;
else
if
(
typeid
(
T
)
==
typeid
(
unsigned
int
))
return
"unsigned_int"
;
else
if
(
typeid
(
T
)
==
typeid
(
long
int
))
return
"long"
;
else
if
(
typeid
(
T
)
==
typeid
(
unsigned
long
int
))
return
"unsigned_long"
;
else
if
(
typeid
(
T
)
==
typeid
(
bool
))
return
"bit"
;
return
""
;
}
/*! \brief Set a conversion map between A and B
*
* Convert A to B
*
* \tparam B destination type
* \tparam A source type
*
*/
template
<
typename
A
>
class
convert
{
public:
template
<
typename
B
>
static
B
to
(
const
A
&
data
)
{
return
static_cast
<
B
>
(
data
);
}
};
/*! \brief Partial specialization when A is a string
*
*
*/
template
<
>
class
convert
<
std
::
string
>
{
public:
template
<
typename
B
>
static
B
to
(
const
std
::
string
&
data
)
{
return
atof
(
data
.
c_str
());
}
};
/*! \brief It specify the VTK output file type
*
*/
enum
file_type
{
BINARY
,
ASCII
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the vertex
* properties
*
* \tparam G graph type
* \tparam attr has the vertex attributes
*
*/
template
<
typename
G
,
bool
attr
>
struct
vtk_vertex_node
{
// Vertex spatial type information
typedef
typename
G
::
V_type
::
s_type
s_type
;
s_type
(
&
x
)[
3
];
// Vertex object container
typename
G
::
V_container
&
vo
;
// vertex node string
std
::
string
&
v_node
;
/*! \brief Constructor
*
* Create a vertex properties list
*
* \param v_node std::string that is filled with the graph properties in the GraphML format
* \param n_obj object container to access its properties for example encapc<...>
*
*/
vtk_vertex_node
(
std
::
string
&
v_node
,
typename
G
::
V_container
&
n_obj
,
s_type
(
&
x
)[
3
])
:
x
(
x
),
vo
(
n_obj
),
v_node
(
v_node
)
{
};
//! \brief Write collected information
void
write
()
{
v_node
+=
std
::
to_string
(
x
[
0
])
+
" "
+
std
::
to_string
(
x
[
1
])
+
" "
+
std
::
to_string
(
x
[
2
])
+
"
\n
"
;
}
//! It call the functor for each member
template
<
typename
T
>
void
operator
()(
T
&
t
)
{
// if the attribute name is x y or z, create a string with the value of the properties and store it
if
(
G
::
V_type
::
attributes
::
name
[
T
::
value
]
==
"x"
){
x
[
0
]
=
convert
<
typename
boost
::
remove_reference
<
decltype
(
vo
.
template
get
<
T
::
value
>())
>::
type
>::
template
to
<
s_type
>(
vo
.
template
get
<
T
::
value
>());}
else
if
(
G
::
V_type
::
attributes
::
name
[
T
::
value
]
==
"y"
){
x
[
1
]
=
convert
<
typename
boost
::
remove_reference
<
decltype
(
vo
.
template
get
<
T
::
value
>())
>::
type
>::
template
to
<
s_type
>(
vo
.
template
get
<
T
::
value
>());}
else
if
(
G
::
V_type
::
attributes
::
name
[
T
::
value
]
==
"z"
){
x
[
2
]
=
convert
<
typename
boost
::
remove_reference
<
decltype
(
vo
.
template
get
<
T
::
value
>())
>::
type
>::
template
to
<
s_type
>(
vo
.
template
get
<
T
::
value
>());}
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the vertex
* properties
*
* Specialization when we do not have vertex attributes
*
* \tparam G graph type
*
*/
template
<
typename
G
>
struct
vtk_vertex_node
<
G
,
false
>
{
// Vertex object container
typename
G
::
V_container
&
vo
;
// vertex node string
std
::
string
&
v_node
;
/*! \brief Constructor
*
* Create a vertex properties list
*
* \param v_node std::string that is filled with the graph properties in the GraphML format
* \param n_obj object container to access its properties for example encapc<...>
*
*/
vtk_vertex_node
(
std
::
string
&
v_node
,
typename
G
::
V_container
&
n_obj
)
:
vo
(
n_obj
),
v_node
(
v_node
)
{
};
//! It call the functor for each member
template
<
typename
T
>
void
operator
()(
T
&
t
)
{
v_node
+=
"0 0 0
\n
"
;
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the edge
* properties
*
*/
template
<
typename
G
>
struct
vtk_edge_node
{
// Vertex object container
typename
G
::
E_container
&
vo
;
// edge node string
std
::
string
&
e_node
;
/*! \brief Constructor
*
* Create an edge node
*
* \param e_node std::string that is filled with the graph properties in the GraphML format
* \param n_obj object container to access the object properties for example encapc<...>
* \param n_prop number of properties
*
*/
vtk_edge_node
(
std
::
string
&
e_node
,
typename
G
::
E_container
&
n_obj
)
:
vo
(
n_obj
),
e_node
(
e_node
)
{
};