This example first loads a VTI file on the disk. The VTI file contains three scalar fields namely Rho, log(Rho), and log(s). We are interested in topological analysis of the log(Rho) scalar field which corresponds to the electron density distribution around a simple molecule.
The MorseSmaleComplex is computed for this scalar field. The reason for computing Morse-Smale complex is that many chemically relevant concepts, for example, covalent bonds can be directly translated to topological structures computed using the Morse-Smale complex. The critical points of this scalar field also have chemical relevance. The maxima correspond to the atom locations and 2-saddles occur along chemical bonds.
Then the critical points are then converted into spheres using IcospheresFromPoints. The maxima are selected and highlighted as bigger spheres.
Then using appropriate filtering, the 1-separatrices corresponding to the covalent bonds are selected. The criteria used is to select the 1-sepatrices which have no critical points on the boundary and for which SeparatrixType = 2, that is they connect a 2-saddle to a maximum. Also, GeometrySmoother is used to make the jagged lines generated by the Morse-Smale complex a little smoother. Then, another type of 1-separatrix is extracted which connects a 2-saddle on a covalent bond to its neighbouring 1-saddles on the boundary.
Lastly, 2-separatrices incident on the covalent bonds (of SeparatrixType = 1) are extracted which correspond to separating walls between adjacent atoms. Another type (SeparatrixType = 2) of separating wall is also extracted.
fromparaview.simpleimport*# create a new 'XML Image Data Reader'builtInExamplevti=XMLImageDataReader(FileName=["BuiltInExample2.vti"])# create a new 'TTK MorseSmaleComplex'tTKMorseSmaleComplex1=TTKMorseSmaleComplex(Input=builtInExamplevti)tTKMorseSmaleComplex1.ScalarField=["POINTS","log(Rho)"]tTKMorseSmaleComplex1.Ascending2Separatrices=1tTKMorseSmaleComplex1.Descending2Separatrices=1# Generate spheres for the critical points using 'TTK IcospheresFromPoints'tTKIcospheresFromPoints1=TTKIcospheresFromPoints(Input=tTKMorseSmaleComplex1)tTKIcospheresFromPoints1.Radius=1.5# Generate bigger spheres for the critical points using 'TTK IcospheresFromPoints'tTKIcospheresFromPoints2=TTKIcospheresFromPoints(Input=tTKMorseSmaleComplex1)tTKIcospheresFromPoints2.Radius=3.0# Then select critical points of CellDimension 3 using 'Threshold' to select maximathreshold3=Threshold(Input=tTKIcospheresFromPoints2)threshold3.Scalars=["POINTS","CellDimension"]threshold3.ThresholdMethod="Between"threshold3.LowerThreshold=3.0threshold3.UpperThreshold=3.0# create a new 'Threshold'threshold1=Threshold(Input=OutputPort(tTKMorseSmaleComplex1,1))threshold1.Scalars=["CELLS","NumberOfCriticalPointsOnBoundary"]threshold1.ThresholdMethod="Between"threshold1.LowerThreshold=0.0threshold1.UpperThreshold=0.0# create a new 'Threshold'threshold2=Threshold(Input=threshold1)threshold2.Scalars=["CELLS","SeparatrixType"]threshold2.ThresholdMethod="Between"threshold2.LowerThreshold=2.0threshold2.UpperThreshold=2.0# create a new 'TTK GeometrySmoother'tTKGeometrySmoother1=TTKGeometrySmoother(Input=threshold2)tTKGeometrySmoother1.IterationNumber=50# create a new 'Clean to Grid'cleantoGrid1=CleantoGrid(Input=tTKGeometrySmoother1)# create a new 'Extract Surface'extractSurface1=ExtractSurface(Input=cleantoGrid1)# create a new 'Tube'tube1=Tube(Input=extractSurface1)tube1.Scalars=["POINTS","CellDimension"]tube1.Radius=1.25# create a new 'Threshold'threshold8=Threshold(Input=OutputPort(tTKMorseSmaleComplex1,1))threshold8.Scalars=["CELLS","SeparatrixType"]threshold8.ThresholdMethod="Between"threshold8.LowerThreshold=1.0threshold8.UpperThreshold=1.0# create a new 'Threshold'threshold9=Threshold(Input=threshold8)threshold9.Scalars=["CELLS","NumberOfCriticalPointsOnBoundary"]threshold9.ThresholdMethod="Between"threshold9.LowerThreshold=1.0threshold9.UpperThreshold=1.0# create a new 'Threshold'threshold11=Threshold(Input=threshold9)threshold11.Scalars=["CELLS","SeparatrixId"]threshold11.ThresholdMethod="Between"threshold11.LowerThreshold=75.0threshold11.UpperThreshold=76.0# create a new 'Threshold'threshold10=Threshold(Input=threshold9)threshold10.Scalars=["CELLS","SeparatrixId"]threshold10.ThresholdMethod="Between"threshold10.LowerThreshold=73.0threshold10.UpperThreshold=74.0# create a new 'Append Datasets'appendDatasets1=AppendDatasets(Input=[threshold10,threshold11])# create a new 'Clean to Grid'cleantoGrid4=CleantoGrid(Input=appendDatasets1)# create a new 'TTK GeometrySmoother'tTKGeometrySmoother4=TTKGeometrySmoother(Input=cleantoGrid4)tTKGeometrySmoother4.IterationNumber=10# create a new 'Extract Surface'extractSurface3=ExtractSurface(Input=tTKGeometrySmoother4)# create a new 'Tube'tube2=Tube(Input=extractSurface3)tube2.Scalars=["POINTS","CellDimension"]tube2.Radius=0.75# create a new 'Threshold'threshold4=Threshold(Input=OutputPort(tTKMorseSmaleComplex1,2))threshold4.Scalars=["CELLS","SeparatrixType"]threshold4.ThresholdMethod="Between"threshold4.LowerThreshold=1.0threshold4.UpperThreshold=1.0# create a new 'Clean to Grid'cleantoGrid2=CleantoGrid(Input=threshold4)# create a new 'Tetrahedralize'tetrahedralize1=Tetrahedralize(Input=cleantoGrid2)# create a new 'Extract Surface'extractSurface2=ExtractSurface(Input=tetrahedralize1)# create a new 'TTK GeometrySmoother'tTKGeometrySmoother2=TTKGeometrySmoother(Input=extractSurface2)tTKGeometrySmoother2.IterationNumber=20# select 2-separatrices using 'Threshold'threshold5=Threshold(Input=OutputPort(tTKMorseSmaleComplex1,2))threshold5.Scalars=["CELLS","SeparatrixType"]threshold5.ThresholdMethod="Between"threshold5.LowerThreshold=2.0threshold5.UpperThreshold=2.0# create a new 'Threshold'threshold6=Threshold(Input=threshold5)threshold6.Scalars=["CELLS","NumberOfCriticalPointsOnBoundary"]threshold6.ThresholdMethod="Between"threshold6.LowerThreshold=4.0threshold6.UpperThreshold=4.0# select a particular 2-separatrix using 'Threshold'threshold7=Threshold(Input=threshold6)threshold7.Scalars=["CELLS","SeparatrixId"]threshold7.ThresholdMethod="Between"threshold7.LowerThreshold=2.0threshold7.UpperThreshold=2.0# create a new 'Clean to Grid'cleantoGrid3=CleantoGrid(Input=threshold7)# create a new 'Tetrahedralize'tetrahedralize2=Tetrahedralize(Input=cleantoGrid3)# create a new 'TTK GeometrySmoother'tTKGeometrySmoother3=TTKGeometrySmoother(Input=tetrahedralize2)tTKGeometrySmoother3.IterationNumber=20# save the outputSaveData("CriticalPoints.vtp",tTKIcospheresFromPoints1)SaveData("Maxima.vtu",threshold3)SaveData("CovalentBonds.vtp",tube1)SaveData("Selected2saddle1saddleConnectors.vtp",tube2)SaveData("CovalentBondSeparatrixWalls.vtp",tTKGeometrySmoother2)SaveData("SelectedType2SeparatrixWall.vtu",tTKGeometrySmoother3)
To run the above Python script, go to your ttk-data directory and enter the following command:
CriticalPoints.vtp: All the output critical points in VTK file format (small spheres in the above screenshot).
Maxima.vtu: The computed maxima which also correspond to atom locations in VTK file format (bigger green spheres).
CovalentBonds.vtp: Selected 1-separatrices corresponding to the covalent bonds in the molecule (the thick white tubes)
Selected2saddle1saddleConnectors.vtp: Geometry of selected separatrices connecting a 2-saddle on a covalent bond to its neighbouring 1-saddles (the dark grey tubes in the screenshot above).
CovalentBondSeparatrixWalls.vtp: Surface corresponding to 2-separatrices (walls) incident on the covalent bonds (the translucent blue surfaces in the above screenshot)
SelectedType2SeparatrixWall.vtu: Surface corresponding to another type of wall (the green surface).
Note that you are free to change the VTK file extensions to that of any other supported file format (e.g. csv) in the above python script.