TTK
Loading...
Searching...
No Matches
ttkMergeTreeClustering.cpp
Go to the documentation of this file.
1#include <FTMStructures.h>
2#include <FTMTree.h>
3#include <FTMTreeUtils.h>
4#include <MergeTreeUtils.h>
7#include <ttkMergeTreeUtils.h>
9
10#include <vtkDataObject.h> // For port information
11#include <vtkObjectFactory.h> // for new macro
12
13#include <vtkCellData.h>
14#include <vtkDataArray.h>
15#include <vtkDataSet.h>
16#include <vtkFloatArray.h>
17#include <vtkInformation.h>
18#include <vtkInformationVector.h>
19#include <vtkMultiBlockDataSet.h>
20#include <vtkPointData.h>
21#include <vtkTable.h>
22
23#include <string>
24
25using namespace ttk;
26using namespace ftm;
27
28// A VTK macro that enables the instantiation of this class via ::New()
29// You do not have to modify this
31
45 this->setDebugMsgPrefix("MergeTreeClustering");
46 this->SetNumberOfInputPorts(2);
47 this->SetNumberOfOutputPorts(3);
48}
49
51
60 vtkInformation *info) {
61 if(port == 0)
62 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkMultiBlockDataSet");
63 else if(port == 1) {
64 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkMultiBlockDataSet");
65 info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
66 } else
67 return 0;
68
69 return 1;
70}
71
88 vtkInformation *info) {
89 if(port == 0 || port == 1 || port == 2) {
90 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
91 } else {
92 return 0;
93 }
94 return 1;
95}
96
111 vtkInformationVector **inputVector,
112 vtkInformationVector *outputVector) {
113 // ------------------------------------------------------------------------------------
114 // --- Get input object from input vector
115 // ------------------------------------------------------------------------------------
116 auto blocks = vtkMultiBlockDataSet::GetData(inputVector[0], 0);
117 auto blocks2 = vtkMultiBlockDataSet::GetData(inputVector[1], 0);
118
119 if(Backend == 0) {
120 baseModule = 0;
121 } else if(Backend == 1) {
122 baseModule = 0;
123 } else if(Backend == 3) {
124 baseModule = 1;
125 } else if(Backend == 4) {
126 baseModule = 2;
127 } else {
128 baseModule = 0;
129 }
130
131 // filter out new backends (not yet supported)
132 if(baseModule != 0) {
133 printErr("Invalid Backend chosen. Path Mapping Distance and Branch Mapping "
134 "Distance not yet supported. Canceling computation.");
135 return 1;
136 }
137
138 // ------------------------------------------------------------------------------------
139 // --- Load blocks
140 // ------------------------------------------------------------------------------------
141 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> inputTrees, inputTrees2;
142 loadBlocks(inputTrees, blocks);
143 loadBlocks(inputTrees2, blocks2);
144
145 // If we have already computed once but the input has changed
146 if(treesNodes.size() != 0 and inputTrees[0]->GetBlock(0) != treesNodes[0])
147 resetDataVisualization();
148
149 return run<float>(outputVector, inputTrees, inputTrees2);
150}
151
152template <class dataType>
154 vtkInformationVector *outputVector,
155 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &inputTrees,
156 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &inputTrees2) {
157 if(not isDataVisualizationFilled())
158 runCompute<dataType>(outputVector, inputTrees, inputTrees2);
159 runOutput<dataType>(outputVector, inputTrees, inputTrees2);
160 return 1;
161}
162
163template <class dataType>
165 vtkInformationVector *ttkNotUsed(outputVector),
166 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &inputTrees,
167 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &inputTrees2) {
168 // ------------------------------------------------------------------------------------
169 // --- Construct trees
170 // ------------------------------------------------------------------------------------
171 const int numInputs = inputTrees.size();
172 const int numInputs2
173 = (not inputTrees[0]->GetBlock(0)->IsA("vtkUnstructuredGrid")
174 ? inputTrees2.size()
175 : (JoinSplitMixtureCoefficient != 0
176 and JoinSplitMixtureCoefficient != 1
177 ? numInputs
178 : 0));
179
180 setDataVisualization(numInputs, numInputs2);
181
182 std::vector<MergeTree<dataType>> intermediateMTrees(numInputs),
183 intermediateMTrees2(numInputs2), barycenters(NumberOfBarycenters),
184 barycenters2((numInputs2 != 0) * NumberOfBarycenters);
185 std::vector<FTMTree_MT *> intermediateTrees(numInputs),
186 intermediateTrees2(numInputs2);
187
188 bool const useSadMaxPairs = (JoinSplitMixtureCoefficient == 0);
189 IsPersistenceDiagram
190 = constructTrees<dataType>(inputTrees, intermediateMTrees, treesNodes,
191 treesArcs, treesSegmentation, useSadMaxPairs);
192 if(not IsPersistenceDiagram
193 or (JoinSplitMixtureCoefficient != 0
194 and JoinSplitMixtureCoefficient != 1)) {
195 auto &inputTrees2ToUse
196 = (not IsPersistenceDiagram ? inputTrees2 : inputTrees);
197 constructTrees<dataType>(inputTrees2ToUse, intermediateMTrees2, treesNodes2,
198 treesArcs2, treesSegmentation2, !useSadMaxPairs);
199 }
200
201 mergeTreeToFTMTree<dataType>(intermediateMTrees, intermediateTrees);
202 mergeTreeToFTMTree<dataType>(intermediateMTrees2, intermediateTrees2);
203
204 // ------------------------------------------------------------------------------------
205 // --- Call base
206 // ------------------------------------------------------------------------------------
207 bool const AddNodes = true;
208 // Classical distance
209 double distance = 0;
210
211 // Verify parameters
212 if(Backend == 0) {
213 BranchDecomposition = true;
214 NormalizedWasserstein = true;
215 KeepSubtree = false;
216 } else if(Backend == 1) {
217 BranchDecomposition = false;
218 NormalizedWasserstein = false;
219 KeepSubtree = true;
220 ComputeBarycenter = false;
221 }
222 if(IsPersistenceDiagram) {
223 BranchDecomposition = true;
224 }
225 if(ComputeBarycenter) {
226 if(not BranchDecomposition)
227 printMsg("BranchDecomposition is set to true since the barycenter "
228 "computation is asked.");
229 BranchDecomposition = true;
230 if(KeepSubtree)
231 printMsg("KeepSubtree is set to false since the barycenter computation "
232 "is asked.");
233 KeepSubtree = false;
234 }
235 if(not BranchDecomposition) {
236 if(NormalizedWasserstein)
237 printMsg("NormalizedWasserstein is set to false since branch "
238 "decomposition is not asked.");
239 NormalizedWasserstein = false;
240 }
241 EpsilonTree2 = EpsilonTree1;
242 Epsilon2Tree2 = Epsilon2Tree1;
243 Epsilon3Tree2 = Epsilon3Tree1;
244 printMsg("BranchDecomposition: " + std::to_string(BranchDecomposition));
245 printMsg("NormalizedWasserstein: " + std::to_string(NormalizedWasserstein));
246 printMsg("KeepSubtree: " + std::to_string(KeepSubtree));
247
248 // Call base
249 if(not ComputeBarycenter) {
250 MergeTreeDistance mergeTreeDistance;
251 mergeTreeDistance.setAssignmentSolver(AssignmentSolver);
252 mergeTreeDistance.setEpsilonTree1(EpsilonTree1);
253 mergeTreeDistance.setEpsilonTree2(EpsilonTree2);
254 mergeTreeDistance.setEpsilon2Tree1(Epsilon2Tree1);
255 mergeTreeDistance.setEpsilon2Tree2(Epsilon2Tree2);
256 mergeTreeDistance.setEpsilon3Tree1(Epsilon3Tree1);
257 mergeTreeDistance.setEpsilon3Tree2(Epsilon3Tree2);
258 mergeTreeDistance.setBranchDecomposition(BranchDecomposition);
259 mergeTreeDistance.setPersistenceThreshold(PersistenceThreshold);
260 mergeTreeDistance.setNormalizedWasserstein(NormalizedWasserstein);
261 mergeTreeDistance.setKeepSubtree(KeepSubtree);
262 mergeTreeDistance.setUseMinMaxPair(UseMinMaxPair);
263 mergeTreeDistance.setCleanTree(true);
264 mergeTreeDistance.setPostprocess(OutputTrees);
265 mergeTreeDistance.setDeleteMultiPersPairs(DeleteMultiPersPairs);
266 mergeTreeDistance.setEpsilon1UseFarthestSaddle(Epsilon1UseFarthestSaddle);
267 mergeTreeDistance.setIsPersistenceDiagram(IsPersistenceDiagram);
268 mergeTreeDistance.setNonMatchingWeight(NonMatchingWeight);
269 mergeTreeDistance.setThreadNumber(this->threadNumber_);
270 mergeTreeDistance.setDebugLevel(this->debugLevel_);
271
272 distance = mergeTreeDistance.execute<dataType>(
273 intermediateMTrees[0], intermediateMTrees[1], outputMatching);
274 trees1NodeCorrMesh = mergeTreeDistance.getTreesNodeCorr();
275 finalDistances = std::vector<double>{distance};
276 } else {
277 if(NumberOfBarycenters == 1) { // and numInputs2==0){
278 MergeTreeBarycenter mergeTreeBarycenter;
279 mergeTreeBarycenter.setAssignmentSolver(AssignmentSolver);
280 mergeTreeBarycenter.setEpsilonTree1(EpsilonTree1);
281 mergeTreeBarycenter.setEpsilonTree2(EpsilonTree2);
282 mergeTreeBarycenter.setEpsilon2Tree1(Epsilon2Tree1);
283 mergeTreeBarycenter.setEpsilon2Tree2(Epsilon2Tree2);
284 mergeTreeBarycenter.setEpsilon3Tree1(Epsilon3Tree1);
285 mergeTreeBarycenter.setEpsilon3Tree2(Epsilon3Tree2);
286 mergeTreeBarycenter.setBranchDecomposition(BranchDecomposition);
287 mergeTreeBarycenter.setPersistenceThreshold(PersistenceThreshold);
288 mergeTreeBarycenter.setNormalizedWasserstein(NormalizedWasserstein);
289 mergeTreeBarycenter.setKeepSubtree(KeepSubtree);
290 mergeTreeBarycenter.setUseMinMaxPair(UseMinMaxPair);
291 mergeTreeBarycenter.setAddNodes(AddNodes);
292 mergeTreeBarycenter.setDeterministic(Deterministic);
293 mergeTreeBarycenter.setBarycenterSizeLimitPercent(
294 BarycenterSizeLimitPercent);
295 mergeTreeBarycenter.setAlpha(Alpha);
296 mergeTreeBarycenter.setPostprocess(OutputTrees);
297 mergeTreeBarycenter.setDeleteMultiPersPairs(DeleteMultiPersPairs);
298 mergeTreeBarycenter.setEpsilon1UseFarthestSaddle(
299 Epsilon1UseFarthestSaddle);
300 mergeTreeBarycenter.setIsPersistenceDiagram(IsPersistenceDiagram);
301 mergeTreeBarycenter.setThreadNumber(this->threadNumber_);
302 mergeTreeBarycenter.setDebugLevel(this->debugLevel_);
303
304 mergeTreeBarycenter.execute<dataType>(
305 intermediateMTrees, outputMatchingBarycenter[0], barycenters[0]);
306 trees1NodeCorrMesh = mergeTreeBarycenter.getTreesNodeCorr();
307 finalDistances = mergeTreeBarycenter.getFinalDistances();
308 } else {
309 MergeTreeClustering<dataType> mergeTreeClustering;
310 mergeTreeClustering.setAssignmentSolver(AssignmentSolver);
311 mergeTreeClustering.setEpsilonTree1(EpsilonTree1);
312 mergeTreeClustering.setEpsilonTree2(EpsilonTree2);
313 mergeTreeClustering.setEpsilon2Tree1(Epsilon2Tree1);
314 mergeTreeClustering.setEpsilon2Tree2(Epsilon2Tree2);
315 mergeTreeClustering.setEpsilon3Tree1(Epsilon3Tree1);
316 mergeTreeClustering.setEpsilon3Tree2(Epsilon3Tree2);
317 mergeTreeClustering.setBranchDecomposition(BranchDecomposition);
318 mergeTreeClustering.setPersistenceThreshold(PersistenceThreshold);
319 mergeTreeClustering.setNormalizedWasserstein(NormalizedWasserstein);
320 mergeTreeClustering.setKeepSubtree(KeepSubtree);
321 mergeTreeClustering.setUseMinMaxPair(UseMinMaxPair);
322 mergeTreeClustering.setAddNodes(AddNodes);
323 mergeTreeClustering.setDeterministic(Deterministic);
324 mergeTreeClustering.setNoCentroids(NumberOfBarycenters);
325 mergeTreeClustering.setBarycenterSizeLimitPercent(
326 BarycenterSizeLimitPercent);
327 mergeTreeClustering.setPostprocess(OutputTrees);
328 mergeTreeClustering.setDeleteMultiPersPairs(DeleteMultiPersPairs);
329 mergeTreeClustering.setEpsilon1UseFarthestSaddle(
330 Epsilon1UseFarthestSaddle);
331 mergeTreeClustering.setIsPersistenceDiagram(IsPersistenceDiagram);
332 mergeTreeClustering.setMixtureCoefficient(JoinSplitMixtureCoefficient);
333 mergeTreeClustering.setThreadNumber(this->threadNumber_);
334 mergeTreeClustering.setDebugLevel(this->debugLevel_);
335
336 mergeTreeClustering.template execute<dataType>(
337 intermediateMTrees, outputMatchingBarycenter, clusteringAssignment,
338 intermediateMTrees2, outputMatchingBarycenter2, barycenters,
339 barycenters2);
340 trees1NodeCorrMesh = mergeTreeClustering.getTreesNodeCorr();
341 trees2NodeCorrMesh = mergeTreeClustering.getTrees2NodeCorr();
342 finalDistances = mergeTreeClustering.getFinalDistances();
343 }
344 }
345
346 mergeTreesTemplateToDouble<dataType>(intermediateMTrees, intermediateSTrees);
347 if(numInputs2 != 0)
348 mergeTreesTemplateToDouble<dataType>(
349 intermediateMTrees2, intermediateSTrees2);
350 if(ComputeBarycenter) {
351 mergeTreesTemplateToDouble<dataType>(barycenters, barycentersS);
352 if(numInputs2 != 0)
353 mergeTreesTemplateToDouble<dataType>(barycenters2, barycentersS2);
354 }
355
356 return 1;
357}
358
359static void addFieldData(vtkDataSet *in, vtkDataSet *out) {
360 auto inFieldData = in->GetFieldData();
361 auto outFieldData = out->GetFieldData();
362 for(int i = 0; i < inFieldData->GetNumberOfArrays(); ++i) {
363 outFieldData->AddArray(inFieldData->GetAbstractArray(i));
364 }
365}
366
367template <class dataType>
369 ttkMergeTreeVisualization &visuMaker,
371 std::vector<FTMTree_MT *> &intermediateTrees2,
372 std::vector<FTMTree_MT *> &barycentersTree2,
373 std::vector<std::vector<
374 std::vector<std::tuple<ttk::ftm::idNode, ttk::ftm::idNode, double>>>>
375 &outputMatchingBarycenter2,
376 std::vector<std::vector<int>> &trees2NodeCorrMesh,
377 vtkUnstructuredGrid *treeNodes,
378 int i,
379 std::vector<SimplexId> &nodeCorr2) {
380 int const nodeCorrShift = vtkOutputNode->GetNumberOfPoints();
381 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputNode2
383 visuMaker.setVtkOutputNode(vtkOutputNode2);
384 visuMaker.setVtkOutputArc(vtkOutputNode2);
385 visuMaker.setOutputMatchingBarycenter(outputMatchingBarycenter2);
386 visuMaker.clearAllCustomArrays();
387 if(treeNodes)
388 visuMaker.copyPointData(treeNodes, trees2NodeCorrMesh[i]);
389 visuMaker.setTreesNodeCorrMesh(trees2NodeCorrMesh);
390 visuMaker.setIsPDSadMax(true);
391 visuMaker.makeTreesOutput<dataType>(intermediateTrees2, barycentersTree2);
392 auto nodeCorrT = visuMaker.getNodeCorr();
393 nodeCorr2 = nodeCorrT[i];
394 for(unsigned int j = 0; j < nodeCorr2.size(); ++j)
395 nodeCorr2[j] += nodeCorrShift;
396
397 vtkNew<vtkAppendFilter> appendFilter{};
398 appendFilter->AddInputData(vtkOutputNode);
399 appendFilter->AddInputData(vtkOutputNode2);
400 appendFilter->SetMergePoints(false);
401 appendFilter->Update();
402 vtkOutputNode->ShallowCopy(appendFilter->GetOutput());
403}
404
405template <class dataType>
407 ttkMergeTreeVisualization &visuMakerMatching,
408 vtkSmartPointer<vtkUnstructuredGrid> &vtkOutputMatching,
409 std::vector<FTMTree_MT *> &intermediateTrees2,
410 std::vector<FTMTree_MT *> &barycentersTree2,
411 std::vector<std::vector<
412 std::vector<std::tuple<ttk::ftm::idNode, ttk::ftm::idNode, double>>>>
413 &outputMatchingBarycenter2,
414 std::vector<std::vector<SimplexId>> &nodeCorr2,
415 std::vector<std::vector<SimplexId>> &nodeCorrBary2,
416 std::vector<std::vector<float>> &allBaryPercentMatch2) {
417 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputMatching2
419 visuMakerMatching.setVtkOutputMatching(vtkOutputMatching2);
420 visuMakerMatching.setOutputMatchingBarycenter(outputMatchingBarycenter2);
421 visuMakerMatching.setAllBaryPercentMatch(allBaryPercentMatch2);
422 visuMakerMatching.setNodeCorr1(nodeCorr2);
423 visuMakerMatching.setNodeCorr2(nodeCorrBary2);
424 visuMakerMatching.makeMatchingOutput<dataType>(
425 intermediateTrees2, barycentersTree2);
426
427 vtkNew<vtkAppendFilter> appendFilter{};
428 appendFilter->AddInputData(vtkOutputMatching);
429 appendFilter->AddInputData(vtkOutputMatching2);
430 appendFilter->SetMergePoints(false);
431 appendFilter->Update();
432 vtkOutputMatching->ShallowCopy(appendFilter->GetOutput());
433}
434
435template <class dataType>
437 vtkInformationVector *outputVector,
438 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &inputTrees,
439 std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &ttkNotUsed(inputTrees2)) {
440 std::vector<MergeTree<dataType>> intermediateMTrees, intermediateMTrees2;
441 mergeTreesDoubleToTemplate<dataType>(intermediateSTrees, intermediateMTrees);
442 mergeTreesDoubleToTemplate<dataType>(
443 intermediateSTrees2, intermediateMTrees2);
444 std::vector<FTMTree_MT *> intermediateTrees, intermediateTrees2;
445 mergeTreeToFTMTree<dataType>(intermediateMTrees, intermediateTrees);
446 mergeTreeToFTMTree<dataType>(intermediateMTrees2, intermediateTrees2);
447
448 std::vector<MergeTree<dataType>> barycenters, barycenters2;
449 if(ComputeBarycenter) {
450 mergeTreesDoubleToTemplate<dataType>(barycentersS, barycenters);
451 mergeTreesDoubleToTemplate<dataType>(barycentersS2, barycenters2);
452 }
453
454 const int numInputs = inputTrees.size();
455 const int numInputs2 = intermediateMTrees2.size();
456 // ------------------------------------------------------------------------------------
457 // --- Create output
458 // ------------------------------------------------------------------------------------
459 Timer t_makeTreesOutput;
460
461 auto output_clusters = vtkMultiBlockDataSet::GetData(outputVector, 0);
462 auto output_centroids = vtkMultiBlockDataSet::GetData(outputVector, 1);
463 auto output_matchings = vtkMultiBlockDataSet::GetData(outputVector, 2);
464
465 // Declare internal arrays
466 std::vector<std::vector<SimplexId>> nodeCorr(numInputs),
467 nodeCorr2(numInputs2);
468
469 if(not ComputeBarycenter) {
470 // ---------------------------------------------------------------
471 // - Classical output
472 // ---------------------------------------------------------------
473 if(OutputTrees) {
474 FTMTree_MT *tree1 = intermediateTrees[0], *tree2 = intermediateTrees[1];
475 // ------------------------------------------
476 // --- Input trees
477 // ------------------------------------------
478 // Declare vtk objects
479 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputNode1
481 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputArc1
483 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputSegmentation1
485
486 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputNode2
488 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputArc2
490 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputSegmentation2
492
493 vtkSmartPointer<vtkMultiBlockDataSet> const vtkBlockNodes
499
500 // Fill vtk objects
502 visuMaker.setPlanarLayout(PlanarLayout);
504 BranchDecompositionPlanarLayout);
505 visuMaker.setBranchSpacing(BranchSpacing);
506 visuMaker.setRescaleTreesIndividually(RescaleTreesIndividually);
507 visuMaker.setOutputSegmentation(OutputSegmentation);
508 visuMaker.setDimensionSpacing(DimensionSpacing);
509 visuMaker.setDimensionToShift(DimensionToShift);
510 visuMaker.setImportantPairs(ImportantPairs);
511 visuMaker.setMaximumImportantPairs(MaximumImportantPairs);
512 visuMaker.setMinimumImportantPairs(MinimumImportantPairs);
513 visuMaker.setImportantPairsSpacing(ImportantPairsSpacing);
514 visuMaker.setNonImportantPairsSpacing(NonImportantPairsSpacing);
515 visuMaker.setNonImportantPairsProximity(NonImportantPairsProximity);
516 visuMaker.setExcludeImportantPairsHigher(ExcludeImportantPairsHigher);
517 visuMaker.setExcludeImportantPairsLower(ExcludeImportantPairsLower);
518 visuMaker.setIsPersistenceDiagram(IsPersistenceDiagram);
519
520 nodeCorr.clear();
521 // First tree
522 visuMaker.setNoSampleOffset(1);
523 visuMaker.setTreesNodes(treesNodes[0]);
524 visuMaker.copyPointData(treesNodes[0], trees1NodeCorrMesh[0]);
525 visuMaker.setTreesNodeCorrMesh(trees1NodeCorrMesh[0]);
526 visuMaker.setTreesSegmentation(treesSegmentation[0]);
527 visuMaker.setVtkOutputNode(vtkOutputNode1);
528 if(IsPersistenceDiagram)
529 visuMaker.setVtkOutputArc(vtkOutputNode1);
530 else
531 visuMaker.setVtkOutputArc(vtkOutputArc1);
532 visuMaker.setVtkOutputSegmentation(vtkOutputSegmentation1);
533 visuMaker.setDebugLevel(this->debugLevel_);
534 visuMaker.setIsPersistenceDiagram(IsPersistenceDiagram);
535
536 visuMaker.makeTreesOutput<dataType>(tree1);
537 nodeCorr.push_back(visuMaker.getNodeCorr()[0]);
538
539 // Second tree
540 visuMaker.setISampleOffset(1);
541 visuMaker.setTreesNodes(treesNodes[1]);
542 visuMaker.clearAllCustomArrays();
543 visuMaker.copyPointData(treesNodes[1], trees1NodeCorrMesh[1]);
544 visuMaker.setTreesNodeCorrMesh(trees1NodeCorrMesh[1]);
545 visuMaker.setTreesSegmentation(treesSegmentation[1]);
546 visuMaker.setVtkOutputNode(vtkOutputNode2);
547 if(IsPersistenceDiagram)
548 visuMaker.setVtkOutputArc(vtkOutputNode2);
549 else
550 visuMaker.setVtkOutputArc(vtkOutputArc2);
551 visuMaker.setVtkOutputSegmentation(vtkOutputSegmentation2);
552
553 visuMaker.makeTreesOutput<dataType>(tree2);
554 nodeCorr.push_back(visuMaker.getNodeCorr()[0]);
555
556 // Field data
557 vtkOutputNode1->GetFieldData()->ShallowCopy(
558 treesNodes[0]->GetFieldData());
559 vtkOutputNode2->GetFieldData()->ShallowCopy(
560 treesNodes[1]->GetFieldData());
561 if(not IsPersistenceDiagram) {
562 vtkOutputArc1->GetFieldData()->ShallowCopy(
563 treesArcs[0]->GetFieldData());
564 vtkOutputArc2->GetFieldData()->ShallowCopy(
565 treesArcs[1]->GetFieldData());
566 }
567 if(treesSegmentation[0])
568 addFieldData(treesSegmentation[0], vtkOutputNode1);
569 if(treesSegmentation[1])
570 addFieldData(treesSegmentation[1], vtkOutputNode2);
571 if(OutputSegmentation) {
572 vtkOutputSegmentation1->GetFieldData()->ShallowCopy(
573 treesSegmentation[0]->GetFieldData());
574 vtkOutputSegmentation2->GetFieldData()->ShallowCopy(
575 treesSegmentation[1]->GetFieldData());
576 }
577
578 // Construct multiblock
579 if(IsPersistenceDiagram and not OutputSegmentation) {
580 output_clusters->SetNumberOfBlocks(2);
581 output_clusters->SetBlock(0, vtkOutputNode1);
582 output_clusters->SetBlock(1, vtkOutputNode2);
583 } else {
584 vtkBlockNodes->SetNumberOfBlocks(2);
585 vtkBlockNodes->SetBlock(0, vtkOutputNode1);
586 vtkBlockNodes->SetBlock(1, vtkOutputNode2);
587
588 if(not IsPersistenceDiagram) {
589 vtkBlockArcs->SetNumberOfBlocks(2);
590 vtkBlockArcs->SetBlock(0, vtkOutputArc1);
591 vtkBlockArcs->SetBlock(1, vtkOutputArc2);
592 }
593
594 output_clusters->SetNumberOfBlocks(1 + !IsPersistenceDiagram
595 + OutputSegmentation);
596 output_clusters->SetBlock(0, vtkBlockNodes);
597 if(not IsPersistenceDiagram)
598 output_clusters->SetBlock(1, vtkBlockArcs);
599 if(OutputSegmentation) {
600 vtkBlockSegs->SetNumberOfBlocks(2);
601 vtkBlockSegs->SetBlock(0, vtkOutputSegmentation1);
602 vtkBlockSegs->SetBlock(1, vtkOutputSegmentation2);
603 int const segBlockID = 1 + !IsPersistenceDiagram;
604 output_clusters->SetBlock(segBlockID, vtkBlockSegs);
605 }
606 }
607
608 // ------------------------------------------
609 // --- Matching
610 // ------------------------------------------
611 // Declare vtk objects
612 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputMatching
614
615 // Fill vtk objects
616 ttkMergeTreeVisualization visuMakerMatching;
617 visuMakerMatching.setVtkOutputMatching(vtkOutputMatching);
618 visuMakerMatching.setOutputMatching(outputMatching);
619 visuMakerMatching.setVtkOutputNode2(vtkOutputNode1);
620 visuMakerMatching.setVtkOutputNode1(vtkOutputNode2);
621 visuMakerMatching.setNodeCorr1(nodeCorr);
622 visuMakerMatching.setDebugLevel(this->debugLevel_);
623
624 visuMakerMatching.makeMatchingOutput<dataType>(tree1, tree2);
625
626 // Field data
627 vtkNew<vtkDoubleArray> vtkDistance{};
628 vtkDistance->SetName("Distance");
629 vtkDistance->SetNumberOfTuples(1);
630 vtkDistance->SetTuple1(0, finalDistances[0]);
631 vtkOutputMatching->GetFieldData()->AddArray(vtkDistance);
632
633 // Construct multiblock
634 output_matchings->SetNumberOfBlocks(1);
635 output_matchings->SetBlock(0, vtkOutputMatching);
636 }
637 } else {
638 // ---------------------------------------------------------------
639 // - Barycenter/Clustering output
640 // ---------------------------------------------------------------
641 if(OutputTrees) {
642 // --- Declare internal arrays
643 std::vector<std::vector<SimplexId>> nodeCorrBary(NumberOfBarycenters),
644 nodeCorrBary2((numInputs2 != 0) * NumberOfBarycenters);
645 std::vector<std::vector<float>> allBaryPercentMatch(NumberOfBarycenters),
646 allBaryPercentMatch2((numInputs2 != 0) * NumberOfBarycenters);
647 std::vector<FTMTree_MT *> barycentersTree, barycentersTree2;
648 mergeTreeToFTMTree<dataType>(barycenters, barycentersTree);
649 mergeTreeToFTMTree<dataType>(barycenters2, barycentersTree2);
650
651 // ------------------------------------------
652 // --- Input trees
653 // ------------------------------------------
654 if(IsPersistenceDiagram and not OutputSegmentation) {
655 output_clusters->SetNumberOfBlocks(numInputs);
656 } else {
657 output_clusters->SetNumberOfBlocks((OutputSegmentation ? 3 : 2));
658 vtkSmartPointer<vtkMultiBlockDataSet> const vtkBlockNodes
660 vtkBlockNodes->SetNumberOfBlocks(numInputs);
661 output_clusters->SetBlock(0, vtkBlockNodes);
664 vtkBlockArcs->SetNumberOfBlocks(numInputs);
665 output_clusters->SetBlock(1, vtkBlockArcs);
666 if(OutputSegmentation) {
669 vtkBlockSegs->SetNumberOfBlocks(numInputs);
670 output_clusters->SetBlock(2, vtkBlockSegs);
671 }
672 }
673 for(unsigned int c = 0; c < NumberOfBarycenters; ++c) {
674#ifdef TTK_ENABLE_OPENMP
675#pragma omp parallel for schedule(dynamic) num_threads(this->threadNumber_)
676#endif
677 for(int i = 0; i < numInputs; ++i) {
678 if(clusteringAssignment[i] != (int)c)
679 continue;
680
681 // Declare vtk objects
684 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputArc
686 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputSegmentation
688
689 // Fill vtk objects
691 visuMaker.setPlanarLayout(PlanarLayout);
693 BranchDecompositionPlanarLayout);
694 visuMaker.setBranchSpacing(BranchSpacing);
695 visuMaker.setRescaleTreesIndividually(RescaleTreesIndividually);
696 visuMaker.setOutputSegmentation(OutputSegmentation);
697 visuMaker.setDimensionSpacing(DimensionSpacing);
698 visuMaker.setDimensionToShift(DimensionToShift);
699 visuMaker.setImportantPairs(ImportantPairs);
700 visuMaker.setMaximumImportantPairs(MaximumImportantPairs);
701 visuMaker.setMinimumImportantPairs(MinimumImportantPairs);
702 visuMaker.setImportantPairsSpacing(ImportantPairsSpacing);
703 visuMaker.setNonImportantPairsSpacing(NonImportantPairsSpacing);
704 visuMaker.setNonImportantPairsProximity(NonImportantPairsProximity);
705 visuMaker.setExcludeImportantPairsHigher(ExcludeImportantPairsHigher);
706 visuMaker.setExcludeImportantPairsLower(ExcludeImportantPairsLower);
707 visuMaker.setIsPersistenceDiagram(IsPersistenceDiagram);
708 visuMaker.setTreesNodes(treesNodes);
709 visuMaker.copyPointData(treesNodes[i], trees1NodeCorrMesh[i]);
710 visuMaker.setTreesNodeCorrMesh(trees1NodeCorrMesh);
711 visuMaker.setTreesSegmentation(treesSegmentation);
712 visuMaker.setVtkOutputNode(vtkOutputNode);
713 if(IsPersistenceDiagram)
714 visuMaker.setVtkOutputArc(vtkOutputNode);
715 else
716 visuMaker.setVtkOutputArc(vtkOutputArc);
717 visuMaker.setVtkOutputSegmentation(vtkOutputSegmentation);
718 visuMaker.setClusteringAssignment(clusteringAssignment);
719 visuMaker.setOutputMatchingBarycenter(outputMatchingBarycenter);
720 visuMaker.setPrintTreeId(i);
721 visuMaker.setPrintClusterId(c);
722 visuMaker.setDebugLevel(this->debugLevel_);
723 visuMaker.setIsPersistenceDiagram(IsPersistenceDiagram);
724 visuMaker.setIsPDSadMax(JoinSplitMixtureCoefficient == 0);
725
726 visuMaker.makeTreesOutput<dataType>(
727 intermediateTrees, barycentersTree);
728 auto nodeCorrT = visuMaker.getNodeCorr();
729 nodeCorr[i] = nodeCorrT[i];
730 if(IsPersistenceDiagram and JoinSplitMixtureCoefficient != 0
731 and JoinSplitMixtureCoefficient != 1)
732 makeDoubleInputPersistenceDiagramOutput<dataType>(
733 visuMaker, vtkOutputNode, intermediateTrees2, barycentersTree2,
734 outputMatchingBarycenter2, trees2NodeCorrMesh, treesNodes[i], i,
735 nodeCorr2[i]);
736
737 // Field data
738 vtkOutputNode->GetFieldData()->ShallowCopy(
739 treesNodes[i]->GetFieldData());
740 if(not IsPersistenceDiagram)
741 vtkOutputArc->GetFieldData()->ShallowCopy(
742 treesArcs[i]->GetFieldData());
743 if(treesSegmentation[i])
744 addFieldData(treesSegmentation[i], vtkOutputNode);
745 if(OutputSegmentation)
746 vtkOutputSegmentation->GetFieldData()->ShallowCopy(
747 treesSegmentation[i]->GetFieldData());
748
749 vtkNew<vtkDoubleArray> vtkClusterAssignment{};
750 vtkClusterAssignment->SetName("ClusterAssignment");
751 vtkClusterAssignment->SetNumberOfTuples(1);
752 vtkClusterAssignment->SetTuple1(0, clusteringAssignment[i]);
753 vtkOutputNode->GetFieldData()->AddArray(vtkClusterAssignment);
754
755 // Construct multiblock
756 if(IsPersistenceDiagram and not OutputSegmentation) {
757 output_clusters->SetBlock(i, vtkOutputNode);
758 } else {
759 vtkMultiBlockDataSet::SafeDownCast(output_clusters->GetBlock(0))
760 ->SetBlock(i, vtkOutputNode);
761 if(not IsPersistenceDiagram)
762 vtkMultiBlockDataSet::SafeDownCast(output_clusters->GetBlock(1))
763 ->SetBlock(i, vtkOutputArc);
764 if(OutputSegmentation) {
765 int const segBlockID = 1 + !IsPersistenceDiagram;
766 vtkMultiBlockDataSet::SafeDownCast(
767 output_clusters->GetBlock(segBlockID))
768 ->SetBlock(i, vtkOutputSegmentation);
769 }
770 }
771 }
772 }
773
774 // ------------------------------------------
775 // --- Barycenter(s)
776 // ------------------------------------------
777 if(IsPersistenceDiagram) {
778 output_centroids->SetNumberOfBlocks(NumberOfBarycenters);
779 } else {
780 output_centroids->SetNumberOfBlocks(2);
781 vtkSmartPointer<vtkMultiBlockDataSet> const vtkBlockNodes2
783 vtkBlockNodes2->SetNumberOfBlocks(NumberOfBarycenters);
784 output_centroids->SetBlock(0, vtkBlockNodes2);
785 vtkSmartPointer<vtkMultiBlockDataSet> const vtkBlockArcs2
787 vtkBlockArcs2->SetNumberOfBlocks(NumberOfBarycenters);
788 output_centroids->SetBlock(1, vtkBlockArcs2);
789 }
790 for(unsigned int c = 0; c < NumberOfBarycenters; ++c) {
791
792 // Declare vtk objects
795 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputArc
797 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputSegmentation
799
800 // Fill vtk objects
801 ttkMergeTreeVisualization visuMakerBary;
802 visuMakerBary.setPlanarLayout(PlanarLayout);
804 BranchDecompositionPlanarLayout);
805 visuMakerBary.setBranchSpacing(BranchSpacing);
806 visuMakerBary.setRescaleTreesIndividually(RescaleTreesIndividually);
807 visuMakerBary.setOutputSegmentation(false);
808 visuMakerBary.setDimensionSpacing(DimensionSpacing);
809 visuMakerBary.setDimensionToShift(DimensionToShift);
810 visuMakerBary.setImportantPairs(ImportantPairs);
811 visuMakerBary.setMaximumImportantPairs(MaximumImportantPairs);
812 visuMakerBary.setMinimumImportantPairs(MinimumImportantPairs);
813 visuMakerBary.setImportantPairsSpacing(ImportantPairsSpacing);
814 visuMakerBary.setNonImportantPairsSpacing(NonImportantPairsSpacing);
815 visuMakerBary.setNonImportantPairsProximity(NonImportantPairsProximity);
816 visuMakerBary.setExcludeImportantPairsHigher(
817 ExcludeImportantPairsHigher);
818 visuMakerBary.setExcludeImportantPairsLower(ExcludeImportantPairsLower);
819 visuMakerBary.setIsPersistenceDiagram(IsPersistenceDiagram);
820 visuMakerBary.setShiftMode(1); // Star Barycenter
821 visuMakerBary.setTreesNodes(treesNodes);
822 visuMakerBary.setTreesNodeCorrMesh(trees1NodeCorrMesh);
823 visuMakerBary.setTreesSegmentation(treesSegmentation);
824 visuMakerBary.setVtkOutputNode(vtkOutputNode);
825 if(IsPersistenceDiagram)
826 visuMakerBary.setVtkOutputArc(vtkOutputNode);
827 else
828 visuMakerBary.setVtkOutputArc(vtkOutputArc);
829 visuMakerBary.setVtkOutputSegmentation(vtkOutputSegmentation);
830 visuMakerBary.setClusteringAssignment(clusteringAssignment);
831 visuMakerBary.setOutputMatchingBarycenter(outputMatchingBarycenter);
832 visuMakerBary.setPrintTreeId(c);
833 visuMakerBary.setPrintClusterId(c);
834 if(numInputs == 2 and NumberOfBarycenters == 1) {
835 visuMakerBary.setBarycenterPositionAlpha(BarycenterPositionAlpha);
836 visuMakerBary.setAlpha(Alpha);
837 }
838 visuMakerBary.setDebugLevel(this->debugLevel_);
839 visuMakerBary.setIsPersistenceDiagram(IsPersistenceDiagram);
840 visuMakerBary.setIsPDSadMax(JoinSplitMixtureCoefficient == 0);
841
842 visuMakerBary.makeTreesOutput<dataType>(
843 intermediateTrees, barycentersTree);
844 auto nodeCorrBaryT = visuMakerBary.getNodeCorr();
845 nodeCorrBary[c] = nodeCorrBaryT[c];
846 auto allBaryPercentMatchT = visuMakerBary.getAllBaryPercentMatch();
847 allBaryPercentMatch[c] = allBaryPercentMatchT[c];
848
849 if(IsPersistenceDiagram and JoinSplitMixtureCoefficient != 0
850 and JoinSplitMixtureCoefficient != 1) {
851 makeDoubleInputPersistenceDiagramOutput<dataType>(
852 visuMakerBary, vtkOutputNode, intermediateTrees2, barycentersTree2,
853 outputMatchingBarycenter2, trees2NodeCorrMesh, nullptr, c,
854 nodeCorrBary2[c]);
855 allBaryPercentMatchT = visuMakerBary.getAllBaryPercentMatch();
856 allBaryPercentMatch2[c] = allBaryPercentMatchT[c];
857 }
858
859 // Field data
860 vtkNew<vtkDoubleArray> vtkClusterAssignment{};
861 vtkClusterAssignment->SetName("ClusterAssignment");
862 vtkClusterAssignment->SetNumberOfTuples(1);
863 vtkClusterAssignment->SetTuple1(0, c);
864 vtkOutputNode->GetFieldData()->AddArray(vtkClusterAssignment);
865
866 // Construct multiblock
867 if(IsPersistenceDiagram) {
868 output_centroids->SetBlock(c, vtkOutputNode);
869 } else {
870 vtkMultiBlockDataSet::SafeDownCast(output_centroids->GetBlock(0))
871 ->SetBlock(c, vtkOutputNode);
872 vtkMultiBlockDataSet::SafeDownCast(output_centroids->GetBlock(1))
873 ->SetBlock(c, vtkOutputArc);
874 }
875 }
876
877 // ------------------------------------------
878 // --- Matching
879 // ------------------------------------------
880 output_matchings->SetNumberOfBlocks(numInputs);
881 for(unsigned int c = 0; c < NumberOfBarycenters; ++c) {
882 for(int i = 0; i < numInputs; ++i) {
883 if(clusteringAssignment[i] != (int)c)
884 continue;
885
886 // Declare vtk objects
889 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputNode1
890 = vtkUnstructuredGrid::SafeDownCast(
891 (IsPersistenceDiagram and not OutputSegmentation
892 ? output_clusters->GetBlock(i)
893 : vtkMultiBlockDataSet::SafeDownCast(
894 output_clusters->GetBlock(0))
895 ->GetBlock(i)));
896 vtkSmartPointer<vtkUnstructuredGrid> const vtkOutputNode2
897 = vtkUnstructuredGrid::SafeDownCast(
898 (IsPersistenceDiagram ? output_centroids->GetBlock(c)
899 : vtkMultiBlockDataSet::SafeDownCast(
900 output_centroids->GetBlock(0))
901 ->GetBlock(c)));
902
903 // Fill vtk objects
904 ttkMergeTreeVisualization visuMakerMatching;
905 visuMakerMatching.setVtkOutputMatching(vtkOutputMatching);
906 visuMakerMatching.setOutputMatchingBarycenter(
907 outputMatchingBarycenter);
908 visuMakerMatching.setAllBaryPercentMatch(allBaryPercentMatch);
909 visuMakerMatching.setVtkOutputNode1(vtkOutputNode1);
910 visuMakerMatching.setVtkOutputNode2(vtkOutputNode2);
911 visuMakerMatching.setNodeCorr1(nodeCorr);
912 visuMakerMatching.setNodeCorr2(nodeCorrBary);
913 visuMakerMatching.setPrintTreeId(i);
914 visuMakerMatching.setPrintClusterId(c);
915 visuMakerMatching.setDebugLevel(this->debugLevel_);
916
917 visuMakerMatching.makeMatchingOutput<dataType>(
918 intermediateTrees, barycentersTree);
919 if(IsPersistenceDiagram and JoinSplitMixtureCoefficient != 0
920 and JoinSplitMixtureCoefficient != 1)
921 makeDoubleInputPersistenceDiagramMatching<dataType>(
922 visuMakerMatching, vtkOutputMatching, intermediateTrees2,
923 barycentersTree2, outputMatchingBarycenter2, nodeCorr2,
924 nodeCorrBary2, allBaryPercentMatch2);
925
926 // Field data
927 vtkNew<vtkDoubleArray> vtkDistance{};
928 vtkDistance->SetName("Distance");
929 vtkDistance->SetNumberOfTuples(1);
930 vtkDistance->SetTuple1(0, finalDistances[i]);
931 vtkOutputMatching->GetFieldData()->AddArray(vtkDistance);
932
933 // Construct multiblock
934 output_matchings->SetBlock(i, vtkOutputMatching);
935 }
936 }
937 }
938 }
939
940 printMsg(
941 "Trees output", 1, t_makeTreesOutput.getElapsedTime(), this->threadNumber_);
942
943 return 1;
944}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
TTK VTK-filter that wraps the ttk::MergeTreeClustering module.
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int runCompute(vtkInformationVector *outputVector, std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees, std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees2)
int run(vtkInformationVector *outputVector, std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees, std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees2)
int runOutput(vtkInformationVector *outputVector, std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees, std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees2)
int FillInputPortInformation(int port, vtkInformation *info) override
~ttkMergeTreeClustering() override
void setTreesSegmentation(std::vector< vtkDataSet * > &segmentation)
void copyPointData(vtkUnstructuredGrid *treeNodes, std::vector< int > &nodeCorrT)
void setVtkOutputNode1(vtkUnstructuredGrid *vtkNode1)
void setNodeCorr1(std::vector< std::vector< SimplexId > > &nodeCorrT)
void setOutputMatchingBarycenter(std::vector< std::vector< std::vector< std::tuple< idNode, idNode, double > > > > &matching)
void setVtkOutputSegmentation(vtkDataSet *vtkSegmentation)
void setTreesNodeCorrMesh(std::vector< std::vector< int > > &nodeCorrMesh)
void setVtkOutputMatching(vtkUnstructuredGrid *vtkMatching)
void setClusteringAssignment(std::vector< int > &asgn)
std::vector< std::vector< float > > getAllBaryPercentMatch()
std::vector< std::vector< SimplexId > > getNodeCorr()
void makeTreesOutput(FTMTree_MT *tree1)
void setVtkOutputNode2(vtkUnstructuredGrid *vtkNode2)
void makeMatchingOutput(FTMTree_MT *tree1, FTMTree_MT *tree2)
void setVtkOutputArc(vtkUnstructuredGrid *vtkArc)
void setNodeCorr2(std::vector< std::vector< SimplexId > > &nodeCorrT)
void setVtkOutputNode(vtkUnstructuredGrid *vtkNode)
void setOutputMatching(std::vector< std::tuple< idNode, idNode, double > > &matching)
void setTreesNodes(std::vector< vtkUnstructuredGrid * > &nodes)
void setAllBaryPercentMatch(std::vector< std::vector< float > > &baryPercentMatch)
virtual int setThreadNumber(const int threadNumber)
Definition BaseClass.h:80
int debugLevel_
Definition Debug.h:379
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
virtual int setDebugLevel(const int &debugLevel)
Definition Debug.cpp:147
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
void setAddNodes(bool addNodesT)
void setPostprocess(bool postproc)
void setDeterministic(bool deterministicT)
void setBarycenterSizeLimitPercent(double percent)
std::vector< double > getFinalDistances()
void execute(std::vector< ftm::MergeTree< dataType > > &trees, std::vector< double > &alphas, std::vector< std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > > &finalMatchings, ftm::MergeTree< dataType > &baryMergeTree, bool finalAsgnDoubleInput=false, bool finalAsgnFirstInput=true)
void setBranchDecomposition(bool useBD)
void setNormalizedWasserstein(bool normalizedWasserstein)
void setEpsilon3Tree1(double epsilon)
void setEpsilonTree1(double epsilon)
void setAssignmentSolver(int assignmentSolver)
std::vector< std::vector< int > > getTreesNodeCorr()
void setEpsilon2Tree1(double epsilon)
void setEpsilonTree2(double epsilon)
void setPersistenceThreshold(double pt)
void setNonMatchingWeight(double weight)
void setCleanTree(bool clean)
void setEpsilon2Tree2(double epsilon)
void setKeepSubtree(bool keepSubtree)
void setEpsilon1UseFarthestSaddle(bool b)
void setDeleteMultiPersPairs(bool deleteMultiPersPairsT)
void setUseMinMaxPair(bool useMinMaxPair)
void setEpsilon3Tree2(double epsilon)
void setIsPersistenceDiagram(bool isPD)
void setMixtureCoefficient(double coef)
void setNoCentroids(unsigned int noCentroidsT)
std::vector< std::vector< int > > getTrees2NodeCorr()
void setPostprocess(bool postproc)
dataType execute(ftm::MergeTree< dataType > &mTree1, ftm::MergeTree< dataType > &mTree2, std::vector< std::tuple< ftm::idNode, ftm::idNode, double > > &outputMatching)
void setExcludeImportantPairsLower(std::string &d)
void setExcludeImportantPairsHigher(std::string &d)
double getElapsedTime()
Definition Timer.h:15
std::string to_string(__int128)
Definition ripserpy.cpp:99
void loadBlocks(std::vector< vtkSmartPointer< vtkMultiBlockDataSet > > &inputTrees, vtkMultiBlockDataSet *blocks)
The Topology ToolKit.
vtkStandardNewMacro(ttkMergeTreeClustering)
void makeDoubleInputPersistenceDiagramOutput(ttkMergeTreeVisualization &visuMaker, vtkSmartPointer< vtkUnstructuredGrid > &vtkOutputNode, std::vector< FTMTree_MT * > &intermediateTrees2, std::vector< FTMTree_MT * > &barycentersTree2, std::vector< std::vector< std::vector< std::tuple< ttk::ftm::idNode, ttk::ftm::idNode, double > > > > &outputMatchingBarycenter2, std::vector< std::vector< int > > &trees2NodeCorrMesh, vtkUnstructuredGrid *treeNodes, int i, std::vector< SimplexId > &nodeCorr2)
void makeDoubleInputPersistenceDiagramMatching(ttkMergeTreeVisualization &visuMakerMatching, vtkSmartPointer< vtkUnstructuredGrid > &vtkOutputMatching, std::vector< FTMTree_MT * > &intermediateTrees2, std::vector< FTMTree_MT * > &barycentersTree2, std::vector< std::vector< std::vector< std::tuple< ttk::ftm::idNode, ttk::ftm::idNode, double > > > > &outputMatchingBarycenter2, std::vector< std::vector< SimplexId > > &nodeCorr2, std::vector< std::vector< SimplexId > > &nodeCorrBary2, std::vector< std::vector< float > > &allBaryPercentMatch2)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)