TTK
Loading...
Searching...
No Matches
ttkPersistenceDiagramDictionary.cpp
Go to the documentation of this file.
1#include <ttkMacros.h>
4#include <ttkUtils.h>
5
6#include <vtkAlgorithm.h>
7#include <vtkCellData.h>
8#include <vtkCharArray.h>
9#include <vtkDataArray.h>
10#include <vtkDataSet.h>
11#include <vtkDoubleArray.h>
12#include <vtkFloatArray.h>
13#include <vtkMultiBlockDataSet.h>
14#include <vtkNew.h>
15#include <vtkObjectFactory.h>
16#include <vtkPointData.h>
17#include <vtkTable.h>
18
20
22 SetNumberOfInputPorts(2);
23 SetNumberOfOutputPorts(2);
24}
25
27 int port, vtkInformation *info) {
28 if(port == 0) {
29 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkMultiBlockDataSet");
30 return 1;
31 } else if(port == 1) {
32 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkMultiBlockDataSet");
33 info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
34 return 1;
35 }
36 return 0;
37}
38
40 int port, vtkInformation *info) {
41 if(port == 0) {
42 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
43 return 1;
44 } else if(port == 1) {
45 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTable");
46 return 1;
47 } else {
48 return 0;
49 }
50}
51
52// to adapt if your wrapper does not inherit from vtkDataSetAlgorithm
54 vtkInformation * /*request*/,
55 vtkInformationVector **inputVector,
56 vtkInformationVector *outputVector) {
58
59 // Get input data
60 auto blocks = vtkMultiBlockDataSet::GetData(inputVector[0], 0);
61 auto atomBlocks = vtkMultiBlockDataSet::GetData(inputVector[1], 0);
62
63 // Flat storage for diagrams extracted from blocks
64 std::vector<vtkUnstructuredGrid *> inputDiagrams;
65
66 std::vector<vtkUnstructuredGrid *> inputAtoms;
67
68 int numInputAtoms = 0;
69 if(atomBlocks != nullptr) {
70 numInputAtoms = atomBlocks->GetNumberOfBlocks();
71 inputAtoms.resize(numInputAtoms);
72 for(int i = 0; i < numInputAtoms; ++i) {
73 inputAtoms[i]
74 = vtkUnstructuredGrid::SafeDownCast(atomBlocks->GetBlock(i));
75 }
76 }
78 AtomNumber_ = numInputAtoms;
79 }
80 if(blocks != nullptr) {
81 int numInputs = blocks->GetNumberOfBlocks();
82 inputDiagrams.resize(numInputs);
83 for(int i = 0; i < numInputs; ++i) {
84 inputDiagrams[i] = vtkUnstructuredGrid::SafeDownCast(blocks->GetBlock(i));
85 }
86 }
87
88 const int numAtom = this->GetAtomNumber_();
89 printMsg("Number of atoms: " + ttk::debug::output::YELLOW
90 + ttk::debug::output::UNDERLINED + std::to_string(numAtom)
92
93 // total number of diagrams
94 const int nDiags = inputDiagrams.size();
95
96 // Sanity check
97 for(const auto vtu : inputDiagrams) {
98 if(vtu == nullptr) {
99 this->printErr("Input diagrams are not all vtkUnstructuredGrid");
100 return 0;
101 }
102 }
103
104 // Set output
105 auto outputDgm = vtkMultiBlockDataSet::GetData(outputVector, 0);
106 auto outputWeights = vtkTable::GetData(outputVector, 1);
107
108 outputDgm->SetNumberOfBlocks(numAtom);
109
111 for(int i = 0; i < numAtom; ++i) {
112 vtkNew<vtkUnstructuredGrid> vtu;
113 vtu->DeepCopy(inputAtoms[i]);
114 outputDgm->SetBlock(i, vtu);
115 }
116 } else {
117 for(int i = 0; i < numAtom; ++i) {
118 vtkNew<vtkUnstructuredGrid> vtu;
119 vtu->DeepCopy(inputDiagrams[i]);
120 outputDgm->SetBlock(i, vtu);
121 }
122 }
123
124 std::vector<ttk::DiagramType> intermediateDiagrams(nDiags);
125 std::vector<ttk::DiagramType> intermediateAtoms(numInputAtoms);
126
127 double max_dimension_total = 0.0;
128 for(int i = 0; i < nDiags; ++i) {
129
130 const auto ret
131 = VTUToDiagram(intermediateDiagrams[i], inputDiagrams[i], *this);
132
133 double maxPers = this->getMaxPers(intermediateDiagrams[i]);
134 double percentage = this->Percent_;
135
136 intermediateDiagrams[i].erase(
137 std::remove_if(intermediateDiagrams[i].begin(),
138 intermediateDiagrams[i].end(),
139 [maxPers, percentage](ttk::PersistencePair &t) {
140 return (t.death.sfValue - t.birth.sfValue)
141 < (percentage / 100.) * maxPers;
142 }),
143 intermediateDiagrams[i].end());
144
145 if(ret != 0) {
146 this->printErr("Could not read Persistence Diagram");
147 return 0;
148 }
149 if(max_dimension_total < maxPers) {
150 max_dimension_total = maxPers;
151 }
152 }
153 for(int i = 0; i < numInputAtoms; ++i) {
154 const auto ret = VTUToDiagram(intermediateAtoms[i], inputAtoms[i], *this);
155 if(ret != 0) {
156 this->printErr("Could not read Persistence Diagram");
157 return 0;
158 }
159 }
160
161 std::vector<ttk::DiagramType> dictDiagrams;
162 const int seed = this->GetSeed_();
163
164 std::vector<std::vector<double>> vectorWeights(nDiags);
165 for(size_t i = 0; i < vectorWeights.size(); ++i) {
166 std::vector<double> weights(numAtom, 1. / (numAtom * 1.));
167 vectorWeights[i] = std::move(weights);
168 }
169
170 std::vector<double> lossTab;
171 std::vector<std::vector<double>> allLosses(nDiags);
172 this->execute(intermediateDiagrams, intermediateAtoms, dictDiagrams,
173 vectorWeights, seed, numAtom, lossTab, allLosses,
174 this->Percent_);
175 // zero-padd column name to keep Row Data columns ordered
176 outputWeights->SetNumberOfRows(nDiags);
177
178 const auto zeroPad
179 = [](std::string &colName, const size_t numberCols, const size_t colIdx) {
180 std::string max{std::to_string(numberCols - 1)};
181 std::string cur{std::to_string(colIdx)};
182 std::string zer(max.size() - cur.size(), '0');
183 colName.append(zer).append(cur);
184 };
185 for(int i = 0; i < numAtom; ++i) {
186 std::string name{"Atom"};
187 zeroPad(name, numAtom, i);
188 // name
189 vtkNew<vtkDoubleArray> col{};
190 col->SetNumberOfValues(nDiags);
191 col->SetName(name.c_str());
192 for(int j = 0; j < nDiags; ++j) {
193 col->SetValue(j, vectorWeights[j][i]);
194 }
195 col->Modified();
196 outputWeights->AddColumn(col);
197 }
198
199 vtkNew<vtkFieldData> fd{};
200 fd->CopyStructure(inputDiagrams[0]->GetFieldData());
201 fd->SetNumberOfTuples(nDiags);
202 for(int i = 0; i < nDiags; ++i) {
203 fd->SetTuple(i, 0, inputDiagrams[i]->GetFieldData());
204 }
205
206 for(int i = 0; i < fd->GetNumberOfArrays(); ++i) {
207 outputWeights->AddColumn(fd->GetAbstractArray(i));
208 }
209
210 vtkNew<vtkFloatArray> dummy{};
211
212 for(int i = 0; i < numAtom; ++i) {
213 vtkNew<vtkUnstructuredGrid> vtu;
214 ttk::DiagramType &diagram = dictDiagrams[i];
215 DiagramToVTU(vtu, diagram, dummy, *this, 3, false);
216 outputDgm->SetBlock(i, vtu);
217 }
218 return 1;
219}
TTK processing package for the computation of a Dictionary of Persistence Diagrams and barycentric we...
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
void execute(std::vector< ttk::DiagramType > &intermediateDiagrams, const std::vector< ttk::DiagramType > &intermediateAtoms, std::vector< ttk::DiagramType > &dictDiagrams, std::vector< std::vector< double > > &vectorWeights, const int seed, const int numAtom, std::vector< double > &lossTab, std::vector< std::vector< double > > &allLosses, double percent)
double getMaxPers(const ttk::DiagramType &data)
const std::string ENDCOLOR
Definition Debug.h:82
const std::string YELLOW
Definition Debug.h:77
const std::string UNDERLINED
Definition Debug.h:70
std::vector< PersistencePair > DiagramType
Persistence Diagram type as a vector of Persistence pairs.
T end(std::pair< T, T > &p)
Definition ripser.cpp:503
T begin(std::pair< T, T > &p)
Definition ripser.cpp:499
vtkStandardNewMacro(ttkPersistenceDiagramDictionary)
int DiagramToVTU(vtkUnstructuredGrid *vtu, const ttk::DiagramType &diagram, vtkDataArray *const inputScalars, const ttk::Debug &dbg, const int dim, const bool embedInDomain)
Converts a Persistence Diagram in the ttk::DiagramType format to the VTK Unstructured Grid format (as...
int VTUToDiagram(ttk::DiagramType &diagram, vtkUnstructuredGrid *vtu, const ttk::Debug &dbg)
Converts a Persistence Diagram in the VTK Unstructured Grid format (as generated by the ttkPersistenc...
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)