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
15namespace Gudhi {
16
17namespace coxeter_triangulation {
18
19template <class T>
20std::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 */
34struct Straighten {
35 Straighten(const Eigen::VectorXd& vector) : vector_(vector) {}
36 const Eigen::VectorXd& vector_;
37};
38
39std::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
51std::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
61template <typename T>
62std::string to_string(const T& t) {
63 std::ostringstream oss;
64 oss << t;
65 return oss.str();
66}
67
68struct 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};
79std::list<MT_inserted_info> mt_seed_inserted_list, mt_inserted_list;
80
81struct 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};
86using CC_summary_list = std::list<CC_summary_info>;
87std::vector<CC_summary_list> cc_interior_summary_lists, cc_boundary_summary_lists;
88
89struct 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};
98using CC_detail_list = std::list<CC_detail_info>;
99std::vector<CC_detail_list> cc_interior_detail_lists, cc_boundary_detail_lists;
100std::vector<CC_detail_list> cc_interior_insert_detail_lists, cc_boundary_insert_detail_lists;
101
102struct 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};
111using CC_prejoin_list = std::list<CC_prejoin_info>;
112std::vector<CC_prejoin_list> cc_interior_prejoin_lists, cc_boundary_prejoin_lists;
113
114struct 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};
123bool join_switch = false;
124std::vector<CC_detail_list> cc_interior_join_detail_lists, cc_boundary_join_detail_lists;
125
126std::map<std::string, std::string> cell_vlist_map;
127std::map<std::string, std::string> simplex_vlist_map;
128
129std::ostringstream mt_ostream, vis_ostream;
130std::vector<std::ostringstream> cc_summary_ostream, cc_traces_ostream;
131
132std::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
144std::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
156void 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
252void 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
275void 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
305void 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
512void 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
528void 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