55int finalize(vector<vector<TrackingFromOverlap::Nodes>> &levelTimeNodesMap,
56 vector<vector<TrackingFromOverlap::Edges>> &levelTimeEdgesTMap,
57 vector<vector<TrackingFromOverlap::Edges>> &timeLevelEdgesNMap,
59 const string &labelFieldName,
61 vtkDataObject *trackingGraphObject) {
62 auto trackingGraph = vtkUnstructuredGrid::SafeDownCast(trackingGraphObject);
64 size_t const nL = levelTimeNodesMap.size();
65 size_t const nT = levelTimeNodesMap[0].size();
67 auto prepArray = [](vtkAbstractArray *array,
const string &name,
68 size_t nComponents,
size_t nValues) {
69 array->SetName(name.data());
70 array->SetNumberOfComponents(nComponents);
71 array->SetNumberOfTuples(nValues);
77 for(
size_t t = 0; t < nT; t++)
78 for(
size_t l = 0; l < nL; l++)
79 nNodes += levelTimeNodesMap[l][t].size();
82 points->SetNumberOfPoints(nNodes);
86 prepArray(sequence,
"SequenceIndex", 1, nNodes);
90 prepArray(level,
"LevelIndex", 1, nNodes);
94 prepArray(size,
"Size", 1, nNodes);
98 prepArray(branch,
"BranchId", 1, nNodes);
102 vtkDataArray::CreateDataArray(labelTypeId));
103 prepArray(label, labelFieldName, 1, nNodes);
106 size_t q1 = 0, q2 = 0;
107 for(
size_t t = 0; t < nT; t++) {
108 for(
size_t l = 0; l < nL; l++) {
109 for(
auto &node : levelTimeNodesMap[l][t]) {
110 pointCoords[q1++] = node.x;
111 pointCoords[q1++] = node.y;
112 pointCoords[q1++] = node.z;
114 sequenceData[q2] = t;
116 sizeData[q2] = node.size;
117 branchData[q2] = node.branchID;
118 labelData[q2] = boost::get<labelType>(node.label);
125 trackingGraph->SetPoints(points);
127 auto pointData = trackingGraph->GetPointData();
128 pointData->AddArray(sequence);
129 pointData->AddArray(level);
130 pointData->AddArray(size);
131 pointData->AddArray(label);
132 pointData->AddArray(branch);
137 if(nT * nL + 1 <= 0) {
142 vector<size_t> timeLevelOffsetMap(nT * nL + 1);
144 timeLevelOffsetMap[0] = 0;
146 for(
size_t t = 0; t < nT; t++)
147 for(
size_t l = 0; l < nL; l++) {
148 timeLevelOffsetMap[q]
149 = timeLevelOffsetMap[q - 1] + levelTimeNodesMap[l][t].size();
156 for(
size_t t = 0; t < nT - 1; t++)
157 for(
size_t l = 0; l < nL; l++)
158 nEdgesT += levelTimeEdgesTMap[l][t].size() / 4;
162 for(
size_t l = 0; l < nL - 1; l++)
163 for(
size_t t = 0; t < nT; t++)
164 nEdgesN += timeLevelEdgesNMap[t][l].size() / 4;
167 cells->SetNumberOfValues(3 * nEdgesT + 3 * nEdgesN);
171 prepArray(overlap,
"Overlap", 1, nEdgesT + nEdgesN);
175 prepArray(branch,
"BranchId", 1, nEdgesT + nEdgesN);
179 prepArray(type,
"Type", 1, nEdgesT + nEdgesN);
182 size_t q0 = 0, q1 = 0;
186 for(
size_t t = 1; t < nT; t++) {
187 for(
size_t l = 0; l < nL; l++) {
188 auto &edges = levelTimeEdgesTMap[l][t - 1];
189 for(
size_t i = 0, j = edges.size(); i < j;) {
192 = (vtkIdType)(timeLevelOffsetMap[(t - 1) * nL + l] + edges[i++]);
194 = (vtkIdType)(timeLevelOffsetMap[(t)*nL + l] + edges[i++]);
196 overlapData[q1] = edges[i++];
197 branchData[q1] = edges[i++];
205 for(
size_t l = 1; l < nL; l++) {
206 for(
size_t t = 0; t < nT; t++) {
207 auto &edges = timeLevelEdgesNMap[t][l - 1];
208 size_t const temp = t * nL;
209 for(
size_t i = 0, j = edges.size(); i < j;) {
212 = (vtkIdType)(timeLevelOffsetMap[temp + (l - 1)] + edges[i++]);
214 = (vtkIdType)(timeLevelOffsetMap[temp + (l)] + edges[i++]);
216 overlapData[q1] = edges[i++];
217 branchData[q1] = edges[i++];
224 cellArray->SetCells(nEdgesT + nEdgesN, cells);
225 trackingGraph->SetCells(VTK_LINE, cellArray);
227 auto cellData = trackingGraph->GetCellData();
228 cellData->AddArray(type);
229 cellData->AddArray(overlap);
230 cellData->AddArray(branch);
282 vtkDataObject *inputDataObject, vtkMultiBlockDataSet *packedInput)
const {
300 auto inputAsMB = vtkMultiBlockDataSet::SafeDownCast(inputDataObject);
301 auto inputAsPS = vtkPointSet::SafeDownCast(inputDataObject);
304 size_t const n = inputAsMB->GetNumberOfBlocks();
307 size_t psCounter = 0;
308 size_t mbCounter = 0;
309 for(
size_t i = 0; i < n; i++) {
310 auto block = inputAsMB->GetBlock(i);
311 auto blockAsMB = vtkMultiBlockDataSet::SafeDownCast(block);
312 auto blockAsPS = vtkPointSet::SafeDownCast(block);
321 packedInput->ShallowCopy(inputAsMB);
325 for(
size_t i = 0; i < n; i++) {
326 level->SetBlock(i, vtkPointSet::SafeDownCast(inputAsMB->GetBlock(i)));
328 packedInput->SetBlock(0, level);
332 }
else if(inputAsPS) {
334 level->SetBlock(0, inputAsPS);
335 packedInput->SetBlock(0, level);
341 printErr(
"Unable to convert input into "
342 "'vtkPointSet' collection.");
353 size_t const nL = data->GetNumberOfBlocks();
357 printErr(
"Input must have at least one "
362 for(
size_t l = 0; l < nL; l++) {
363 auto timesteps = vtkMultiBlockDataSet::SafeDownCast(data->GetBlock(l));
364 size_t const n = timesteps->GetNumberOfBlocks();
366 printErr(
"Input must have at least one "
373 printErr(
"Timeseries have unequal length.");
377 for(
size_t t = 0; t < nT; t++) {
378 auto pointSet = vtkPointSet::SafeDownCast(timesteps->GetBlock(t));
379 if(pointSet ==
nullptr) {
382 size_t const nPoints = pointSet->GetNumberOfPoints();
383 auto labels = pointSet->GetPointData()->GetAbstractArray(
386 if(nPoints > 0 && labels ==
nullptr) {
390 if(labels ==
nullptr)
393 int const labelDataType = labels->GetDataType();
394 if(this->LabelDataType < 0)
395 this->LabelDataType = labelDataType;
396 if(this->LabelDataType != labelDataType) {
397 printErr(
"Point labels do not have same "
398 "type across point sets.");
411 vtkMultiBlockDataSet *data)
const {
412 size_t const nL_PI = this->previousIterationData->GetNumberOfBlocks();
413 size_t const nL_CI = streamedData->GetNumberOfBlocks();
415 printErr(
"Number of levels differ over time.");
418 for(
size_t l = 0; l < nL_PI; l++) {
419 auto timestepsPI = vtkMultiBlockDataSet::SafeDownCast(
420 this->previousIterationData->GetBlock(l));
422 = vtkMultiBlockDataSet::SafeDownCast(streamedData->GetBlock(l));
423 size_t const nT_CI = timestepsCI->GetNumberOfBlocks();
428 timesteps->SetBlock(0, timestepsPI->GetBlock(0));
431 for(
size_t t = 0; t < nT_CI; t++)
432 timesteps->SetBlock(t + 1, timestepsCI->GetBlock(t));
434 data->SetBlock(l, timesteps);
474 getNumberOfLevelsAndTimesteps(data, nL, nT);
477 vtkPointSet *pointSet =
nullptr;
478 vtkDataArray *labels =
nullptr;
482 printMsg(
"=======================================================",
483 debug::Priority::INFO);
484 printMsg(
"Computing nodes", debug::Priority::INFO);
486 if(this->levelTimeNodesMap.size() != nL)
487 this->levelTimeNodesMap.resize(nL);
489 for(
size_t l = 0; l < nL; l++) {
491 printMsg(
"-------------------------------------------------------");
493 msg <<
"Level Index: " << l;
494 printMsg(msg.str(), debug::Priority::INFO);
497 vector<Nodes> &timeNodesMap = this->levelTimeNodesMap[l];
498 size_t const timeOffset = timeNodesMap.size();
499 timeNodesMap.resize(timeOffset + nT);
501 for(
size_t t = 0; t < nT; t++) {
504 size_t const nPoints = pointSet->GetNumberOfPoints();
508 switch(this->LabelDataType) {
509 vtkTemplateMacro(this->ttk::TrackingFromOverlap::computeNodes<VTK_TT>(
512 timeNodesMap[timeOffset + t]));
518 printMsg(
"-------------------------------------------------------");
522 printMsg(msg.str(), debug::Priority::PERFORMANCE);
537 getNumberOfLevelsAndTimesteps(data, nL, nT);
543 vtkPointSet *pointSet0 =
nullptr;
544 vtkPointSet *pointSet1 =
nullptr;
545 vtkDataArray *labels0 =
nullptr;
546 vtkDataArray *labels1 =
nullptr;
548 printMsg(
"=======================================================",
549 debug::Priority::INFO);
550 printMsg(
"Computing tracking graphs", debug::Priority::INFO);
552 if(this->levelTimeEdgesTMap.size() != nL)
553 this->levelTimeEdgesTMap.resize(nL);
555 for(
size_t l = 0; l < nL; l++) {
557 printMsg(
"-------------------------------------------------------");
559 msg <<
"Level Index: " << l;
560 printMsg(msg.str(), debug::Priority::INFO);
563 vector<Edges> &timeEdgesTMap = this->levelTimeEdgesTMap[l];
564 size_t const timeOffset = timeEdgesTMap.size();
565 timeEdgesTMap.resize(timeOffset + nT - 1);
567 for(
size_t t = 1; t < nT; t++) {
571 size_t const nPoints0 = pointSet0->GetNumberOfPoints();
572 size_t const nPoints1 = pointSet1->GetNumberOfPoints();
573 if(nPoints0 < 1 || nPoints1 < 1)
576 switch(this->LabelDataType) {
577 vtkTemplateMacro(this->computeOverlap<VTK_TT>(
582 timeEdgesTMap[timeOffset + t - 1]));
588 printMsg(
"-------------------------------------------------------");
590 msg <<
"Tracking graphs computed in " << timer.
getElapsedTime() <<
" s. ("
592 printMsg(msg.str(), debug::Priority::PERFORMANCE);
605 getNumberOfLevelsAndTimesteps(data, nL, nT);
611 vtkPointSet *pointSet0 =
nullptr;
612 vtkPointSet *pointSet1 =
nullptr;
613 vtkDataArray *labels0 =
nullptr;
614 vtkDataArray *labels1 =
nullptr;
616 printMsg(
"=======================================================",
617 debug::Priority::INFO);
618 printMsg(
"Computing nesting trees", debug::Priority::INFO);
620 size_t const timeOffset = this->timeLevelEdgesNMap.size();
621 this->timeLevelEdgesNMap.resize(timeOffset + nT);
623 for(
size_t t = 0; t < nT; t++) {
625 printMsg(
"-------------------------------------------------------");
627 msg <<
"Time Index: " << t;
628 printMsg(msg.str(), debug::Priority::INFO);
631 vector<Edges> &levelEdgesNMap = this->timeLevelEdgesNMap[timeOffset + t];
632 levelEdgesNMap.resize(nL - 1);
634 for(
size_t l = 1; l < nL; l++) {
638 size_t const nPoints0 = pointSet0->GetNumberOfPoints();
639 size_t const nPoints1 = pointSet1->GetNumberOfPoints();
640 if(nPoints0 < 1 || nPoints1 < 1)
643 switch(this->LabelDataType) {
644 vtkTemplateMacro(this->computeOverlap<VTK_TT>(
649 levelEdgesNMap[l - 1]));
655 printMsg(
"-------------------------------------------------------");
657 msg <<
"Nesting trees computed in " << timer.
getElapsedTime() <<
" s. ("
659 printMsg(msg.str(), debug::Priority::PERFORMANCE);
683 vtkInformationVector **inputVector,
684 vtkInformationVector *outputVector) {
690 "===================================================================");
691 printMsg(
"RequestData", debug::Priority::INFO);
695 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
696 auto inputObject = inInfo->Get(vtkDataObject::DATA_OBJECT());
699 auto iterationInformation = vtkDoubleArray::SafeDownCast(
700 inputObject->GetFieldData()->GetAbstractArray(
"_ttk_IterationInfo"));
702 bool const useStreamingOverTime = iterationInformation !=
nullptr;
704 double iteration = 0;
705 double nIterations = 0;
706 if(useStreamingOverTime) {
707 iteration = iterationInformation->GetValue(0);
708 nIterations = iterationInformation->GetValue(1);
712 if(!useStreamingOverTime || iteration == 0)
729 if(useStreamingOverTime && this->previousIterationData !=
nullptr) {
733 data->ShallowCopy(packedInput);
758 if(!useStreamingOverTime || iteration == nIterations - 1) {
760 vtkInformation *outInfo = outputVector->GetInformationObject(0);
761 auto trackingGraph = outInfo->Get(vtkDataObject::DATA_OBJECT());
775 if(!useStreamingOverTime) {
776 printMsg(
"=======================================================");
778 msg <<
"Nested tracking graph generated in " << timer.
getElapsedTime()
780 printMsg(msg.str(), debug::Priority::PERFORMANCE);
int finalize(vector< vector< TrackingFromOverlap::Nodes > > &levelTimeNodesMap, vector< vector< TrackingFromOverlap::Edges > > &levelTimeEdgesTMap, vector< vector< TrackingFromOverlap::Edges > > &timeLevelEdgesNMap, int labelTypeId, const string &labelFieldName, vtkDataObject *trackingGraphObject)