195 vtkInformationVector *
ttkNotUsed(outputVector),
201 const int numInputs = inputTrees.size();
203 = (not inputTrees[0]->GetBlock(0)->
IsA(
"vtkUnstructuredGrid")
205 : (JoinSplitMixtureCoefficient != 0
206 and JoinSplitMixtureCoefficient != 1
210 setDataVisualization(numInputs, numInputs2);
212 std::vector<MergeTree<dataType>> intermediateMTrees(numInputs),
213 intermediateMTrees2(numInputs2), barycenters(NumberOfBarycenters),
214 barycenters2((numInputs2 != 0) * NumberOfBarycenters);
215 std::vector<FTMTree_MT *> intermediateTrees(numInputs),
216 intermediateTrees2(numInputs2);
218 bool const useSecondPairsType = (JoinSplitMixtureCoefficient == 0);
220 inputTrees, intermediateMTrees, treesNodes, treesArcs, treesSegmentation,
221 useSecondPairsType, DiagramPairTypes);
222 if(not IsPersistenceDiagram
223 or (JoinSplitMixtureCoefficient != 0
224 and JoinSplitMixtureCoefficient != 1)) {
225 auto &inputTrees2ToUse
226 = (not IsPersistenceDiagram ? inputTrees2 : inputTrees);
228 treesArcs2, treesSegmentation2,
229 !useSecondPairsType, DiagramPairTypes);
238 bool const AddNodes =
true;
244 BranchDecomposition =
true;
245 NormalizedWasserstein =
true;
247 }
else if(Backend == 1) {
248 BranchDecomposition =
false;
249 NormalizedWasserstein =
false;
251 }
else if(Backend == 3) {
252 BranchDecomposition =
false;
253 NormalizedWasserstein =
false;
255 }
else if(Backend == 4) {
256 BranchDecomposition =
false;
257 NormalizedWasserstein =
false;
260 if(IsPersistenceDiagram) {
261 BranchDecomposition =
true;
263 EpsilonTree2 = EpsilonTree1;
264 Epsilon2Tree2 = Epsilon2Tree1;
265 Epsilon3Tree2 = Epsilon3Tree1;
266 printMsg(
"BranchDecomposition: " + std::to_string(BranchDecomposition));
267 printMsg(
"NormalizedWasserstein: " + std::to_string(NormalizedWasserstein));
268 printMsg(
"KeepSubtree: " + std::to_string(KeepSubtree));
271 if(not ComputeBarycenter) {
272 if(baseModule == 0) {
295 distance = mergeTreeDistance.
execute<dataType>(
296 intermediateMTrees[0], intermediateMTrees[1], outputMatching);
298 finalDistances = std::vector<double>{distance};
299 }
else if(baseModule == 1) {
321 distance = branchDist.
execute<dataType>(
322 intermediateMTrees[0], intermediateMTrees[1], &outputMatching);
324 std::vector<ttk::SimplexId> nodeCorr1(
325 intermediateTrees[0]->getNumberOfNodes());
326 std::vector<ttk::SimplexId> nodeCorr2(
327 intermediateTrees[1]->getNumberOfNodes());
328 for(
unsigned int i = 0; i < nodeCorr1.size(); i++)
330 for(
unsigned int i = 0; i < nodeCorr2.size(); i++)
333 finalDistances = std::vector<double>{distance};
354 distance = pathDist.
execute<dataType>(
355 intermediateMTrees[0], intermediateMTrees[1], &outputMatching);
365 finalDistances = std::vector<double>{distance};
368 if(NumberOfBarycenters == 1) {
381 mergeTreeBarycenter.
setAlpha(Alpha);
388 if(baseModule == 2) {
404 BarycenterSizeLimitPercent);
408 Epsilon1UseFarthestSaddle);
411 mergeTreeBarycenter.
execute<dataType>(
412 intermediateMTrees, outputMatchingBarycenter[0],
413 outputMatchings_path[0], barycenters[0]);
437 BarycenterSizeLimitPercent);
441 Epsilon1UseFarthestSaddle);
447 mergeTreeClustering.template execute<dataType>(
448 intermediateMTrees, outputMatchingBarycenter, clusteringAssignment,
449 intermediateMTrees2, outputMatchingBarycenter2, barycenters,
460 intermediateMTrees2, intermediateSTrees2);
461 if(ComputeBarycenter) {
548 vtkInformationVector *outputVector,
551 std::vector<MergeTree<dataType>> intermediateMTrees, intermediateMTrees2;
554 intermediateSTrees2, intermediateMTrees2);
555 std::vector<FTMTree_MT *> intermediateTrees, intermediateTrees2;
559 std::vector<MergeTree<dataType>> barycenters, barycenters2;
560 if(ComputeBarycenter) {
565 const int numInputs = inputTrees.size();
566 const int numInputs2 = intermediateMTrees2.size();
570 Timer t_makeTreesOutput;
572 auto output_clusters = vtkMultiBlockDataSet::GetData(outputVector, 0);
573 auto output_centroids = vtkMultiBlockDataSet::GetData(outputVector, 1);
574 auto output_matchings = vtkMultiBlockDataSet::GetData(outputVector, 2);
577 std::vector<std::vector<SimplexId>> nodeCorr(numInputs),
578 nodeCorr2(numInputs2);
580 if(not ComputeBarycenter) {
585 FTMTree_MT *tree1 = intermediateTrees[0], *tree2 = intermediateTrees[1];
615 BranchDecompositionPlanarLayout);
638 visuMaker.
copyPointData(treesNodes[0], trees1NodeCorrMesh[0]);
642 if(IsPersistenceDiagram)
657 visuMaker.
copyPointData(treesNodes[1], trees1NodeCorrMesh[1]);
661 if(IsPersistenceDiagram)
671 vtkOutputNode1->GetFieldData()->ShallowCopy(
672 treesNodes[0]->GetFieldData());
673 vtkOutputNode2->GetFieldData()->ShallowCopy(
674 treesNodes[1]->GetFieldData());
675 if(not IsPersistenceDiagram) {
676 vtkOutputArc1->GetFieldData()->ShallowCopy(
677 treesArcs[0]->GetFieldData());
678 vtkOutputArc2->GetFieldData()->ShallowCopy(
679 treesArcs[1]->GetFieldData());
681 if(treesSegmentation[0])
682 addFieldData(treesSegmentation[0], vtkOutputNode1);
683 if(treesSegmentation[1])
684 addFieldData(treesSegmentation[1], vtkOutputNode2);
685 if(OutputSegmentation) {
686 vtkOutputSegmentation1->GetFieldData()->ShallowCopy(
687 treesSegmentation[0]->GetFieldData());
688 vtkOutputSegmentation2->GetFieldData()->ShallowCopy(
689 treesSegmentation[1]->GetFieldData());
693 if(IsPersistenceDiagram and not OutputSegmentation) {
694 output_clusters->SetNumberOfBlocks(2);
695 output_clusters->SetBlock(0, vtkOutputNode1);
696 output_clusters->SetBlock(1, vtkOutputNode2);
698 vtkBlockNodes->SetNumberOfBlocks(2);
699 vtkBlockNodes->SetBlock(0, vtkOutputNode1);
700 vtkBlockNodes->SetBlock(1, vtkOutputNode2);
702 if(not IsPersistenceDiagram) {
703 vtkBlockArcs->SetNumberOfBlocks(2);
704 vtkBlockArcs->SetBlock(0, vtkOutputArc1);
705 vtkBlockArcs->SetBlock(1, vtkOutputArc2);
708 output_clusters->SetNumberOfBlocks(1 + !IsPersistenceDiagram
709 + OutputSegmentation);
710 output_clusters->SetBlock(0, vtkBlockNodes);
711 if(not IsPersistenceDiagram)
712 output_clusters->SetBlock(1, vtkBlockArcs);
713 if(OutputSegmentation) {
714 vtkBlockSegs->SetNumberOfBlocks(2);
715 vtkBlockSegs->SetBlock(0, vtkOutputSegmentation1);
716 vtkBlockSegs->SetBlock(1, vtkOutputSegmentation2);
717 int const segBlockID = 1 + !IsPersistenceDiagram;
718 output_clusters->SetBlock(segBlockID, vtkBlockSegs);
743 vtkNew<vtkDoubleArray> vtkDistance{};
744 vtkDistance->SetName(
"Distance");
745 vtkDistance->SetNumberOfTuples(1);
746 vtkDistance->SetTuple1(0, finalDistances[0]);
747 vtkOutputMatching->GetFieldData()->AddArray(vtkDistance);
750 output_matchings->SetNumberOfBlocks(1);
751 output_matchings->SetBlock(0, vtkOutputMatching);
759 std::vector<std::vector<SimplexId>> nodeCorrBary(NumberOfBarycenters),
760 nodeCorrBary2((numInputs2 != 0) * NumberOfBarycenters);
761 std::vector<std::vector<float>> allBaryPercentMatch(NumberOfBarycenters),
762 allBaryPercentMatch2((numInputs2 != 0) * NumberOfBarycenters);
763 std::vector<FTMTree_MT *> barycentersTree, barycentersTree2;
770 if(IsPersistenceDiagram and not OutputSegmentation) {
771 output_clusters->SetNumberOfBlocks(numInputs);
773 output_clusters->SetNumberOfBlocks((OutputSegmentation ? 3 : 2));
776 vtkBlockNodes->SetNumberOfBlocks(numInputs);
777 output_clusters->SetBlock(0, vtkBlockNodes);
780 vtkBlockArcs->SetNumberOfBlocks(numInputs);
781 output_clusters->SetBlock(1, vtkBlockArcs);
782 if(OutputSegmentation) {
785 vtkBlockSegs->SetNumberOfBlocks(numInputs);
786 output_clusters->SetBlock(2, vtkBlockSegs);
789 for(
unsigned int c = 0; c < NumberOfBarycenters; ++c) {
793 for(
int i = 0; i < numInputs; ++i) {
794 if(clusteringAssignment[i] != (
int)c)
809 BranchDecompositionPlanarLayout);
826 visuMaker.
copyPointData(treesNodes[i], trees1NodeCorrMesh[i]);
830 if(IsPersistenceDiagram)
848 intermediateTrees, barycentersTree);
850 nodeCorr[i] = nodeCorrT[i];
851 if(IsPersistenceDiagram and JoinSplitMixtureCoefficient != 0
852 and JoinSplitMixtureCoefficient != 1)
854 visuMaker, vtkOutputNode, intermediateTrees2, barycentersTree2,
855 outputMatchingBarycenter2, trees2NodeCorrMesh, treesNodes[i], i,
859 vtkOutputNode->GetFieldData()->ShallowCopy(
860 treesNodes[i]->GetFieldData());
861 if(not IsPersistenceDiagram)
862 vtkOutputArc->GetFieldData()->ShallowCopy(
863 treesArcs[i]->GetFieldData());
864 if(treesSegmentation[i])
865 addFieldData(treesSegmentation[i], vtkOutputNode);
866 if(OutputSegmentation)
867 vtkOutputSegmentation->GetFieldData()->ShallowCopy(
868 treesSegmentation[i]->GetFieldData());
870 vtkNew<vtkDoubleArray> vtkClusterAssignment{};
871 vtkClusterAssignment->SetName(
"ClusterAssignment");
872 vtkClusterAssignment->SetNumberOfTuples(1);
873 vtkClusterAssignment->SetTuple1(0, clusteringAssignment[i]);
874 vtkOutputNode->GetFieldData()->AddArray(vtkClusterAssignment);
877 if(IsPersistenceDiagram and not OutputSegmentation) {
878 output_clusters->SetBlock(i, vtkOutputNode);
880 vtkMultiBlockDataSet::SafeDownCast(output_clusters->GetBlock(0))
881 ->SetBlock(i, vtkOutputNode);
882 if(not IsPersistenceDiagram)
883 vtkMultiBlockDataSet::SafeDownCast(output_clusters->GetBlock(1))
884 ->SetBlock(i, vtkOutputArc);
885 if(OutputSegmentation) {
886 int const segBlockID = 1 + !IsPersistenceDiagram;
887 vtkMultiBlockDataSet::SafeDownCast(
888 output_clusters->GetBlock(segBlockID))
889 ->SetBlock(i, vtkOutputSegmentation);
898 if(IsPersistenceDiagram) {
899 output_centroids->SetNumberOfBlocks(NumberOfBarycenters);
901 output_centroids->SetNumberOfBlocks(2);
904 vtkBlockNodes2->SetNumberOfBlocks(NumberOfBarycenters);
905 output_centroids->SetBlock(0, vtkBlockNodes2);
908 vtkBlockArcs2->SetNumberOfBlocks(NumberOfBarycenters);
909 output_centroids->SetBlock(1, vtkBlockArcs2);
911 for(
unsigned int c = 0; c < NumberOfBarycenters; ++c) {
925 BranchDecompositionPlanarLayout);
939 ExcludeImportantPairsHigher);
947 if(IsPersistenceDiagram)
957 if(numInputs == 2 and NumberOfBarycenters == 1) {
963 visuMakerBary.
setIsPDSadMax(JoinSplitMixtureCoefficient == 0);
969 intermediateTrees, barycentersTree);
971 nodeCorrBary[c] = nodeCorrBaryT[c];
973 allBaryPercentMatch[c] = allBaryPercentMatchT[c];
975 if(IsPersistenceDiagram and JoinSplitMixtureCoefficient != 0
976 and JoinSplitMixtureCoefficient != 1) {
978 visuMakerBary, vtkOutputNode, intermediateTrees2, barycentersTree2,
979 outputMatchingBarycenter2, trees2NodeCorrMesh,
nullptr, c,
982 allBaryPercentMatch2[c] = allBaryPercentMatchT[c];
986 vtkNew<vtkDoubleArray> vtkClusterAssignment{};
987 vtkClusterAssignment->SetName(
"ClusterAssignment");
988 vtkClusterAssignment->SetNumberOfTuples(1);
989 vtkClusterAssignment->SetTuple1(0, c);
990 vtkOutputNode->GetFieldData()->AddArray(vtkClusterAssignment);
993 if(IsPersistenceDiagram) {
994 output_centroids->SetBlock(c, vtkOutputNode);
996 vtkMultiBlockDataSet::SafeDownCast(output_centroids->GetBlock(0))
997 ->SetBlock(c, vtkOutputNode);
998 vtkMultiBlockDataSet::SafeDownCast(output_centroids->GetBlock(1))
999 ->SetBlock(c, vtkOutputArc);
1006 output_matchings->SetNumberOfBlocks(numInputs);
1007 for(
unsigned int c = 0; c < NumberOfBarycenters; ++c) {
1008 for(
int i = 0; i < numInputs; ++i) {
1009 if(clusteringAssignment[i] != (
int)c)
1016 = vtkUnstructuredGrid::SafeDownCast(
1017 (IsPersistenceDiagram and not OutputSegmentation
1018 ? output_clusters->GetBlock(i)
1019 : vtkMultiBlockDataSet::SafeDownCast(
1020 output_clusters->GetBlock(0))
1023 = vtkUnstructuredGrid::SafeDownCast(
1024 (IsPersistenceDiagram ? output_centroids->GetBlock(c)
1025 : vtkMultiBlockDataSet::SafeDownCast(
1026 output_centroids->GetBlock(0))
1033 outputMatchingBarycenter);
1046 intermediateTrees, barycentersTree);
1047 if(IsPersistenceDiagram and JoinSplitMixtureCoefficient != 0
1048 and JoinSplitMixtureCoefficient != 1)
1050 visuMakerMatching, vtkOutputMatching, intermediateTrees2,
1051 barycentersTree2, outputMatchingBarycenter2, nodeCorr2,
1052 nodeCorrBary2, allBaryPercentMatch2);
1055 vtkNew<vtkDoubleArray> vtkDistance{};
1056 vtkDistance->SetName(
"Distance");
1057 vtkDistance->SetNumberOfTuples(1);
1058 vtkDistance->SetTuple1(0, finalDistances[i]);
1059 vtkOutputMatching->GetFieldData()->AddArray(vtkDistance);
1062 output_matchings->SetBlock(i, vtkOutputMatching);
1069 "Trees output", 1, t_makeTreesOutput.
getElapsedTime(), this->threadNumber_);