Skip to content

Builtin example 2

Pipeline description

This example demostrates how bivariate analysis can be used for the analysis of molecular data. The input to this pipeline are two scalar fields: the electron density field denoted as log(Rho) and the reduced density gradeint denoted by log(s) for a simple molecule called 1,2-ethanediol.

First, usual univariate scalar field analysis method is used for the analysis. An isosurafce is extracted in log(Rho) field which helps in identification of the location of atoms in the molecule, see black surfaces in the lower left panel of the screenshot above. Similarly, an isosurafce in log(s) identifies the covalent bonds.

Next we perform bivariate analysis which looks at the joint behaviour log(Rho) and log(s) rather than looking at these scalar fields individually. We first compute the ContinuousScatterPlot for this bivariate data. This is shown in the top panel of the screenshot above. We then project the isosrfaces extrated earlier during univariate analysis in the range space using ProjectionFromField. As expected these isosurfaces project to two line segments which are perpendicular to each other and parallel to the X axis and Y axis, repectively.

Note how the continuous scatter plot spreads largely diagonally down from top-left corner to bottom-right in the range space with four distinct protrusions coming out on the top and bottom. These protrusions are of interest. We manually select polylines in the range space at these four protrusions and use them for extraction of fiber surfaces using FiberSurface.

Two of the fiber surfaces correspond to the atoms in the molecule, one of which identifies the Oxygen atoms (red surfaces in bottom right panel of the screenshot) while the other surface identifies the Carbon atoms (grey surfaces in bottom right panel of the screenshot). The other two fiber surfaces identify the bonds or interaction sites in the molecule. One surface clearly identifies the covalent bonds (blue surfaces in bottom right panel of the screenshot), while the other identifies a non-covalent interaction site in the molecule (light green surface in bottom right panel of the screenshot). Note that using univariate analysis of the data it is not straightforward to distinguish between different type of atoms and different types of bonds. However, it is much easier to do so using bivariate data analysis.

Lastly, we also compute the JacobiSet for the bivariate data and project it in the range space. Notice how it aligns with the continuous scatter plot and identifies the boundaries and the distinguishable curves within it.

ParaView

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

paraview states/BuiltInExample2.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
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#### import the simple module from the paraview
from paraview.simple import *

# Load the scalar fields using 'XML Image Data Reader'
example2vti = XMLImageDataReader(FileName=["BuiltInExample2.vti"])

### Univariate data analysis using isosurfaces

# create a new 'Contour' for 'log(Rho)' to identify atoms
contour2 = Contour(Input=example2vti)
contour2.ContourBy = ["POINTS", "log(Rho)"]
contour2.Isosurfaces = [1.57]

# create a new 'Contour' for 'log(s)' to identify atoms
contour3 = Contour(Input=example2vti)
contour3.ContourBy = ["POINTS", "log(s)"]
contour3.Isosurfaces = [-0.575]

### Bivariate data analysis using isosurfaces

# create a new 'TTK ContinuousScatterPlot'
tTKContinuousScatterPlot1 = TTKContinuousScatterPlot(Input=example2vti)
tTKContinuousScatterPlot1.ScalarField1 = ["POINTS", "log(Rho)"]
tTKContinuousScatterPlot1.ScalarField2 = ["POINTS", "log(s)"]
tTKContinuousScatterPlot1.UseAllCores = False

# create a new 'Threshold'
threshold1 = Threshold(Input=tTKContinuousScatterPlot1)
threshold1.Scalars = ["POINTS", "ValidPointMask"]
threshold1.ThresholdMethod = "Between"
threshold1.LowerThreshold = 0.1
threshold1.UpperThreshold = 999999999

# create a new 'TTK ProjectionFromField' to project the 'log(Rho)' contour onto the range space
tTKProjectionFromField1 = TTKProjectionFromField(Input=contour2)
tTKProjectionFromField1.UComponent = ["POINTS", "log(Rho)"]
tTKProjectionFromField1.VComponent = ["POINTS", "log(s)"]

# create a new 'Extract Edges'
extractEdges1 = ExtractEdges(Input=tTKProjectionFromField1)

# create a new 'TTK ProjectionFromField' to project the 'log(s)' contour onto the range space
tTKProjectionFromField2 = TTKProjectionFromField(Input=contour3)
tTKProjectionFromField2.UComponent = ["POINTS", "log(Rho)"]
tTKProjectionFromField2.VComponent = ["POINTS", "log(s)"]

# create a new 'Extract Edges'
extractEdges2 = ExtractEdges(Input=tTKProjectionFromField2)

# Four manually created polylines in the range space to select regions corresponding to
# Oxygen and carbon atoms, followed by covalent and non-covalent bonds
rangePolygonsCoordinates = [
    [
        1.89657,
        -0.278516,
        0.0,
        2.06003,
        -0.24493,
        0.0,
        2.15538,
        -0.278516,
        0.0,
        2.21441,
        -0.416216,
        0.0,
    ],
    [
        1.3744,
        0.000242441,
        0.0,
        1.51061,
        -0.00983316,
        0.0,
        1.65137,
        -0.0434185,
        0.0,
        1.70586,
        -0.181118,
        0.0,
    ],
    [
        1.21547,
        -0.701691,
        0.0,
        1.27904,
        -0.614369,
        0.0,
        1.51061,
        -0.607652,
        0.0,
        1.52878,
        -1.16853,
        0.0,
        1.53786,
        -0.688257,
        0.0,
    ],
    [
        -0.310174,
        -0.325535,
        0.0,
        -0.0150337,
        -0.124023,
        0.0,
        0.216538,
        -0.140816,
        0.0,
        0.466272,
        -0.399423,
        0.0,
    ],
]

# Save the four range space control polygons
polygons = []

