OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
GraphMLWriter.hpp
1 #ifndef GRAPHML_WRITER_HPP
2 #define GRAPHML_WRITER_HPP
3 
4 #include "Graph/map_graph.hpp"
5 #include <iostream>
6 #include <fstream>
7 #include "util/common.hpp"
8 
9 
19 template <typename T>
20 void create_prop(std::string * str)
21 {
22  // if T has attributes defined
24  {
25  // Create properties names based on the attributes name defined
26  for (size_t i = 0 ; i < T::max_prop ; i++)
27  {
28  str[i] = std::string(T::attributes::name[i]);
29  }
30  }
31  else
32  {
33  // Create default properties name
34  for (size_t i = 0 ; i < T::max_prop ; i++)
35  {
36  str[i] = "attr" + std::to_string(i);
37  }
38  }
39 }
40 
50 template<typename G>
52 {
54  int cnt = 0;
55 
57  std::string & v_prop;
58 
60  std::string * attributes_names;
61 
63  int n_attr = 0;
64 
66  bool to_destroy = false;
67 
76  vertex_prop(std::string & v_prop, typename G::V_type::attributes & a_name)
77  :v_prop(v_prop),attributes_names(a_name.name)
78  {
79  // Calculate the number of attributes name
80  n_attr = sizeof(a_name.name)/sizeof(std::string);
81  };
82 
90  vertex_prop(std::string & v_prop)
92  {
93  // Calculate the number of attributes
94  n_attr = G::V_type::max_prop;
95 
96  // Create default property names
97  attributes_names = new std::string[G::V_type::max_prop];
98  to_destroy = true;
99 
100  // Create default property names
101  create_prop<typename G::V_type>(attributes_names);
102  };
103 
106  {
107  if (to_destroy == true)
108  {delete [] attributes_names;}
109  }
110 
116  template<typename T>
117  void operator()(T& t)
118  {
120  if (cnt < n_attr)
121  {
122  // if it is a yFile extension property name, does not process it
123  if (attributes_names[cnt] == "x" || attributes_names[cnt] == "y"
124  || attributes_names[cnt] == "z" || attributes_names[cnt] == "shape" )
125  {cnt++; return ;}
126 
127  // Create a property string based on the type of the property
128  if (std::is_same<T,float>::value)
129  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"float\"/>\n";
130  else if (std::is_same<T,double>::value)
131  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"double\"/>\n";
132  else if (std::is_same<T,int>::value)
133  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"int\"/>\n";
134  else if (std::is_same<T,long int>::value)
135  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"long\"/>\n";
136  else if (std::is_same<T,bool>::value)
137  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"boolean\"/>\n";
138  else if (std::is_same<T,std::string>::value)
139  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"string\"/>\n";
140  }
141 
142  cnt++;
143  }
144 };
145 
155 template<typename G>
157 {
159  const typename G::V_container & vo;
160 
162  int cnt = 0;
163 
165  std::string & v_node;
166 
168  std::string * attributes_names;
169 
171  int n_attr = 0;
172 
174  bool to_destroy = false;
175 
186  inline vertex_node(std::string & v_node, const typename G::V_container & n_obj, typename G::V_type::attributes & a_name)
187  :vo(n_obj),v_node(v_node),attributes_names(a_name.name)
188  {
189  // Calculate the number of attributes name
190  n_attr = sizeof(a_name.name)/sizeof(std::string);
191  };
192 
193 #ifdef DEBUG
194 
200  inline vertex_node(std::string & v_node, const typename G::V_container && n_obj, typename G::V_type::attributes & a_name)
201  :vo(n_obj),v_node(v_node),attributes_names(a_name.name)
202  {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
203 #endif
204 
213  inline vertex_node(std::string & v_node, const typename G::V_container & n_obj)
214  :vo(n_obj),v_node(v_node),attributes_names(NULL)
215  {
216  // Calculate the number of attributes
217  n_attr = G::V_type::max_prop;
218 
219  // Create default property names
220  attributes_names = new std::string[G::V_type::max_prop];
221  to_destroy = true;
222 
223  // Create default property names
224  create_prop<typename G::V_type>(attributes_names);
225  };
226 
227  inline ~vertex_node()
228  {
229  if (to_destroy == true)
230  {delete [] attributes_names;}
231  }
232 
233 #ifdef DEBUG
234 
240  inline vertex_node(std::string & v_node, const typename G::V_container && n_obj)
241  :vo(n_obj),v_node(v_node),attributes_names(NULL)
242  {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
243 #endif
244 
250  void new_node(size_t v_c)
251  {
252  // start a new node
253  v_node += "<node id=\"n"+ std::to_string(v_c) + "\">\n";
254 
255  // reset the counter properties
256  cnt = 0;
257  }
258 
264  void end_node()
265  {
266  // close a node
267  v_node += "</node>\n";
268  }
269 
275  template<typename T>
276  void operator()(T& t)
277  {
279  if (T::value < n_attr)
280  {
281  typedef typename std::remove_reference<decltype(vo.template get<T::value>())>::type type_get;
282 
283  // Create a property string based on the type of the property
284  if (std::is_same<type_get,float>::value)
285  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
286  else if (std::is_same<type_get,double>::value)
287  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
288  else if (std::is_same<type_get,int>::value )
289  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
290  else if (std::is_same<type_get,long int>::value)
291  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
292  else if (std::is_same<type_get,bool>::value)
293  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
294  else if (std::is_same<type_get,std::string>::value)
295  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
296  }
297 
298  cnt++;
299  }
300 };
301 
311 template<typename G>
312 struct edge_prop
313 {
315  int cnt = 0;
316 
318  std::string & e_prop;
319 
321  std::string * attributes_names;
322 
324  int n_attr = 0;
325 
327  bool to_destroy = false;
328 
338  edge_prop(std::string & e_prop, typename G::E_type::attributes & a_name)
339  :e_prop(e_prop),attributes_names(a_name.name)
340  {
341  // Calculate the number of attributes name
342  n_attr = sizeof(a_name.name)/sizeof(std::string);
343  };
344 
352  edge_prop(std::string & e_prop)
354  {
355  // Calculate the number of attributes
356  n_attr = G::E_type::max_prop;
357 
358  // Create default property names
359  attributes_names = new std::string[G::E_type::max_prop];
360  to_destroy = true;
361 
362  // Create default property names
363  create_prop<typename G::E_type>(attributes_names);
364  };
365 
366  inline ~edge_prop()
367  {
368  if (to_destroy == true)
369  {delete [] attributes_names;}
370  }
371 
377  template<typename T>
378  void operator()(T& t)
379  {
381  if (cnt < n_attr)
382  {
383  // Create a property string based on the type of the property
384  if (std::is_same<T,float>::value)
385  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"float\"/>\n";
386  else if (std::is_same<T,double>::value)
387  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"double\"/>\n";
388  else if (std::is_same<T,int>::value)
389  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"int\"/>\n";
390  else if (std::is_same<T,long int>::value)
391  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"long\"/>\n";
392  else if (std::is_same<T,bool>::value)
393  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"boolean\"/>\n";
394  else if (std::is_same<T,std::string>::value)
395  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"string\"/>\n";
396  }
397 
398  cnt++;
399  }
400 };
401 
411 template<typename G>
412 struct edge_node
413 {
415  typename G::E_container & vo;
416 
418  int cnt = 0;
419 
421  std::string & e_node;
422 
424  std::string * attributes_names;
425 
427  int n_attr = 0;
428 
430  bool to_destroy = false;
431 
441  edge_node(std::string & e_node, typename G::E_container & n_obj, typename G::E_type::attributes & a_name)
442  :vo(n_obj),e_node(e_node),attributes_names(a_name.name)
443  {
444  // Calculate the number of attributes name
445  n_attr = sizeof(a_name.name)/sizeof(std::string);
446  };
447 
456  edge_node(std::string & e_node, typename G::E_container & n_obj)
457  :vo(n_obj),e_node(e_node),attributes_names(NULL)
458  {
459  // Calculate the number of attributes
460  n_attr = G::E_type::max_prop;
461 
462  // Create a number of default properties name
463  attributes_names = new std::string[G::E_type::max_prop];
464  to_destroy = true;
465 
466  // Create default property names
467  create_prop<typename G::E_type>(attributes_names);
468 
469  };
470 
471  inline ~edge_node()
472  {
473  if (to_destroy == true)
474  {delete [] attributes_names;}
475  }
476 
484  void new_node(size_t v_c, size_t s, size_t d)
485  {
486  // start a new node
487  e_node += "<edge id=\"e"+ std::to_string(v_c) + "\" source=\"n" + std::to_string(s) + "\" target=\"n" + std::to_string(d) + "\">\n";
488 
489  // reset the counter properties
490  cnt = 0;
491  }
492 
498  void end_node()
499  {
500  // close a node
501  e_node += "</edge>\n";
502  }
503 
509  template<typename T>
510  void operator()(T& t)
511  {
513  if (T::value < n_attr)
514  {
515  typedef typename std::remove_reference<decltype(vo.template get<T::value>())>::type type_get;
516 
517  // Create a property string based on the type of the property
518  if (std::is_same<type_get,float>::value)
519  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
520  else if (std::is_same<type_get,double>::value)
521  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
522  else if (std::is_same<type_get,int>::value)
523  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
524  else if (std::is_same<type_get,long int>::value)
525  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
526  else if (std::is_same<type_get,bool>::value)
527  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
528  else if (std::is_same<type_get,std::string>::value)
529  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
530  }
531 
532  cnt++;
533  }
534 };
535 
542 template <typename Graph>
544 {
546  Graph & g;
547 
558  {
560  std::string v_out("");
561 
562  // create a vertex property functor
563  vertex_prop<Graph> vp(v_out);
564 
565  // Iterate through all the vertex and create the vertex list
566  boost::mpl::for_each_ref< typename Graph::V_type::type >(vp);
567 
568  // return the vertex properties string
569  return v_out;
570  }
571 
580  {
582  std::string e_out;
583 
584  // create a vertex property functor
585  edge_prop<Graph> ep(e_out);
586 
587  // Iterate through all the vertex and create the vertex list
588  boost::mpl::for_each_ref< typename Graph::E_type::type >(ep);
589 
590  // return the edge properties string
591  return e_out;
592  }
593 
599  std::string get_vertex_list()
600  {
601  // node counter
602  size_t nc = 0;
603 
605  std::string v_out;
606 
608  auto it = g.getVertexIterator();
609 
610  // if there is the next element
611  while (it.isNext())
612  {
613  auto v = g.vertex(it.get());
614 
615  // create a vertex list functor
616  vertex_node<Graph> vn(v_out,v);
617 
618  // create new node
619  vn.new_node(nc);
620 
621  // Iterate through all the vertex and create the vertex list
622  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,Graph::V_type::max_prop> >(vn);
623 
624  // end node
625  vn.end_node();
626 
627  // increment the iterator and counter
628  ++it;
629  nc++;
630  }
631 
632  // return the vertex list
633  return v_out;
634  }
635 
641  std::string get_edge_list()
642  {
643  // node counter
644  size_t nc = 0;
645 
647  std::string e_out;
648 
650  auto it = g.getEdgeIterator();
651 
652  // if there is the next element
653  while (it.isNext())
654  {
655  // Get the edge object
656  auto obj = g.edge(it.get());
657 
658  // create an edge list functor
659  edge_node<Graph> en(e_out,obj);
660 
661  // create a new node
662  en.new_node(nc,it.source(),it.target());
663 
664  // Iterate through all the edges and create the edge list
665  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,Graph::E_type::max_prop> >(en);
666 
667  // end new node
668  en.end_node();
669 
670  // increment the operator
671  ++it;
672  nc++;
673  }
674 
675  // return the edge list
676  return e_out;
677  }
678 
679 public:
680 
688  GraphMLWriter(Graph & g)
689  :g(g)
690  {}
691 
698  bool write(std::string file, std::string graph_name="Graph")
699  {
700  // Header for the GraphML
701  std::string gml_header;
702  // Vertex list of the GraphML
703  std::string vertex_list;
704  // End for the GraphML
705  std::string gml_header_end;
706  // Graph header
707  std::string graph_header;
708  // Graph header end
709  std::string graph_header_end;
710  // Edge list of the GraphML
711  std::string edge_list;
712  // vertex properties header
713  std::string vertex_prop_header;
714  // edge properties header
715  std::string edge_prop_header;
716 
717  // GraphML header
718  gml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
719  <graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n\
720  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\
721  xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n\
722  http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n";
723 
724  // Graph header to define an header
725  graph_header = "<graph id=\"" + graph_name + "\" edgedefault=\"undirected\">\n";
726  // Graph header end
727  graph_header_end = "</graph>\n";
728 
729  // Vertex properties header
730  vertex_prop_header = get_vertex_properties_list();
731 
732  // Edge properties header
733  edge_prop_header = get_edge_properties_list();
734 
735  // Get the node graph list
736  vertex_list = get_vertex_list();
737 
738  // Get the edge graph list
739  edge_list = get_edge_list();
740 
741  // Header end
742  gml_header_end = "</graphml>";
743 
744  // write the file
745 
746  std::ofstream ofs(file);
747 
748  // Check if the file is open
749  if (ofs.is_open() == false)
750  {std::cerr << "Error cannot creare the graphML file: " + file;}
751 
752  ofs << gml_header << graph_header << vertex_prop_header << edge_prop_header <<
753  vertex_list << edge_list << graph_header_end << gml_header_end;
754 
755  // Close the file
756 
757  ofs.close();
758 
759  // Completed succefully
760  return true;
761  }
762 };
763 
764 #endif
this class is a functor for "for_each" algorithm
int n_attr
Number of attributes name defined into the vertex.
std::string & v_prop
vertex properties
bool to_destroy
indicate if attributes_names is to destroy
std::string * attributes_names
Attribute names.
vertex_prop(std::string &v_prop)
Constructor.
vertex_node(std::string &v_node, const typename G::V_container &n_obj)
Constructor.
int n_attr
Number of attributes name defined into the vertex.
bool to_destroy
indicate if attributes_names is to destroy
void end_node()
Close a node.
GraphMLWriter(Graph &g)
this class is a functor for "for_each" algorithm
const G::V_container & vo
Vertex object container.
void new_node(size_t v_c, size_t s, size_t d)
Create a new node.
int cnt
Properties counter.
std::string get_vertex_list()
Get the string containing the set of vertices.
Graph & g
Graph to write.
std::string get_edge_list()
return the edge list as a string
int cnt
Properties counter.
edge_node(std::string &e_node, typename G::E_container &n_obj, typename G::E_type::attributes &a_name)
Constructor.
void new_node(size_t v_c)
Create a new node.
bool write(std::string file, std::string graph_name="Graph")
It write a GraphML file from a graph.
int cnt
Properties counter.
std::string & e_prop
edge properties
std::string & e_node
edge node string
edge_node(std::string &e_node, typename G::E_container &n_obj)
Constructor.
int n_attr
Number of attributes name defined into the vertex.
vertex_node(std::string &v_node, const typename G::V_container &n_obj, typename G::V_type::attributes &a_name)
Constructor.
int n_attr
Number of attributes name defined into the vertex.
void operator()(T &t)
std::string * attributes_names
Attribute names.
this class is a functor for "for_each" algorithm
void operator()(T &t)
std::string get_vertex_properties_list()
It get the vertex properties list.
std::string * attributes_names
Attribute names.
vertex_prop(std::string &v_prop, typename G::V_type::attributes &a_name)
Constructor.
void operator()(T &t)
It call the functor for each member.
void operator()(T &t)
It call the functor for each member.
~vertex_prop()
destructor
std::string * attributes_names
Attribute names.
edge_prop(std::string &e_prop, typename G::E_type::attributes &a_name)
Constructor.
this class is a functor for "for_each" algorithm
std::string & v_node
vertex node string
bool to_destroy
indicate if attributes_names is to destroy
G::E_container & vo
Vertex object container.
void end_node()
Close a node.
int cnt
Properties counter.
edge_prop(std::string &e_prop)
Constructor.
std::string get_edge_properties_list()
It get the edge properties list.
bool to_destroy
indicate if attributes_names is to destroy