196 template <
typename scalarType,
typename triangulationType>
199 const scalarType *
const scalars,
200 const triangulationType *triangulation);
209 template <
typename scalarType>
213 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
214 std::vector<PersistencePair> &diagram)
const;
224 template <
typename scalarType,
class triangulationType>
225 int execute(std::vector<PersistencePair> &CTDiagram,
226 const scalarType *inputScalars,
227 const size_t scalarsMTime,
229 const triangulationType *triangulation,
230 const std::vector<bool> *updateMask =
nullptr);
232 template <
typename scalarType,
class triangulationType>
233 int executeFTM(std::vector<PersistencePair> &CTDiagram,
234 const scalarType *inputScalars,
236 const triangulationType *triangulation);
238 template <
class triangulationType>
241 const triangulationType *triangulation);
242 template <
typename scalarType,
class triangulationType>
244 const scalarType *inputScalars,
245 const triangulationType *triangulation);
247 template <
class triangulationType>
250 const triangulationType *triangulation);
252 template <
typename scalarType,
class triangulationType>
254 const scalarType *inputScalars,
255 const size_t scalarsMTime,
257 const triangulationType *triangulation,
258 const std::vector<bool> *updateMask
261 template <
class triangulationType>
264 template <
class triangulationType>
265 void checkManifold(
const triangulationType *
const triangulation);
330template <
typename scalarType>
334 std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>> &pairs,
335 std::vector<PersistencePair> &diagram)
const {
338 diagram.resize(numberOfPairs);
342 const bool type = std::get<3>(pairs[i]);
367 diagram.back().isFinite =
false;
372template <
typename scalarType,
typename triangulationType>
374 std::vector<PersistencePair> &persistencePairs,
375 const scalarType *
const scalars,
376 const triangulationType *triangulation) {
378#ifdef TTK_ENABLE_OPENMP
379#pragma omp parallel for num_threads(threadNumber_)
381 for(std::size_t i = 0; i < persistencePairs.size(); ++i) {
382 auto &pair{persistencePairs[i]};
383 triangulation->getVertexPoint(pair.birth.id, pair.birth.coords[0],
384 pair.birth.coords[1], pair.birth.coords[2]);
385 pair.birth.
sfValue = scalars[pair.birth.id];
386 triangulation->getVertexPoint(pair.death.id, pair.death.coords[0],
387 pair.death.coords[1], pair.death.coords[2]);
388 pair.death.sfValue = scalars[pair.death.id];
392template <
typename scalarType,
class triangulationType>
394 const scalarType *inputScalars,
395 const size_t scalarsMTime,
397 const triangulationType *triangulation,
398 const std::vector<bool> *updateMask) {
402 checkProgressivityRequirement(triangulation);
403 checkManifold(triangulation);
408 case BACKEND::PERSISTENT_SIMPLEX:
409 executePersistentSimplex(CTDiagram, inputOffsets, triangulation);
411 case BACKEND::DISCRETE_MORSE_SANDWICH:
412 executeDiscreteMorseSandwich(CTDiagram, inputScalars, scalarsMTime,
413 inputOffsets, triangulation, updateMask);
415 case BACKEND::PROGRESSIVE_TOPOLOGY:
416 executeProgressiveTopology(CTDiagram, inputOffsets, triangulation);
418 case BACKEND::APPROXIMATE_TOPOLOGY:
419 executeApproximateTopology(CTDiagram, inputScalars, triangulation);
422 executeFTM(CTDiagram, inputScalars, inputOffsets, triangulation);
425 printErr(
"No method was selected");
428 this->
printMsg(
"Complete", 1.0, tm.getElapsedTime(), this->threadNumber_);
431 augmentPersistenceDiagram(CTDiagram, inputScalars, triangulation);
434 sortPersistenceDiagram(CTDiagram, inputOffsets);
441template <
class triangulationType>
443 std::vector<PersistencePair> &CTDiagram,
445 const triangulationType *triangulation) {
448 const auto dim = triangulation->getDimensionality();
450 std::vector<ttk::PersistentSimplexPairs::PersistencePair> pairs{};
452 psp_.setDebugLevel(this->debugLevel_);
453 psp_.setThreadNumber(this->threadNumber_);
454 psp_.computePersistencePairs(pairs, inputOffsets, *triangulation);
455 dms_.setInputOffsets(inputOffsets);
460#ifdef TTK_ENABLE_OPENMP
461#pragma omp parallel for num_threads(threadNumber_)
463 for(
size_t i = 0; i < pairs.size(); ++i) {
464 auto &pair{pairs[i]};
466 pair.birth = dms_.getCellGreaterVertex(
467 Cell{pair.type, pair.birth}, *triangulation);
469 if(pair.death != -1) {
470 pair.death = dms_.getCellGreaterVertex(
471 Cell{pair.type + 1, pair.death}, *triangulation);
475 CTDiagram.reserve(pairs.size() + 1);
478 const auto nVerts = triangulation->getNumberOfVertices();
480 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
483 for(
const auto &p : pairs) {
484 const auto isFinite = (p.death >= 0);
485 const auto death = isFinite ? p.death : globmax;
487 const auto deathType = (isFinite && dim > 1)
493 }
else if(p.type == 1) {
496 const auto deathType = (isFinite && dim == 3)
502 }
else if(p.type == 2) {
513template <
typename scalarType,
class triangulationType>
515 std::vector<PersistencePair> &CTDiagram,
516 const scalarType *inputScalars,
517 const size_t scalarsMTime,
519 const triangulationType *triangulation,
520 const std::vector<bool> *updateMask) {
523 const auto dim = triangulation->getDimensionality();
526 inputScalars, scalarsMTime, inputOffsets, *triangulation, updateMask);
527 std::vector<DiscreteMorseSandwich::PersistencePair> dms_pairs{};
528 dms_.computePersistencePairs(
529 dms_pairs, inputOffsets, *triangulation, this->IgnoreBoundary);
530 CTDiagram.resize(dms_pairs.size());
534#ifdef TTK_ENABLE_OPENMP
535#pragma omp parallel for num_threads(threadNumber_)
537 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
538 auto &pair{dms_pairs[i]};
540 pair.birth = dms_.getCellGreaterVertex(
541 Cell{pair.type, pair.birth}, *triangulation);
543 if(pair.death != -1) {
544 pair.death = dms_.getCellGreaterVertex(
545 Cell{pair.type + 1, pair.death}, *triangulation);
550 const auto nVerts = triangulation->getNumberOfVertices();
552 inputOffsets, std::max_element(inputOffsets, inputOffsets + nVerts));
555#ifdef TTK_ENABLE_OPENMP
556#pragma omp parallel for num_threads(threadNumber_)
558 for(
size_t i = 0; i < dms_pairs.size(); ++i) {
559 const auto &p{dms_pairs[i]};
560 const auto isFinite = (p.death >= 0);
561 const auto death = isFinite ? p.death : globmax;
569 }
else if(p.type == 1) {
577 }
else if(p.type == 2) {
590template <
typename scalarType,
class triangulationType>
592 std::vector<PersistencePair> &CTDiagram,
593 const scalarType *inputScalars,
594 const triangulationType *triangulation) {
596 approxT_.setDebugLevel(debugLevel_);
597 approxT_.setThreadNumber(threadNumber_);
600 approxT_.setStartingResolutionLevel(StartingResolutionLevel);
601 approxT_.setStoppingResolutionLevel(StoppingResolutionLevel);
602 approxT_.setPreallocateMemory(
true);
603 approxT_.setEpsilon(Epsilon);
605 std::vector<ApproximateTopology::PersistencePair> resultDiagram{};
607 approxT_.computeApproximatePD(
608 resultDiagram, inputScalars, (scalarType *)outputScalars_,
609 (
SimplexId *)outputOffsets_, (
int *)outputMonotonyOffsets_);
612 for(
const auto &p : resultDiagram) {
613 if(p.pairType == 0) {
618 }
else if(p.pairType == 2) {
623 }
else if(p.pairType == -1) {
634template <
class triangulationType>
636 std::vector<PersistencePair> &CTDiagram,
638 const triangulationType *triangulation) {
640 progT_.setDebugLevel(debugLevel_);
641 progT_.setThreadNumber(threadNumber_);
644 progT_.setStartingResolutionLevel(StartingResolutionLevel);
645 progT_.setStoppingResolutionLevel(StoppingResolutionLevel);
646 progT_.setTimeLimit(TimeLimit);
647 progT_.setIsResumable(IsResumable);
648 progT_.setPreallocateMemory(
true);
650 std::vector<ProgressiveTopology::PersistencePair> resultDiagram{};
652 progT_.computeProgressivePD(resultDiagram, inputOffsets);
655 for(
const auto &p : resultDiagram) {
656 if(p.pairType == 0) {
661 }
else if(p.pairType == 2) {
666 }
else if(p.pairType == -1) {
677template <
typename scalarType,
class triangulationType>
679 std::vector<PersistencePair> &CTDiagram,
680 const scalarType *inputScalars,
682 const triangulationType *triangulation) {
684 contourTree_.setVertexScalars(inputScalars);
686 contourTree_.setVertexSoSoffsets(inputOffsets);
687 contourTree_.setSegmentation(
false);
688 contourTree_.build<scalarType>(triangulation);
691 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> JTPairs;
692 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType>> STPairs;
693 contourTree_.computePersistencePairs<scalarType>(JTPairs,
true);
694 contourTree_.computePersistencePairs<scalarType>(STPairs,
false);
697 const auto JTSize = JTPairs.size();
698 const auto STSize = STPairs.size();
699 std::vector<std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool>>
700 CTPairs(JTSize + STSize);
701 for(
size_t i = 0; i < JTSize; ++i) {
702 const auto &x = JTPairs[i];
704 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
true);
706 for(
size_t i = 0; i < STSize; ++i) {
707 const auto &x = STPairs[i];
709 = std::make_tuple(std::get<0>(x), std::get<1>(x), std::get<2>(x),
false);
713 if(!CTPairs.empty()) {
716 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &a,
717 const std::tuple<ttk::SimplexId, ttk::SimplexId, scalarType, bool> &b) {
718 return std::get<2>(a) < std::get<2>(b);
721 std::sort(CTPairs.begin(), CTPairs.end(), cmp);
722 CTPairs.erase(CTPairs.end() - 1);
726 computeCTPersistenceDiagram<scalarType>(contourTree_, CTPairs, CTDiagram);
731template <
class triangulationType>
733 const triangulationType *
ttkNotUsed(triangulation)) {
735 if((BackEnd == BACKEND::PROGRESSIVE_TOPOLOGY
736 || BackEnd == BACKEND::APPROXIMATE_TOPOLOGY)
737 && !std::is_same<ttk::ImplicitWithPreconditions, triangulationType>::value
738 && !std::is_same<ttk::ImplicitNoPreconditions, triangulationType>::value) {
740 printWrn(
"Explicit, Compact or Periodic triangulation detected.");
741 printWrn(
"Defaulting to the FTM backend.");
743 BackEnd = BACKEND::FTM;
747template <
class triangulationType>
749 const triangulationType *
const triangulation) {
751 if(this->BackEnd != BACKEND::DISCRETE_MORSE_SANDWICH) {
755 if(!triangulation->isManifold()) {
756 this->printWrn(
"Non-manifold data-set detected.");
757 this->printWrn(
"Defaulting to the Persistence Simplex backend.");
759 this->BackEnd = BACKEND::PERSISTENT_SIMPLEX;
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual int preconditionBoundaryVertices()
virtual int preconditionManifold()
TTK processing package for progressive Topological Data Analysis.
void setDelta(double data)
virtual int setThreadNumber(const int threadNumber)
Minimalist debugging class.
virtual int setDebugLevel(const int &debugLevel)
TTK DiscreteMorseSandwich processing package.
void setComputeSadMax(const bool data)
void setComputeMinSad(const bool data)
void preconditionTriangulation(AbstractTriangulation *const data)
void setComputeSadSad(const bool data)
ImplicitTriangulation is a class that provides time and memory efficient traversal methods on triangu...
TTK processing package for the computation of persistence diagrams.
int executePersistentSimplex(std::vector< PersistencePair > &CTDiagram, const SimplexId *inputOffsets, const triangulationType *triangulation)
int StoppingResolutionLevel
ftm::FTMTreePP contourTree_
void setComputeSadSad(const bool data)
void setOutputMonotonyOffsets(void *data)
void sortPersistenceDiagram(std::vector< PersistencePair > &diagram, const SimplexId *const offsets) const
void preconditionTriangulation(AbstractTriangulation *triangulation)
ttk::ProgressiveTopology progT_
void setDeltaApproximate(double data)
void setBackend(const BACKEND be)
ttk::CriticalType getNodeType(ftm::FTMTree_MT *tree, ftm::TreeType treeType, const SimplexId vertexId) const
void checkProgressivityRequirement(const triangulationType *triangulation)
void setOutputScalars(void *data)
@ DISCRETE_MORSE_SANDWICH
int executeFTM(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const SimplexId *inputOffsets, const triangulationType *triangulation)
dcg::DiscreteGradient dcg_
int executeProgressiveTopology(std::vector< PersistencePair > &CTDiagram, const SimplexId *inputOffsets, const triangulationType *triangulation)
int execute(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const size_t scalarsMTime, const SimplexId *inputOffsets, const triangulationType *triangulation, const std::vector< bool > *updateMask=nullptr)
ttk::ApproximateTopology approxT_
DiscreteMorseSandwich dms_
int executeDiscreteMorseSandwich(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const size_t scalarsMTime, const SimplexId *inputOffsets, const triangulationType *triangulation, const std::vector< bool > *updateMask=nullptr)
void setComputeMinSad(const bool data)
void setOutputOffsets(void *data)
void augmentPersistenceDiagram(std::vector< PersistencePair > &persistencePairs, const scalarType *const scalars, const triangulationType *triangulation)
Complete a ttk::DiagramType instance with scalar field values (useful for persistence) and 3D coordin...
void setComputeSadMax(const bool data)
void * outputMonotonyOffsets_
int executeApproximateTopology(std::vector< PersistencePair > &CTDiagram, const scalarType *inputScalars, const triangulationType *triangulation)
PersistentSimplexPairs psp_
void checkManifold(const triangulationType *const triangulation)
int StartingResolutionLevel
int computeCTPersistenceDiagram(ftm::FTMTreePP &tree, const std::vector< std::tuple< ttk::SimplexId, ttk::SimplexId, scalarType, bool > > &pairs, std::vector< PersistencePair > &diagram) const
Textbook algorithm to find persistence pairs.
void preconditionTriangulation(AbstractTriangulation *const data)
Preprocess all the required connectivity requests on the triangulation.
TTK processing package for progressive Topological Data Analysis.
TTK discreteGradient processing package.
int setThreadNumber(const int n) override
FTMTree_MT * getSplitTree()
int setDebugLevel(const int &d) override
FTMTree_MT * getJoinTree()
void preconditionTriangulation(AbstractTriangulation *tri, const bool preproc=true)
CriticalType
default value for critical index
int SimplexId
Identifier type for simplices of any dimension.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)