Files
rdkit/Code/GraphMol/Wrap/testSGroups.py
Ric 880a8e5725 Reformat Python code for 2023.03 release (#6294)
* run yapf

* run isort

---------

Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
2023-04-28 06:53:56 +02:00

611 lines
18 KiB
Python

#
# Copyright (C) 2019 Greg Landrum
# All Rights Reserved
#
# This file is part of the RDKit.
# The contents are covered by the terms of the BSD license
# which is included in the file license.txt, found at the root
# of the RDKit source tree.
#
import os
import sys
import unittest
from rdkit import Chem, Geometry
from rdkit.Chem import RDConfig
class TestCase(unittest.TestCase):
def setUp(self):
mb = """
ACCLDraw04231812452D
13 13 0 0 0 0 0 0 0 0999 V2000
5.0960 -4.3327 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.4016 -4.3321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
5.0960 -5.6718 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.2539 -6.3314 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.2510 -2.3329 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.4056 -1.6662 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
5.0963 -1.6662 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.2510 -3.6663 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8.5505 -6.3291 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8.5505 -7.6624 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
9.7052 -5.6625 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
7.4016 -5.6658 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.9416 -2.3329 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3 4 2 0 0 0 0
1 3 1 0 0 0 0
5 8 1 0 0 0 0
5 7 2 0 0 0 0
5 6 1 0 0 0 0
1 8 2 0 0 0 0
2 8 1 0 0 0 0
9 12 1 0 0 0 0
9 11 2 0 0 0 0
9 10 1 0 0 0 0
4 12 1 0 0 0 0
2 12 2 0 0 0 0
7 13 1 0 0 0 0
M STY 2 1 DAT 2 DAT
M SLB 2 1 1 2 2
M SAL 1 1 10
M SDT 1 pH
M SDD 1 0.0000 0.0000 DR ALL 1 6
M SED 1 4.6
M SAL 2 2 5 7
M SBL 2 1 4
M SDT 2 Stereo
M SDD 2 0.0000 0.0000 DR ALL 1 6
M SED 2 E/Z unknown
M END"""
self.m1 = Chem.MolFromMolBlock(mb)
mb3000 = '''
Mrv2102 09042105562D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 13 13 2 0 0
M V30 BEGIN ATOM
M V30 1 C 5.8858 -5.0042 0 0
M V30 2 C 8.5487 -5.0035 0 0
M V30 3 C 5.8858 -6.5508 0 0
M V30 4 C 7.2232 -7.3127 0 0
M V30 5 C 7.2198 -2.6945 0 0
M V30 6 C 8.5534 -1.9244 0 0
M V30 7 C 5.8862 -1.9244 0 0
M V30 8 C 7.2198 -4.2345 0 0
M V30 9 C 9.8757 -7.31 0 0
M V30 10 O 9.8757 -8.85 0 0
M V30 11 O 11.2094 -6.5401 0 0
M V30 12 C 8.5487 -6.5439 0 0
M V30 13 C 4.5525 -2.6945 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 2 3 4
M V30 2 1 1 3
M V30 3 1 5 8
M V30 4 2 5 7
M V30 5 1 5 6
M V30 6 2 1 8
M V30 7 1 2 8
M V30 8 1 9 12
M V30 9 2 9 11
M V30 10 1 9 10
M V30 11 1 4 12
M V30 12 2 2 12
M V30 13 1 7 13
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 DAT 0 ATOMS=(1 10) FIELDNAME=pH -
M V30 FIELDDISP=" 0.0000 0.0000 DR ALL 1 6" FIELDDATA=4.6
M V30 2 DAT 0 ATOMS=(2 5 7) FIELDNAME=Stereo -
M V30 FIELDDISP=" 0.0000 0.0000 DR ALL 1 6" -
M V30 FIELDDATA="E/Z unknown"
M V30 END SGROUP
M V30 END CTAB
M END
'''
self.m2 = Chem.MolFromMolBlock(mb3000)
def testBasics(self):
self.assertTrue(self.m1 is not None)
sgs = Chem.GetMolSubstanceGroups(self.m1)
self.assertEqual(len(sgs), 2)
self.assertTrue(sgs[0].HasProp("TYPE"))
self.assertTrue(sgs[1].HasProp("TYPE"))
self.assertEqual(sgs[0].GetProp("TYPE"), "DAT")
self.assertEqual(sgs[1].GetProp("TYPE"), "DAT")
self.assertTrue(sgs[0].HasProp("FIELDNAME"))
self.assertEqual(sgs[0].GetProp("FIELDNAME"), "pH")
self.assertEqual(sorted(sgs[0].GetPropNames()),
['DATAFIELDS', 'FIELDDISP', 'FIELDNAME', 'ID', 'TYPE', 'index'])
dd = sgs[0].GetPropsAsDict()
self.assertTrue("TYPE" in dd)
self.assertEqual(dd["TYPE"], "DAT")
self.assertTrue("FIELDNAME" in dd)
self.assertEqual(dd["FIELDNAME"], "pH")
sgs[0].ClearProp("FIELDNAME")
self.assertFalse(sgs[0].HasProp("FIELDNAME"))
# The property doesn't exist anymore, but this should not fail
sgs[0].ClearProp("FIELDNAME")
self.assertFalse(sgs[0].HasProp("FIELDNAME"))
Chem.ClearMolSubstanceGroups(self.m1)
self.assertEqual(len(Chem.GetMolSubstanceGroups(self.m1)), 0)
def testBasics3000(self):
self.assertTrue(self.m2 is not None)
sgs = Chem.GetMolSubstanceGroups(self.m2)
self.assertEqual(len(sgs), 2)
self.assertTrue(sgs[0].HasProp("TYPE"))
self.assertTrue(sgs[1].HasProp("TYPE"))
self.assertEqual(sgs[0].GetProp("TYPE"), "DAT")
self.assertEqual(sgs[1].GetProp("TYPE"), "DAT")
self.assertTrue(sgs[0].HasProp("FIELDNAME"))
self.assertEqual(sgs[0].GetProp("FIELDNAME"), "pH")
self.assertEqual(sorted(sgs[0].GetPropNames()),
['DATAFIELDS', 'FIELDDISP', 'FIELDNAME', 'TYPE', 'index'])
dd = sgs[0].GetPropsAsDict()
self.assertTrue("TYPE" in dd)
self.assertEqual(dd["TYPE"], "DAT")
self.assertTrue("FIELDNAME" in dd)
self.assertEqual(dd["FIELDNAME"], "pH")
Chem.ClearMolSubstanceGroups(self.m2)
self.assertEqual(len(Chem.GetMolSubstanceGroups(self.m2)), 0)
def testLifetime(self):
self.assertTrue(self.m1 is not None)
mcpy = Chem.Mol(self.m1)
smi = Chem.MolToSmiles(mcpy)
sgs = Chem.GetMolSubstanceGroups(mcpy)
self.assertEqual(len(sgs), 2)
mcpy = None
parent = sgs[0].GetOwningMol()
self.assertEqual(smi, Chem.MolToSmiles(parent))
sgl = list(sgs)
sgs = None
parent = sgl[0].GetOwningMol()
self.assertEqual(smi, Chem.MolToSmiles(parent))
def testSetProp(self):
self.assertTrue(self.m1 is not None)
mcpy = Chem.Mol(self.m1)
sg = Chem.GetMolSubstanceGroupWithIdx(mcpy, 0)
sg.SetProp("foo", "bar")
sgs2 = Chem.GetMolSubstanceGroups(mcpy)
pd = sgs2[0].GetPropsAsDict()
self.assertTrue('foo' in pd)
self.assertEqual(pd['foo'], 'bar')
def testCreateSGroup(self):
mol = Chem.MolFromMolBlock('''
Mrv1810 10061910532D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 4 3 0 0 0
M V30 BEGIN ATOM
M V30 1 O -14.8632 3.7053 0 0
M V30 2 C -13.3232 3.7053 0 0
M V30 3 O -11.7832 3.7053 0 0
M V30 4 * -10.2453 3.6247 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 1 3 4
M V30 END BOND
M V30 END CTAB
M END''')
self.assertTrue(mol is not None)
mcpy = Chem.Mol(mol)
sg = Chem.CreateMolSubstanceGroup(mcpy, "SRU")
self.assertEqual(sg.GetProp("TYPE"), "SRU")
sg = Chem.GetMolSubstanceGroupWithIdx(mcpy, 0)
sg.AddBracket((Geometry.Point3D(-11.1, 4.6, 0), Geometry.Point3D(-11.1, 2.7, 0)))
sg.AddBracket((Geometry.Point3D(-13.9, 2.7, 0), Geometry.Point3D(-13.9, 4.6, 0)))
sg.AddAtomWithIdx(1)
sg.AddAtomWithIdx(2)
sg.AddBondWithIdx(0)
sg.AddBondWithIdx(2)
sg.SetProp("CONNECT", "HT")
sg.SetProp("LABEL", "n")
mb = Chem.MolToMolBlock(mcpy, forceV3000=True)
self.assertNotEqual(mb.find('V30 1 SRU'), -1)
self.assertNotEqual(mb.find('BRKXYZ'), -1)
self.assertNotEqual(mb.find('CONNECT=HT'), -1)
def testXBONDS(self):
mol = Chem.MolFromMolBlock('''
Mrv1824 06192020192D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 6 6 1 0 0
M V30 BEGIN ATOM
M V30 1 C -1.25 0.7484 0 0
M V30 2 C -2.5837 -0.0216 0 0
M V30 3 C -2.5837 -1.5617 0 0
M V30 4 C -1.25 -2.3317 0 0
M V30 5 C 0.0837 -1.5617 0 0
M V30 6 C 0.0837 -0.0216 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 1 3 4
M V30 4 1 4 5
M V30 5 1 5 6
M V30 6 1 1 6
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 SRU 0 ATOMS=(1 1) XBONDS=(2 1 6) XBHEAD=(2 6 1) XBCORR=(4 6 6 1 1) -
M V30 BRKXYZ=(9 -2.02 -0.0216 0 -2.02 1.5184 0 0 0 0) BRKXYZ=(9 -0.48 1.5184 -
M V30 0 -0.48 -0.0216 0 0 0 0) CONNECT=HT LABEL="1-3"
M V30 END SGROUP
M V30 END CTAB
M END
''')
self.assertIsNotNone(mol)
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 1)
sg = sgs[0]
self.assertEqual(sg.GetProp('TYPE'), 'SRU')
v = sg.GetUnsignedVectProp('XBHEAD')
self.assertEqual(len(v), 2)
self.assertEqual(list(v), [5, 0])
v = sg.GetUnsignedVectProp('XBCORR')
self.assertEqual(len(v), 4)
self.assertEqual(list(v), [5, 5, 0, 0])
def testDataFields(self):
mol = Chem.MolFromMolBlock('''
Mrv2007 06242013252D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 7 6 1 0 0
M V30 BEGIN ATOM
M V30 1 C -5.1782 0.0827 0 0
M V30 2 C -6.5119 -0.6873 0 0
M V30 3 C -3.8446 -0.6873 0 0
M V30 4 O -2.5109 0.0826 0 0
M V30 5 C -1.0732 -0.4692 0 0
M V30 6 C -5.1782 1.6227 0 0
M V30 7 C -6.5119 2.3927 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 2 1 3
M V30 3 1 3 4
M V30 4 1 4 5
M V30 5 1 1 6
M V30 6 1 7 6
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 DAT 0 ATOMS=(2 1 6) FIELDNAME=property -
M V30 FIELDDISP=" -5.1782 0.0827 DA ALL 0 0" -
M V30 FIELDDATA=val2 FIELDDATA=val1
M V30 END SGROUP
M V30 END CTAB
M END
''')
self.assertIsNotNone(mol)
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 1)
sg = sgs[0]
self.assertEqual(sg.GetProp('TYPE'), 'DAT')
pv = sg.GetStringVectProp('DATAFIELDS')
self.assertEqual(list(pv), ['val2', 'val1'])
def testCopying(self):
mol = Chem.MolFromMolBlock('''
Mrv2014 07312005252D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 7 6 3 0 0
M V30 BEGIN ATOM
M V30 1 * -12.75 11.5 0 0
M V30 2 O -11.4163 12.27 0 0
M V30 3 C -10.0826 11.5 0 0
M V30 4 C -8.749 12.27 0 0
M V30 5 O -10.0826 9.96 0 0
M V30 6 N -7.4153 11.5 0 0
M V30 7 C -6.0816 12.27 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 1 3 4
M V30 4 2 3 5
M V30 5 1 4 6
M V30 6 1 6 7
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 SRU 0 ATOMS=(3 2 3 5) XBONDS=(2 1 3) BRKXYZ=(9 -9.9955 12.6173 0 -
M V30 -9.0715 11.0169 0 0 0 0) BRKXYZ=(9 -11.5035 11.1527 0 -12.4275 12.7531 -
M V30 0 0 0 0) CONNECT=HT LABEL=n
M V30 2 DAT 0 ATOMS=(1 6) FIELDNAME=foo_data -
M V30 FIELDDISP=" -7.4153 11.5000 DAU ALL 0 0" -
M V30 MRV_FIELDDISP=0 FIELDDATA=bar
M V30 3 DAT 0 ATOMS=(1 7) FIELDNAME=bar_data -
M V30 FIELDDISP=" -6.0816 12.2700 DAU ALL 0 0" -
M V30 MRV_FIELDDISP=0 FIELDDATA=baz
M V30 END SGROUP
M V30 END CTAB
M END''')
self.assertEqual(len(Chem.GetMolSubstanceGroups(mol)), 3)
mol2 = Chem.Mol(mol)
Chem.ClearMolSubstanceGroups(mol2)
self.assertEqual(len(Chem.GetMolSubstanceGroups(mol2)), 0)
sgs = Chem.GetMolSubstanceGroups(mol)
Chem.AddMolSubstanceGroup(mol2, sgs[0])
Chem.AddMolSubstanceGroup(mol2, sgs[2])
self.assertEqual(len(Chem.GetMolSubstanceGroups(mol2)), 2)
molb = Chem.MolToV3KMolBlock(mol2)
self.assertEqual(molb.find("foo_data"), -1)
self.assertGreater(molb.find("M V30 2 DAT 0 ATOMS=(1 7) FIELDNAME=bar_data"), 0)
# we can also use this to copy SGroups:
sgs2 = Chem.GetMolSubstanceGroups(mol2)
newsg = Chem.AddMolSubstanceGroup(mol2, sgs[1])
newsg.SetProp("FIELDNAME", "blah_data")
molb = Chem.MolToV3KMolBlock(mol2)
self.assertGreater(molb.find("M V30 3 DAT 0 ATOMS=(1 6) FIELDNAME=blah_data"), 0)
def testCStates(self):
mol = Chem.MolFromMolBlock('''
ACCLDraw08282007542D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 9 9 1 0 0
M V30 BEGIN ATOM
M V30 1 C 8.759 -6.2839 0 0
M V30 2 C 10.8013 -6.2833 0 0
M V30 3 C 9.7821 -5.6936 0 0
M V30 4 C 10.8013 -7.4648 0 0
M V30 5 C 8.759 -7.4701 0 0
M V30 6 C 9.7847 -8.0543 0 0
M V30 7 C 11.8245 -5.6926 0 0
M V30 8 O 12.8482 -6.2834 0 0
M V30 9 O 11.8245 -4.5104 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 6 4
M V30 2 2 5 6
M V30 3 1 2 3
M V30 4 1 1 5
M V30 5 2 4 2
M V30 6 2 3 1
M V30 7 2 7 9
M V30 8 1 7 8
M V30 9 1 2 7
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 SUP 1 ATOMS=(3 7 8 9) XBONDS=(1 9) CSTATE=(4 9 -1.02 -0.59 0) LABEL=-
M V30 CO2H
M V30 END SGROUP
M V30 END CTAB
M END
''')
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 1)
sg0 = sgs[0]
pd = sg0.GetPropsAsDict()
self.assertTrue('TYPE' in pd)
self.assertEqual(pd['TYPE'], 'SUP')
cstates = sg0.GetCStates()
self.assertEqual(len(cstates), 1)
cs0 = cstates[0]
self.assertEqual(cs0.bondIdx, 8)
self.assertAlmostEqual(cs0.vector.x, -1.02, 2)
self.assertAlmostEqual(cs0.vector.y, -0.59, 2)
def testBrackets(self):
mol = Chem.MolFromMolBlock('''
Mrv2014 08282011142D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 6 5 1 0 0
M V30 BEGIN ATOM
M V30 1 C -15.7083 2 0 0
M V30 2 C -14.3747 2.77 0 0
M V30 3 O -13.041 2 0 0
M V30 4 C -11.7073 2.77 0 0
M V30 5 C -10.3736 2 0 0
M V30 6 C -9.0399 2.77 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 1 3 4
M V30 4 1 4 5
M V30 5 1 5 6
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 MON 0 ATOMS=(2 3 4) BRKXYZ=(9 -13.811 1.23 0 -13.811 3.54 0 0 0 0) -
M V30 BRKXYZ=(9 -10.9373 3.54 0 -10.9373 1.23 0 0 0 0)
M V30 END SGROUP
M V30 END CTAB
M END''')
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 1)
sg0 = sgs[0]
pd = sg0.GetPropsAsDict()
self.assertTrue('TYPE' in pd)
self.assertEqual(pd['TYPE'], 'MON')
brackets = sg0.GetBrackets()
self.assertEqual(len(brackets), 2)
b = brackets[0]
self.assertEqual(len(b), 3)
self.assertAlmostEqual(b[0].x, -13.811, 3)
self.assertAlmostEqual(b[0].y, 1.230, 3)
self.assertAlmostEqual(b[1].x, -13.811, 3)
self.assertAlmostEqual(b[1].y, 3.540, 3)
self.assertAlmostEqual(b[2].x, 0, 3)
self.assertAlmostEqual(b[2].y, 0, 3)
b = brackets[1]
self.assertEqual(len(b), 3)
self.assertAlmostEqual(b[0].x, -10.937, 3)
self.assertAlmostEqual(b[0].y, 3.54, 3)
self.assertAlmostEqual(b[1].x, -10.937, 3)
self.assertAlmostEqual(b[1].y, 1.23, 3)
self.assertAlmostEqual(b[2].x, 0, 3)
self.assertAlmostEqual(b[2].y, 0, 3)
def testAttachPoints(self):
mol = Chem.MolFromMolBlock('''
Mrv2014 09012006262D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 4 3 1 0 0
M V30 BEGIN ATOM
M V30 1 C -5.0833 0.0833 0 0
M V30 2 C -3.7497 0.8533 0 0
M V30 3 O -2.416 0.0833 0 0
M V30 4 O -3.7497 2.3933 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 2 2 4
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 SUP 0 ATOMS=(3 2 3 4) SAP=(3 2 1 1) XBONDS=(1 1) LABEL=CO2H ESTATE=E
M V30 END SGROUP
M V30 END CTAB
M END''')
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 1)
sg0 = sgs[0]
pd = sg0.GetPropsAsDict()
self.assertTrue('TYPE' in pd)
self.assertEqual(pd['TYPE'], 'SUP')
aps = sg0.GetAttachPoints()
self.assertEqual(len(aps), 1)
self.assertEqual(aps[0].aIdx, 1)
self.assertEqual(aps[0].lvIdx, 0)
self.assertEqual(aps[0].id, '1')
mol = Chem.MolFromMolBlock('''
Mrv2014 09012006262D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 4 3 0 0 0
M V30 BEGIN ATOM
M V30 1 C -5.0833 0.0833 0 0
M V30 2 C -3.7497 0.8533 0 0
M V30 3 O -2.416 0.0833 0 0
M V30 4 O -3.7497 2.3933 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 2 2 4
M V30 END BOND
M V30 END CTAB
M END''')
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 0)
sg = Chem.CreateMolSubstanceGroup(mol, "SUP")
sg.AddAtomWithIdx(1)
sg.AddAtomWithIdx(2)
sg.AddAtomWithIdx(3)
sg.AddBondWithIdx(0)
sg.SetProp('LABEL', 'CO2H')
sg.AddAttachPoint(1, 0, '1')
molb = Chem.MolToV3KMolBlock(mol)
self.assertGreater(
molb.find('M V30 1 SUP 0 ATOMS=(3 2 3 4) XBONDS=(1 1) LABEL=CO2H SAP=(3 2 1 1)'), 0)
def testClearValues(self):
mol = Chem.MolFromMolBlock('''example
-ISIS- 10171405052D
0 0 0 0 0 999 V3000
M V30 BEGIN CTAB
M V30 COUNTS 14 15 1 0 0
M V30 BEGIN ATOM
M V30 1 C 6.4292 -1.1916 0 0 CFG=3
M V30 2 C 7.0125 -0.6042 0 0
M V30 3 N 6.4292 -0.0250999 0 0
M V30 4 C 5.8416 -0.6042 0 0
M V30 5 C 5.8416 -1.7708 0 0
M V30 6 N 6.4292 -2.3584 0 0 CFG=3
M V30 7 C 7.0125 -1.7708 0 0
M V30 8 O 5.7166 -3.5875 0 0
M V30 9 C 5.7166 -4.4125 0 0 CFG=3
M V30 10 C 4.8875 -4.4125 0 0
M V30 11 C 6.5376 -4.4166 0 0
M V30 12 C 5.7166 -5.2376 0 0
M V30 13 C 6.4292 -3.175 0 0
M V30 14 O 7.1375 -3.5875 0 0
M V30 END ATOM
M V30 BEGIN BOND
M V30 1 1 1 2
M V30 2 1 2 3
M V30 3 1 3 4
M V30 4 1 4 1
M V30 5 1 1 5
M V30 6 1 5 6
M V30 7 1 6 7
M V30 8 1 7 1
M V30 9 1 6 13
M V30 10 1 8 9
M V30 11 1 9 10
M V30 12 1 9 11
M V30 13 1 9 12
M V30 14 2 13 14
M V30 15 1 8 13
M V30 END BOND
M V30 BEGIN SGROUP
M V30 1 SUP 0 ATOMS=(7 8 9 10 11 12 13 14) XBONDS=(1 9) BRKXYZ=(9 6.24 -2.9 0 -
M V30 6.24 -2.9 0 0 0 0) CSTATE=(4 9 0 0.82 0) LABEL=Boc SAP=(3 13 6 1)
M V30 END SGROUP
M V30 END CTAB
M END''')
sgs = Chem.GetMolSubstanceGroups(mol)
self.assertEqual(len(sgs), 1)
self.assertEqual(len(sgs[0].GetBrackets()), 1)
sgs[0].ClearBrackets()
self.assertEqual(len(sgs[0].GetBrackets()), 0)
self.assertEqual(len(sgs[0].GetCStates()), 1)
sgs[0].ClearCStates()
self.assertEqual(len(sgs[0].GetCStates()), 0)
self.assertEqual(len(sgs[0].GetAttachPoints()), 1)
sgs[0].ClearAttachPoints()
self.assertEqual(len(sgs[0].GetAttachPoints()), 0)
def testCreateDataSGroup(self):
mol = Chem.MolFromSmiles('CC(=O)O')
sg = Chem.CreateMolDataSubstanceGroup(mol, "pKa", "4.5")
sg.SetAtoms([1, 2, 3])
sg = Chem.GetMolSubstanceGroups(mol)[0]
self.assertEqual(sg.GetProp("TYPE"), "DAT")
self.assertEqual(sg.GetProp("FIELDNAME"), "pKa")
self.assertEqual(sg.GetStringVectProp("DATAFIELDS")[0], "4.5")
if __name__ == '__main__':
print("Testing SubstanceGroups wrapper")
unittest.main()