output_debug_traces_to_html.h
1 #ifndef IO_OUTPUT_DEBUG_TRACES_TO_HTML_H_
2 #define IO_OUTPUT_DEBUG_TRACES_TO_HTML_H_
3 
4 #ifdef DEBUG_TRACES // All this part of code can be skipped if DEBUG_TRACES are not ON - cmake -DDEBUG_TRACES=ON .
5 
6 #include <sstream>
7 #include <fstream>
8 #include <vector>
9 #include <list>
10 #include <string>
11 #include <regex>
12 
13 #include <Eigen/Dense>
14 
15 namespace Gudhi {
16 
17 namespace coxeter_triangulation {
18 
19 template <class T>
20 std::ostream& operator<<(std::ostream& os, const std::vector<T>& vector) {
21  os << "(";
22  if (vector.empty()) {
23  os << ")";
24  return os;
25  }
26  auto v_it = vector.begin();
27  os << *v_it++;
28  for (; v_it != vector.end(); ++v_it) os << ", " << *v_it;
29  os << ")";
30  return os;
31 }
32 
33 /* A class to make the vector horizontal instead of vertical */
34 struct Straighten {
35  Straighten(const Eigen::VectorXd& vector) : vector_(vector) {}
36  const Eigen::VectorXd& vector_;
37 };
38 
39 std::ostream& operator<<(std::ostream& os, const Straighten& str) {
40  std::size_t size = str.vector_.size();
41  os << "(" << str.vector_(0);
42  if (size == 0) {
43  os << ")";
44  return os;
45  }
46  for (std::size_t i = 1; i < size; ++i) os << ", " << str.vector_(i);
47  os << ")";
48  return os;
49 }
50 
51 std::string id_from_simplex(const std::string& simplex) {
52  std::regex r("\\s+"), r2("\\(|\\)|\\{|\\}"), r3(","), r4("\\["), r5("\\]");
53  std::string output = std::regex_replace(simplex, r, "");
54  output = std::regex_replace(output, r2, ":");
55  output = std::regex_replace(output, r3, ".");
56  output = std::regex_replace(output, r4, "_");
57  output = std::regex_replace(output, r5, "");
58  return output;
59 }
60 
61 template <typename T>
62 std::string to_string(const T& t) {
63  std::ostringstream oss;
64  oss << t;
65  return oss.str();
66 }
67 
68 struct MT_inserted_info {
69  std::string qr_face_, init_face_, qr_intersection_;
70  bool qr_success_, is_boundary_;
71  template <class Query_result, class Simplex_handle>
72  MT_inserted_info(const Query_result& qr, const Simplex_handle& face, bool is_boundary)
73  : qr_face_(to_string(face)),
74  init_face_(to_string(face)),
75  qr_intersection_(to_string(qr.intersection)),
76  qr_success_(qr.success),
77  is_boundary_(is_boundary) {}
78 };
79 std::list<MT_inserted_info> mt_seed_inserted_list, mt_inserted_list;
80 
81 struct CC_summary_info {
82  std::string face_, cell_;
83  template <class SC_pair>
84  CC_summary_info(const SC_pair& sc_pair) : face_(to_string(sc_pair.first)), cell_(to_string(sc_pair.second)) {}
85 };
86 using CC_summary_list = std::list<CC_summary_info>;
87 std::vector<CC_summary_list> cc_interior_summary_lists, cc_boundary_summary_lists;
88 
89 struct CC_detail_info {
90  enum class Result_type { self, face, coface, inserted, join_single, join_is_face };
91  std::string simplex_, trigger_, init_simplex_;
92  Result_type status_;
93  bool join_trigger_ = false;
94  std::list<std::string> faces_, post_faces_, cofaces_;
95  template <class Simplex_handle>
96  CC_detail_info(const Simplex_handle& simplex) : simplex_(to_string(simplex)) {}
97 };
98 using CC_detail_list = std::list<CC_detail_info>;
99 std::vector<CC_detail_list> cc_interior_detail_lists, cc_boundary_detail_lists;
100 std::vector<CC_detail_list> cc_interior_insert_detail_lists, cc_boundary_insert_detail_lists;
101 
102 struct CC_prejoin_info {
103  enum class Result_type { join_single, join_is_face, join_different, join_same };
104  std::string simplex_, join_;
105  std::vector<std::string> faces_;
106  std::size_t dimension_;
107  Result_type status_;
108  template <class Simplex_handle>
109  CC_prejoin_info(const Simplex_handle& simplex) : simplex_(to_string(simplex)), dimension_(simplex.dimension()) {}
110 };
111 using CC_prejoin_list = std::list<CC_prejoin_info>;
112 std::vector<CC_prejoin_list> cc_interior_prejoin_lists, cc_boundary_prejoin_lists;
113 
114 struct CC_join_info {
115  enum class Result_type { self, face, coface, inserted, join_single, join_is_face };
116  std::string simplex_, join_, trigger_;
117  Result_type status_;
118  std::list<std::string> boundary_faces_;
119  std::list<std::string> faces_, post_faces_, cofaces_;
120  template <class Simplex_handle>
121  CC_join_info(const Simplex_handle& simplex) : simplex_(to_string(simplex)) {}
122 };
123 bool join_switch = false;
124 std::vector<CC_detail_list> cc_interior_join_detail_lists, cc_boundary_join_detail_lists;
125 
126 std::map<std::string, std::string> cell_vlist_map;
127 std::map<std::string, std::string> simplex_vlist_map;
128 
129 std::ostringstream mt_ostream, vis_ostream;
130 std::vector<std::ostringstream> cc_summary_ostream, cc_traces_ostream;
131 
132 std::string simplex_format(const std::string& simplex, bool is_boundary) {
133  std::string b_simplex = (is_boundary ? "B" : "I") + simplex;
134  std::string tooltiptext;
135  auto it = simplex_vlist_map.find(b_simplex);
136  if (it == simplex_vlist_map.end())
137  tooltiptext = "deleted";
138  else
139  tooltiptext = simplex_vlist_map.at(b_simplex);
140  return (std::string) "<a class=\"" + (is_boundary ? "boundary" : "interior") + "\" href=\"#" +
141  id_from_simplex(b_simplex) + "\">" + b_simplex + "<span class=\"tooltiptext\">" + tooltiptext + "</span></a>";
142 }
143 
144 std::string simplex_format(const std::string& b_simplex) {
145  bool is_boundary = b_simplex[0] == 'B';
146  std::string tooltiptext;
147  auto it = simplex_vlist_map.find(b_simplex);
148  if (it == simplex_vlist_map.end())
149  tooltiptext = "deleted";
150  else
151  tooltiptext = simplex_vlist_map.at(b_simplex);
152  return (std::string) "<a class=\"" + (is_boundary ? "boundary" : "interior") + "\" href=\"#" +
153  id_from_simplex(b_simplex) + "\">" + b_simplex + "<span class=\"tooltiptext\">" + tooltiptext + "</span></a>";
154 }
155 
156 void write_head(std::ofstream& ofs) {
157  ofs << " <head>\n"
158  << " <title>Cell complex debug trace</title>\n"
159  << " <style>\n"
160  << " a.boundary {\n"
161  << " position: relative;\n"
162  << " display: inline-block;\n"
163  << " color: darkred;\n"
164  << " background-color: lightgreen\n"
165  << " }\n"
166  << " a.interior {\n"
167  << " position: relative;\n"
168  << " display: inline-block;\n"
169  << " color: navy;\n"
170  << " background-color: yellow\n"
171  << " }\n"
172  << " .tooltiptext {\n"
173  << " visibility: hidden;\n"
174  << " width: 120px;\n"
175  << " background-color: #555;\n"
176  << " color: #fff;\n"
177  << " text-align: center;\n"
178  << " padding: 5px 0;\n"
179  << " border-radius: 6px;\n"
180  << " position: absolute;\n"
181  << " z-index: 1;\n"
182  << " bottom: 125%;\n"
183  << " left: 50%;\n"
184  << " margin-left: -60px;\n"
185  << " opacity: 0;\n"
186  << " transition: opacity 0.3s;\n"
187  << " }\n"
188  << " .boundary .tooltiptext::after {\n"
189  << " content: \"\";\n"
190  << " position: absolute;\n"
191  << " top: 100%;\n"
192  << " left: 50%;\n"
193  << " margin-left: -5px;\n"
194  << " border-width: 5px;\n"
195  << " border-style: solid;\n"
196  << " border-color: #555 transparent transparent transparent;\n"
197  << " }\n"
198  << " .interior .tooltiptext::after {\n"
199  << " content: \"\";\n"
200  << " position: absolute;\n"
201  << " top: 100%;\n"
202  << " left: 50%;\n"
203  << " margin-left: -5px;\n"
204  << " border-width: 5px;\n"
205  << " border-style: solid;\n"
206  << " border-color: #555 transparent transparent transparent;\n"
207  << " }\n"
208  << " .boundary:hover .tooltiptext {\n"
209  << " visibility: visible;\n"
210  << " opacity: 1;\n"
211  << " }\n"
212  << " .interior:hover .tooltiptext {\n"
213  << " visibility: visible;\n"
214  << " opacity: 1;\n"
215  << " }\n"
216  << " ul.nav {\n"
217  << " list-style-type: none;\n"
218  << " margin: 0;\n"
219  << " padding: 0;\n"
220  << " overflow: auto;\n"
221  << " background-color: #333;\n"
222  << " position: fixed;\n"
223  << " height: 100%;\n"
224  << " width: 15%;\n"
225  << " }\n"
226  << " ul.nav li a {\n"
227  << " display: block;\n"
228  << " color: white;\n"
229  << " text-align: left;\n"
230  << " padding: 14px 16px;\n"
231  << " text-decoration: none;\n"
232  << " }\n"
233  << " .active {\n"
234  << " background-color: #4CAF50;\n"
235  << " }\n"
236  << " div {\n"
237  << " margin-left: 15%;\n"
238  << " padding: 1px 16px\n"
239  << " }\n"
240  << " div.navi {\n"
241  << " margin-left: 0%;\n"
242  << " padding: 0px 0px\n"
243  << " }\n"
244  << " h1 {\n"
245  << " margin-left: 15%;\n"
246  << " padding: 1px 16px\n"
247  << " }\n"
248  << " </style>\n"
249  << " </head>\n";
250 }
251 
252 void write_nav(std::ofstream& ofs) {
253  ofs << " <div class=\"navi\" style=\"margin-top:30px;background-color:#1abc9c;\">\n"
254  << " <ul class=\"nav\">\n"
255  << " <li><a href=\"#mant\">Manifold tracing</a></li>\n"
256  << " <li><a href=\"#cell\">Cell complex</a>\n"
257  << " <ul>\n";
258  for (std::size_t i = 0; i < cc_interior_summary_lists.size(); ++i) {
259  ofs << " <li><a href=\"#dim" << i << "\">Dimension " << i << "</a>\n";
260  ofs << " <ul>\n";
261  ofs << " <li><a href=\"#dim" << i << "i\">Interior</a></li>\n";
262  if (i < cc_boundary_summary_lists.size()) {
263  ofs << " <li><a href=\"#dim" << i << "b\">Boundary</a></li>\n";
264  }
265  ofs << " </ul>\n";
266  ofs << " </li>\n";
267  }
268  ofs << " </ul>\n"
269  << " </li>\n"
270  << " <li><a href=\"#visu\">Visualization details</a></li>\n"
271  << " </ul>\n"
272  << " </div>\n";
273 }
274 
275 void write_mt(std::ofstream& ofs) {
276  ofs << " <div id=\"mant\">\n";
277  ofs << " <h2> Manifold debug trace </h2>\n";
278  ofs << " <h3> Simplices inserted during the seed phase </h3>\n";
279  ofs << " <ul>\n";
280  for (const MT_inserted_info& mt_info : mt_seed_inserted_list) {
281  if (mt_info.qr_success_) {
282  ofs << " <li>Inserted " << simplex_format(mt_info.qr_face_, mt_info.is_boundary_);
283  if (mt_info.qr_face_ != mt_info.init_face_)
284  ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")";
285  ofs << " intersection point is " << mt_info.qr_intersection_ << "</li>\n";
286  } else
287  ofs << " <li>Failed to insert " << mt_info.init_face_ << "</li>\n";
288  }
289  ofs << " </ul>\n";
290  ofs << " <h3> Simplices inserted during the while loop phase </h3>\n";
291  ofs << " <ul>\n";
292  for (const MT_inserted_info& mt_info : mt_inserted_list) {
293  if (mt_info.qr_success_) {
294  ofs << " <li>Inserted " << simplex_format(mt_info.qr_face_, mt_info.is_boundary_);
295  if (mt_info.qr_face_ != mt_info.init_face_)
296  ofs << " (initially " << simplex_format(mt_info.init_face_, mt_info.is_boundary_) << ")";
297  ofs << " intersection point is " << mt_info.qr_intersection_ << "</li>\n";
298  } else
299  ofs << " <li>Failed to insert " << mt_info.init_face_ << ")</li>\n";
300  }
301  ofs << " </ul>\n";
302  ofs << " </div>\n";
303 }
304 
305 void write_cc(std::ofstream& ofs) {
306  ofs << " <div id=\"cell\">\n"
307  << " <h2> Cell complex debug trace </h2>\n"
308  << " <p>Go to:</p>\n"
309  << " <ul>\n";
310  for (std::size_t i = 0; i < cc_interior_summary_lists.size(); ++i) {
311  ofs << " <li><a href=\"#dim" << i << "\">Dimension " << i << "</a></li>\n";
312  }
313  ofs << " </ul>\n";
314  for (std::size_t i = 0; i < cc_interior_summary_lists.size(); ++i) {
315  ofs << " <h3 id=\"dim" << i << "\"> Dimension " << i << "</h3>\n";
316  ofs << " <h4 id=\"dim" << i << "i\"> Summary for interior simplices</h4>\n";
317  if (i < cc_boundary_summary_lists.size()) ofs << " <p><a href=\"#dim" << i << "b\">Go to boundary</a></p>\n";
318  ofs << " <ul>\n";
319  for (const CC_summary_info& cc_info : cc_interior_summary_lists[i])
320  ofs << " <li id = \"" << id_from_simplex("I" + cc_info.face_) << "\">"
321  << simplex_format(cc_info.face_, false) << " cell =" << cc_info.cell_ << "</li>\n";
322  ofs << " </ul>\n";
323  ofs << " <h4> Prejoin state of the interior cells of dimension " << i << "</h4>\n";
324  auto prejoin_it = cc_interior_prejoin_lists[i].begin();
325  while (prejoin_it != cc_interior_prejoin_lists[i].end()) {
326  std::size_t j = prejoin_it->dimension_;
327  ofs << " <h5>" << j << "-dimensional ambient simplices</h5>\n";
328  ofs << " <ul>\n";
329  for (; prejoin_it->dimension_ == j; ++prejoin_it) {
330  ofs << " <li>" << simplex_format(prejoin_it->simplex_, false)
331  << " join = " << simplex_format(prejoin_it->join_, false) << " boundary:\n"
332  << " <ul>\n";
333  for (const auto& face : prejoin_it->faces_) ofs << " <li>" << simplex_format(face) << "</li>";
334  ofs << " </ul>\n";
335  switch (prejoin_it->status_) {
336  case (CC_prejoin_info::Result_type::join_single):
337  ofs << " <p style=\"color: red\">Deleted " << simplex_format(prejoin_it->simplex_, false)
338  << " as it has a single face.</p>";
339  break;
340  case (CC_prejoin_info::Result_type::join_is_face):
341  ofs << " <p style=\"color: red\">Deleted " << simplex_format(prejoin_it->simplex_, false)
342  << " as its join " << simplex_format(prejoin_it->join_, false) << " is one of the faces.</p>";
343  break;
344  case (CC_prejoin_info::Result_type::join_different):
345  ofs << " <p style=\"color: magenta\">Deleted " << simplex_format(prejoin_it->simplex_, false)
346  << " and replaced by its join " << simplex_format(prejoin_it->join_, false) << ".</p>";
347  break;
348  case (CC_prejoin_info::Result_type::join_same):
349  ofs << " <p style=\"color: green\">Kept " << simplex_format(prejoin_it->simplex_, false)
350  << ".</p>";
351  }
352  ofs << " </li>";
353  }
354  ofs << " </ul>\n";
355  }
356  ofs << " <h4> Details for interior simplices</h4>\n";
357  ofs << " <ul>\n";
358  for (const CC_detail_info& cc_info : cc_interior_detail_lists[i]) {
359  if (cc_info.status_ == CC_detail_info::Result_type::join_single) {
360  ofs << " <li style=\"color:magenta\" id = \"" << id_from_simplex("I" + cc_info.simplex_)
361  << "\"> Simplex " << simplex_format(cc_info.simplex_, false) << " has only one face ("
362  << simplex_format(cc_info.trigger_, false) << ") and is deleted.";
363  continue;
364  }
365  if (cc_info.status_ == CC_detail_info::Result_type::join_single) {
366  ofs << " <li style=\"color:darkmagenta\" id = \"" << id_from_simplex("I" + cc_info.simplex_)
367  << "\"> The join of the simplex " << simplex_format(cc_info.simplex_, false) << " is one of its faces ("
368  << simplex_format(cc_info.trigger_, false) << "), hence it is is deleted.";
369  continue;
370  }
371  ofs << " <li> Insert_cell called for " << simplex_format(cc_info.simplex_, false) << "\n";
372  ofs << " <ul>\n";
373  // for (const std::string& cof: cc_info.faces_)
374  // ofs << " <li>Checking if " << simplex_format(cc_info.simplex_, false)
375  // << " is a face of " << simplex_format(cof, false) << "\n";
376  ofs << " </ul>\n";
377  ofs << " <ul>\n";
378  if (cc_info.status_ == CC_detail_info::Result_type::self) {
379  ofs << " <p><span style=\"color:blue\">The simplex " << simplex_format(cc_info.simplex_, false)
380  << " already exists in the cell complex!</span></p>\n";
381  }
382  if (cc_info.status_ == CC_detail_info::Result_type::face) {
383  ofs << " <p><span style=\"color:red\">The simplex " << simplex_format(cc_info.simplex_, false)
384  << " is a face of the simplex " << simplex_format(cc_info.trigger_, false) << "!</span><br>\n";
385  ofs << " <ul>\n";
386  for (const std::string post_face : cc_info.post_faces_)
387  ofs << " <li id = \"" << id_from_simplex("I" + post_face) << "\">"
388  << "Post deleting " << simplex_format(post_face, false) << "</li>\n";
389  ofs << " </ul>\n";
390  ofs << " </p>\n";
391  ofs << " <p id = \"" << id_from_simplex("I" + cc_info.trigger_) << "\">"
392  << "Deleting " << simplex_format(cc_info.trigger_, false) << "</p>\n";
393  }
394  // for (const std::string& fac: cc_info.cofaces_)
395  // ofs << " <li>Checking if " << simplex_format(cc_info.simplex_, false)
396  // << " is a coface of " << simplex_format(fac, false) << "\n";
397  if (cc_info.status_ == CC_detail_info::Result_type::coface) {
398  ofs << " <p><span style=\"color:darkorange\">The simplex " << simplex_format(cc_info.simplex_, false)
399  << " is a coface of the simplex " << simplex_format(cc_info.trigger_, false) << "!</span><p>\n";
400  }
401  if (cc_info.status_ == CC_detail_info::Result_type::inserted) {
402  ofs << " <p><span style=\"color:green\">Successfully inserted "
403  << simplex_format(cc_info.simplex_, false) << "!</span><p>\n";
404  }
405  ofs << " </ul>\n";
406  ofs << " </li>\n";
407  }
408  ofs << " </ul>\n";
409 
410  if (i < cc_boundary_summary_lists.size()) {
411  ofs << " <h4 id=\"dim" << i << "b\"> Summary for boundary simplices</h4>\n";
412  ofs << " <p><a href=\"#dim" << i << "i\">Go to interior</a></p>\n";
413  ofs << " <ul>\n";
414  for (const CC_summary_info& cc_info : cc_boundary_summary_lists[i])
415  ofs << " <li id = \"" << id_from_simplex("B" + cc_info.face_) << "\">"
416  << simplex_format(cc_info.face_, true) << " cell =" << cc_info.cell_ << "</li>\n";
417  ofs << " </ul>\n";
418  ofs << " <h4> Prejoin state of the boundary cells of dimension " << i << "</h4>\n";
419  auto prejoin_it = cc_boundary_prejoin_lists[i].begin();
420  while (prejoin_it != cc_boundary_prejoin_lists[i].end()) {
421  std::size_t j = prejoin_it->dimension_;
422  ofs << " <h5>" << j << "-dimensional ambient simplices</h5>\n";
423  ofs << " <ul>\n";
424  for (; prejoin_it->dimension_ == j; ++prejoin_it) {
425  ofs << " <li>" << simplex_format(prejoin_it->simplex_, true)
426  << " join = " << simplex_format(prejoin_it->join_, true) << " boundary:\n"
427  << " <ul>\n";
428  for (const auto& face : prejoin_it->faces_) ofs << " <li>" << simplex_format(face) << "</li>";
429  ofs << " </ul>\n";
430  switch (prejoin_it->status_) {
431  case (CC_prejoin_info::Result_type::join_single):
432  ofs << " <p style=\"color: red\">Deleted " << simplex_format(prejoin_it->simplex_, true)
433  << " as it has a single face.</p>";
434  break;
435  case (CC_prejoin_info::Result_type::join_is_face):
436  ofs << " <p style=\"color: red\">Deleted " << simplex_format(prejoin_it->simplex_, true)
437  << " as its join " << simplex_format(prejoin_it->join_, true) << " is one of the faces.</p>";
438  break;
439  case (CC_prejoin_info::Result_type::join_different):
440  ofs << " <p style=\"color: magenta\">Deleted " << simplex_format(prejoin_it->simplex_, true)
441  << " and replaced by its join " << simplex_format(prejoin_it->join_, true) << ".</p>";
442  break;
443  case (CC_prejoin_info::Result_type::join_same):
444  ofs << " <p style=\"color: green\">Kept " << simplex_format(prejoin_it->simplex_, true)
445  << ".</p>";
446  }
447  ofs << " </li>";
448  }
449  ofs << " </ul>\n";
450  }
451  }
452  if (i < cc_boundary_detail_lists.size()) {
453  ofs << " <h4> Details for boundary simplices</h4>\n"
454  << " <ul>\n";
455  for (const CC_detail_info& cc_info : cc_boundary_detail_lists[i]) {
456  if (cc_info.status_ == CC_detail_info::Result_type::join_single) {
457  ofs << " <li style=\"color:magenta\" id = \"" << id_from_simplex("B" + cc_info.simplex_)
458  << "\"> Simplex " << simplex_format(cc_info.simplex_, true) << " has only one face ("
459  << simplex_format(cc_info.trigger_, true) << ") and is deleted.";
460  continue;
461  }
462  if (cc_info.status_ == CC_detail_info::Result_type::join_single) {
463  ofs << " <li style=\"color:darkmagenta\" id = \"" << id_from_simplex("B" + cc_info.simplex_)
464  << "\"> The join of the simplex " << simplex_format(cc_info.simplex_, true) << " is one of its faces ("
465  << simplex_format(cc_info.trigger_, true) << "), hence it is is deleted.";
466  continue;
467  }
468  ofs << " <li> Insert_simplex called on " << simplex_format(cc_info.simplex_, true);
469  ofs << " <ul>\n";
470  // for (const std::string& cof: cc_info.faces_)
471  // ofs << " <li>Checking if " << simplex_format(cc_info.simplex_, true)
472  // << " is a face of " << simplex_format(cof, true) << "\n";
473  ofs << " </ul>\n";
474  ofs << " <ul>\n";
475  if (cc_info.status_ == CC_detail_info::Result_type::self) {
476  ofs << " <p><span style=\"color:blue\">The simplex " << simplex_format(cc_info.simplex_, true)
477  << " already exists in the cell complex!</span></p>\n";
478  }
479  if (cc_info.status_ == CC_detail_info::Result_type::face) {
480  ofs << " <p><span style=\"color:red\">The simplex " << simplex_format(cc_info.simplex_, true)
481  << " is a face of the simplex " << simplex_format(cc_info.trigger_, true) << "!</span><br>\n";
482  ofs << " <ul>\n";
483  for (const std::string post_face : cc_info.post_faces_)
484  ofs << " <li id=\"" << id_from_simplex("B" + post_face) << "\">Post deleting "
485  << simplex_format(post_face, true) << "</li>\n";
486  ofs << " </ul>\n";
487  ofs << " </p>\n";
488  ofs << " <p id=\"" << id_from_simplex(cc_info.trigger_) << "\">Deleting "
489  << simplex_format(cc_info.trigger_, true) << "</p>\n";
490  }
491  // for (const std::string& fac: cc_info.cofaces_)
492  // ofs << " <li>Checking if " << simplex_format(cc_info.simplex_, true)
493  // << " is a coface of " << simplex_format(fac, true) << "\n";
494  ofs << " </ul>\n";
495  ofs << " </li>\n";
496  if (cc_info.status_ == CC_detail_info::Result_type::coface) {
497  ofs << " <p><span style=\"color:darkorange\">The simplex "
498  << simplex_format(cc_info.simplex_, true) << " is a coface of the simplex "
499  << simplex_format(cc_info.trigger_, true) << "!</span><p>\n";
500  }
501  if (cc_info.status_ == CC_detail_info::Result_type::inserted) {
502  ofs << " <p><span style=\"color:green\">Successfully inserted "
503  << simplex_format(cc_info.simplex_, true) << "!</span><p>\n";
504  }
505  }
506  ofs << " </ul>\n";
507  }
508  }
509  ofs << " </div>\n";
510 }
511 
512 void write_visu(std::ofstream& ofs) {
513  ofs << " <div id=\"visu\">\n"
514  << " <h2> Visualization details debug trace </h2>\n";
515  // std::vector<std::map<std::string, std::string> > vs_maps(cc_interior_summary_lists.size());
516  std::map<std::string, std::string> vs_map;
517  for (const auto& sv_pair : simplex_vlist_map) vs_map.emplace(sv_pair.second, sv_pair.first);
518  ofs << " <ul>\n";
519  for (const auto& vs_pair : vs_map) {
520  std::string w_simplex = vs_pair.second.substr(1);
521  bool is_boundary = vs_pair.second[0] == 'B';
522  ofs << " <li><b>" << vs_pair.first << "</b>: " << simplex_format(w_simplex, is_boundary) << "</li>\n";
523  }
524  ofs << " </ul>\n";
525  ofs << " </div>\n";
526 }
527 
528 void write_to_html(std::string file_name) {
529  std::ofstream ofs(file_name + ".html", std::ofstream::out);
530  ofs << "<!DOCTYPE html>\n"
531  << "<html>\n";
532  write_head(ofs);
533  ofs << " <body>\n";
534  write_nav(ofs);
535  ofs << " <h1> Debug traces for " << file_name << " </h1>\n";
536  write_mt(ofs);
537  write_cc(ofs);
538  write_visu(ofs);
539  ofs << " </body>\n";
540  ofs << "</html>\n";
541 
542  ofs.close();
543 }
544 
545 } // namespace coxeter_triangulation
546 
547 } // namespace Gudhi
548 
549 #endif // DEBUG_TRACES
550 #endif // IO_OUTPUT_DEBUG_TRACES_TO_HTML_H_
std::ostream & operator<<(std::ostream &os, const Permutahedral_representation< Vertex, OrderedSetPartition > &simplex)
Print a permutahedral representation to a stream.
Definition: Permutahedral_representation.h:173
GUDHIdev  Version 3.5.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : MIT Generated on Sun May 1 2022 09:19:32 for GUDHIdev by Doxygen 1.9.1