Files
rdkit/Code/Geometry/Wrap/testGeometry.py
Greg Landrum c90cee9b77 Add Molecular Interaction Fields (#7993)
* Add RealValueVect.

* Add UniformRealValueGrid3D

* Add Molecular Interaction Fields (MIFs)

* line endings

* cherry-pick f1bc94a4c8

* format

* Adapt tests for python3.

* Adapt RealValueVector pickling for python3.

* Speed-up of MIF calculations.

* Bugfix in MIFDescriptors.cpp.

* all tests pass

* clean up some memory leaks

* update copyrights

* rename

* rename the library

* complete the rename

* lost file

* another forgotten file

* cleanup

* clang-tidy

* clang-tidy

* windows DLL builds work

* python wrapper and tests cleanup

* convert to catch2 testing

* switch RealValueVect to use std::vector

* remove obsolete friend

* - Replace explicit loops with stdlib implicit equivalents
- Replace explicit types with auto where possible
- Avoid unnecessary copy operations where possible
- Replace raw pointers with exception-safe unique_ptr
- Replace C-style #define with constexpr
- Replace C-style casts with C++ casts
- Replace C-style arrays with std::vector
- Avoid code duplication with templated operators
- Replace VdWaals class taking multiple atom type definitions and force-field name as string parameter with force-field-specific classes deriving from an abstract VdWaals class
- Replace x,y,z doubles with Point3D class where possible
- Removed unused (and untested) DistanceToClosestAtom class
- Renamed some variables and functions for better clarity
- Converted tabs to spaces
- Made the mol parameter in cube read/write functions optional for convenience
- Made the Python wrappers more pythonic (e.g., avoid C++-style passing objects as parameters which are modified in place)
- Implemented alternative Python class constructors using boost::python::make_constructor rather than with external non-class functions
- The Python wrappers taking a sequence of Point3D now take a sequence of sequences, such that the output of Conformer.GetPositions() can be passed
- Made the Python wrapper sequence parsing more robust
- Removed duplicated code from Python wrappers

* - avoid an unnecessary copy

* progress

* works

* more cleanup

* all tests pass

* changes in response to review

---------

Co-authored-by: dfhahn <dfhahn@users.noreply.github.com>
Co-authored-by: ptosco <paolo.tosco@novartis.com>
2024-12-14 17:08:43 +01:00

812 lines
26 KiB
Python

import copy
import math
import os
import pickle
import sys
import unittest
from rdkit import DataStructs, RDConfig
from rdkit.Geometry import rdGeometry as geom
def feq(v1, v2, tol=1.0e-4):
return abs(v1 - v2) < tol
class TestCase(unittest.TestCase):
def setUp(self):
pass
def test1aPoint3D(self):
pt = geom.Point3D()
self.assertTrue(feq(pt.x, 0.0))
self.assertTrue(feq(pt.y, 0.0))
self.assertTrue(feq(pt.z, 0.0))
pt = geom.Point3D(3., 4., 5.)
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.z, 5.0))
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[1], 4.0))
self.assertTrue(feq(pt[2], 5.0))
self.assertTrue(feq(pt[-3], 3.0))
self.assertTrue(feq(pt[-2], 4.0))
self.assertTrue(feq(pt[-1], 5.0))
lst = list(pt)
self.assertTrue(feq(lst[0], 3.0))
self.assertTrue(feq(lst[1], 4.0))
self.assertTrue(feq(lst[2], 5.0))
pt2 = geom.Point3D(1., 1., 1.)
pt3 = pt + pt2
self.assertTrue(feq(pt3.x, 4.0))
self.assertTrue(feq(pt3.y, 5.0))
self.assertTrue(feq(pt3.z, 6.0))
pt += pt2
self.assertTrue(feq(pt.x, 4.0))
self.assertTrue(feq(pt.y, 5.0))
self.assertTrue(feq(pt.z, 6.0))
pt3 = pt - pt2
self.assertTrue(feq(pt3.x, 3.0))
self.assertTrue(feq(pt3.y, 4.0))
self.assertTrue(feq(pt3.z, 5.0))
pt -= pt2
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.z, 5.0))
pt *= 2.0
self.assertTrue(feq(pt.x, 6.0))
self.assertTrue(feq(pt.y, 8.0))
self.assertTrue(feq(pt.z, 10.0))
pt /= 2
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.z, 5.0))
self.assertTrue(feq(pt.Length(), 7.0711))
self.assertTrue(feq(pt.LengthSq(), 50.0))
pt.Normalize()
self.assertTrue(feq(pt.Length(), 1.0))
pt1 = geom.Point3D(1.0, 0.0, 0.0)
pt2 = geom.Point3D(2.0 * math.cos(math.pi / 6), 2.0 * math.sin(math.pi / 6), 0.0)
ang = pt1.AngleTo(pt2)
self.assertTrue(feq(ang, math.pi / 6))
prod = pt1.DotProduct(pt2)
self.assertTrue(feq(prod, 2.0 * math.cos(math.pi / 6)))
pt3 = pt1.CrossProduct(pt2)
self.assertTrue(feq(pt3.x, 0.0))
self.assertTrue(feq(pt3.y, 0.0))
self.assertTrue(feq(pt3.z, 1.0))
def test1bPoint2D(self):
pt = geom.Point2D()
self.assertTrue(feq(pt.x, 0.0))
self.assertTrue(feq(pt.y, 0.0))
pt = geom.Point2D(3., 4.)
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[1], 4.0))
self.assertTrue(feq(pt[-2], 3.0))
self.assertTrue(feq(pt[-1], 4.0))
lst = list(pt)
self.assertTrue(feq(lst[0], 3.0))
self.assertTrue(feq(lst[1], 4.0))
pt2 = geom.Point2D(1., 1.)
pt3 = pt + pt2
self.assertTrue(feq(pt3.x, 4.0))
self.assertTrue(feq(pt3.y, 5.0))
pt += pt2
self.assertTrue(feq(pt.x, 4.0))
self.assertTrue(feq(pt.y, 5.0))
pt3 = pt - pt2
self.assertTrue(feq(pt3.x, 3.0))
self.assertTrue(feq(pt3.y, 4.0))
pt -= pt2
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
pt *= 2.0
self.assertTrue(feq(pt.x, 6.0))
self.assertTrue(feq(pt.y, 8.0))
pt /= 2
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.Length(), 5.0))
self.assertTrue(feq(pt.LengthSq(), 25.0))
pt.Normalize()
self.assertTrue(feq(pt.Length(), 1.0))
pt1 = geom.Point2D(1.0, 0.0)
pt2 = geom.Point2D(2.0 * math.cos(math.pi / 6), 2.0 * math.sin(math.pi / 6))
ang = pt1.AngleTo(pt2)
self.assertTrue(feq(ang, math.pi / 6))
prod = pt1.DotProduct(pt2)
self.assertTrue(feq(prod, 2.0 * math.cos(math.pi / 6)))
def test1cPointND(self):
dim = 4
pt = geom.PointND(4)
for i in range(dim):
self.assertTrue(feq(pt[i], 0.0))
pt[0] = 3
pt[3] = 4
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[3], 4.0))
self.assertTrue(feq(pt[-4], 3.0))
self.assertTrue(feq(pt[-1], 4.0))
lst = list(pt)
self.assertTrue(feq(lst[0], 3.0))
self.assertTrue(feq(lst[3], 4.0))
pt2 = geom.PointND(4)
pt2[0] = 1.
pt2[2] = 1.
pt3 = pt + pt2
self.assertTrue(feq(pt3[0], 4.0))
self.assertTrue(feq(pt3[2], 1.0))
self.assertTrue(feq(pt3[3], 4.0))
pt += pt2
self.assertTrue(feq(pt[0], 4.0))
self.assertTrue(feq(pt[2], 1.0))
self.assertTrue(feq(pt[3], 4.0))
pt3 = pt - pt2
self.assertTrue(feq(pt3[0], 3.0))
self.assertTrue(feq(pt3[2], 0.0))
self.assertTrue(feq(pt3[3], 4.0))
pt -= pt2
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[2], 0.0))
self.assertTrue(feq(pt[3], 4.0))
pt *= 2.0
self.assertTrue(feq(pt[0], 6.0))
self.assertTrue(feq(pt[1], 0.0))
self.assertTrue(feq(pt[2], 0.0))
self.assertTrue(feq(pt[3], 8.0))
pt /= 2
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[1], 0.0))
self.assertTrue(feq(pt[2], 0.0))
self.assertTrue(feq(pt[3], 4.0))
self.assertTrue(feq(pt.Length(), 5.0))
self.assertTrue(feq(pt.LengthSq(), 25.0))
pt.Normalize()
self.assertTrue(feq(pt.Length(), 1.0))
pkl = pickle.dumps(pt)
pt2 = pickle.loads(pkl)
self.assertTrue(len(pt) == len(pt2))
for i in range(len(pt)):
self.assertTrue(feq(pt2[i], pt[i]))
def test3UniformGrid(self):
ugrid = geom.UniformGrid3D(20, 18, 15)
self.assertTrue(ugrid.GetNumX() == 40)
self.assertTrue(ugrid.GetNumY() == 36)
self.assertTrue(ugrid.GetNumZ() == 30)
dvect = ugrid.GetOccupancyVect()
ugrid = geom.UniformGrid3D(20, 18, 15, 0.5, DataStructs.DiscreteValueType.TWOBITVALUE)
dvect = ugrid.GetOccupancyVect()
self.assertTrue(dvect.GetValueType() == DataStructs.DiscreteValueType.TWOBITVALUE)
grd = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5)
grd.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, 2.0, 0.0), 1.5, 0.25)
geom.WriteGridToFile(grd, "junk.grd")
grd2 = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25)
grd2.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25)
dist = geom.TanimotoDistance(grd, grd2)
self.assertTrue(dist == 0.25)
dist = geom.ProtrudeDistance(grd, grd2)
self.assertTrue(dist == 0.25)
dist = geom.ProtrudeDistance(grd2, grd)
self.assertTrue(dist == 0.0)
grd2 = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5, DataStructs.DiscreteValueType.FOURBITVALUE)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25, 3)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25, 3)
grd2.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25, 3)
self.assertRaises(ValueError, lambda: geom.TanimotoDistance(grd, grd2))
grd2 = geom.UniformGrid3D(10.0, 10.0, 10.0, 1.0)
self.assertRaises(ValueError, lambda: geom.TanimotoDistance(grd, grd2))
grd2 = geom.UniformGrid3D(11.0, 10.0, 10.0, 1.0)
self.assertRaises(ValueError, lambda: geom.TanimotoDistance(grd, grd2))
def testSymmetry(self):
grd = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5)
grd.SetSphereOccupancy(geom.Point3D(-2.2, -2.0, 0.0), 1.65, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.2, -2.0, 0.0), 1.65, 0.25)
bPt1 = geom.Point3D(-4.0, -2.0, -2.0)
bPt2 = geom.Point3D(4.0, -2.0, -2.0)
for k in range(8):
bPt1 += geom.Point3D(0.0, 0.0, 0.5)
bPt2 += geom.Point3D(0.0, 0.0, 0.5)
for j in range(8):
bPt1 += geom.Point3D(0.0, 0.5, 0.0)
bPt2 += geom.Point3D(0.0, 0.5, 0.0)
for i in range(8):
bPt1 += geom.Point3D(0.5, 0.0, 0.0)
bPt2 -= geom.Point3D(0.5, 0.0, 0.0)
self.assertTrue(grd.GetValPoint(bPt1) == grd.GetValPoint(bPt2))
bPt1.x = -4.0
bPt2.x = 4.0
bPt1.y = -2.0
bPt2.y = -2.0
def testPointPickles(self):
pt = geom.Point3D(2.0, -3.0, 1.0)
pt2 = pickle.loads(pickle.dumps(pt))
self.assertTrue(feq(pt.x, pt2.x, 1e-6))
self.assertTrue(feq(pt.y, pt2.y, 1e-6))
self.assertTrue(feq(pt.z, pt2.z, 1e-6))
pt = geom.Point2D(2.0, -4.0)
pt2 = pickle.loads(pickle.dumps(pt))
self.assertTrue(feq(pt.x, pt2.x, 1e-6))
self.assertTrue(feq(pt.y, pt2.y, 1e-6))
def test4GridPickles(self):
grd = geom.UniformGrid3D(10.0, 9.0, 8.0, 0.5)
self.assertTrue(grd.GetNumX() == 20)
self.assertTrue(grd.GetNumY() == 18)
self.assertTrue(grd.GetNumZ() == 16)
grd.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, 2.0, 0.0), 1.5, 0.25)
self.assertTrue(geom.TanimotoDistance(grd, grd) == 0.0)
grd2 = pickle.loads(pickle.dumps(grd))
self.assertTrue(grd2.GetNumX() == 20)
self.assertTrue(grd2.GetNumY() == 18)
self.assertTrue(grd2.GetNumZ() == 16)
self.assertTrue(geom.TanimotoDistance(grd, grd2) == 0.0)
def test5GridOps(self):
grd = geom.UniformGrid3D(10, 10, 10)
grd.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.0, 0.25)
grd.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.0, 0.25)
grd2 = geom.UniformGrid3D(10, 10, 10)
grd2.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.0, 0.25)
grd2.SetSphereOccupancy(geom.Point3D(2.0, 2.0, 0.0), 1.0, 0.25)
self.assertTrue(geom.TanimotoDistance(grd, grd) == 0.0)
self.assertTrue(geom.TanimotoDistance(grd, grd2) == 1.0)
grd3 = copy.deepcopy(grd)
grd3 |= grd2
self.assertTrue(geom.TanimotoDistance(grd3, grd) == .5)
self.assertTrue(geom.TanimotoDistance(grd3, grd2) == .5)
grd3 = copy.deepcopy(grd)
grd3 += grd2
self.assertTrue(geom.TanimotoDistance(grd3, grd) == .5)
self.assertTrue(geom.TanimotoDistance(grd3, grd2) == .5)
grd3 -= grd
self.assertTrue(geom.TanimotoDistance(grd3, grd) == 1.0)
self.assertTrue(geom.TanimotoDistance(grd3, grd2) == 0)
grd4 = geom.UniformGrid3D(10, 10, 10)
grd4.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.0, 0.25)
grd4.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.0, 0.25)
grd4.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.0, 0.25)
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd), .3333))
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd2), .75))
grd4 &= grd2
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd), 1.0))
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd2), .5))
def test6Dihedrals(self):
p1 = geom.Point3D(1, 0, 0)
p2 = geom.Point3D(0, 0, 0)
p3 = geom.Point3D(0, 1, 0)
p4 = geom.Point3D(.5, 1, .5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, -math.pi / 4, 4)
p4 = geom.Point3D(-.5, 1, .5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 3 * math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, -3 * math.pi / 4, 4)
p4 = geom.Point3D(.5, 1, -.5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 4, 4)
p4 = geom.Point3D(-.5, 1, -.5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 3 * math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 3 * math.pi / 4, 4)
p4 = geom.Point3D(0, 1, 1)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 2, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, -math.pi / 2, 4)
p4 = geom.Point3D(0, 1, -1)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 2, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 2, 4)
p4 = geom.Point3D(1, 1, 0)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 0, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 0, 4)
p4 = geom.Point3D(-1, 1, 0)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi, 4)
def test7UniformGridIndices(self):
ugrid = geom.UniformGrid3D(20, 18, 15)
idx = ugrid.GetGridIndex(3, 2, 1)
xi, yi, zi = ugrid.GetGridIndices(idx)
self.assertEqual(xi, 3)
self.assertEqual(yi, 2)
self.assertEqual(zi, 1)
def test8InitPoint2DFromPoint3D(self):
p3 = geom.Point3D(1., 2., 3.)
p2 = geom.Point2D(p3)
self.assertEqual(p2.x, p3.x)
self.assertEqual(p2.y, p3.y)
def test1bPoint2D(self):
pt = geom.Point2D()
self.assertTrue(feq(pt.x, 0.0))
self.assertTrue(feq(pt.y, 0.0))
pt = geom.Point2D(3., 4.)
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[1], 4.0))
self.assertTrue(feq(pt[-2], 3.0))
self.assertTrue(feq(pt[-1], 4.0))
lst = list(pt)
self.assertTrue(feq(lst[0], 3.0))
self.assertTrue(feq(lst[1], 4.0))
pt2 = geom.Point2D(1., 1.)
pt3 = pt + pt2
self.assertTrue(feq(pt3.x, 4.0))
self.assertTrue(feq(pt3.y, 5.0))
pt += pt2
self.assertTrue(feq(pt.x, 4.0))
self.assertTrue(feq(pt.y, 5.0))
pt3 = pt - pt2
self.assertTrue(feq(pt3.x, 3.0))
self.assertTrue(feq(pt3.y, 4.0))
pt -= pt2
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
pt *= 2.0
self.assertTrue(feq(pt.x, 6.0))
self.assertTrue(feq(pt.y, 8.0))
pt /= 2
self.assertTrue(feq(pt.x, 3.0))
self.assertTrue(feq(pt.y, 4.0))
self.assertTrue(feq(pt.Length(), 5.0))
self.assertTrue(feq(pt.LengthSq(), 25.0))
pt.Normalize()
self.assertTrue(feq(pt.Length(), 1.0))
pt1 = geom.Point2D(1.0, 0.0)
pt2 = geom.Point2D(2.0 * math.cos(math.pi / 6), 2.0 * math.sin(math.pi / 6))
ang = pt1.AngleTo(pt2)
self.assertTrue(feq(ang, math.pi / 6))
prod = pt1.DotProduct(pt2)
self.assertTrue(feq(prod, 2.0 * math.cos(math.pi / 6)))
def test1cPointND(self):
dim = 4
pt = geom.PointND(4)
for i in range(dim):
self.assertTrue(feq(pt[i], 0.0))
pt[0] = 3
pt[3] = 4
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[3], 4.0))
self.assertTrue(feq(pt[-4], 3.0))
self.assertTrue(feq(pt[-1], 4.0))
lst = list(pt)
self.assertTrue(feq(lst[0], 3.0))
self.assertTrue(feq(lst[3], 4.0))
pt2 = geom.PointND(4)
pt2[0] = 1.
pt2[2] = 1.
pt3 = pt + pt2
self.assertTrue(feq(pt3[0], 4.0))
self.assertTrue(feq(pt3[2], 1.0))
self.assertTrue(feq(pt3[3], 4.0))
pt += pt2
self.assertTrue(feq(pt[0], 4.0))
self.assertTrue(feq(pt[2], 1.0))
self.assertTrue(feq(pt[3], 4.0))
pt3 = pt - pt2
self.assertTrue(feq(pt3[0], 3.0))
self.assertTrue(feq(pt3[2], 0.0))
self.assertTrue(feq(pt3[3], 4.0))
pt -= pt2
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[2], 0.0))
self.assertTrue(feq(pt[3], 4.0))
pt *= 2.0
self.assertTrue(feq(pt[0], 6.0))
self.assertTrue(feq(pt[1], 0.0))
self.assertTrue(feq(pt[2], 0.0))
self.assertTrue(feq(pt[3], 8.0))
pt /= 2
self.assertTrue(feq(pt[0], 3.0))
self.assertTrue(feq(pt[1], 0.0))
self.assertTrue(feq(pt[2], 0.0))
self.assertTrue(feq(pt[3], 4.0))
self.assertTrue(feq(pt.Length(), 5.0))
self.assertTrue(feq(pt.LengthSq(), 25.0))
pt.Normalize()
self.assertTrue(feq(pt.Length(), 1.0))
pkl = pickle.dumps(pt)
pt2 = pickle.loads(pkl)
self.assertTrue(len(pt) == len(pt2))
for i in range(len(pt)):
self.assertTrue(feq(pt2[i], pt[i]))
def test3UniformGrid(self):
ugrid = geom.UniformGrid3D(20, 18, 15)
self.assertTrue(ugrid.GetNumX() == 40)
self.assertTrue(ugrid.GetNumY() == 36)
self.assertTrue(ugrid.GetNumZ() == 30)
dvect = ugrid.GetOccupancyVect()
ugrid = geom.UniformGrid3D(20, 18, 15, 0.5, DataStructs.DiscreteValueType.TWOBITVALUE)
dvect = ugrid.GetOccupancyVect()
self.assertTrue(dvect.GetValueType() == DataStructs.DiscreteValueType.TWOBITVALUE)
grd = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5)
grd.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, 2.0, 0.0), 1.5, 0.25)
geom.WriteGridToFile(grd, "junk.grd")
grd2 = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25)
grd2.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25)
dist = geom.TanimotoDistance(grd, grd2)
self.assertTrue(dist == 0.25)
dist = geom.ProtrudeDistance(grd, grd2)
self.assertTrue(dist == 0.25)
dist = geom.ProtrudeDistance(grd2, grd)
self.assertTrue(dist == 0.0)
grd2 = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5, DataStructs.DiscreteValueType.FOURBITVALUE)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25, 3)
grd2.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25, 3)
grd2.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25, 3)
self.assertRaises(ValueError, lambda: geom.TanimotoDistance(grd, grd2))
grd2 = geom.UniformGrid3D(10.0, 10.0, 10.0, 1.0)
self.assertRaises(ValueError, lambda: geom.TanimotoDistance(grd, grd2))
grd2 = geom.UniformGrid3D(11.0, 10.0, 10.0, 1.0)
self.assertRaises(ValueError, lambda: geom.TanimotoDistance(grd, grd2))
def testSymmetry(self):
grd = geom.UniformGrid3D(10.0, 10.0, 10.0, 0.5)
grd.SetSphereOccupancy(geom.Point3D(-2.2, -2.0, 0.0), 1.65, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.2, -2.0, 0.0), 1.65, 0.25)
bPt1 = geom.Point3D(-4.0, -2.0, -2.0)
bPt2 = geom.Point3D(4.0, -2.0, -2.0)
for k in range(8):
bPt1 += geom.Point3D(0.0, 0.0, 0.5)
bPt2 += geom.Point3D(0.0, 0.0, 0.5)
for j in range(8):
bPt1 += geom.Point3D(0.0, 0.5, 0.0)
bPt2 += geom.Point3D(0.0, 0.5, 0.0)
for i in range(8):
bPt1 += geom.Point3D(0.5, 0.0, 0.0)
bPt2 -= geom.Point3D(0.5, 0.0, 0.0)
self.assertTrue(grd.GetValPoint(bPt1) == grd.GetValPoint(bPt2))
bPt1.x = -4.0
bPt2.x = 4.0
bPt1.y = -2.0
bPt2.y = -2.0
def test4UniformRealValueGrid(self):
ugrid = geom.UniformRealValueGrid3D(20, 18, 15)
self.assertTrue(ugrid.GetNumX() == 40)
self.assertTrue(ugrid.GetNumY() == 36)
self.assertTrue(ugrid.GetNumZ() == 30)
dvect = ugrid.GetOccupancyVect()
ugrid = geom.UniformRealValueGrid3D(20, 18, 15, 0.5)
ugrid.SetVal(50, 2.3)
val = ugrid.GetVal(50)
self.assertTrue(feq(val, 2.3))
def test5PointPickles(self):
pt = geom.Point3D(2.0, -3.0, 1.0)
pt2 = pickle.loads(pickle.dumps(pt))
self.assertTrue(feq(pt.x, pt2.x, 1e-6))
self.assertTrue(feq(pt.y, pt2.y, 1e-6))
self.assertTrue(feq(pt.z, pt2.z, 1e-6))
pt = geom.Point2D(2.0, -4.0)
pt2 = pickle.loads(pickle.dumps(pt))
self.assertTrue(feq(pt.x, pt2.x, 1e-6))
self.assertTrue(feq(pt.y, pt2.y, 1e-6))
def test6GridPickles(self):
grd = geom.UniformGrid3D(10.0, 9.0, 8.0, 0.5)
self.assertTrue(grd.GetNumX() == 20)
self.assertTrue(grd.GetNumY() == 18)
self.assertTrue(grd.GetNumZ() == 16)
grd.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.5, 0.25)
grd.SetSphereOccupancy(geom.Point3D(2.0, 2.0, 0.0), 1.5, 0.25)
self.assertTrue(geom.TanimotoDistance(grd, grd) == 0.0)
grd2 = pickle.loads(pickle.dumps(grd))
self.assertTrue(grd2.GetNumX() == 20)
self.assertTrue(grd2.GetNumY() == 18)
self.assertTrue(grd2.GetNumZ() == 16)
self.assertTrue(geom.TanimotoDistance(grd, grd2) == 0.0)
def test7RealGridPickles(self):
grd = geom.UniformRealValueGrid3D(10.0, 9.0, 8.0, 0.5)
self.assertTrue(grd.GetNumX() == 20)
self.assertTrue(grd.GetNumY() == 18)
self.assertTrue(grd.GetNumZ() == 16)
grd2 = pickle.loads(pickle.dumps(grd))
self.assertTrue(grd2.GetNumX() == 20)
self.assertTrue(grd2.GetNumY() == 18)
self.assertTrue(grd2.GetNumZ() == 16)
def test8GridOps(self):
grd = geom.UniformGrid3D(10, 10, 10)
grd.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.0, 0.25)
grd.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.0, 0.25)
grd2 = geom.UniformGrid3D(10, 10, 10)
grd2.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.0, 0.25)
grd2.SetSphereOccupancy(geom.Point3D(2.0, 2.0, 0.0), 1.0, 0.25)
self.assertTrue(geom.TanimotoDistance(grd, grd) == 0.0)
self.assertTrue(geom.TanimotoDistance(grd, grd2) == 1.0)
grd3 = copy.deepcopy(grd)
grd3 |= grd2
self.assertTrue(geom.TanimotoDistance(grd3, grd) == .5)
self.assertTrue(geom.TanimotoDistance(grd3, grd2) == .5)
grd3 = copy.deepcopy(grd)
grd3 += grd2
self.assertTrue(geom.TanimotoDistance(grd3, grd) == .5)
self.assertTrue(geom.TanimotoDistance(grd3, grd2) == .5)
grd3 -= grd
self.assertTrue(geom.TanimotoDistance(grd3, grd) == 1.0)
self.assertTrue(geom.TanimotoDistance(grd3, grd2) == 0)
grd4 = geom.UniformGrid3D(10, 10, 10)
grd4.SetSphereOccupancy(geom.Point3D(-2.0, -2.0, 0.0), 1.0, 0.25)
grd4.SetSphereOccupancy(geom.Point3D(-2.0, 2.0, 0.0), 1.0, 0.25)
grd4.SetSphereOccupancy(geom.Point3D(2.0, -2.0, 0.0), 1.0, 0.25)
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd), .3333))
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd2), .75))
grd4 &= grd2
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd), 1.0))
self.assertTrue(feq(geom.TanimotoDistance(grd4, grd2), .5))
def test9RealGridOps(self):
grd1 = geom.UniformRealValueGrid3D(5.0, 5.0, 5.0, 0.1)
grd2 = geom.UniformRealValueGrid3D(5.0, 5.0, 5.0, 0.1)
grd1.SetVal(50, 37.37)
grd2.SetVal(50, 1.03)
grd3 = copy.deepcopy(grd2)
grd4 = geom.UniformRealValueGrid3D(grd2)
grd1 |= grd2
self.assertTrue(feq(grd1.GetVal(50), 37.37))
self.assertTrue(feq(grd2.GetVal(50), 1.03))
grd2 |= grd1
self.assertTrue(feq(grd1.GetVal(50), 37.37))
self.assertTrue(feq(grd2.GetVal(50), 37.37))
grd2 &= grd3
self.assertTrue(feq(grd2.GetVal(50), 1.03))
self.assertTrue(feq(grd3.GetVal(50), 1.03))
grd3 &= grd1
self.assertTrue(feq(grd1.GetVal(50), 37.37))
self.assertTrue(feq(grd3.GetVal(50), 1.03))
grd2 &= grd4
self.assertTrue(feq(grd2.GetVal(50), 1.03))
self.assertTrue(feq(grd4.GetVal(50), 1.03))
grd4 &= grd1
self.assertTrue(feq(grd1.GetVal(50), 37.37))
self.assertTrue(feq(grd4.GetVal(50), 1.03))
grd1 += grd2
self.assertTrue(feq(grd1.GetVal(50), 38.40))
self.assertTrue(feq(grd2.GetVal(50), 1.03))
grd1 -= grd2
self.assertTrue(feq(grd1.GetVal(50), 37.37))
self.assertTrue(feq(grd2.GetVal(50), 1.03))
grd2 -= grd1
self.assertTrue(feq(grd1.GetVal(50), 37.37))
self.assertTrue(feq(grd2.GetVal(50), -36.34))
def test10Dihedrals(self):
p1 = geom.Point3D(1, 0, 0)
p2 = geom.Point3D(0, 0, 0)
p3 = geom.Point3D(0, 1, 0)
p4 = geom.Point3D(.5, 1, .5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, -math.pi / 4, 4)
p4 = geom.Point3D(-.5, 1, .5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 3 * math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, -3 * math.pi / 4, 4)
p4 = geom.Point3D(.5, 1, -.5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 4, 4)
p4 = geom.Point3D(-.5, 1, -.5)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 3 * math.pi / 4, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 3 * math.pi / 4, 4)
p4 = geom.Point3D(0, 1, 1)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 2, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, -math.pi / 2, 4)
p4 = geom.Point3D(0, 1, -1)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 2, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi / 2, 4)
p4 = geom.Point3D(1, 1, 0)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 0, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, 0, 4)
p4 = geom.Point3D(-1, 1, 0)
ang = geom.ComputeDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi, 4)
ang = geom.ComputeSignedDihedralAngle(p1, p2, p3, p4)
self.assertAlmostEqual(ang, math.pi, 4)
def test11UniformGridIndices(self):
ugrid = geom.UniformGrid3D(20, 18, 15)
idx = ugrid.GetGridIndex(3, 2, 1)
xi, yi, zi = ugrid.GetGridIndices(idx)
self.assertEqual(xi, 3)
self.assertEqual(yi, 2)
self.assertEqual(zi, 1)
def test12UniformRealGridIndices(self):
ugrid = geom.UniformRealValueGrid3D(20, 18, 15)
idx = ugrid.GetGridIndex(3, 2, 1)
xi, yi, zi = ugrid.GetGridIndices(idx)
self.assertEqual(xi, 3)
self.assertEqual(yi, 2)
self.assertEqual(zi, 1)
pt = ugrid.GetOffset()
ugrid.SetValPoint(pt, 2.3)
idx = ugrid.GetGridPointIndex(pt)
self.assertTrue(feq(ugrid.GetValPoint(pt), 2.3))
self.assertTrue(idx == 0)
self.assertTrue(feq(ugrid.GetVal(idx), 2.3))
pt2 = ugrid.GetGridPointLoc(idx)
self.assertTrue(feq(pt.x, pt2.x))
self.assertTrue(feq(pt.y, pt2.y))
self.assertTrue(feq(pt.z, pt2.z))
if __name__ == '__main__':
print("Testing Geometry wrapper")
unittest.main()