Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MergeTree] saddle-saddle pairs processing #1066

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 50 additions & 12 deletions core/vtk/ttkMergeTree/ttkMergeTreeUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,29 @@ namespace ttk {
return mergeTree;
}

// Returns a branch decomposition tree
/**
* @brief Create a MergeTree (as a branch decomposition tree) object given a
* vtkUnstructuredGrid representing a persistence diagram (in the TTK
* format).
*
* @param[in] persistenceDiagram vtk object representing the persistence
* diagram.
* @param[in] useSecondPairsType boolean to choose which pair type to use
* depending on the value of diagramPairTypes, by default the choice is
* between min-saddle and saddle-max, true for the second type and false for
* the first type.
* @param[in] diagramPairTypes 0 to choose between min-saddle and
* saddle-max, 1 to choose between min-saddle and saddle-saddle, 2 to choose
* between saddle-saddle and saddle-max.
*
* @return a MergeTree object corresponding to the input persistence
* diagram.
*/
template <class dataType>
MergeTree<dataType>
makeBDTreeFromPDGrid(vtkUnstructuredGrid *persistenceDiagram,
bool useSadMaxPairs = true) {
bool useSecondPairsType = true,
int diagramPairTypes = 0) {
auto birthArray
= persistenceDiagram->GetCellData()->GetArray(PersistenceBirthName);
auto persArray
Expand Down Expand Up @@ -126,6 +144,18 @@ namespace ttk {
// Init critical type enum values
auto locMin = static_cast<int>(CriticalType::Local_minimum);
auto locMax = static_cast<int>(CriticalType::Local_maximum);
auto locSad1 = static_cast<int>(CriticalType::Saddle1);
auto locSad2 = static_cast<int>(CriticalType::Saddle2);

// 0 : min-saddle ; 1 : saddle-saddle : 2 : saddle-max
int pairsType
= (useSecondPairsType
and (diagramPairTypes == 0 or diagramPairTypes == 2)
? 2
: (not useSecondPairsType
and (diagramPairTypes == 0 or diagramPairTypes == 1)
? 0
: 1));

// Get Min-Max pair index
int minMaxPairIndex = -1;
Expand All @@ -151,8 +181,11 @@ namespace ttk {
auto ct1 = criticalTypeArray->GetTuple1(pts[0]);
auto ct2 = criticalTypeArray->GetTuple1(pts[1]);
if((pairType == -1
or (useSadMaxPairs and ct1 != locMax and ct2 != locMax)
or (not useSadMaxPairs and ct1 != locMin and ct2 != locMin))
or (pairsType == 2 and ct1 != locMax and ct2 != locMax)
or (pairsType == 1
and not((ct1 == locSad1 and ct2 == locSad2)
or (ct1 == locSad2 and ct2 == locSad1)))
or (pairsType == 0 and ct1 != locMin and ct2 != locMin))
and i != minMaxPairIndex)
continue;
int const index1
Expand Down Expand Up @@ -218,7 +251,8 @@ namespace ttk {
std::vector<vtkUnstructuredGrid *> &treesNodes,
std::vector<vtkUnstructuredGrid *> &treesArcs,
std::vector<vtkDataSet *> &treesSegmentation,
std::vector<bool> useSadMaxPairs) {
const std::vector<bool> &useSecondPairsTypeVec,
int diagramPairTypes = 0) {
bool isPersistenceDiagram = false;
const int numInputs = inputTrees.size();
intermediateTrees.resize(numInputs);
Expand All @@ -242,7 +276,7 @@ namespace ttk {
vtkUnstructuredGrid *persistenceDiagram
= vtkUnstructuredGrid::SafeDownCast(inputTrees[i]->GetBlock(0));
intermediateTrees[i] = makeBDTreeFromPDGrid<dataType>(
persistenceDiagram, useSadMaxPairs[i]);
persistenceDiagram, useSecondPairsTypeVec[i], diagramPairTypes);
isPersistenceDiagram = true;
}
}
Expand All @@ -256,23 +290,27 @@ namespace ttk {
std::vector<vtkUnstructuredGrid *> &treesNodes,
std::vector<vtkUnstructuredGrid *> &treesArcs,
std::vector<vtkDataSet *> &treesSegmentation,
bool useSadMaxPairs = true) {
std::vector<bool> const useSadMaxPairsVec(
inputTrees.size(), useSadMaxPairs);
bool useSecondPairsType = true,
int diagramPairTypes = 0) {
const std::vector<bool> useSecondPairsTypeVec(
inputTrees.size(), useSecondPairsType);
return constructTrees(inputTrees, intermediateTrees, treesNodes,
treesArcs, treesSegmentation, useSadMaxPairsVec);
treesArcs, treesSegmentation, useSecondPairsTypeVec,
diagramPairTypes);
}

