From f6a17078fb2c0924d8c6c3f0d2a2fcc0722a2baa Mon Sep 17 00:00:00 2001
From: Pietro Incardona <incardon@mpi-cbg.de>
Date: Fri, 26 Jun 2015 18:22:20 +0200
Subject: [PATCH] Added CSV and VTK writer

---
 src/CSVWriter.hpp                | 268 +++++++++++++++
 src/CSVWriter_unit_tests.hpp     |  39 +++
 src/GraphMLWriter.hpp            |  10 +-
 src/GraphMLWriter_unit_tests.hpp |  26 +-
 src/VTKWriter.hpp                | 252 +++++++++++++++
 src/VTKWriter_graph.hpp          | 539 +++++++++++++++++++++++++++++++
 src/VTKWriter_unit_tests.hpp     | 226 +++++++++++++
 src/VTKWriter_vector_box.hpp     | 458 ++++++++++++++++++++++++++
 vtk_graph_test.vtk               | 140 ++++++++
 9 files changed, 1940 insertions(+), 18 deletions(-)
 create mode 100644 src/CSVWriter.hpp
 create mode 100644 src/CSVWriter_unit_tests.hpp
 create mode 100644 src/VTKWriter.hpp
 create mode 100644 src/VTKWriter_graph.hpp
 create mode 100644 src/VTKWriter_unit_tests.hpp
 create mode 100644 src/VTKWriter_vector_box.hpp
 create mode 100644 vtk_graph_test.vtk

diff --git a/src/CSVWriter.hpp b/src/CSVWriter.hpp
new file mode 100644
index 0000000..e272a3b
--- /dev/null
+++ b/src/CSVWriter.hpp
@@ -0,0 +1,268 @@
+/*
+ * 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_ */
+
diff --git a/src/CSVWriter_unit_tests.hpp b/src/CSVWriter_unit_tests.hpp
new file mode 100644
index 0000000..048ed85
--- /dev/null
+++ b/src/CSVWriter_unit_tests.hpp
@@ -0,0 +1,39 @@
+#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
diff --git a/src/GraphMLWriter.hpp b/src/GraphMLWriter.hpp
index 02046c9..6801c05 100644
--- a/src/GraphMLWriter.hpp
+++ b/src/GraphMLWriter.hpp
@@ -1,10 +1,8 @@
 #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 += "</node>\n";
+		e_node += "</edge>\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=\"undirected\">\n";
 		// Graph header end
 		graph_header_end =  "</graph>\n";
 
