1#include <vtkDoubleArray.h>
2#include <vtkInformation.h>
3#include <vtkIntArray.h>
5#include <vtkPointData.h>
19 this->SetNumberOfInputPorts(1);
20 this->SetNumberOfOutputPorts(2);
24 vtkInformation *info) {
26 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkUnstructuredGrid");
30 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkDataSet");
36 vtkInformation *info) {
38 info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
46 vtkInformationVector **inputVector,
47 vtkInformationVector *outputVector) {
49 vtkInformation *outInfo = outputVector->GetInformationObject(0);
51 && !vtkUnstructuredGrid::SafeDownCast(
52 outInfo->Get(vtkDataObject::DATA_OBJECT()))) {
53 vtkNew<vtkUnstructuredGrid> ug;
54 outInfo->Set(vtkDataObject::DATA_OBJECT(), ug);
57 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
58 vtkInformation *outInfo1 = outputVector->GetInformationObject(1);
59 if(!inInfo || !outInfo1)
62 vtkDataObject *inputDO = inInfo->Get(vtkDataObject::DATA_OBJECT());
63 vtkDataObject *currentDO = outInfo1->Get(vtkDataObject::DATA_OBJECT());
65 if(inputDO ==
nullptr)
68 if(currentDO ==
nullptr || !currentDO->IsA(inputDO->GetClassName())) {
71 outInfo1->Set(vtkDataObject::DATA_OBJECT(), newDO);
78template <
class dataType,
class triangulationType>
79int ttkTrackingFromFields::trackWithPersistenceMatching(
80 vtkUnstructuredGrid *output,
81 unsigned long fieldNumber,
82 const triangulationType *triangulation) {
84 std::vector<ttk::DiagramType> persistenceDiagrams(fieldNumber);
87 (
int)fieldNumber, persistenceDiagrams, triangulation);
89 std::vector<std::vector<ttk::MatchingType>> outputMatchings(fieldNumber - 1);
91 double const spacing = Spacing;
92 std::string
const algorithm = DistanceAlgorithm;
93 double const tolerance = Tolerance;
94 std::string
const wasserstein = WassersteinMetric;
100 (
int)fieldNumber, persistenceDiagrams, outputMatchings,
102 wasserstein, tolerance, PX, PY, PZ, PS, PE
105 vtkNew<vtkPoints>
const points{};
106 vtkNew<vtkUnstructuredGrid>
const persistenceDiagram{};
108 vtkNew<vtkDoubleArray> persistenceScalars{};
109 vtkNew<vtkDoubleArray> valueScalars{};
110 vtkNew<vtkIntArray> matchingIdScalars{};
111 vtkNew<vtkIntArray> lengthScalars{};
112 vtkNew<vtkIntArray> timeScalars{};
113 vtkNew<vtkIntArray> componentIds{};
114 vtkNew<vtkIntArray> pointTypeScalars{};
116 persistenceScalars->SetName(
"Cost");
117 valueScalars->SetName(
"Scalar");
118 matchingIdScalars->SetName(
"MatchingIdentifier");
119 lengthScalars->SetName(
"ComponentLength");
120 timeScalars->SetName(
"TimeStep");
121 componentIds->SetName(
"ConnectedComponentId");
122 pointTypeScalars->SetName(
"CriticalType");
124 std::vector<ttk::trackingTuple> trackingsBase;
125 tfp.
performTracking(persistenceDiagrams, outputMatchings, trackingsBase);
127 std::vector<std::set<int>> trackingTupleToMerged(trackingsBase.size());
131 trackingTupleToMerged, PostProcThresh);
134 bool const useGeometricSpacing = UseGeometricSpacing;
138 trackingsBase, outputMatchings, persistenceDiagrams, useGeometricSpacing,
139 spacing, DoPostProc, trackingTupleToMerged, points, persistenceDiagram,
140 persistenceScalars, valueScalars, matchingIdScalars, lengthScalars,
141 timeScalars, componentIds, pointTypeScalars, *
this);
143 output->ShallowCopy(persistenceDiagram);
148template <
class dataType,
class triangulationType>
149int ttkTrackingFromFields::trackWithCriticalPointMatching(
150 vtkUnstructuredGrid *output,
151 unsigned long fieldNumber,
152 const triangulationType *triangulation) {
156 float x = 0, y = 0, z = 0;
157 float maxX = 0, minX = 0, maxY = 0, minY = 0, maxZ = 0, minZ = 0;
158 triangulation->getVertexPoint(0, minX, minY, minZ);
159 triangulation->getVertexPoint(0, maxX, maxY, maxZ);
161 for(
int i = 0; i < triangulation->getNumberOfVertices(); i++) {
162 triangulation->getVertexPoint(i, x, y, z);
163 maxX = std::max(x, maxX);
164 maxX = std::min(x, minX);
165 maxY = std::max(y, maxX);
166 minY = std::min(y, minY);
167 maxZ = std::max(z, maxZ);
168 minZ = std::min(z, minZ);
171 double const relativeDestructionCost = RelativeDestructionCost;
172 double const tolerance = (double)Tolerance;
174 = std::sqrt(std::pow(maxX - minX, 2) + std::pow(maxY - minY, 2)
175 + std::pow(maxZ - minZ, 2));
176 int assignmentMethod = AssignmentMethod;
178 ttk::TrackingFromCriticalPoints tracker;
189 std::vector<ttk::DiagramType> persistenceDiagrams(fieldNumber);
191 (
int)fieldNumber, persistenceDiagrams, triangulation);
196 std::vector<std::vector<ttk::MatchingType>> maximaMatchings(fieldNumber - 1);
197 std::vector<std::vector<ttk::MatchingType>> sad_1_Matchings(fieldNumber - 1);
198 std::vector<std::vector<ttk::MatchingType>> sad_2_Matchings(fieldNumber - 1);
199 std::vector<std::vector<ttk::MatchingType>> minimaMatchings(fieldNumber - 1);
201 std::vector<std::vector<ttk::SimplexId>> maxMap(fieldNumber);
202 std::vector<std::vector<ttk::SimplexId>> sad_1Map(fieldNumber);
203 std::vector<std::vector<ttk::SimplexId>> sad_2Map(fieldNumber);
204 std::vector<std::vector<ttk::SimplexId>> minMap(fieldNumber);
207 sad_1_Matchings, sad_2_Matchings, minimaMatchings,
208 maxMap, sad_1Map, sad_2Map, minMap);
214 vtkNew<vtkPoints>
const points{};
215 vtkNew<vtkUnstructuredGrid>
const outputMesh{};
217 vtkNew<vtkDoubleArray> costs{};
218 vtkNew<vtkDoubleArray> averagePersistences{};
219 vtkNew<vtkDoubleArray> integratedPersistences{};
220 vtkNew<vtkDoubleArray> maximalPersistences{};
221 vtkNew<vtkDoubleArray> minimalPersistences{};
222 vtkNew<vtkDoubleArray> instantPersistences{};
223 vtkNew<vtkDoubleArray> valueScalars{};
224 vtkNew<vtkIntArray> globalVertexIds{};
225 vtkNew<vtkIntArray> lengthScalars{};
226 vtkNew<vtkIntArray> timeScalars{};
227 vtkNew<vtkIntArray> connectedComponentIds{};
228 vtkNew<vtkIntArray> pointsCriticalType{};
230 costs->SetName(
"Costs");
231 averagePersistences->SetName(
"AveragePersistence");
232 integratedPersistences->SetName(
"IntegratedPersistence");
233 maximalPersistences->SetName(
"MaximalPersistence");
234 minimalPersistences->SetName(
"MinimalPersistence");
235 instantPersistences->SetName(
"InstantPersistence");
236 valueScalars->SetName(
"Scalar");
237 globalVertexIds->SetName(
"VertexGlobalId");
238 lengthScalars->SetName(
"ComponentLength");
239 timeScalars->SetName(
"TimeStep");
240 connectedComponentIds->SetName(
"ConnectedComponentId");
241 pointsCriticalType->SetName(
"CriticalType");
243 std::vector<ttk::trackingTuple> allTrackings;
244 std::vector<std::vector<double>> allTrackingsCosts;
245 std::vector<std::vector<double>> allTrackingsInstantPersistence;
247 unsigned int typesArrayLimits[3] = {};
250 persistenceDiagrams, maximaMatchings, sad_1_Matchings, sad_2_Matchings,
251 minimaMatchings, maxMap, sad_1Map, sad_2Map, minMap, allTrackings,
252 allTrackingsCosts, allTrackingsInstantPersistence, typesArrayLimits);
258 double const spacing = Spacing;
259 bool const useGeometricSpacing = UseGeometricSpacing;
262 triangulation, allTrackings, allTrackingsCosts,
263 allTrackingsInstantPersistence, useGeometricSpacing, spacing, points,
264 outputMesh, pointsCriticalType, timeScalars, lengthScalars, globalVertexIds,
265 connectedComponentIds, costs, averagePersistences, integratedPersistences,
266 maximalPersistences, minimalPersistences, instantPersistences,
273 output->ShallowCopy(outputMesh);
278template <
class dataType,
class triangulationType>
279int ttkTrackingFromFields::applyPostProcessing(
280 vtkUnstructuredGrid *output,
281 vtkDataSet *segOutput,
283 const std::vector<vtkDataArray *> &inputScalarFields,
284 const triangulationType *triangulation) {
289 const bool rebuildMesh = (DoLinearize || DoFusion);
290 if(!rebuildMesh && !DoMergeTree) {
291 this->
printMsg(
"Nothing to do: all post-processing flags disabled.");
295 vtkIntArray *compIdArray = vtkIntArray::SafeDownCast(
296 output->GetCellData()->GetArray(
"ConnectedComponentId"));
297 vtkIntArray *timeArray
298 = vtkIntArray::SafeDownCast(output->GetPointData()->GetArray(
"TimeStep"));
299 vtkIntArray *vertexGlobalIdArray = vtkIntArray::SafeDownCast(
300 output->GetPointData()->GetArray(
"VertexGlobalId"));
301 vtkIntArray *criticalTypeArray = vtkIntArray::SafeDownCast(
302 output->GetPointData()->GetArray(
"CriticalType"));
304 if(!compIdArray || !timeArray || !vertexGlobalIdArray) {
305 this->
printErr(
"Tracking mesh is missing "
306 "ConnectedComponentId/TimeStep/VertexGlobalId; "
307 "skipping post-processing.");
311 const vtkIdType numCells = output->GetNumberOfCells();
312 std::map<int, std::vector<vtkIdType>> cellsByTraj;
313 for(vtkIdType cellId = 0; cellId < numCells; ++cellId)
314 cellsByTraj[compIdArray->GetValue(cellId)].push_back(cellId);
316 const int numTraj =
static_cast<int>(cellsByTraj.size());
317 std::vector<int> originalCCIds(numTraj, -1);
318 std::vector<std::vector<int>> trajTime(numTraj);
319 std::vector<std::vector<int>> trajVertexId(numTraj);
320 std::vector<std::vector<double>> trajX, trajY;
321 std::vector<int> trajCriticalType(numTraj, -1);
323 trajX.assign(numTraj, {});
324 trajY.assign(numTraj, {});
327 vtkNew<vtkIdList> cellPointIds;
328 auto collectUniqueSortedPointIds = [&](
const std::vector<vtkIdType> &cellIds,
329 std::vector<vtkIdType> &pointIds) {
331 pointIds.reserve(cellIds.size() * 2);
332 for(
const vtkIdType cId : cellIds) {
333 cellPointIds->Reset();
334 output->GetCellPoints(cId, cellPointIds);
335 const vtkIdType n = cellPointIds->GetNumberOfIds();
336 for(vtkIdType k = 0; k < n; ++k)
337 pointIds.push_back(cellPointIds->GetId(k));
339 std::sort(pointIds.begin(), pointIds.end());
341 std::unique(pointIds.begin(), pointIds.end()), pointIds.end());
342 std::sort(pointIds.begin(), pointIds.end(), [&](vtkIdType a, vtkIdType b) {
343 return timeArray->GetValue(a) < timeArray->GetValue(b);
348 for(
const auto &kv : cellsByTraj) {
349 originalCCIds[tIdx] = kv.first;
350 std::vector<vtkIdType> pointIds;
351 collectUniqueSortedPointIds(kv.second, pointIds);
353 auto &ts = trajTime[tIdx];
354 auto &vid = trajVertexId[tIdx];
355 ts.reserve(pointIds.size());
356 vid.reserve(pointIds.size());
358 trajX[tIdx].reserve(pointIds.size());
359 trajY[tIdx].reserve(pointIds.size());
363 for(
const vtkIdType pId : pointIds) {
364 ts.push_back(timeArray->GetValue(pId));
365 vid.push_back(vertexGlobalIdArray->GetValue(pId));
367 output->GetPoint(pId, xyz);
368 trajX[tIdx].push_back(xyz[0]);
369 trajY[tIdx].push_back(xyz[1]);
372 if(criticalTypeArray && !pointIds.empty())
373 trajCriticalType[tIdx] = criticalTypeArray->GetValue(pointIds.front());
377 ttk::TrackingPostProcessing ppt;
395 double *bounds = input->GetBounds();
404 std::vector<void *> inputFields;
405 inputFields.reserve(inputScalarFields.size());
406 for(vtkDataArray *a : inputScalarFields)
411 std::vector<std::vector<int>> vertexTrajPerFrame;
415 std::vector<ttk::TrackingPostProcessing::LinearTrajectory> rawTraj;
416 rawTraj.reserve(numTraj);
417 for(
int i = 0; i < numTraj; ++i) {
418 if(trajTime[i].empty())
420 ttk::TrackingPostProcessing::LinearTrajectory lt{};
427 for(
size_t k = 0; k < trajTime[i].size(); ++k)
430 rawTraj.push_back(std::move(lt));
433 std::vector<double> surfMin, surfMax, surfMean;
435 triangulation, rawTraj, surfMin, surfMax, surfMean, vertexTrajPerFrame);
437 this->
printWrn(
"Merge-tree segmentation failed; "
438 "keeping the raw tracking mesh.");
442 writeSegmentationArrays(segOutput, vertexTrajPerFrame);
444 this->
printMsg(
"Post-processing (merge-tree only, "
445 + std::to_string(rawTraj.size()) +
" trajectories)",
452 std::vector<ttk::TrackingPostProcessing::LinearTrajectory> linearTraj;
453 std::vector<ttk::TrackingPostProcessing::LinearTrajectory> finalTraj;
454 std::vector<ttk::TrackingPostProcessing::FuseRecord> fuseRecords;
455 std::vector<double> surfMin, surfMax, surfMean;
457 const int status = ppt.
execute<dataType, triangulationType>(
458 trajTime, trajVertexId, trajX, trajY, trajCriticalType, linearTraj,
459 finalTraj, fuseRecords, surfMin, surfMax, surfMean, vertexTrajPerFrame,
462 this->
printWrn(
"Post-processing returned non-success status; "
463 "keeping the raw tracking mesh.");
467 const vtkIdType nOut =
static_cast<vtkIdType
>(finalTraj.size());
470 for(
const auto &c : finalTraj) {
471 if(c.finalChainId > maxChainId)
472 maxChainId = c.finalChainId;
474 const int nChains = maxChainId + 1;
475 std::vector<int> chainCriticalType(std::max(nChains, 0), -1);
476 for(
size_t i = 0; i < linearTraj.size() && i < trajCriticalType.size(); ++i) {
477 const int cid = linearTraj[i].finalChainId;
478 if(cid >= 0 && cid < nChains && chainCriticalType[cid] < 0)
479 chainCriticalType[cid] = trajCriticalType[i];
482 vtkNew<vtkUnstructuredGrid> newGrid{};
483 vtkNew<vtkPoints> newPoints{};
484 vtkNew<vtkCellArray> newLines{};
485 newPoints->SetNumberOfPoints(2 * nOut);
487 auto makeIntArr = [](
const char *name, vtkIdType n) {
488 auto a = vtkSmartPointer<vtkIntArray>::New();
490 a->SetNumberOfTuples(n);
493 auto makeDblArr = [](
const char *name, vtkIdType n) {
494 auto a = vtkSmartPointer<vtkDoubleArray>::New();
496 a->SetNumberOfTuples(n);
500 auto trajIdArr = makeIntArr(
"TrajId", nOut);
501 auto startFrameArr = makeIntArr(
"StartFrame", nOut);
502 auto endFrameArr = makeIntArr(
"EndFrame", nOut);
503 auto durationArr = makeIntArr(
"Duration", nOut);
504 auto criticalTypeOut = makeIntArr(
"CriticalType", nOut);
505 auto axArr = makeDblArr(
"ax", nOut);
506 auto bxArr = makeDblArr(
"bx", nOut);
507 auto ayArr = makeDblArr(
"ay", nOut);
508 auto byArr = makeDblArr(
"by", nOut);
509 auto surfMinArr = makeDblArr(
"SegmentationMin", nOut);
510 auto surfMaxArr = makeDblArr(
"SegmentationMax", nOut);
511 auto surfMeanArr = makeDblArr(
"SegmentationMean", nOut);
512 vtkSmartPointer<vtkIntArray> compIdOut;
514 compIdOut = makeIntArr(
"ConnectedComponentId", nOut);
516 for(vtkIdType i = 0; i < nOut; ++i) {
517 const auto &c = finalTraj[i];
519 double x0, y0, x1, y1;
521 if(DoStartFrame && (DoLinearize || LinearizeFuse)) {
526 const int eF = c.endFrame;
532 }
else if(!c.criticalPoints.empty()) {
539 if(v0 >= 0 && v0 < triangulation->getNumberOfVertices()) {
541 triangulation->getVertexPoint(v0, a, b, cZ);
545 if(v1 >= 0 && v1 < triangulation->getNumberOfVertices()) {
547 triangulation->getVertexPoint(v1, a, b, cZ);
558 const vtkIdType p0 = 2 * i + 0;
559 const vtkIdType p1 = 2 * i + 1;
560 const double spacing = Spacing;
562 newPoints->SetPoint(p0, x0, y0,
static_cast<double>(sF * spacing));
563 newPoints->SetPoint(p1, x1, y1,
static_cast<double>(eF * spacing));
565 vtkNew<vtkLine> line{};
566 line->GetPointIds()->SetId(0, p0);
567 line->GetPointIds()->SetId(1, p1);
568 newLines->InsertNextCell(line);
570 trajIdArr->SetValue(i, c.finalChainId);
571 startFrameArr->SetValue(i, c.startFrame);
572 endFrameArr->SetValue(i, eF);
573 durationArr->SetValue(i, (eF - c.startFrame) + 1);
575 const int cid = c.finalChainId;
576 const int t = (cid >= 0 && cid < nChains) ? chainCriticalType[cid] : -1;
577 criticalTypeOut->SetValue(i, t);
579 axArr->SetValue(i, c.ax);
580 bxArr->SetValue(i, c.bx);
581 ayArr->SetValue(i, c.ay);
582 byArr->SetValue(i, c.by);
583 surfMinArr->SetValue(i, surfMin[i]);
584 surfMaxArr->SetValue(i, surfMax[i]);
585 surfMeanArr->SetValue(i, surfMean[i]);
587 compIdOut->SetValue(i, c.originalTrajId);
590 newGrid->SetPoints(newPoints);
591 newGrid->SetCells(VTK_LINE, newLines);
592 newGrid->GetCellData()->AddArray(trajIdArr);
594 newGrid->GetCellData()->AddArray(compIdOut);
595 newGrid->GetCellData()->AddArray(startFrameArr);
596 newGrid->GetCellData()->AddArray(endFrameArr);
597 newGrid->GetCellData()->AddArray(durationArr);
598 newGrid->GetCellData()->AddArray(criticalTypeOut);
599 newGrid->GetCellData()->AddArray(axArr);
600 newGrid->GetCellData()->AddArray(bxArr);
601 newGrid->GetCellData()->AddArray(ayArr);
602 newGrid->GetCellData()->AddArray(byArr);
604 newGrid->GetCellData()->AddArray(surfMinArr);
605 newGrid->GetCellData()->AddArray(surfMaxArr);
606 newGrid->GetCellData()->AddArray(surfMeanArr);
609 output->ShallowCopy(newGrid);
612 writeSegmentationArrays(segOutput, vertexTrajPerFrame);
618void ttkTrackingFromFields::writeSegmentationArrays(
619 vtkDataSet *segOutput,
620 const std::vector<std::vector<int>> &vertexTrajPerFrame) {
622 if(vertexTrajPerFrame.empty())
625 const vtkIdType nPts = segOutput->GetNumberOfPoints();
626 const int nFrames =
static_cast<int>(vertexTrajPerFrame.size());
628 for(
int frame = 0; frame < nFrames; ++frame) {
629 const auto &labels = vertexTrajPerFrame[frame];
630 if(
static_cast<vtkIdType
>(labels.size()) != nPts) {
631 this->
printWrn(
"Segmentation output size mismatch on frame "
632 + std::to_string(frame));
636 std::snprintf(segName,
sizeof(segName),
"Seg_%04d", frame);
637 vtkNew<vtkIntArray> segArr;
638 segArr->SetName(segName);
639 segArr->SetNumberOfComponents(1);
640 segArr->SetNumberOfTuples(nPts);
641 for(vtkIdType v = 0; v < nPts; ++v)
642 segArr->SetValue(v, labels[v]);
643 segOutput->GetPointData()->AddArray(segArr);
648 vtkInformationVector **inputVector,
649 vtkInformationVector *outputVector) {
651 auto input = vtkDataSet::GetData(inputVector[0]);
652 auto output = vtkUnstructuredGrid::GetData(outputVector, 0);
653 auto segOutput = vtkDataSet::GetData(outputVector, 1);
660 if(input ==
nullptr || output ==
nullptr || segOutput ==
nullptr) {
663 segOutput->ShallowCopy(input);
664 std::vector<vtkDataArray *> inputScalarFieldsRaw;
665 std::vector<vtkDataArray *> inputScalarFields;
666 const auto pointData = input->GetPointData();
667 int numberOfInputFields = pointData->GetNumberOfArrays();
668 if(numberOfInputFields < 3) {
669 this->
printErr(
"Not enough input fields to perform tracking.");
672 vtkDataArray *firstScalarField = pointData->GetArray(0);
674 for(
int i = 0; i < numberOfInputFields; ++i) {
675 vtkDataArray *currentScalarField = pointData->GetArray(i);
676 if(currentScalarField ==
nullptr
677 || currentScalarField->GetName() ==
nullptr) {
680 std::string
const sfname{currentScalarField->GetName()};
681 if(sfname.rfind(
"_Order") == (sfname.size() - 6)) {
684 if(firstScalarField->GetDataType() != currentScalarField->GetDataType()) {
685 this->
printErr(
"Inconsistent field data type or size between fields `"
686 + std::string{firstScalarField->GetName()} +
"' and `"
690 inputScalarFieldsRaw.push_back(currentScalarField);
693 std::sort(inputScalarFieldsRaw.begin(), inputScalarFieldsRaw.end(),
694 [](vtkDataArray *a, vtkDataArray *b) {
695 std::string s1 = a->GetName();
696 std::string s2 = b->GetName();
697 return std::lexicographical_compare(
698 s1.begin(), s1.end(), s2.begin(), s2.end());
701 numberOfInputFields = inputScalarFieldsRaw.size();
702 int const end = EndTimestep <= 0 ? numberOfInputFields
703 : std::min(numberOfInputFields, EndTimestep);
704 for(
int i = StartTimestep; i <
end; i += Sampling) {
705 vtkDataArray *currentScalarField = inputScalarFieldsRaw[i];
708 inputScalarFields.push_back(currentScalarField);
712 std::string
const algorithm = DistanceAlgorithm;
713 int const pvalg = PVAlgorithm;
714 bool useTTKMethod =
false;
715 bool trackWithCriticalPoints = (pvalg == 2);
728 this->
printMsg(
"Unrecognized tracking method.");
733 switch(str2int(algorithm.c_str())) {
737 case str2int(
"legacy"):
739 case str2int(
"geometric"):
741 case str2int(
"parallel"):
745 case str2int(
"greedy"):
748 this->
printMsg(
"Unrecognized tracking method.");
754 int const fieldNumber = inputScalarFields.size();
755 std::vector<void *> inputFields(fieldNumber);
756 for(
int i = 0; i < fieldNumber; i++) {
762 std::vector<ttk::SimplexId *> inputOrders(fieldNumber);
763 for(
int i = 0; i < fieldNumber; ++i) {
764 this->SetInputArrayToProcess(0, 0, 0, 0, inputScalarFields[i]->GetName());
766 = this->
GetOrderArray(input, 0, triangulation,
false, 0,
false);
773 this->
printMsg(
"Tracking trajectories over " + std::to_string(fieldNumber)
775 if(useTTKMethod && !trackWithCriticalPoints) {
777 inputScalarFields[0]->GetDataType(), triangulation->
getType(),
778 (status = this->trackWithPersistenceMatching<VTK_TT, TTK_TT>(
779 output, fieldNumber, (TTK_TT *)triangulation->
getData())));
780 }
else if(useTTKMethod && trackWithCriticalPoints) {
782 inputScalarFields[0]->GetDataType(), triangulation->
getType(),
783 (status = this->trackWithCriticalPointMatching<VTK_TT, TTK_TT>(
784 output, fieldNumber, (TTK_TT *)triangulation->
getData())));
786 this->
printMsg(
"The specified matching method is not supported.");
789 if(status == 1 && EnablePostProc) {
792 (this->applyPostProcessing<VTK_TT, TTK_TT>(
793 output, segOutput, input, inputScalarFields,
794 (TTK_TT *)triangulation->
getData())));
#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 RequestDataObject(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
static int buildMeshAlt(const triangulationType *triangulation, const std::vector< ttk::trackingTuple > &trackings, const std::vector< std::vector< double > > &allTrackingsCosts, const std::vector< std::vector< double > > &allTrackingsInstantPersistence, const bool useGeometricSpacing, const double spacing, vtkPoints *points, vtkUnstructuredGrid *outputMesh, vtkIntArray *pointsCriticalType, vtkIntArray *timeScalars, vtkIntArray *lengthScalars, vtkIntArray *globalVertexIds, vtkIntArray *connectedComponentIds, vtkDoubleArray *costs, vtkDoubleArray *averagePersistence, vtkDoubleArray *integratedPersistence, vtkDoubleArray *maximalPersistence, vtkDoubleArray *minimalPersistence, vtkDoubleArray *instantPersistence, unsigned int *sizes)
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 printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
virtual int setDebugLevel(const int &debugLevel)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void setAssignmentPrecision(double p)
void setMeshDiameter(double r)
void setTolerance(double t)
void setAssignmentMethod(int a)
void setWeights(double PX, double PY, double PZ, double PF)
void performMatchings(const std::vector< DiagramType > &persistenceDiagrams, std::vector< std::vector< MatchingType > > &maximaMatchings, std::vector< std::vector< MatchingType > > &sad_1_Matchings, std::vector< std::vector< MatchingType > > &sad_2_Matchings, std::vector< std::vector< MatchingType > > &minimaMatchings, std::vector< std::vector< SimplexId > > &maxMap, std::vector< std::vector< SimplexId > > &sad_1Map, std::vector< std::vector< SimplexId > > &sad_2Map, std::vector< std::vector< SimplexId > > &minMap)
void performTrackings(const std::vector< DiagramType > &persistenceDiagrams, const std::vector< std::vector< MatchingType > > &maximaMatchings, const std::vector< std::vector< MatchingType > > &sad_1_Matchings, const std::vector< std::vector< MatchingType > > &sad_2_Matchings, const std::vector< std::vector< MatchingType > > &minimaMatchings, const std::vector< std::vector< SimplexId > > &maxMap, const std::vector< std::vector< SimplexId > > &sad_1Map, const std::vector< std::vector< SimplexId > > &sad_2Map, const std::vector< std::vector< SimplexId > > &minMap, std::vector< trackingTuple > &allTrackings, std::vector< std::vector< double > > &allTrackingsCost, std::vector< std::vector< double > > &allTrackingsInstantPersistences, unsigned int(&typesArrayLimits)[3])
void setEpsilon(double e)
void setInputOffsets(std::vector< SimplexId * > &io)
void preconditionTriangulation(AbstractTriangulation *triangulation)
void setInputScalars(std::vector< void * > &is)
int performDiagramComputation(int fieldNumber, std::vector< ttk::DiagramType > &persistenceDiagrams, const triangulationType *triangulation)
int performMatchings(int numInputs, std::vector< ttk::DiagramType > &inputPersistenceDiagrams, std::vector< std::vector< MatchingType > > &outputMatchings, const std::string &algorithm, const std::string &wasserstein, double tolerance, double px, double py, double pz, double ps, double pe)
int performTracking(std::vector< ttk::DiagramType > &allDiagrams, std::vector< std::vector< MatchingType > > &allMatchings, std::vector< trackingTuple > &trackings)
int performPostProcess(const std::vector< ttk::DiagramType > &allDiagrams, const std::vector< trackingTuple > &trackings, std::vector< std::set< int > > &trackingTupleToMerged, const double postProcThresh)
void setUseSplitTree(int v)
void setDoLinearizeFuse(bool v)
void setMaxSurfSize(int v)
int execute(const std::vector< std::vector< int > > &trajTime, const std::vector< std::vector< int > > &trajVertexId, const std::vector< std::vector< double > > &coordsX, const std::vector< std::vector< double > > &coordsY, const std::vector< int > &trajCriticalType, std::vector< LinearTrajectory > &linearTraj, std::vector< LinearTrajectory > &finalTraj, std::vector< FuseRecord > &fuseRecords, std::vector< double > &surfMin, std::vector< double > &surfMax, std::vector< double > &surfMean, std::vector< std::vector< int > > &vertexTrajPerFrame, const triangulationType *triangulation)
correctTrajectory + computeMergeTree.
void setInputScalars(const std::vector< void * > &inputScalars)
void setBoundaryXMax(double v)
void setBoundaryYMin(double v)
void setMaxRadius(double v)
void setMaxFrameDist(int v)
int preconditionTriangulation(ttk::AbstractTriangulation *triangulation) const
void setPersistenceThreshold(double v)
void setDoMergeTree(bool v)
void setBoundaryXMin(double v)
void setBoundaryYMax(double v)
void setUseOtsuSimplification(bool v)
int computeMergeTree(const triangulationType *triangulation, const std::vector< LinearTrajectory > &finalTraj, std::vector< double > &surfMin, std::vector< double > &surfMax, std::vector< double > &surfMean, std::vector< std::vector< int > > &vertexTrajPerFrame)
Compute merge-tree-based segmentation per trajectory && per frame.
void setDoLinearize(bool v)
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
AbstractTriangulation * getData()
Triangulation::Type getType() const
int SimplexId
Identifier type for simplices of any dimension.
constexpr unsigned long long str2int(const char *str, int h=0)
T end(std::pair< T, T > &p)
std::vector< std::pair< int, ttk::SimplexId > > criticalPoints
#define ttkVtkTemplateMacro(dataType, triangulationType, call)
vtkStandardNewMacro(ttkTrackingFromFields)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)