template <class dataType>
bool constructTrees(
std::vector<vtkSmartPointer<vtkMultiBlockDataSet>> &inputTrees,
std::vector<MergeTree<dataType>> &intermediateTrees,
bool useSadMaxPairs = true) {
bool useSecondPairsType = true,
int diagramPairTypes = 0) {
std::vector<vtkUnstructuredGrid *> treesNodes;
std::vector<vtkUnstructuredGrid *> treesArcs;
std::vector<vtkDataSet *> treesSegmentation;
return constructTrees(inputTrees, intermediateTrees, treesNodes,
treesArcs, treesSegmentation, useSadMaxPairs);
treesArcs, treesSegmentation, useSecondPairsType,
diagramPairTypes);
}
} // namespace ftm
} // namespace ttk
11 changes: 8 additions & 3 deletions core/vtk/ttkMergeTreeAutoencoder/ttkMergeTreeAutoencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ int ttkMergeTreeAutoencoder::runCompute(
std::vector<ttk::ftm::MergeTree<float>> intermediateMTrees,
intermediateMTrees2;

bool useSadMaxPairs = (mixtureCoefficient_ == 0);
bool useSecondPairsType = (mixtureCoefficient_ == 0);
isPersistenceDiagram_ = ttk::ftm::constructTrees<float>(
inputTrees, intermediateMTrees, treesNodes, treesArcs, treesSegmentation,
useSadMaxPairs);
useSecondPairsType, DiagramPairTypes);
// If merge trees are provided in input and normalization is not asked
convertToDiagram_
= (not isPersistenceDiagram_ and not normalizedWasserstein_);
Expand All @@ -200,7 +200,7 @@ int ttkMergeTreeAutoencoder::runCompute(
= (not isPersistenceDiagram_ ? inputTrees2 : inputTrees);
ttk::ftm::constructTrees<float>(inputTrees2ToUse, intermediateMTrees2,
treesNodes2, treesArcs2, treesSegmentation2,
!useSadMaxPairs);
!useSecondPairsType, DiagramPairTypes);
}
isPersistenceDiagram_ |= (not normalizedWasserstein_);

Expand Down Expand Up @@ -529,6 +529,11 @@ int ttkMergeTreeAutoencoder::runOutput(
arrayActivateFunction->InsertNextTuple1(activationFunction_);
output_coef->GetFieldData()->AddArray(arrayActivateFunction);

vtkNew<vtkIntArray> diagramPairTypesArray{};
diagramPairTypesArray->SetName("DiagramPairTypes");
diagramPairTypesArray->InsertNextTuple1(DiagramPairTypes);
output_coef->GetFieldData()->AddArray(diagramPairTypesArray);

// ------------------------------------------
// --- Axes Vectors
// ------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions core/vtk/ttkMergeTreeAutoencoder/ttkMergeTreeAutoencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class TTKMERGETREEAUTOENCODER_EXPORT ttkMergeTreeAutoencoder
*/
// Input options
double oldEpsilonTree1;
int DiagramPairTypes = 0;

// ----------------------
// Data for visualization
Expand Down Expand Up @@ -442,6 +443,13 @@ class TTKMERGETREEAUTOENCODER_EXPORT ttkMergeTreeAutoencoder
return mixtureCoefficient_;
}

