TTK
Loading...
Searching...
No Matches
ContourTreeAlignment.h
Go to the documentation of this file.
1
37
38#pragma once
39
40// base code includes
41#include <CTA_contourtree.h>
42#include <Debug.h>
43
44#include <algorithm>
45#include <memory>
46#include <random>
47
48namespace ttk {
49
50 namespace cta {
51
53 // enum Type_Match { matchNodes, matchArcs };
55
75 std::shared_ptr<ttk::cta::AlignmentTree> child1;
76 std::shared_ptr<ttk::cta::AlignmentTree> child2;
77 std::shared_ptr<ttk::cta::BinaryTree> node1;
78 std::shared_ptr<ttk::cta::BinaryTree> node2;
79 int size;
80 int height;
81 // int freq;
82 };
83
84 struct AlignmentEdge;
85
109
111 int freq;
114
115 std::vector<std::shared_ptr<ttk::cta::AlignmentEdge>> edgeList;
116
117 std::vector<std::pair<int, int>> nodeRefs;
118 };
119
144
145 std::weak_ptr<ttk::cta::AlignmentNode> node1;
146 std::weak_ptr<ttk::cta::AlignmentNode> node2;
148 float area;
149 float volume;
150 std::vector<int> region;
151 int freq;
152
153 std::vector<std::pair<int, int>> arcRefs;
154 };
155
156 } // namespace cta
157
158} // namespace ttk
159
160namespace ttk {
161
162 class ContourTreeAlignment : virtual public Debug {
163
164 public:
167 this->setDebugMsgPrefix("ContourTreeAlignment");
168 }
169
172 contourtrees.clear();
173 nodes.clear();
174 arcs.clear();
175 }
176
180 void setArcMatchMode(int mode) {
181 arcMatchMode = static_cast<ttk::cta::Mode_ArcMatch>(mode);
182 }
187 void setWeightCombinatorialMatch(float weight) {
189 }
194 void setWeightArcMatch(float weight) {
195 weightArcMatch = weight;
196 }
201 void setWeightScalarValueMatch(float weight) {
202 weightScalarValueMatch = weight;
203 }
208 void setAlignmenttreeType(int type) {
210 }
211
254 template <class scalarType>
255 int execute(const std::vector<void *> &scalarsVP,
256 const std::vector<int *> &regionSizes,
257 const std::vector<int *> &segmentationIds,
258 const std::vector<long long *> &topologies,
259 const std::vector<size_t> &nVertices,
260 const std::vector<size_t> &nEdges,
261 const std::vector<int *> &segmentations,
262 const std::vector<size_t> &segsizes,
263
264 std::vector<float> &outputVertices,
265 std::vector<long long> &outputFrequencies,
266 std::vector<long long> &outputVertexIds,
267 std::vector<long long> &outputBranchIds,
268 std::vector<long long> &outputSegmentationIds,
269 std::vector<long long> &outputArcIds,
270 std::vector<int> &outputEdges,
271 int seed);
272
274
279 bool alignTree(const std::shared_ptr<ContourTree> &t);
284 bool initialize(const std::shared_ptr<ContourTree> &t);
289 bool alignTree_consistentRoot(const std::shared_ptr<ContourTree> &t);
295 bool initialize_consistentRoot(const std::shared_ptr<ContourTree> &t,
296 int rootIdx);
297
300 std::vector<std::pair<std::vector<std::shared_ptr<ttk::cta::CTNode>>,
301 std::vector<std::shared_ptr<ttk::cta::CTEdge>>>>
302 getGraphs();
306 std::vector<std::shared_ptr<ContourTree>> getContourTrees();
307
310 std::pair<std::vector<std::shared_ptr<ttk::cta::AlignmentNode>>,
311 std::vector<std::shared_ptr<ttk::cta::AlignmentEdge>>>
316 std::shared_ptr<ttk::cta::BinaryTree> getAlignmentGraphRooted();
320
326 std::pair<float, std::shared_ptr<ttk::cta::AlignmentTree>>
327 getAlignmentBinary(const std::shared_ptr<ttk::cta::BinaryTree> &t1,
328 const std::shared_ptr<ttk::cta::BinaryTree> &t2);
329
332 void computeBranches();
333
334 protected:
335 // filter parameters
338 float weightArcMatch = 1;
341
342 // alignment graph data
343 std::vector<std::shared_ptr<ttk::cta::AlignmentNode>> nodes;
344 std::vector<std::shared_ptr<ttk::cta::AlignmentEdge>> arcs;
345
346 // iteration variables
347 std::vector<std::shared_ptr<ContourTree>> contourtrees;
348 std::vector<size_t> permutation;
349 std::shared_ptr<ttk::cta::AlignmentNode> alignmentRoot;
352
353 // functions for aligning two trees (computing the alignment value and
354 // memoization matrix)
355 float alignTreeBinary(const std::shared_ptr<ttk::cta::BinaryTree> &t1,
356 const std::shared_ptr<ttk::cta::BinaryTree> &t2,
357 std::vector<std::vector<float>> &memT,
358 std::vector<std::vector<float>> &memF);
359 float alignForestBinary(const std::shared_ptr<ttk::cta::BinaryTree> &t1,
360 const std::shared_ptr<ttk::cta::BinaryTree> &t2,
361 std::vector<std::vector<float>> &memT,
362 std::vector<std::vector<float>> &memF);
363
364 // functions for the traceback of the alignment computation (computing the
365 // actual alignment tree)
366 std::shared_ptr<ttk::cta::AlignmentTree>
367 traceAlignmentTree(const std::shared_ptr<ttk::cta::BinaryTree> &t1,
368 const std::shared_ptr<ttk::cta::BinaryTree> &t2,
369 std::vector<std::vector<float>> &memT,
370 std::vector<std::vector<float>> &memF);
371 std::vector<std::shared_ptr<ttk::cta::AlignmentTree>>
372 traceAlignmentForest(const std::shared_ptr<ttk::cta::BinaryTree> &t1,
373 const std::shared_ptr<ttk::cta::BinaryTree> &t2,
374 std::vector<std::vector<float>> &memT,
375 std::vector<std::vector<float>> &memF);
376 std::shared_ptr<ttk::cta::AlignmentTree>
377 traceNullAlignment(const std::shared_ptr<ttk::cta::BinaryTree> &t,
378 bool first);
379
380 // function that defines the local editing costs of two nodes
381 float editCost(const std::shared_ptr<ttk::cta::BinaryTree> &t1,
382 const std::shared_ptr<ttk::cta::BinaryTree> &t2);
383
384 // helper functions for tree data structures
385 bool isBinary(const std::shared_ptr<ttk::cta::Tree> &t);
386 std::shared_ptr<ttk::cta::BinaryTree>
387 rootAtNode(const std::shared_ptr<ttk::cta::AlignmentNode> &root);
388 std::shared_ptr<ttk::cta::BinaryTree>
389 computeRootedTree(const std::shared_ptr<ttk::cta::AlignmentNode> &node,
390 const std::shared_ptr<ttk::cta::AlignmentEdge> &parent,
391 int &id);
392 std::shared_ptr<ttk::cta::BinaryTree>
393 computeRootedDualTree(const std::shared_ptr<ttk::cta::AlignmentEdge> &arc,
394 bool parent1,
395 int &id);
397 const std::shared_ptr<ttk::cta::AlignmentTree> &res);
398
399 // helper functions for branch decomposition
400 std::pair<float, std::vector<std::shared_ptr<ttk::cta::AlignmentNode>>>
401 pathToMax(const std::shared_ptr<ttk::cta::AlignmentNode> &root,
402 const std::shared_ptr<ttk::cta::AlignmentNode> &parent);
403 std::pair<float, std::vector<std::shared_ptr<ttk::cta::AlignmentNode>>>
404 pathToMin(const std::shared_ptr<ttk::cta::AlignmentNode> &root,
405 const std::shared_ptr<ttk::cta::AlignmentNode> &parent);
406 };
407} // namespace ttk
408
409template <class scalarType>
411 const std::vector<void *> &scalarsVP,
412 const std::vector<int *> &regionSizes,
413 const std::vector<int *> &segmentationIds,
414 const std::vector<long long *> &topologies,
415 const std::vector<size_t> &nVertices,
416 const std::vector<size_t> &nEdges,
417 const std::vector<int *> &segmentations,
418 const std::vector<size_t> &segsizes,
419 std::vector<float> &outputVertices,
420 std::vector<long long> &outputFrequencies,
421 std::vector<long long> &outputVertexIds,
422 std::vector<long long> &outputBranchIds,
423 std::vector<long long> &outputSegmentationIds,
424 std::vector<long long> &outputArcIds,
425 std::vector<int> &outputEdges,
426 int seed) {
427
428 Timer timer;
429
430 const size_t nTrees = nVertices.size();
431
432 std::vector<float *> scalars(nTrees);
433 for(size_t t = 0; t < nTrees; t++) {
434 scalars[t] = (float *)((scalarType *)scalarsVP[t]);
435 }
436
437 // Print Input
438 {
439 this->printMsg(ttk::debug::Separator::L1); // L1 is the '=' separator
440 this->printMsg("Execute base layer");
441 this->printMsg("Computing Alignment for " + std::to_string(nTrees)
442 + " trees.");
443 }
444
445 for(size_t t = 0; t < nTrees; t++) {
447 this->printMsg("Input Tree " + std::to_string(t) + " topology:",
449
450 std::vector<std::vector<std::string>> tableLines;
451 tableLines.push_back(
452 {"cellId", "vId0", "vId1", "scalar0", "scalar1", "region", "segId"});
453 for(size_t i = 0; i < nEdges[t]; i++) {
454 const long long vertexId0 = topologies[t][i * 2 + 0];
455 const long long vertexId1 = topologies[t][i * 2 + 1];
456 const int regionSize = regionSizes[t][i];
457 const int segmentationId = segmentationIds[t][i];
458 scalarType scalarOfVertexId0 = scalars[t][vertexId0];
459 scalarType scalarOfVertexId1 = scalars[t][vertexId1];
460
461 std::vector<std::string> tableLine;
462 tableLine.push_back(std::to_string(i));
463 tableLine.push_back(std::to_string(vertexId0));
464 tableLine.push_back(std::to_string(vertexId1));
465 tableLine.push_back(std::to_string(scalarOfVertexId0));
466 tableLine.push_back(std::to_string(scalarOfVertexId1));
467 tableLine.push_back(std::to_string(regionSize));
468 tableLine.push_back(std::to_string(segmentationId));
469
470 tableLines.push_back(tableLine);
471 }
472 this->printMsg(tableLines, debug::Priority::VERBOSE);
473 }
474
475 std::vector<std::vector<std::vector<int>>> segRegions;
476 if(!segsizes.empty()) {
477 for(size_t i = 0; i < nTrees; i++) {
478 int maxSegId = -1;
479 std::vector<int> seg(segsizes[i]);
480 for(size_t j = 0; j < segsizes[i]; j++) {
481 maxSegId = std::max(maxSegId, segmentations[i][j]);
482 seg[j] = segmentations[i][j];
483 }
484 std::vector<std::vector<int>> reg(maxSegId + 1);
485 for(size_t j = 0; j < segsizes[i]; j++) {
486 reg[segmentations[i][j]].push_back(j);
487 }
488 segRegions.push_back(reg);
489 }
490 for(size_t i = 0; i < nTrees; i++) {
491 int sum = 0;
492 for(const auto &seg : segRegions[i]) {
493 sum += seg.size();
494 }
495 this->printMsg("Tree " + std::to_string(i)
496 + ", sum of segment sizes: " + std::to_string(sum));
497 sum = 0;
498 for(size_t j = 0; j < nEdges[i]; j++) {
499 sum += regionSizes[i][j];
500 }
501 this->printMsg("Tree " + std::to_string(i)
502 + ", sum of region sizes: " + std::to_string(sum));
503 }
504 }
505
506 // prepare data structures
507 contourtrees = std::vector<std::shared_ptr<ContourTree>>();
508 nodes = std::vector<std::shared_ptr<ttk::cta::AlignmentNode>>();
509 arcs = std::vector<std::shared_ptr<ttk::cta::AlignmentEdge>>();
510 int bestRootIdx{};
511
513 this->printMsg("Shuffling input trees. Used seed: " + std::to_string(seed), 0,
515
516 // permute list input trees randomly with given seed
517 permutation = std::vector<size_t>();
518 for(size_t i = 0; i < nTrees; i++) {
519 permutation.push_back(i);
520 }
521
522 // initialize random engine using user-provided seed
523 std::mt19937 random_engine{};
524 random_engine.seed(seed);
525
527 // shuffle using the random engine
528 std::shuffle(permutation.begin(), permutation.end(), random_engine);
529 }
530
531 this->printMsg(
532 "Shuffling input trees. Used seed: " + std::to_string(seed), 1);
533
534 // print permutation
535 if(this->debugLevel_ >= static_cast<int>(debug::Priority::DETAIL)) {
536 std::string permutationString = "";
537 for(size_t i = 0; i < permutation.size(); i++) {
538 permutationString += std::to_string(permutation[i])
539 + (i == permutation.size() - 1 ? "" : ",");
540 }
541 this->printMsg(
542 "Permutation: " + permutationString, debug::Priority::DETAIL);
543 }
544
545 this->printMsg("Starting alignment heuristic.");
546
547 std::tuple<std::vector<std::shared_ptr<ttk::cta::AlignmentNode>>,
548 std::vector<std::shared_ptr<ttk::cta::AlignmentEdge>>,
549 std::vector<std::shared_ptr<ContourTree>>>
550 bestAlignment;
551 float bestAlignmentValue = FLT_MAX;
552
554 printMsg("Filtering input contour trees", 0, debug::LineMode::REPLACE);
555
556 std::vector<std::shared_ptr<ContourTree>> contourtreesToAlign;
557 for(size_t i = 0; i < nTrees; i++) {
558 auto ct = std::make_shared<ContourTree>(
559 scalars[permutation[i]], regionSizes[permutation[i]],
560 segmentationIds[permutation[i]], topologies[permutation[i]],
561 nVertices[permutation[i]], nEdges[permutation[i]],
562 segRegions.empty() ? std::vector<std::vector<int>>() : segRegions[i]);
563 if(ct->isBinary()) {
564 contourtreesToAlign.push_back(ct);
565 } else {
566 this->printWrn("Input " + std::to_string(permutation[i])
567 + " not binary. Will not be aligned.");
568 }
569 printMsg("Filtering input contour trees (" + std::to_string(i) + "/"
570 + std::to_string(nTrees) + ")",
571 (float)i / (float)nTrees, debug::LineMode::REPLACE);
572 }
573 if(contourtreesToAlign.empty()) {
574
575 this->printErr("No input binary.");
576
577 return 0;
578 }
579
580 printMsg("Filtering input contour trees", 1);
581
582 for(size_t rootIdx = 0;
583 rootIdx < contourtreesToAlign[0]->getGraph().first.size(); rootIdx++) {
584
585 contourtrees.clear();
586 nodes.clear();
587 arcs.clear();
588 alignmentVal = 0;
589
591 this->printMsg("Starting alignment computation with root "
592 + std::to_string(rootIdx));
593
594 // initialize alignment with first tree
595 size_t i = 0;
596
597 this->printMsg(
598 "Initializing alignment with tree " + std::to_string(permutation[i]), 0,
600 initialize_consistentRoot(contourtreesToAlign[i], rootIdx);
601 this->printMsg(
602 "Initializing alignment with tree " + std::to_string(permutation[i]), 1,
604
606
607 this->printMsg("Initialized root is saddle, alignment aborted.");
608
609 continue;
610 }
611
612 // construct other contour tree objects and align them
613
614 i++;
615 while(i < contourtreesToAlign.size()) {
616
617 this->printMsg("Aligning tree " + std::to_string(permutation[i]), 0,
619 alignTree_consistentRoot(contourtreesToAlign[i]);
620 this->printMsg("Aligning tree " + std::to_string(permutation[i]), 1,
622
623 i++;
624 }
625
626 this->printMsg("All trees aligned. Total alignment value: "
627 + std::to_string(alignmentVal));
628
629 if(alignmentVal < bestAlignmentValue) {
630
631 bestAlignmentValue = alignmentVal;
632 bestAlignment = std::make_tuple(nodes, arcs, contourtrees);
633 bestRootIdx = rootIdx;
634 }
635 }
636
637 nodes = std::get<0>(bestAlignment);
638 arcs = std::get<1>(bestAlignment);
639 contourtrees = std::get<2>(bestAlignment);
640
642 this->printMsg("Alignment iteration complete.");
643 this->printMsg("Root of optimal alignment: " + std::to_string(bestRootIdx)
644 + ".");
645 this->printMsg(
646 "Value of optimal alignment: " + std::to_string(bestAlignmentValue) + ".");
648 this->printMsg(
649 "Computing branches", 0, timer.getElapsedTime(), debug::LineMode::REPLACE);
650
652
653 this->printMsg("Computing branches", 1, timer.getElapsedTime());
655 this->printMsg("Writing output pointers", 0, timer.getElapsedTime(),
657
658 for(const auto &node : nodes) {
659
660 outputVertices.push_back(node->scalarValue);
661 outputFrequencies.push_back(node->freq);
662 outputBranchIds.push_back(node->branchID);
663 std::vector<long long> refs(nTrees, -1);
664 std::vector<long long> segRefs(nTrees, -1);
665 for(auto ref : node->nodeRefs) {
666 refs[permutation[ref.first]] = ref.second;
667 const int eId
668 = contourtrees[ref.first]->getGraph().first[ref.second]->edgeList[0];
669 segRefs[permutation[ref.first]]
670 = contourtrees[ref.first]->getGraph().second[eId]->segId;
671 }
672 for(int ref : refs) {
673 outputVertexIds.push_back(ref);
674 }
675 for(int segRef : segRefs) {
676 outputSegmentationIds.push_back(segRef);
677 }
678 }
679
680 for(const auto &edge : arcs) {
681
682 int i = 0;
683 for(const auto &node : nodes) {
684
685 if(node == edge->node1.lock()) {
686 outputEdges.push_back(i);
687 }
688
689 if(node == edge->node2.lock()) {
690 outputEdges.push_back(i);
691 }
692
693 i++;
694 }
695
696 std::vector<long long> arcRefs(nTrees, -1);
697 for(auto ref : edge->arcRefs) {
698 arcRefs[permutation[ref.first]] = ref.second;
699 }
700 for(int ref : arcRefs) {
701 outputArcIds.push_back(ref);
702 }
703 }
704 this->printMsg("Writing output pointers", 1, timer.getElapsedTime());
705
706 // Print performance
707 {
709 this->printMsg("Alignment computed in "
710 + std::to_string(timer.getElapsedTime()) + " s. ("
711 + std::to_string(threadNumber_) + " thread(s)).");
712 this->printMsg("Number of nodes in alignment: "
713 + std::to_string(nodes.size()));
714 }
715
716 return 1;
717}
TTK contourTreeAlignment processing package.
float alignTreeBinary(const std::shared_ptr< ttk::cta::BinaryTree > &t1, const std::shared_ptr< ttk::cta::BinaryTree > &t2, std::vector< std::vector< float > > &memT, std::vector< std::vector< float > > &memF)
bool alignTree_consistentRoot(const std::shared_ptr< ContourTree > &t)
~ContourTreeAlignment() override
Destructor of the Alignment Object.
std::vector< size_t > permutation
ttk::cta::Type_Alignmenttree alignmenttreeType
std::shared_ptr< ttk::cta::BinaryTree > computeRootedDualTree(const std::shared_ptr< ttk::cta::AlignmentEdge > &arc, bool parent1, int &id)
std::shared_ptr< ttk::cta::AlignmentNode > alignmentRoot
std::vector< std::shared_ptr< ttk::cta::AlignmentTree > > traceAlignmentForest(const std::shared_ptr< ttk::cta::BinaryTree > &t1, const std::shared_ptr< ttk::cta::BinaryTree > &t2, std::vector< std::vector< float > > &memT, std::vector< std::vector< float > > &memF)
std::vector< std::shared_ptr< ttk::cta::AlignmentEdge > > arcs
std::vector< std::pair< std::vector< std::shared_ptr< ttk::cta::CTNode > >, std::vector< std::shared_ptr< ttk::cta::CTEdge > > > > getGraphs()
bool initialize(const std::shared_ptr< ContourTree > &t)
std::shared_ptr< ttk::cta::AlignmentTree > traceAlignmentTree(const std::shared_ptr< ttk::cta::BinaryTree > &t1, const std::shared_ptr< ttk::cta::BinaryTree > &t2, std::vector< std::vector< float > > &memT, std::vector< std::vector< float > > &memF)
std::pair< float, std::shared_ptr< ttk::cta::AlignmentTree > > getAlignmentBinary(const std::shared_ptr< ttk::cta::BinaryTree > &t1, const std::shared_ptr< ttk::cta::BinaryTree > &t2)
void computeNewAlignmenttree(const std::shared_ptr< ttk::cta::AlignmentTree > &res)
std::pair< std::vector< std::shared_ptr< ttk::cta::AlignmentNode > >, std::vector< std::shared_ptr< ttk::cta::AlignmentEdge > > > getAlignmentGraph()
int execute(const std::vector< void * > &scalarsVP, const std::vector< int * > &regionSizes, const std::vector< int * > &segmentationIds, const std::vector< long long * > &topologies, const std::vector< size_t > &nVertices, const std::vector< size_t > &nEdges, const std::vector< int * > &segmentations, const std::vector< size_t > &segsizes, std::vector< float > &outputVertices, std::vector< long long > &outputFrequencies, std::vector< long long > &outputVertexIds, std::vector< long long > &outputBranchIds, std::vector< long long > &outputSegmentationIds, std::vector< long long > &outputArcIds, std::vector< int > &outputEdges, int seed)
float editCost(const std::shared_ptr< ttk::cta::BinaryTree > &t1, const std::shared_ptr< ttk::cta::BinaryTree > &t2)
void setWeightCombinatorialMatch(float weight)
std::vector< std::shared_ptr< ttk::cta::AlignmentNode > > nodes
bool isBinary(const std::shared_ptr< ttk::cta::Tree > &t)
bool alignTree(const std::shared_ptr< ContourTree > &t)
std::shared_ptr< ttk::cta::BinaryTree > getAlignmentGraphRooted()
float alignForestBinary(const std::shared_ptr< ttk::cta::BinaryTree > &t1, const std::shared_ptr< ttk::cta::BinaryTree > &t2, std::vector< std::vector< float > > &memT, std::vector< std::vector< float > > &memF)
void setWeightArcMatch(float weight)
ttk::cta::Mode_ArcMatch arcMatchMode
std::pair< float, std::vector< std::shared_ptr< ttk::cta::AlignmentNode > > > pathToMin(const std::shared_ptr< ttk::cta::AlignmentNode > &root, const std::shared_ptr< ttk::cta::AlignmentNode > &parent)
std::shared_ptr< ttk::cta::BinaryTree > computeRootedTree(const std::shared_ptr< ttk::cta::AlignmentNode > &node, const std::shared_ptr< ttk::cta::AlignmentEdge > &parent, int &id)
std::pair< float, std::vector< std::shared_ptr< ttk::cta::AlignmentNode > > > pathToMax(const std::shared_ptr< ttk::cta::AlignmentNode > &root, const std::shared_ptr< ttk::cta::AlignmentNode > &parent)
std::vector< std::shared_ptr< ContourTree > > getContourTrees()
bool initialize_consistentRoot(const std::shared_ptr< ContourTree > &t, int rootIdx)
std::shared_ptr< ttk::cta::AlignmentTree > traceNullAlignment(const std::shared_ptr< ttk::cta::BinaryTree > &t, bool first)
void setWeightScalarValueMatch(float weight)
std::shared_ptr< ttk::cta::BinaryTree > rootAtNode(const std::shared_ptr< ttk::cta::AlignmentNode > &root)
std::vector< std::shared_ptr< ContourTree > > contourtrees
ContourTreeAlignment()
Constructor of the Alignment Object.
Minimalist debugging class.
Definition Debug.h:88
int debugLevel_
Definition Debug.h:379
int printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:159
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
double getElapsedTime()
Definition Timer.h:15
Contour Tree Data Structure for an unrooted contour tree of unbounded degree for internal use from th...
The Topology ToolKit.
Basic data structure for an edge of an unrooted alignment tree.
std::weak_ptr< ttk::cta::AlignmentNode > node1
std::vector< std::pair< int, int > > arcRefs
std::weak_ptr< ttk::cta::AlignmentNode > node2
Basic data structure for a node of an unrooted alignment tree.
std::vector< std::shared_ptr< ttk::cta::AlignmentEdge > > edgeList
std::vector< std::pair< int, int > > nodeRefs
Basic tree data structure for an alignment of two rooted binary trees.
std::shared_ptr< ttk::cta::BinaryTree > node1
std::shared_ptr< ttk::cta::AlignmentTree > child1
std::shared_ptr< ttk::cta::AlignmentTree > child2
std::shared_ptr< ttk::cta::BinaryTree > node2
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)