diff --git a/src/GraphMLWriter_unit_tests.hpp b/src/GraphMLWriter_unit_tests.hpp
index 1abc9be..c00a953 100644
--- a/src/GraphMLWriter_unit_tests.hpp
+++ b/src/GraphMLWriter_unit_tests.hpp
@@ -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()
diff --git a/src/VTKWriter.hpp b/src/VTKWriter.hpp
new file mode 100644
index 0000000..fa32395
--- /dev/null
+++ b/src/VTKWriter.hpp
@@ -0,0 +1,252 @@
+/*
+ * 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)
+	{
+	};
+
+	/*! \brief Create a new node
+	 *
+	 * \param vc node number
+	 *
+	 */
+	void new_node(size_t v_c, size_t s, size_t d)
+	{
+		// start a new node
+		e_node += "2 " + std::to_string(s) + " " + std::to_string(d) + "\n";
+	}
+};
+
+#define GRAPH 1
+#define VECTOR_BOX 2
+
+template <typename Graph, unsigned int imp>
+class VTKWriter
+{
+
+};
+
+#include "VTKWriter_graph.hpp"
+#include "VTKWriter_vector_box.hpp"
+
+#endif /* VTKWRITER_HPP_ */
diff --git a/src/VTKWriter_graph.hpp b/src/VTKWriter_graph.hpp
new file mode 100644
index 0000000..caa4f5d
--- /dev/null
+++ b/src/VTKWriter_graph.hpp
@@ -0,0 +1,539 @@
+/*
+ * VTKWriter_graph.hpp
+ *
+ *  Created on: May 5, 2015
+ *      Author: i-bird
+ */
+
+#ifndef VTKWRITER_GRAPH_HPP_
+#define VTKWRITER_GRAPH_HPP_
+
+/*! \brief This class specialize functions in the case the type T
+ * has or not defined attributes
+ *
+ * In C++ partial specialization of a function is not allowed so we have to
+ * encapsulate this function in a class
+ *
+ * \tparam has_attributes parameter that specialize the function in case the vertex
+ *         define or not attributes name
+ *
+ * \tparam Graph type of graph we are processing
+ * \tparam p the property we are going to write
+ *
+ */
+
+template<bool has_attributes, typename Graph, unsigned int i>
+class prop_output
+{
+public:
+
+	/*! \brief For each vertex set the value
+	 *
+	 * \tparam i vertex property to print
+	 *
+	 */
+
+	static std::string get_point_data(Graph & g)
+	{
+		//! vertex node output string
+		std::string v_out;
+
+		//! Get a vertex iterator
+		auto it = g.getVertexIterator();
+
+		// if there is the next element
+		while (it.isNext())
+		{
+			// Print the property
+			v_out += std::to_string(g.vertex(it.get()).template get<i>()) + "\n";
+
+			// increment the iterator and counter
+			++it;
+		}
+
+		return v_out;
+	}
+
+	/*! \brief Given a Graph return the point data header for a typename T
+	 *
+	 * \tparam T type to write
+	 * \param n_node number of the node
+	 *
+	 */
+
+	static std::string get_point_property_header(size_t prop)
+	{
+		//! vertex node output string
+		std::string v_out;
+
+		// Check if T is a supported format
+		// for now we support only scalar of native type
+
+		std::string type = getType<typename boost::fusion::result_of::at<typename Graph::V_type::type,boost::mpl::int_<i>>::type>();
+
+		// if the type is not supported return
+		if (type.size() == 0)
+		{return v_out;}
+
+		// Create point data properties
+		v_out += "SCALARS " + get_attributes() + " " + type + "\n";
+
+		// Default lookup table
+		v_out += "LOOKUP_TABLE default\n";
+
+		// return the vertex list
+		return v_out;
+	}
+
+	/*! \brief Get the attributes name
+	 *
+	 */
+
+	static std::string get_attributes()
+	{
+		return Graph::V_type::attributes::name[i];
+	}
+};
+
+/*! \brief This class specialize functions in the case the type T
+ * has not defined attributes
+ *
+ * In C++ partial specialization of a function is not allowed so we have to
+ * encapsulate this function in a class
+ *
+ * \tparam has_attributes parameter that specialize the function in case the vertex
+ *         define or not attributes name
+ *
+ * \tparam i id of the property we are going to write
+ *
+ */
+
+template<typename Graph, unsigned int i>
+class prop_output<false,Graph,i>
+{
+	/*! \brief For each vertex set the value
+	 *
+	 * \tparam i vertex property to print
+	 *
+	 */
+
+	static std::string get_point_data(Graph & g)
+	{
+		//! vertex node output string
+		std::string v_out;
+
+		//! Get a vertex iterator
+		auto it = g.getVertexIterator();
+
+		// if there is the next element
+		while (it.isNext())
+		{
+			// Print the property
+			v_out += std::to_string(g.vertex(it.get()).template get<i>()) + "\n";
+
+			// increment the iterator and counter
+			++it;
+		}
+
+		return v_out;
+	}
+
+	/*! \brief Given a Graph return the point data header for a typename T
+	 *
+	 * \tparam T type to write
+	 *
+	 * \param n_node number of the node
+	 * \param prop id of the property
+	 *
+	 */
+
+	static std::string get_point_property_header(size_t prop)
+	{
+		//! vertex node output string
+		std::string v_out;
+
+		// Check if T is a supported format
+		// for now we support only scalar of native type
+
+		std::string type = getType<boost::fusion::result_of::at<typename Graph::V_type::type,boost::mpl::int_<i>>>("attr" + std::to_string(prop));
+
+		// if the type is not supported return
+		if (type.size() == 0)
+		{return v_out;}
+
+		// Create point data properties
+		v_out += "SCALARS " + get_attributes() + " " + type + "\n";
+
+		// Default lookup table
+		v_out += "LOOKUP_TABLE default\n";
+
+		// return the vertex list
+		return v_out;
+	}
+
+	/*! \brief Get the attributes name
+	 *
+	 * \tparam has_prop true if T has properties name defined
+	 * \tparam T type to process
+	 *
+	 * \param i attribute to get
+	 *
+	 */
+
+	static std::string get_attributes()
+	{
+		return "attr" + std::to_string(i);
+	}
+};
+
+/*! \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 produce at output for each property
+ *
+ * \tparam Graph graph we are processing
+ *
+ * \param dim Dimensionality
+ * \param S type of grid
+ *
+ */
+
+template<typename Graph>
+struct prop_out
+{
+	// property output string
+	std::string & v_out;
+
+	// Graph that we are processing
+	Graph & g;
+
+	/*! \brief constructor
+	 *
+	 * \param v_out string to fill with the vertex properties
+	 *
+	 */
+	prop_out(std::string & v_out, Graph & g)
+	:v_out(v_out),g(g)
+	{};
+
+	//! It produce an output for each property
+    template<typename T>
+    void operator()(T& t) const
+    {
+    	// actual string size
+    	size_t sz = v_out.size();
+
+		// Produce the point properties header
+		v_out += prop_output<has_attributes<typename Graph::V_type>::value ,Graph,T::value>::get_point_property_header(t);
+
+		// If the output has changed, we have to write the properties
+		if (v_out.size() != sz)
+		{
+			std::string attr = prop_output<has_attributes<typename Graph::V_type>::value,Graph,T::value>::get_attributes();
+
+			// Produce point data
+			v_out += prop_output<has_attributes<typename Graph::V_type>::value ,Graph ,T::value>::get_point_data(g);
+		}
+    }
+};
+
+/*!
+ *
+ * It write a VTK format file in case for a graph
+ *
+ * \tparam Type of graph
+ *
+ */
+
+template <typename Graph>
+class VTKWriter<Graph,GRAPH>
+{
+	Graph & g;
+
+	/*! \brief It get the vertex properties list
+	 *
+	 * It get the vertex properties list of the vertex defined as VTK header
+	 *
+	 * \return a string that define the vertex properties in graphML format
+	 *
+	 */
+
+	std::string get_vertex_properties_list()
+	{
+		//! vertex property output string
+		std::string v_out;
+
+		// write the number of vertex
+		v_out += "VERTICES " + std::to_string(g.getNVertex()) + " " + std::to_string(g.getNVertex() * 2) + "\n";
+
+		// return the vertex properties string
+		return v_out;
+	}
+
+	/*! \brief It get the vertex properties list
+	 *
+	 * It get the vertex properties list of the vertex defined as a VTK header
+	 *
+	 * \return a string that define the vertex properties in graphML format
+	 *
+	 */
+
+	std::string get_point_properties_list()
+	{
+		//! vertex property output string
+		std::string v_out;
+
+		// write the number of vertex
+		v_out += "POINTS " + std::to_string(g.getNVertex()) + " float" + "\n";
+
+		// return the vertex properties string
+		return v_out;
+	}
+
+	/*! \brief It get the edge properties list
+	 *
+	 * It get the edge properties list of the edge defined as a GraphML header
+	 *
+	 * \return a string that define the edge properties in graphML format
+	 *
+	 */
+
+	std::string get_edge_properties_list()
+	{
+		//! vertex property output string
+		std::string e_out;
+
+		// write the number of lines
+		e_out += "LINES " + std::to_string(g.getNEdge()) + " " + std::to_string(3*g.getNEdge()) + "\n";
+
+		// return the vertex properties string
+		return e_out;
+	}
+
+	/*! \brief Create the VTK point definition
+	 *
+	 * \tparam s_type spatial type of the data
+	 * \tparam attr false x,y,z are set to 0 for each vertex
+	 *
+	 */
+
+	template <bool attr> std::string get_point_list()
+	{
+		//! VTK spatial information
+		typename Graph::V_type::s_type x[3] = {0,0,0};
+
+		//! vertex node output string
+		std::string v_out;
+
+		//! Get a vertex iterator
+		auto it = g.getVertexIterator();
+
+		// if there is the next element
+		while (it.isNext())
+		{
+			// Get vtk vertex node
+			auto obj = g.vertex(it.get());
+
+			// create a vertex list functor
+			vtk_vertex_node<Graph,attr> vn(v_out,obj,x);
+
+			// Iterate through all the vertex and create the vertex list
+			boost::mpl::for_each< boost::mpl::range_c<int,0,Graph::V_type::max_prop-1> >(vn);
+
+			// write the node string
+			vn.write();
+
+			// increment the iterator and counter
+			++it;
+		}
+
+		// return the vertex list
+		return v_out;
+	}
+
+	/*! \brief Create the VTK vertex definition
+	 *
+	 * \tparam s_type spatial type of the data
+	 * \tparam attr false x,y,z are set to 0 for each vertex
+	 *
+	 */
+
+	std::string get_vertex_list()
+	{
+		//! vertex node output string
+		std::string v_out;
+
+		//! For each point create a vertex
+		for (size_t i = 0 ; i < g.getNVertex() ; i++)
+		{
+			v_out += "1 " + std::to_string(i) + "\n";
+		}
+
+		// return the vertex list
+		return v_out;
+	}
+
+	/*! \brief Get the point data header
+	 *
+	 * \return a string with the point data header for VTK format
+	 *
+	 */
+
+	std::string get_point_data_header()
+	{
+		std::string v_out;
+
+		v_out += "POINT_DATA " + std::to_string(g.getNVertex()) + "\n";
+
+		return v_out;
+	}
+
+	/*! \brief Return the edge list
+	 *
+	 * \return the edge list
+	 *
+	 */
+
+	std::string get_edge_list()
+	{
+		//! edge node output string
+		std::string e_out;
+
+		//! Get an edge iterator
+		auto it = g.getEdgeIterator();
+
+		// if there is the next element
+		while (it.isNext())
+		{
+			// create an edge list functor
+//			edge_node<Graph> en(e_out,g.edge(it.get()));
+
+			e_out += "2 " + std::to_string(it.source()) + " " + std::to_string(it.target()) + "\n";
+
+			// increment the operator
+			++it;
+		}
+
+		// return the edge list
+		return e_out;
+	}
+
+public:
+
+	/*!
+	 *
+	 * VTKWriter constructor, it take a graph and write a GraphML format
+	 *
+	 * \param g Graph to write
+	 *
+	 */
+	VTKWriter(Graph & g)
+	:g(g)
+	{}
+
+	/*! \brief It write a VTK file from a graph
+	 *
+	 * \tparam prp_out which properties to output [default = -1 (all)]
+	 *
+	 * \param file path where to write
+	 * \param name of the graph
+	 * \param file_type specify if it is a VTK BINARY or ASCII file [default = ASCII]
+	 *
+	 */
+
+	template<int prp = -1> bool write(std::string file, std::string graph_name="Graph", file_type ft = file_type::ASCII)
+	{
+		// Check that the Vertex type define x y and z attributes
+
+		if (has_attributes<typename Graph::V_type>::value == false)
+		{
+			std::cerr << "Error writing a graph: Vertex must has defines x,y,z properties" << "\n";
+			return false;
+		}
+
+		// Header for the vtk
+		std::string vtk_header;
+		// Point list of the VTK
+		std::string point_list;
+		// Vertex list of the VTK
+		std::string vertex_list;
+		// Graph header
+		std::string vtk_binary_or_ascii;
+		// Edge list of the GraphML
+		std::string edge_list;
+		// vertex properties header
+		std::string point_prop_header;
+		// edge properties header
+		std::string vertex_prop_header;
+		// edge properties header
+		std::string edge_prop_header;
+		// Data point header
+		std::string point_data_header;
+		// Data point
+		std::string point_data;
+
+		// VTK header
+		vtk_header = "# vtk DataFile Version 3.0\n"
+				     + graph_name + "\n";
+
+		// Choose if binary or ASCII
+		if (ft == file_type::ASCII)
+		{vtk_header += "ASCII\n";}
+		else
+		{vtk_header += "BINARY\n";}
+
+		// Data type for graph is DATASET POLYDATA
+		vtk_header += "DATASET POLYDATA\n";
+
+		// point properties header
+		point_prop_header = get_point_properties_list();
+
+		// Get point list
+		point_list = get_point_list<has_attributes<typename Graph::V_type>::value>();
+
+		// vertex properties header
+		vertex_prop_header = get_vertex_properties_list();
+
+		// Get vertex list
+		vertex_list = get_vertex_list();
+
+		// Edge properties header
+		edge_prop_header = get_edge_properties_list();
+
+		// Get the edge graph list
+		edge_list = get_edge_list();
+
+		// Get the point data header
+		point_data_header = get_point_data_header();
+
+		// For each property in the vertex type produce a point data
+
+		prop_out<Graph> pp(point_data, g);
+
+		if (prp == -1)
+			boost::mpl::for_each< boost::mpl::range_c<int,0, Graph::V_type::max_prop> >(pp);
+		else
+			boost::mpl::for_each< boost::mpl::range_c<int,prp, prp> >(pp);
+
+		// write the file
+		std::ofstream ofs(file);
+
+		// Check if the file is open
+		if (ofs.is_open() == false)
+		{std::cerr << "Error cannot create the VTK file: " + file;}
+
+		ofs << vtk_header << point_prop_header << point_list <<
+				vertex_prop_header << vertex_list << edge_prop_header << edge_list << point_data_header << point_data;
+
+		// Close the file
+
+		ofs.close();
+
+		// Completed succefully
+		return true;
+	}
+};
+
+
+#endif /* VTKWRITER_GRAPH_HPP_ */
diff --git a/src/VTKWriter_unit_tests.hpp b/src/VTKWriter_unit_tests.hpp
new file mode 100644
index 0000000..eb7ed81
--- /dev/null
+++ b/src/VTKWriter_unit_tests.hpp
@@ -0,0 +1,226 @@
+/*
+ * VTKWriter_unit_tests.hpp
+ *
+ *  Created on: May 6, 2015
+ *      Author: Pietro Incardona
+ */
+
+#ifndef VTKWRITER_UNIT_TESTS_HPP_
+#define VTKWRITER_UNIT_TESTS_HPP_
+
+BOOST_AUTO_TEST_SUITE( vtk_writer_test )
+
+/* \brief Sub-domain vertex graph node
+ *
+ */
+
+struct vertex
+{
+	//! The node contain 3 unsigned long integer for communication computation memory and id
+	typedef boost::fusion::vector<float,float,float,float,size_t,double,unsigned char,long int> type;
+
+	typedef typename memory_traits_inte<type>::type memory_int;
+	typedef typename memory_traits_lin<type>::type memory_lin;
+
+	//! type of the positional field
+	typedef float s_type;
+
+	//! Attributes name
+	struct attributes
+	{
+		static const std::string name[];
+	};
+
+	//! The data
+	type data;
+
+	//! computation property id in boost::fusion::vector
+	static const unsigned int x = 0;
+	//! computation property id in boost::fusion::vector
+	static const unsigned int y = 1;
+	//! memory property id in boost::fusion::vector
+	static const unsigned int z = 2;
+	//! computation property id in boost::fusion::vector
+	static const unsigned int prp1 = 3;
+	//! computation property id in boost::fusion::vector
+	static const unsigned int prp2 = 4;
+	//! memory property id in boost::fusion::vector
+	static const unsigned int prp3 = 5;
+	//! memory property id in boost::fusion::vector
+	static const unsigned int prp4 = 6;
+	//! memory property sub_id in boost::fusion::vector
+	static const unsigned int prp5 = 7;
+
+	//! total number of properties boost::fusion::vector
+	static const unsigned int max_prop = 8;
+
+	/*!
+	 * Default constructor
+	 *
+	 */
+	vertex()
+	{
+
+	}
+
+	/*! \brief Initialize the VTKVertex
+	 *
+	 * \param
+	 *
+	 */
+	vertex(float x, float y, float z)
+	{
+		boost::fusion::at_c<vertex::x>(data) = x;
+		boost::fusion::at_c<vertex::y>(data) = y;
+		boost::fusion::at_c<vertex::z>(data) = z;
+	}
+};
+
+// use the vertex like the edge
+typedef vertex edge;
+
+const std::string vertex::attributes::name[] = {"x","y","z","prp1","prp2","prp3","prp4","prp5"};
+
+BOOST_AUTO_TEST_CASE( vtk_writer_use_graph)
+{
+	// Create some graphs and output them
+
+	std::cout << "Graph unit test start" << "\n";
+
+	// Graph
+
+	Graph_CSR<vertex,edge> gr;
+
+	// Create a cube graph
+
+	gr.addVertex(vertex(0.0,0.0,0.0));
+	gr.addVertex(vertex(0.0,0.0,1.0));
+	gr.addVertex(vertex(0.0,1.0,0.0));
+	gr.addVertex(vertex(0.0,1.0,1.0));
+	gr.addVertex(vertex(1.0,0.0,0.0));
+	gr.addVertex(vertex(1.0,0.0,1.0));
+	gr.addVertex(vertex(1.0,1.0,0.0));
+	gr.addVertex(vertex(1.0,1.0,1.0));
+
+	gr.addEdge(0,6);
+	gr.addEdge(6,4);
+	gr.addEdge(4,0);
+
+	gr.addEdge(0,2);
+	gr.addEdge(2,6);
+	gr.addEdge(6,0);
+
+	gr.addEdge(0,3);
+	gr.addEdge(3,2);
+	gr.addEdge(2,0);
+
+	gr.addEdge(0,1);
+	gr.addEdge(1,3);
+	gr.addEdge(3,0);
+
+	gr.addEdge(2,7);
+	gr.addEdge(7,6);
+	gr.addEdge(6,2);
+
+	gr.addEdge(2,3);
+	gr.addEdge(3,7);
+	gr.addEdge(7,2);
+
+	gr.addEdge(4,6);
+	gr.addEdge(6,7);
+	gr.addEdge(7,4);
+
+	gr.addEdge(4,7);
+	gr.addEdge(7,5);
+	gr.addEdge(5,4);
+
+	gr.addEdge(0,4);
+	gr.addEdge(4,5);
+	gr.addEdge(5,0);
+
+	gr.addEdge(0,5);
+	gr.addEdge(5,1);
+	gr.addEdge(1,0);
+
+	gr.addEdge(1,5);
+	gr.addEdge(5,7);
+	gr.addEdge(7,1);
+
+	gr.addEdge(1,7);
+	gr.addEdge(7,3);
+	gr.addEdge(3,1);
+
+	// Write the VTK file
+
+	VTKWriter<Graph_CSR<vertex,edge>,GRAPH> vtk(gr);
+	vtk.write("vtk_graph.vtk");
+
+	// check that match
+
+	bool test = compare("vtk_graph.vtk","vtk_graph_test.vtk");
+	BOOST_REQUIRE_EQUAL(true,test);
+}
+
+BOOST_AUTO_TEST_CASE( vtk_writer_use_vector_box)
+{
+	// Create a vector of boxes
+	openfpm::vector<Box<2,float>> vb;
+
+	vb.add(Box<2,float>({0.2,0.2},{1.0,0.5}));
+	vb.add(Box<2,float>({0.0,0.0},{0.2,0.2}));
+	vb.add(Box<2,float>({0.2,0.0},{0.5,0.2}));
+	vb.add(Box<2,float>({0.5,0.0},{1.0,0.2}));
+	vb.add(Box<2,float>({0.0,0.2},{0.2,0.5}));
+	vb.add(Box<2,float>({0.0,0.5},{1.0,1.0}));
+
+	// Create a writer and write
+	VTKWriter<openfpm::vector<Box<2,float>>,VECTOR_BOX> vtk_box;
+	vtk_box.add(vb);
+	vtk_box.write("vtk_box.vtk");
+
+	// Check that match
+	bool test = compare("vtk_box.vtk","vtk_box_test.vtk");
+	BOOST_REQUIRE_EQUAL(test,true);
+
+	// Create a vector of boxes
+	openfpm::vector<Box<3,float>> vb2;
+
+	vb2.add(Box<3,float>({0.2,0.2,0.0},{1.0,0.5,0.5}));
+	vb2.add(Box<3,float>({0.0,0.0,0.0},{0.2,0.2,0.5}));
+	vb2.add(Box<3,float>({0.2,0.0,0.0},{0.5,0.2,0.5}));
+	vb2.add(Box<3,float>({0.5,0.0,0.0},{1.0,0.2,0.5}));
+	vb2.add(Box<3,float>({0.0,0.2,0.0},{0.2,0.5,0.5}));
+	vb2.add(Box<3,float>({0.0,0.5,0.0},{1.0,1.0,0.5}));
+
+	// Create a writer and write
+	VTKWriter<openfpm::vector<Box<3,float>>,VECTOR_BOX> vtk_box2;
+	vtk_box2.add(vb2);
+	vtk_box2.write("vtk_box_3D.vtk");
+
+	// Check that match
+	test = compare("vtk_box_3D.vtk","vtk_box_3D_test.vtk");
+	BOOST_REQUIRE_EQUAL(test,true);
+
+	// Create a vector of boxes
+	openfpm::vector<Box<3,float>> vb3;
+	vb3.add(Box<3,float>({0.2,0.2,0.5},{1.0,0.5,1.0}));
+	vb3.add(Box<3,float>({0.0,0.0,0.5},{0.2,0.2,1.0}));
+	vb3.add(Box<3,float>({0.2,0.0,0.5},{0.5,0.2,1.0}));
+	vb3.add(Box<3,float>({0.5,0.0,0.5},{1.0,0.2,1.0}));
+	vb3.add(Box<3,float>({0.0,0.2,0.5},{0.2,0.5,1.0}));
+	vb3.add(Box<3,float>({0.0,0.5,0.5},{1.0,1.0,1.0}));
+
+	// Create a writer and write
+	VTKWriter<openfpm::vector<Box<3,float>>,VECTOR_BOX> vtk_box3;
+	vtk_box3.add(vb2);
+	vtk_box3.add(vb3);
+	vtk_box3.write("vtk_box_3D_2.vtk");
+
+	// Check that match
+	test = compare("vtk_box_3D_2.vtk","vtk_box_3D_2_test.vtk");
+	BOOST_REQUIRE_EQUAL(test,true);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+#endif /* VTKWRITER_UNIT_TESTS_HPP_ */
diff --git a/src/VTKWriter_vector_box.hpp b/src/VTKWriter_vector_box.hpp
new file mode 100644
index 0000000..b217982
--- /dev/null
+++ b/src/VTKWriter_vector_box.hpp
@@ -0,0 +1,458 @@
+/*
+ * VTKWriter_vector_box.hpp
+ *
+ *  Created on: May 5, 2015
+ *      Author: i-bird
+ */
+
+#ifndef VTKWRITER_VECTOR_BOX_HPP_
+#define VTKWRITER_VECTOR_BOX_HPP_
+
+#include <boost/math/special_functions/pow.hpp>
+#include "Space/Shape/HyperCube.hpp"
+#include <random>
+#include "util.hpp"
+
+template <typename vector>
+class v_box
+{
+public:
+
+	v_box(const vector & v)
+	:v(v)
+	{}
+
+	std::string dataset;
+	const vector & v;
+};
+
+/*!
+ *
+ * From a basic structure it write a VTK format file in case of a vector of Boxes
+ *
+ * \tparam vector type
+ *
+ */
+
+template <typename vector>
+class VTKWriter<vector,VECTOR_BOX>
+{
+	openfpm::vector<v_box<vector>> v;
+
+	/*! \brief It get the vertex properties list
+	 *
+	 * It get the vertex properties list of the vertex defined as a VTK header
+	 *
+	 * \return a string that define the vertex properties in graphML format
+	 *
+	 */
+
+	std::string get_point_properties_list()
+	{
+		//! vertex property output string
+		std::string v_out;
+
+		// number of points
+		size_t np = 0;
+
+		// count the number of points
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			np += v.get(i).v.size() * boost::math::pow<vector::value_type::dims>(2);
+		}
+
+		// write the number of vertex
+		v_out += "POINTS " + std::to_string(np) + " float" + "\n";
+
+		// return the vertex properties string
+		return v_out;
+	}
+
+	/*! \brief It get the edge properties list
+	 *
+	 * It get the edge properties list of the edge defined as a GraphML header
+	 *
+	 * \return a string that define the edge properties in graphML format
+	 *
+	 */
+
+	std::string get_cell_properties_list()
+	{
+		//! vertex property output string
+		std::string e_out;
+
+		//! number of cells and box
+		size_t nc = 0;
+		size_t nb = 0;
+
+		// count the number of cells
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			nb += v.get(i).v.size();
+		}
+
+		nc = nb * (boost::math::pow<vector::value_type::dims>(2) + 1);
+
+		// write the number of lines
+		e_out += "CELLS " + std::to_string(nb) + " " + std::to_string(nc) + "\n";
+
+		// return the vertex properties string
+		return e_out;
+	}
+
+	/*! \brief Create the VTK point definition
+	 *
+	 * \tparam s_type spatial type of the data
+	 * \tparam attr false x,y,z are set to 0 for each vertex
+	 *
+	 */
+
+	std::string get_point_list()
+	{
+		//! vertex node output string
+		std::string v_out;
+
+		//! for each vertex dataset
+
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			auto it = v.get(i).v.getIterator();
+
+			// if there is the next element
+			while (it.isNext())
+			{
+				// Get the box
+				auto box = v.get(i).v.get(it.get());
+
+				// Create an hyper-cube and get the vertex combinations
+
+				HyperCube<vector::value_type::dims> hyp;
+				std::vector<comb<vector::value_type::dims>> comb =  hyp.getCombinations_R(0);
+
+				// Create the box vertex points
+
+				for (size_t j = 0; j < comb.size() ; j++)
+				{
+					Point<vector::value_type::dims,float> p;
+
+					for (size_t k = 0 ; k < 3 ; k++)
+					{
+						if (k < vector::value_type::dims)
+						{
+							if (comb[j].value(k) < 0)
+								v_out += std::to_string(box.template get<vector::value_type::p1>()[k]) + " ";
+							else
+								v_out += std::to_string(box.template get<vector::value_type::p2>()[k]) + " ";
+						}
+						else
+						{
+							v_out += "0.0";
+						}
+					}
+					v_out += "\n";
+				}
+
+				// increment the iterator and counter
+				++it;
+			}
+		}
+		// return the vertex list
+		return v_out;
+	}
+
+	/*! \brief Create the VTK vertex definition
+	 *
+	 * \tparam s_type spatial type of the data
+	 * \tparam attr false x,y,z are set to 0 for each vertex
+	 *
+	 */
+
+	std::string get_cell_list()
+	{
+		// base
+		size_t base = 0;
+
+		//! vertex node output string
+		std::string v_out;
+
+		//! for each vector in the dataset
+
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			auto it = v.get(i).v.getIterator();
+
+			// for each box
+			while (it.isNext())
+			{
+				// Output the box vertex id
+				v_out += std::to_string((size_t)boost::math::pow<vector::value_type::dims>(2)) + " ";
+				for (size_t k = 0 ; k < boost::math::pow<vector::value_type::dims>(2) ; k++)
+				{
+					v_out += " " + std::to_string(base+k);
+				}
+				base += boost::math::pow<vector::value_type::dims>(2);
+				v_out += "\n";
+
+				++it;
+			}
+			v_out += "\n";
+		}
+
+		// return the vertex list
+		return v_out;
+	}
+
+	/*! \brief Get the point data header
+	 *
+	 * \return a string with the point data header for VTK format
+	 *
+	 */
+
+	std::string get_point_data_header()
+	{
+		std::string v_out;
+
+		// number of points
+		size_t np = 0;
+
+		// count the number of points
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			np += v.get(i).v.size() * boost::math::pow<vector::value_type::dims>(2);
+		}
+
+
+		v_out += "POINT_DATA " + std::to_string(np) + "\n";
+
+		return v_out;
+	}
+
+	std::string get_cell_types_header()
+	{
+		//! vertex property output string
+		std::string e_out;
+
+		//! number of cells and box
+		size_t nb = 0;
+
+		// count the number of cells
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			nb += v.get(i).v.size();
+		}
+
+		// write the number of lines
+		e_out += "CELL_TYPES " + std::to_string(nb) + "\n";
+
+		// return the vertex properties string
+		return e_out;
+	}
+
+	std::string get_cell_types_list()
+	{
+		// Cell id
+		size_t cell_id;
+		if (vector::value_type::dims == 2)
+			cell_id = 8;
+		else
+			cell_id = 11;
+
+		//! vertex node output string
+		std::string v_out;
+
+		//! for each vector in the dataset
+
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			auto it = v.get(i).v.getIterator();
+
+			// for each box
+			while (it.isNext())
+			{
+				v_out += std::to_string(cell_id) + "\n";
+
+				++it;
+			}
+		}
+
+		// return the vertex list
+		return v_out;
+	}
+
+
+	std::string get_cell_data_header()
+	{
+		//! vertex property output string
+		std::string e_out;
+
+		//! number of cells and box
+		size_t nb = 0;
+
+		// count the number of cells
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			nb += v.get(i).v.size();
+		}
+
+		// write the number of lines
+		e_out += "CELL_DATA " + std::to_string(nb) + "\n";
+		e_out += "COLOR_SCALARS data 4\n";
+
+		// return the vertex properties string
+		return e_out;
+	}
+
+	std::string get_cell_data_list()
+	{
+		// random engine
+		std::default_random_engine generator;
+		std::uniform_real_distribution<float> d(0.0,1.0);
+
+		//! vertex node output string
+		std::string v_out;
+
+		size_t col_group = 0;
+
+		//! for each vector in the dataset
+		for (size_t i = 0 ; i < v.size() ; i++)
+		{
+			auto it = v.get(i).v.getIterator();
+
+			// for each box
+			while (it.isNext())
+			{
+				// write a color
+				v_out += getColor(col_group,d,generator).toString() + " 1.0" + "\n";
+
+				++it;
+			}
+			v_out += "\n";
+			col_group++;
+		}
+
+		// return the vertex list
+		return v_out;
+	}
+
+public:
+
+	/*!
+	 *
+	 * VTKWriter constructor
+	 *
+	 */
+	VTKWriter()
+	{}
+
+	/*! \brief Add box vector dataset
+	 *
+	 * \param v vector to add
+	 *
+	 */
+	void add(const vector & vc)
+	{
+		v_box<vector> t(vc);
+
+		v.add(t);
+	}
+
+	/*! \brief It write a VTK file from a graph
+	 *
+	 * \tparam prp_out which properties to output [default = -1 (all)]
+	 *
+	 * \param file path where to write
+	 * \param name of the graph
+	 * \param file_type specify if it is a VTK BINARY or ASCII file [default = ASCII]
+	 *
+	 */
+
+	template<int prp = -1> bool write(std::string file, std::string graph_name="Graph", file_type ft = file_type::ASCII)
+	{
+		// Header for the vtk
+		std::string vtk_header;
+		// Point list of the VTK
+		std::string point_list;
+		// Vertex list of the VTK
+		std::string cell_list;
+		// Graph header
+		std::string vtk_binary_or_ascii;
+		// Edge list of the GraphML
+		std::string edge_list;
+		// vertex properties header
+		std::string point_prop_header;
+		// edge properties header
+		std::string cell_prop_header;
+		// edge properties header
+		std::string edge_prop_header;
+		// Data point header
+		std::string point_data_header;
+		// Data point
+		std::string point_data;
+		// Cell type header
+		std::string cell_types_header;
+		// Cell type list
+		std::string cell_types_list;
+		// Cell data header
+		std::string cell_data_header;
+		// Cell data list
+		std::string cell_data_list;
+
+		// VTK header
+		vtk_header = "# vtk DataFile Version 3.0\n"
+				     + graph_name + "\n";
+
+		// Choose if binary or ASCII
+		if (ft == file_type::ASCII)
+		{vtk_header += "ASCII\n";}
+		else
+		{vtk_header += "BINARY\n";}
+
+		// Data type for graph is DATASET POLYDATA
+		vtk_header += "DATASET UNSTRUCTURED_GRID\n";
+
+		// point properties header
+		point_prop_header = get_point_properties_list();
+
+		// Get point list
+		point_list = get_point_list();
+
+		// cell properties header
+		cell_prop_header = get_cell_properties_list();
+
+		// Get cell list
+		cell_list = get_cell_list();
+
+		// Get cell types
+		cell_types_header = get_cell_types_header();
+
+		// Get cell type list
+		cell_types_list = get_cell_types_list();
+
+		// Get cell data header
+		cell_data_header = get_cell_data_header();
+
+		// Get cell data list
+		cell_data_list = get_cell_data_list();
+
+		// write the file
+		std::ofstream ofs(file);
+
+		// Check if the file is open
+		if (ofs.is_open() == false)
+		{std::cerr << "Error cannot create the VTK file: " + file;}
+
+		ofs << vtk_header << point_prop_header << point_list <<
+				cell_prop_header << cell_list << cell_types_header << cell_types_list << cell_data_header << cell_data_list;
+
+		// Close the file
+
+		ofs.close();
+
+		// Completed succefully
+		return true;
+	}
+};
+
+
+
+#endif /* VTKWRITER_VECTOR_BOX_HPP_ */
diff --git a/vtk_graph_test.vtk b/vtk_graph_test.vtk
new file mode 100644
index 0000000..4d9aa58
--- /dev/null
+++ b/vtk_graph_test.vtk
@@ -0,0 +1,140 @@
+# vtk DataFile Version 3.0
+Graph
+ASCII
+DATASET POLYDATA
+POINTS 8 float
+0.000000 0.000000 0.000000
+0.000000 0.000000 1.000000
+0.000000 1.000000 0.000000
+0.000000 1.000000 1.000000
+1.000000 0.000000 0.000000
+1.000000 0.000000 1.000000
+1.000000 1.000000 0.000000
+1.000000 1.000000 1.000000
+VERTICES 8 16
+1 0
+1 1
+1 2
+1 3
+1 4
+1 5
+1 6
+1 7
+LINES 36 108
+2 0 6
+2 0 2
+2 0 3
+2 0 1
+2 0 4
+2 0 5
+2 1 3
+2 1 0
+2 1 5
+2 1 7
+2 2 6
+2 2 0
+2 2 7
+2 2 3
+2 3 2
+2 3 0
+2 3 7
+2 3 1
+2 4 0
+2 4 6
+2 4 7
+2 4 5
+2 5 4
+2 5 0
+2 5 1
+2 5 7
+2 6 4
+2 6 0
+2 6 2
+2 6 7
+2 7 6
+2 7 2
+2 7 4
+2 7 5
+2 7 1
+2 7 3
+POINT_DATA 8
+SCALARS x float
+LOOKUP_TABLE default
+0.000000
+0.000000
+0.000000
+0.000000
+1.000000
+1.000000
+1.000000
+1.000000
+SCALARS y float
+LOOKUP_TABLE default
+0.000000
+0.000000
+1.000000
+1.000000
+0.000000
+0.000000
+1.000000
+1.000000
+SCALARS z float
+LOOKUP_TABLE default
+0.000000
+1.000000
+0.000000
+1.000000
+0.000000
+1.000000
+0.000000
+1.000000
+SCALARS prp1 float
+LOOKUP_TABLE default
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+SCALARS prp2 unsigned_long
+LOOKUP_TABLE default
+0
+0
+0
+0
+0
+0
+0
+0
+SCALARS prp3 double
+LOOKUP_TABLE default
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+SCALARS prp4 unsigned_char
+LOOKUP_TABLE default
+0
+0
+0
+0
+0
+0
+0
+0
+SCALARS prp5 long
+LOOKUP_TABLE default
+0
+0
+0
+0
+0
+0
+0
+0
-- 
GitLab