1#include <vtkDoubleArray.h>
2#include <vtkInformation.h>
3#include <vtkPointData.h>
13 this->SetNumberOfInputPorts(1);
14 this->SetNumberOfOutputPorts(1);
18 vtkInformation *info) {
20 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkUnstructuredGrid");
26 vtkInformation *info) {
28 info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
35template <
class dataType,
class triangulationType>
36int ttkTrackingFromFields::trackWithPersistenceMatching(
37 vtkUnstructuredGrid *output,
38 unsigned long fieldNumber,
39 const triangulationType *triangulation) {
44 std::vector<ttk::DiagramType> persistenceDiagrams(fieldNumber);
46 this->performDiagramComputation<dataType, triangulationType>(
47 (
int)fieldNumber, persistenceDiagrams, triangulation);
50 std::vector<std::vector<ttk::MatchingType>> outputMatchings(fieldNumber - 1);
52 double const spacing = Spacing;
53 std::string
const algorithm = DistanceAlgorithm;
54 double const tolerance = Tolerance;
55 std::string
const wasserstein = WassersteinMetric;
61 (
int)fieldNumber, persistenceDiagrams, outputMatchings,
63 wasserstein, tolerance, PX, PY, PZ, PS, PE
66 vtkNew<vtkPoints>
const points{};
67 vtkNew<vtkUnstructuredGrid>
const persistenceDiagram{};
69 vtkNew<vtkDoubleArray> persistenceScalars{};
70 vtkNew<vtkDoubleArray> valueScalars{};
71 vtkNew<vtkIntArray> matchingIdScalars{};
72 vtkNew<vtkIntArray> lengthScalars{};
73 vtkNew<vtkIntArray> timeScalars{};
74 vtkNew<vtkIntArray> componentIds{};
75 vtkNew<vtkIntArray> pointTypeScalars{};
77 persistenceScalars->SetName(
"Cost");
78 valueScalars->SetName(
"Scalar");
79 matchingIdScalars->SetName(
"MatchingIdentifier");
80 lengthScalars->SetName(
"ComponentLength");
81 timeScalars->SetName(
"TimeStep");
82 componentIds->SetName(
"ConnectedComponentId");
83 pointTypeScalars->SetName(
"CriticalType");
86 std::vector<trackingTuple> trackingsBase;
87 tfp.performTracking(persistenceDiagrams, outputMatchings, trackingsBase);
89 std::vector<std::set<int>> trackingTupleToMerged(trackingsBase.size());
92 tfp.performPostProcess(persistenceDiagrams, trackingsBase,
93 trackingTupleToMerged, PostProcThresh);
96 bool const useGeometricSpacing = UseGeometricSpacing;
100 trackingsBase, outputMatchings, persistenceDiagrams, useGeometricSpacing,
101 spacing, DoPostProc, trackingTupleToMerged, points, persistenceDiagram,
102 persistenceScalars, valueScalars, matchingIdScalars, lengthScalars,
103 timeScalars, componentIds, pointTypeScalars, *
this);
105 output->ShallowCopy(persistenceDiagram);
111 vtkInformationVector **inputVector,
112 vtkInformationVector *outputVector) {
114 auto input = vtkDataSet::GetData(inputVector[0]);
115 auto output = vtkUnstructuredGrid::GetData(outputVector);
124 if(input ==
nullptr || output ==
nullptr) {
129 std::vector<vtkDataArray *> inputScalarFieldsRaw;
130 std::vector<vtkDataArray *> inputScalarFields;
131 const auto pointData = input->GetPointData();
132 int numberOfInputFields = pointData->GetNumberOfArrays();
133 if(numberOfInputFields < 3) {
134 this->
printErr(
"Not enough input fields to perform tracking.");
137 vtkDataArray *firstScalarField = pointData->GetArray(0);
139 for(
int i = 0; i < numberOfInputFields; ++i) {
140 vtkDataArray *currentScalarField = pointData->GetArray(i);
141 if(currentScalarField ==
nullptr
142 || currentScalarField->GetName() ==
nullptr) {
145 std::string
const sfname{currentScalarField->GetName()};
146 if(sfname.rfind(
"_Order") == (sfname.size() - 6)) {
149 if(firstScalarField->GetDataType() != currentScalarField->GetDataType()) {
150 this->
printErr(
"Inconsistent field data type or size between fields `"
151 + std::string{firstScalarField->GetName()} +
"' and `"
155 inputScalarFieldsRaw.push_back(currentScalarField);
158 std::sort(inputScalarFieldsRaw.begin(), inputScalarFieldsRaw.end(),
159 [](vtkDataArray *a, vtkDataArray *b) {
160 std::string s1 = a->GetName();
161 std::string s2 = b->GetName();
162 return std::lexicographical_compare(
163 s1.begin(), s1.end(), s2.begin(), s2.end());
166 numberOfInputFields = inputScalarFieldsRaw.size();
167 int const end = EndTimestep <= 0 ? numberOfInputFields
168 : std::min(numberOfInputFields, EndTimestep);
169 for(
int i = StartTimestep; i <
end; i += Sampling) {
170 vtkDataArray *currentScalarField = inputScalarFieldsRaw[i];
173 inputScalarFields.push_back(currentScalarField);
177 std::string
const algorithm = DistanceAlgorithm;
178 int const pvalg = PVAlgorithm;
179 bool useTTKMethod =
false;
192 this->
printMsg(
"Unrecognized tracking method.");
197 switch(str2int(algorithm.c_str())) {
201 case str2int(
"legacy"):
203 case str2int(
"geometric"):
205 case str2int(
"parallel"):
209 case str2int(
"greedy"):
212 this->
printMsg(
"Unrecognized tracking method.");
218 int const fieldNumber = inputScalarFields.size();
219 std::vector<void *> inputFields(fieldNumber);
220 for(
int i = 0; i < fieldNumber; ++i) {
226 std::vector<ttk::SimplexId *> inputOrders(fieldNumber);
227 for(
int i = 0; i < fieldNumber; ++i) {
228 this->SetInputArrayToProcess(0, 0, 0, 0, inputScalarFields[i]->GetName());
230 = this->
GetOrderArray(input, 0, triangulation,
false, 0,
false);
239 inputScalarFields[0]->GetDataType(), triangulation->
getType(),
240 (status = this->trackWithPersistenceMatching<VTK_TT, TTK_TT>(
241 output, fieldNumber, (TTK_TT *)triangulation->
getData())));
243 this->
printMsg(
"The specified matching method is not supported.");
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
vtkDataArray * GetOrderArray(vtkDataSet *const inputData, const int scalarArrayIdx, ttk::Triangulation *triangulation, const bool getGlobalOrder=false, const int orderArrayIdx=0, const bool enforceOrderArrayIdx=false)
TTK VTK-filter that takes an input time-varying data set (represented by a list of scalar fields) and...
int FillOutputPortInformation(int port, vtkInformation *info) override
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
static int buildMesh(const std::vector< ttk::trackingTuple > &trackings, const std::vector< std::vector< ttk::MatchingType > > &outputMatchings, const std::vector< ttk::DiagramType > &inputPersistenceDiagrams, const bool useGeometricSpacing, const double spacing, const bool doPostProc, const std::vector< std::set< int > > &trackingTupleToMerged, vtkPoints *points, vtkUnstructuredGrid *persistenceDiagram, vtkDoubleArray *persistenceScalars, vtkDoubleArray *valueScalars, vtkIntArray *matchingIdScalars, vtkIntArray *lengthScalars, vtkIntArray *timeScalars, vtkIntArray *componentIds, vtkIntArray *pointTypeScalars, const ttk::Debug &dbg)
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
virtual int setThreadNumber(const int threadNumber)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void setInputOffsets(std::vector< SimplexId * > &io)
void preconditionTriangulation(AbstractTriangulation *triangulation)
void setInputScalars(std::vector< void * > &is)
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
AbstractTriangulation * getData()
Triangulation::Type getType() const
constexpr unsigned long long str2int(const char *str, int h=0)
std::tuple< int, int, std::vector< SimplexId > > trackingTuple
int SimplexId
Identifier type for simplices of any dimension.
T end(std::pair< T, T > &p)
#define ttkVtkTemplateMacro(dataType, triangulationType, call)
vtkStandardNewMacro(ttkTrackingFromFields)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)