OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
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)
91  :v_prop(v_prop),attributes_names(NULL)
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 (typeid(T) == typeid(float))
129  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"float\"/>\n";
130  else if (typeid(T) == typeid(double))
131  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"double\"/>\n";
132  else if (typeid(T) == typeid(int))
133  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"int\"/>\n";
134  else if (typeid(T) == typeid(long int))
135  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"long\"/>\n";
136  else if (typeid(T) == typeid(bool))
137  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"boolean\"/>\n";
138  else if (typeid(T) == typeid(std::string))
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  // Create a property string based on the type of the property
282  if (typeid(decltype(vo.template get<T::value>())) == typeid(float))
283  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
284  else if (typeid(decltype(vo.template get<T::value>())) == typeid(double))
285  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
286  else if (typeid(decltype(vo.template get<T::value>())) == typeid(int))
287  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
288  else if (typeid(decltype(vo.template get<T::value>())) == typeid(long int))
289  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
290  else if (typeid(decltype(vo.template get<T::value>())) == typeid(bool))
291  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
292  else if (typeid(decltype(vo.template get<T::value>())) == typeid(std::string))
293  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
294  }
295 
296  cnt++;
297  }
298 };
299 
309 template<typename G>
310 struct edge_prop
311 {
313  int cnt = 0;
314 
316  std::string & e_prop;
317 
319  std::string * attributes_names;
320 
322  int n_attr = 0;
323 
325  bool to_destroy = false;
326 
336  edge_prop(std::string & e_prop, typename G::E_type::attributes & a_name)
337  :e_prop(e_prop),attributes_names(a_name.name)
338  {
339  // Calculate the number of attributes name
340  n_attr = sizeof(a_name.name)/sizeof(std::string);
341  };
342 
350  edge_prop(std::string & e_prop)
351  :e_prop(e_prop),attributes_names(NULL)
352  {
353  // Calculate the number of attributes
354  n_attr = G::E_type::max_prop;
355 
356  // Create default property names
357  attributes_names = new std::string[G::E_type::max_prop];
358  to_destroy = true;
359 
360  // Create default property names
361  create_prop<typename G::E_type>(attributes_names);
362  };
363 
364  inline ~edge_prop()
365  {
366  if (to_destroy == true)
367  {delete [] attributes_names;}
368  }
369 
375  template<typename T>
376  void operator()(T& t)
377  {
379  if (cnt < n_attr)
380  {
381  // Create a property string based on the type of the property
382  if (typeid(T) == typeid(float))
383  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"float\"/>\n";
384  else if (typeid(T) == typeid(double))
385  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"double\"/>\n";
386  else if (typeid(T) == typeid(int))
387  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"int\"/>\n";
388  else if (typeid(T) == typeid(long int))
389  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"long\"/>\n";
390  else if (typeid(T) == typeid(bool))
391  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"boolean\"/>\n";
392  else if (typeid(T) == typeid(std::string))
393  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"string\"/>\n";
394  }
395 
396  cnt++;
397  }
398 };
399 
409 template<typename G>
410 struct edge_node
411 {
413  typename G::E_container & vo;
414 
416  int cnt = 0;
417 
419  std::string & e_node;
420 
422  std::string * attributes_names;
423 
425  int n_attr = 0;
426 
428  bool to_destroy = false;
429 
439  edge_node(std::string & e_node, typename G::E_container & n_obj, typename G::E_type::attributes & a_name)
440  :vo(n_obj),e_node(e_node),attributes_names(a_name.name)
441  {
442  // Calculate the number of attributes name
443  n_attr = sizeof(a_name.name)/sizeof(std::string);
444  };
445 
454  edge_node(std::string & e_node, typename G::E_container & n_obj)
455  :vo(n_obj),e_node(e_node),attributes_names(NULL)
456  {
457  // Calculate the number of attributes
458  n_attr = G::E_type::max_prop;
459 
460  // Create a number of default properties name
461  attributes_names = new std::string[G::E_type::max_prop];
462  to_destroy = true;
463 
464  // Create default property names
465  create_prop<typename G::E_type>(attributes_names);
466 
467  };
468 
469  inline ~edge_node()
470  {
471  if (to_destroy == true)
472  {delete [] attributes_names;}
473  }
474 
482  void new_node(size_t v_c, size_t s, size_t d)
483  {
484  // start a new node
485  e_node += "<edge id=\"e"+ std::to_string(v_c) + "\" source=\"n" + std::to_string(s) + "\" target=\"n" + std::to_string(d) + "\">\n";
486 
487  // reset the counter properties
488  cnt = 0;
489  }
490 
496  void end_node()
497  {
498  // close a node
499  e_node += "</edge>\n";
500  }
501 
507  template<typename T>
508  void operator()(T& t)
509  {
511  if (T::value < n_attr)
512  {
513  // Create a property string based on the type of the property
514  if (typeid(decltype(vo.template get<T::value>())) == typeid(float))
515  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
516  else if (typeid(decltype(vo.template get<T::value>())) == typeid(double))
517  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
518  else if (typeid(decltype(vo.template get<T::value>())) == typeid(int))
519  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
520  else if (typeid(decltype(vo.template get<T::value>())) == typeid(long int))
521  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
522  else if (typeid(decltype(vo.template get<T::value>())) == typeid(bool))
523  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
524  else if (typeid(decltype(vo.template get<T::value>())) == typeid(std::string))
525  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
526  }
527 
528  cnt++;
529  }
530 };
531 
538 template <typename Graph>
540 {
542  Graph & g;
543 
554  {
556  std::string v_out("");
557 
558  // create a vertex property functor
559  vertex_prop<Graph> vp(v_out);
560 
561  // Iterate through all the vertex and create the vertex list
562  boost::mpl::for_each_ref< typename Graph::V_type::type >(vp);
563 
564  // return the vertex properties string
565  return v_out;
566  }
567 
576  {
578  std::string e_out;
579 
580  // create a vertex property functor
581  edge_prop<Graph> ep(e_out);
582 
583  // Iterate through all the vertex and create the vertex list
584  boost::mpl::for_each_ref< typename Graph::E_type::type >(ep);
585 
586  // return the edge properties string
587  return e_out;
588  }
589 
595  std::string get_vertex_list()
596  {
597  // node counter
598  size_t nc = 0;
599 
601  std::string v_out;
602 
604  auto it = g.getVertexIterator();
605 
606  // if there is the next element
607  while (it.isNext())
608  {
609  auto v = g.vertex(it.get());
610 
611  // create a vertex list functor
612  vertex_node<Graph> vn(v_out,v);
613 
614  // create new node
615  vn.new_node(nc);
616 
617  // Iterate through all the vertex and create the vertex list
618  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,Graph::V_type::max_prop> >(vn);
619 
620  // end node
621  vn.end_node();
622 
623  // increment the iterator and counter
624  ++it;
625  nc++;
626  }
627 
628  // return the vertex list
629  return v_out;
630  }
631 
637  std::string get_edge_list()
638  {
639  // node counter
640  size_t nc = 0;
641 
643  std::string e_out;
644 
646  auto it = g.getEdgeIterator();
647 
648  // if there is the next element
649  while (it.isNext())
650  {
651  // Get the edge object
652  auto obj = g.edge(it.get());
653 
654  // create an edge list functor
655  edge_node<Graph> en(e_out,obj);
656 
657  // create a new node
658  en.new_node(nc,it.source(),it.target());
659 
660  // Iterate through all the edges and create the edge list
661  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,Graph::E_type::max_prop> >(en);
662 
663  // end new node
664  en.end_node();
665 
666  // increment the operator
667  ++it;
668  nc++;
669  }
670 
671  // return the edge list
672  return e_out;
673  }
674 
675 public:
676 
684  GraphMLWriter(Graph & g)
685  :g(g)
686  {}
687 
694  bool write(std::string file, std::string graph_name="Graph")
695  {
696  // Header for the GraphML
697  std::string gml_header;
698  // Vertex list of the GraphML
699  std::string vertex_list;
700  // End for the GraphML
701  std::string gml_header_end;
702  // Graph header
703  std::string graph_header;
704  // Graph header end
705  std::string graph_header_end;
706  // Edge list of the GraphML
707  std::string edge_list;
708  // vertex properties header
709  std::string vertex_prop_header;
710  // edge properties header
711  std::string edge_prop_header;
712 
713  // GraphML header
714  gml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
715  <graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n\
716  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\
717  xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n\
718  http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n";
719 
720  // Graph header to define an header
721  graph_header = "<graph id=\"" + graph_name + "\" edgedefault=\"undirected\">\n";
722  // Graph header end
723  graph_header_end = "</graph>\n";
724 
725  // Vertex properties header
726  vertex_prop_header = get_vertex_properties_list();
727 
728  // Edge properties header
729  edge_prop_header = get_edge_properties_list();
730 
731  // Get the node graph list
732  vertex_list = get_vertex_list();
733 
734  // Get the edge graph list
735  edge_list = get_edge_list();
736 
737  // Header end
738  gml_header_end = "</graphml>";
739 
740  // write the file
741 
742  std::ofstream ofs(file);
743 
744  // Check if the file is open
745  if (ofs.is_open() == false)
746  {std::cerr << "Error cannot creare the graphML file: " + file;}
747 
748  ofs << gml_header << graph_header << vertex_prop_header << edge_prop_header <<
749  vertex_list << edge_list << graph_header_end << gml_header_end;
750 
751  // Close the file
752 
753  ofs.close();
754 
755  // Completed succefully
756  return true;
757  }
758 };
759 
760 #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