void SetDiagramPairTypes(int diagramPairTypes) {
DiagramPairTypes = diagramPairTypes;
Modified();
resetDataVisualization();
}
vtkGetMacro(DiagramPairTypes, int);

void SetEpsilon1UseFarthestSaddle(bool epsilon1UseFarthestSaddle) {
epsilon1UseFarthestSaddle_ = epsilon1UseFarthestSaddle;
Modified();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ int ttkMergeTreeAutoencoderDecoding::RequestData(
else
printMsg("Computation without normalized Wasserstein.");

auto diagramPairTypesArray = fd->GetArray("DiagramPairTypes");
if(diagramPairTypesArray)
DiagramPairTypes = diagramPairTypesArray->GetTuple1(0);

// -----------------
// Origins
// -----------------
Expand All @@ -156,13 +160,13 @@ int ttkMergeTreeAutoencoderDecoding::RequestData(
std::vector<vtkDataSet *> originsTreeSegmentations,
originsPrimeTreeSegmentations;

bool useSadMaxPairs = (mixtureCoefficient_ == 0);
bool useSecondPairsType = (mixtureCoefficient_ == 0);
isPersistenceDiagram_ = ttk::ftm::constructTrees<float>(
origins, originsTrees, originsTreeNodes, originsTreeArcs,
originsTreeSegmentations, useSadMaxPairs);
ttk::ftm::constructTrees<float>(originsPrime, originsPrimeTrees,
originsTreeNodes, originsTreeArcs,
originsTreeSegmentations, useSadMaxPairs);
originsTreeSegmentations, useSecondPairsType, DiagramPairTypes);
ttk::ftm::constructTrees<float>(
originsPrime, originsPrimeTrees, originsTreeNodes, originsTreeArcs,
originsTreeSegmentations, useSecondPairsType, DiagramPairTypes);
// If merge trees are provided in input and normalization is not asked
convertToDiagram_
= (not isPersistenceDiagram_ and not normalizedWasserstein_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ class TTKMERGETREEAUTOENCODERDECODING_EXPORT ttkMergeTreeAutoencoderDecoding
* Add all filter parameters only as private member variables and
* initialize them here.
*/
#ifdef TTK_ENABLE_TORCH
int DiagramPairTypes = 0;
#endif

public:
/**
Expand Down
11 changes: 6 additions & 5 deletions core/vtk/ttkMergeTreeClustering/ttkMergeTreeClustering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,18 @@ int ttkMergeTreeClustering::runCompute(
std::vector<FTMTree_MT *> intermediateTrees(numInputs),
intermediateTrees2(numInputs2);

bool const useSadMaxPairs = (JoinSplitMixtureCoefficient == 0);
IsPersistenceDiagram
= constructTrees<dataType>(inputTrees, intermediateMTrees, treesNodes,
treesArcs, treesSegmentation, useSadMaxPairs);
bool const useSecondPairsType = (JoinSplitMixtureCoefficient == 0);
IsPersistenceDiagram = constructTrees<dataType>(
inputTrees, intermediateMTrees, treesNodes, treesArcs, treesSegmentation,
useSecondPairsType, DiagramPairTypes);
if(not IsPersistenceDiagram
or (JoinSplitMixtureCoefficient != 0
and JoinSplitMixtureCoefficient != 1)) {
auto &inputTrees2ToUse
= (not IsPersistenceDiagram ? inputTrees2 : inputTrees);
constructTrees<dataType>(inputTrees2ToUse, intermediateMTrees2, treesNodes2,
treesArcs2, treesSegmentation2, !useSadMaxPairs);
treesArcs2, treesSegmentation2,
!useSecondPairsType, DiagramPairTypes);
}

mergeTreeToFTMTree<dataType>(intermediateMTrees, intermediateTrees);
Expand Down
8 changes: 8 additions & 0 deletions core/vtk/ttkMergeTreeClustering/ttkMergeTreeClustering.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class TTKMERGETREECLUSTERING_EXPORT ttkMergeTreeClustering
bool oldNW = NormalizedWasserstein;
bool oldKS = KeepSubtree;
double JoinSplitMixtureCoefficient = 0.5;
int DiagramPairTypes = 0;
bool ComputeBarycenter = false;
unsigned int NumberOfBarycenters = 1;
double BarycenterSizeLimitPercent = 0.0;
Expand Down Expand Up @@ -314,6 +315,13 @@ class TTKMERGETREECLUSTERING_EXPORT ttkMergeTreeClustering
}
vtkGetMacro(JoinSplitMixtureCoefficient, double);

void SetDiagramPairTypes(int diagramPairTypes) {
DiagramPairTypes = diagramPairTypes;
Modified();
resetDataVisualization();
}
vtkGetMacro(DiagramPairTypes, int);

void SetComputeBarycenter(bool computeBarycenter) {
ComputeBarycenter = computeBarycenter;
Modified();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,16 @@ int ttkMergeTreeDistanceMatrix::run(
// Construct trees
const int numInputs = inputTrees.size();
std::vector<MergeTree<dataType>> intermediateTrees, intermediateTrees2;
bool const useSadMaxPairs = (mixtureCoefficient_ == 0); // only for PD support
isPersistenceDiagram_
= constructTrees(inputTrees, intermediateTrees, useSadMaxPairs);
bool const useSecondPairsType
= (mixtureCoefficient_ == 0); // only for PD support
isPersistenceDiagram_ = constructTrees(
inputTrees, intermediateTrees, useSecondPairsType, DiagramPairTypes);
if(not isPersistenceDiagram_
or (mixtureCoefficient_ != 0 and mixtureCoefficient_ != 1)) {
auto &inputTrees2ToUse
= (not isPersistenceDiagram_ ? inputTrees2 : inputTrees);
constructTrees(inputTrees2ToUse, intermediateTrees2, !useSadMaxPairs);
constructTrees(inputTrees2ToUse, intermediateTrees2, !useSecondPairsType,
DiagramPairTypes);
}

// Verify parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class TTKMERGETREEDISTANCEMATRIX_EXPORT ttkMergeTreeDistanceMatrix
bool oldKS = keepSubtree_;

bool UseFieldDataParameters = false;
int DiagramPairTypes = 0;

public:
/**
Expand Down Expand Up @@ -190,6 +191,9 @@ class TTKMERGETREEDISTANCEMATRIX_EXPORT ttkMergeTreeDistanceMatrix
vtkSetMacro(mixtureCoefficient_, double);
vtkGetMacro(mixtureCoefficient_, double);

vtkSetMacro(DiagramPairTypes, int);
vtkGetMacro(DiagramPairTypes, int);

/**
* This static method and the macro below are VTK conventions on how to
* instantiate VTK objects. You don't have to modify this.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ int ttkMergeTreePrincipalGeodesics::runCompute(
std::vector<ttk::ftm::MergeTree<dataType>> intermediateMTrees,
intermediateMTrees2;

bool const useSadMaxPairs = (mixtureCoefficient_ == 0);
bool const useSecondPairsType = (mixtureCoefficient_ == 0);
isPersistenceDiagram_ = ttk::ftm::constructTrees<dataType>(
inputTrees, intermediateMTrees, treesNodes, treesArcs, treesSegmentation,
useSadMaxPairs);
useSecondPairsType, DiagramPairTypes);
// If merge trees are provided in input and normalization is not asked
convertToDiagram_
= (not isPersistenceDiagram_ and not normalizedWasserstein_);
Expand All @@ -169,9 +169,9 @@ int ttkMergeTreePrincipalGeodesics::runCompute(
or (mixtureCoefficient_ != 0 and mixtureCoefficient_ != 1)) {
auto &inputTrees2ToUse
= (not isPersistenceDiagram_ ? inputTrees2 : inputTrees);
ttk::ftm::constructTrees<dataType>(inputTrees2ToUse, intermediateMTrees2,
treesNodes2, treesArcs2,
treesSegmentation2, !useSadMaxPairs);
ttk::ftm::constructTrees<dataType>(
inputTrees2ToUse, intermediateMTrees2, treesNodes2, treesArcs2,
treesSegmentation2, !useSecondPairsType, DiagramPairTypes);
}
isPersistenceDiagram_ |= (not normalizedWasserstein_);

Expand Down Expand Up @@ -329,6 +329,10 @@ int ttkMergeTreePrincipalGeodesics::runOutput(
array->InsertNextTuple1(getParamValueFromName(paramName));
output_coef->GetFieldData()->AddArray(array);
}
vtkNew<vtkIntArray> diagramPairTypesArray{};
diagramPairTypesArray->SetName("DiagramPairTypes");
diagramPairTypesArray->InsertNextTuple1(DiagramPairTypes);
output_coef->GetFieldData()->AddArray(diagramPairTypesArray);

// ------------------------------------------
// --- Geodesics Vectors
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class TTKMERGETREEPRINCIPALGEODESICS_EXPORT ttkMergeTreePrincipalGeodesics
*/
// Input options
double oldEpsilonTree1;
int DiagramPairTypes = 0;
// Output options

// ----------------------
Expand Down Expand Up @@ -169,6 +170,13 @@ class TTKMERGETREEPRINCIPALGEODESICS_EXPORT ttkMergeTreePrincipalGeodesics
return mixtureCoefficient_;
}

void SetDiagramPairTypes(int diagramPairTypes) {
DiagramPairTypes = diagramPairTypes;
Modified();
resetDataVisualization();
}
vtkGetMacro(DiagramPairTypes, int);

void SetKeepState(bool keepState) {
keepState_ = keepState;
Modified();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ int ttkMergeTreePrincipalGeodesicsDecoding::RequestData(
else
printMsg("Computation without normalized Wasserstein.");

auto diagramPairTypesArray
= tableCoefficients->GetFieldData()->GetArray("DiagramPairTypes");
if(diagramPairTypesArray)
DiagramPairTypes = diagramPairTypesArray->GetTuple1(0);

// ------------------------------------------------------------------------------------
// --- Load tables
// ------------------------------------------------------------------------------------
Expand Down Expand Up @@ -316,21 +321,21 @@ int ttkMergeTreePrincipalGeodesicsDecoding::runCompute(

std::vector<ttk::ftm::MergeTree<dataType>> baryDTree, inputDTrees;

std::vector<bool> useSadMaxPairsVec{false, true};
std::vector<bool> useSecondPairsTypeVec{false, true};
if(not useDoubleInput_ and mixtureCoefficient_ == 0)
useSadMaxPairsVec.erase(useSadMaxPairsVec.begin()); // {true}
useSecondPairsTypeVec.erase(useSecondPairsTypeVec.begin()); // {true}
ttk::ftm::constructTrees<dataType>(inputBary, baryDTree, baryTreeNodes,
baryTreeArcs, baryTreeSegmentation,
useSadMaxPairsVec);
useSecondPairsTypeVec, DiagramPairTypes);

if(OutputInputTrees
or (ReconstructInputTrees
and (computeReconstructionError_ or transferInputTreesInformation_))) {
bool const useSadMaxPairs
bool const useSecondPairsType
= (useDoubleInput_ and not processFirstInput) or mixtureCoefficient_ == 0;
bool const isInputPD = ttk::ftm::constructTrees<dataType>(
inputTrees, inputDTrees, inputTreesNodes, inputTreesArcs,
inputTreesSegmentation, useSadMaxPairs);
inputTreesSegmentation, useSecondPairsType, DiagramPairTypes);
if(not isInputPD and isPersistenceDiagram_)
mtsFlattening(inputDTrees);
}
Expand Down
Loading
Loading