Skip to content

Morse persistence

Pipeline description

The first step is to create the data for our example. A plane is created to which we add random scalar values to create noise. The obtained scalar field is smoothed using the ScalarFieldSmoother. A sum of sine as scalar values is also added to create the nine main hills.

Then, the PersistenceDiagram is computed and thresholds are applied base on persistence to maintain only the most persistent features. This results in a simplified persistence diagram (bottom right view in the above screenshot).

The PersistenceCurve is also computed (top right view in the above screenshot).

The simplified persistence diagram is then used as a constraint for the TopologicalSimplification of the input scalar data.

This simplified data is then used as the input of the computation of MorseSmaleComplex (center view, above screenshot). This complex is composed of elements of 3 dimensions: dimension 0, which corresponds to the critical points of the Morse-Smale Complex, dimension 1, which corresponds to its edges (in grey in the screenshot) and dimension 2, which corresponds to its surfaces.

ParaView

To reproduce the above screenshot, go to your ttk-data directory and enter the following command:

$ paraview --state=states/morsePersistence.pvsm

Python code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python

from paraview.simple import *

# paraview 5.9 VS 5.10 compatibility ===========================================
def ThresholdBetween(threshold, lower, upper):
    try:
        # paraview 5.9
        threshold.ThresholdRange = [lower, upper]
    except:
        # paraview 5.10
        threshold.ThresholdMethod = "Between"
        threshold.LowerThreshold = lower
        threshold.UpperThreshold = upper
# end of comphatibility ========================================================

# create a new 'Plane'
plane1 = Plane()
plane1.XResolution = 300
plane1.YResolution = 300

# create a new 'Tetrahedralize'
tetrahedralize2 = Tetrahedralize(Input=plane1)

# create a new 'Random Attributes'
randomAttributes1 = RandomAttributes(Input=tetrahedralize2)
randomAttributes1.DataType = 'Float'
randomAttributes1.ComponentRange = [0.0, 1.0]
randomAttributes1.GeneratePointScalars = 1

# create a new 'TTK ScalarFieldSmoother'
tTKScalarFieldSmoother1 = TTKScalarFieldSmoother(Input=randomAttributes1)
tTKScalarFieldSmoother1.ScalarField = ['POINTS', 'RandomPointScalars']
tTKScalarFieldSmoother1.IterationNumber = 6

# create a new 'Calculator'
sine = Calculator(Input=tTKScalarFieldSmoother1)
sine.ResultArrayName = 'Sine'
sine.Function = 'sin(20*coordsX+1.5)+sin(20*coordsY+1.5)'

# create a new 'Calculator'
distanceField = Calculator(Input=sine)
distanceField.ResultArrayName = 'DistanceField'
distanceField.Function = '-sqrt(coordsX*coordsX+coordsY*coordsY)'

# create a new 'Calculator'
calculator1 = Calculator(Input=distanceField)
calculator1.ResultArrayName = 'Blend'
calculator1.Function = 'Sine+5*DistanceField+5*RandomPointScalars'

# create a new 'Extract Surface'
extractSurface6 = ExtractSurface(Input=calculator1)

# create a new 'Warp By Scalar'
warpByScalar1 = WarpByScalar(Input=extractSurface6)
warpByScalar1.Scalars = ['POINTS', 'Blend']
warpByScalar1.ScaleFactor = 0.05

# create a new 'TTK PersistenceCurve'
tTKPersistenceCurve1 = TTKPersistenceCurve(Input=warpByScalar1)
tTKPersistenceCurve1.ScalarField = ['POINTS', 'Blend']

# create a new 'TTK PersistenceDiagram'
tTKPersistenceDiagram1 = TTKPersistenceDiagram(Input=warpByScalar1)
tTKPersistenceDiagram1.ScalarField = ['POINTS', 'Blend']

# create a new 'Threshold'
threshold1 = Threshold(Input=tTKPersistenceDiagram1)
threshold1.Scalars = ['CELLS', 'PairIdentifier']
ThresholdBetween(threshold1, 0.0, 100000.0)

# create a new 'Threshold'
persistenceThreshold = Threshold(Input=threshold1)
persistenceThreshold.Scalars = ['CELLS', 'Persistence']
ThresholdBetween(persistenceThreshold, 0.7, 10000.0)

# create a new 'TTK TopologicalSimplification'
tTKTopologicalSimplification1 = TTKTopologicalSimplification(Domain=warpByScalar1,
    Constraints=persistenceThreshold)
tTKTopologicalSimplification1.ScalarField = ['POINTS', 'Blend']

# create a new 'TTK MorseSmaleComplex'
tTKMorseSmaleComplex1 = TTKMorseSmaleComplex(Input=tTKTopologicalSimplification1)
tTKMorseSmaleComplex1.ScalarField = ['POINTS', 'Blend']

# save the ouput
SaveData('PersistenceDiagram.vtu', tTKPersistenceDiagram1)
SaveData('PersistenceCurve.csv', OutputPort(tTKPersistenceCurve1, 3))
SaveData('MorseComplexeCriticalPoints.vtp', OutputPort(tTKMorseSmaleComplex1, 0))
SaveData('MorseComplexe1Separatrices.vtp', OutputPort(tTKMorseSmaleComplex1, 1))
SaveData('MorseComplexeSegmentation.vtp', OutputPort(tTKMorseSmaleComplex1, 3))

Inputs

  • None

Outputs

  • PersistenceDiagram.vtu: the output persistence diagram in VTK file format (bottom right view, above screenshot). You are free to change the vtu file extension to that of any other supported file format (e.g. csv) in the above python script.
  • PersistenceCurve.csv: the output persistence curve.
  • MorseComplexeCriticalPoints.vtp: the output critical points (or 0 dimensional elements) of the Morse Smale Complex in VTK file format (center view, above screenshot). You are free to change the vtp file extension to that of any other supported file format (e.g. csv) in the above python script.
  • MorseComplexe1Separatrices.vtp: cylinders, representing the edges (or 1 dimensional elements) of the output Morse Smale Complexe in VTK file format (center view, above screenshot). You are free to change the vtp file extension to that of any other supported file format (e.g. csv) in the above python script.
  • MorseComplexeSegmentation.vtp: surfaces, representing the segmentation of the output Morse Smale Complexe in VTK file format (center view, above screenshot). You are free to change the vtp file extension to that of any other supported file format (e.g. csv) in the above python script.

C++/Python API

ScalarFieldSmoother

MorseSmaleComplex

PersistenceCurve

PersistenceDiagram

TopologicalSimplification