OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
19template <typename T>
20void 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
50template<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
155template<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
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
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
311template<typename G>
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
411template<typename G>
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
542template <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
679public:
680
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
Graph & g
Graph to write.
std::string get_vertex_properties_list()
It get the vertex properties list.
std::string get_edge_properties_list()
It get the edge properties list.
bool write(std::string file, std::string graph_name="Graph")
It write a GraphML file from a graph.
std::string get_edge_list()
return the edge list as a string
std::string get_vertex_list()
Get the string containing the set of vertices.
GraphMLWriter(Graph &g)
this class is a functor for "for_each" algorithm
bool to_destroy
indicate if attributes_names is to destroy
int cnt
Properties counter.
std::string * attributes_names
Attribute names.
void end_node()
Close a node.
int n_attr
Number of attributes name defined into the vertex.
edge_node(std::string &e_node, typename G::E_container &n_obj)
Constructor.
void new_node(size_t v_c, size_t s, size_t d)
Create a new node.
G::E_container & vo
Vertex object container.
std::string & e_node
edge node string
void operator()(T &t)
edge_node(std::string &e_node, typename G::E_container &n_obj, typename G::E_type::attributes &a_name)
Constructor.
this class is a functor for "for_each" algorithm
edge_prop(std::string &e_prop, typename G::E_type::attributes &a_name)
Constructor.
int cnt
Properties counter.
std::string & e_prop
edge properties
int n_attr
Number of attributes name defined into the vertex.
edge_prop(std::string &e_prop)
Constructor.
void operator()(T &t)
It call the functor for each member.
std::string * attributes_names
Attribute names.
bool to_destroy
indicate if attributes_names is to destroy
this class is a functor for "for_each" algorithm
void end_node()
Close a node.
void operator()(T &t)
It call the functor for each member.
std::string & v_node
vertex node string
bool to_destroy
indicate if attributes_names is to destroy
int cnt
Properties counter.
vertex_node(std::string &v_node, const typename G::V_container &n_obj)
Constructor.
vertex_node(std::string &v_node, const typename G::V_container &n_obj, typename G::V_type::attributes &a_name)
Constructor.
void new_node(size_t v_c)
Create a new node.
int n_attr
Number of attributes name defined into the vertex.
std::string * attributes_names
Attribute names.
const G::V_container & vo
Vertex object container.
this class is a functor for "for_each" algorithm
bool to_destroy
indicate if attributes_names is to destroy
vertex_prop(std::string &v_prop)
Constructor.
std::string * attributes_names
Attribute names.
std::string & v_prop
vertex properties
int cnt
Properties counter.
vertex_prop(std::string &v_prop, typename G::V_type::attributes &a_name)
Constructor.
int n_attr
Number of attributes name defined into the vertex.
void operator()(T &t)
~vertex_prop()
destructor