# Save the corresponding four fiber surfaces
fiberSurfaces = []

for coords in rangePolygonsCoordinates:
    # create a new 'Poly Line Source'
    polyLineSource1 = PolyLineSource()
    polyLineSource1.Points = coords

    # create a new 'Resample With Dataset'
    resampleWithDataset1 = ResampleWithDataset(
        SourceDataArrays=tTKContinuousScatterPlot1, DestinationMesh=polyLineSource1
    )

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

    # create a new 'TTK FiberSurface'
    tTKFiberSurface1 = TTKFiberSurface(
        InputDomain=example2vti, RangePolygon=tetrahedralize2
    )
    tTKFiberSurface1.DomainUComponent = ["POINTS", "log(Rho)"]
    tTKFiberSurface1.DomainVComponent = ["POINTS", "log(s)"]
    tTKFiberSurface1.PolygonUComponent = ["POINTS", "log(Rho)"]
    tTKFiberSurface1.PolygonVComponent = ["POINTS", "log(s)"]
    tTKFiberSurface1.WithPointMerging = 1

    # create a new 'Generate Surface Normals'
    generateSurfaceNormals1 = GenerateSurfaceNormals(Input=tTKFiberSurface1)

    fiberSurfaces.append(generateSurfaceNormals1)

    # create a new 'Extract Surface'
    extractSurface1 = ExtractSurface(Input=resampleWithDataset1)

    polygons.append(extractSurface1)

# compute 'TTK JacobiSet' for the bivariate data
tTKJacobiSet1 = TTKJacobiSet(Input=example2vti)
tTKJacobiSet1.UComponent = ["POINTS", "log(Rho)"]
tTKJacobiSet1.VComponent = ["POINTS", "log(s)"]
tTKJacobiSet1.Withedgeidentifiers = 1
tTKJacobiSet1.Withvertexscalars = 1

# project the Jacobi set onto the range space using 'TTK ProjectionFromField'
tTKProjectionFromField3 = TTKProjectionFromField(Input=tTKJacobiSet1)
tTKProjectionFromField3.UComponent = ["POINTS", "log(Rho)"]
tTKProjectionFromField3.VComponent = ["POINTS", "log(s)"]

# save the output
SaveData("logRhoIsosurfaceAtoms.vtp", contour2)
SaveData("logSIsosurfaceBonds.vtp", contour3)

SaveData("ContinuousScatterPlot.vtu", threshold1)
SaveData("logRhoIsosurfaceRangeProjection.vtp", extractEdges1)
SaveData("logSIsosurfaceRangeProjection.vtp", extractEdges2)
SaveData("OxygenAtomsRangePolygon.vtp", polygons[0])
SaveData("CarbonAtomsRangePolygon.vtp", polygons[1])
SaveData("CovalentBondsRangePolygon.vtp", polygons[2])
SaveData("NonCovalentIntercationSiteRangePolygon.vtp", polygons[3])

SaveData("OxygenAtomsFiberSurface.vtp", fiberSurfaces[0])
SaveData("CarbonAtomsFiberSurface.vtp", fiberSurfaces[1])
SaveData("CovalentBondsFiberSurface.vtp", fiberSurfaces[2])
SaveData("NonCovalentIntercationSiteFiberSurface.vtp", fiberSurfaces[3])

SaveData("JacobiSetRangeProjection.vtu", tTKProjectionFromField3)

Inputs

  • BuiltInExample2.vti: Bivariate field corresponding to electron density distribution log(Rho) and the reduced density gradient log(s) around a simple molecule 1,2-ethanediol.

Outputs

Univariate analysis outputs

  • logRhoIsosurfaceAtoms.vtp: An isosurface extracted from log(Rho) scalar field which identifies the locations of the atoms.
  • logSIsosurfaceBonds.vtp: An isosurface extracted from log(s) scalar field which identifies the locations of the bonds or interaction sites.

Bivariate analysis outputs

Continuous scatter plot and projection of isocontours

  • ContinuousScatterPlot.vtu: The continuous scatter plot for the log(Rho) and log(s) bivariate field.
  • logRhoIsosurfaceRangeProjection.vtp: The projection of the isosurface extracted from log(Rho) onto the bivariate range space.
  • logSIsosurfaceRangeProjection.vtp: The projection of the isosurface extracted from log(s) onto the bivariate range space.

Interesting control polygons in range space

  • OxygenAtomsRangePolygon.vtp: Manually specified control polygon in range space to select the two Oxygen atoms in the molecule.
  • CarbonAtomsRangePolygon.vtp: Manually specified control polygon to select the Carbon atoms in the molecule.
  • CovalentBondsRangePolygon.vtp: Manually specified control polygon to identify the covalent bonds in the molecule.
  • NonCovalentIntercationSiteRangePolygon.vtp: Manually specified control polygon to identify the non-covalent interaction sites in the molecule.

Corresponding fiber surfaces in spatial domain

  • OxygenAtomsFiberSurface.vtp: The corresponding fiber surface in the spatial domain for the Oxygen atom control polygon.
  • CarbonAtomsFiberSurface.vtp: The corresponding fiber surface in the spatial domain for the Carbon atom control polygon.
  • CovalentBondsFiberSurface.vtp: The corresponding fiber surface in the spatial domain for the covalent bonds control polygon.
  • NonCovalentIntercationSiteFiberSurface.vtp: The corresponding fiber surface in the spatial domain for the non-covalent bonds control polygon.

Jacobi set projection onto the continuous scatter plot

  • JacobiSetRangeProjection.vtu: The projection of the Jacobi set of the bivariate field onto the bivariate range space.

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.

C++/Python API

ContinuousScatterPlot

FiberSurface

JacobiSet

ProjectionFromField