Skip to content

Commit 13d0fc0

Browse files
committed
Fix inconsistencies in merge code.
1 parent cc56ae7 commit 13d0fc0

1 file changed

Lines changed: 108 additions & 123 deletions

File tree

python/BioSimSpace/Align/_merge.py

Lines changed: 108 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,45 +1027,23 @@ def merge(
10271027
"or 'allow_ring_size_change' options."
10281028
)
10291029

1030-
# Create the connectivity object.
1031-
conn = _SireMol.Connectivity(edit_mol.info()).edit()
1032-
10331030
# Connectivity in the merged molecule.
10341031
conn0 = _SireMol.Connectivity(edit_mol.info()).edit()
10351032
conn1 = _SireMol.Connectivity(edit_mol.info()).edit()
10361033

1037-
bonds_atoms0 = {
1038-
frozenset([bond.atom0(), bond.atom1()])
1039-
for bond in edit_mol.property("bond0").potentials()
1040-
}
1041-
bonds_atoms1 = {
1042-
frozenset([bond.atom0(), bond.atom1()])
1043-
for bond in edit_mol.property("bond1").potentials()
1044-
}
1045-
1046-
for atom0, atom1 in bonds_atoms0:
1047-
conn0.connect(atom0, atom1)
1048-
1049-
for atom0, atom1 in bonds_atoms1:
1050-
conn1.connect(atom0, atom1)
1051-
1052-
# We only add a bond to the total connectivity if it's defined in both states
1053-
# This results in a "broken" topology if one writes it in GROMACS
1054-
# But GROMACS can't handle bond breaks anyway
1055-
for atom0, atom1 in bonds_atoms0 & bonds_atoms1:
1056-
conn.connect(atom0, atom1)
1057-
1058-
conn = conn.commit()
1034+
# Connect the bonded atoms in both end states.
1035+
for bond in edit_mol.property("bond0").potentials():
1036+
conn0.connect(bond.atom0(), bond.atom1())
10591037
conn0 = conn0.commit()
1038+
for bond in edit_mol.property("bond1").potentials():
1039+
conn1.connect(bond.atom0(), bond.atom1())
10601040
conn1 = conn1.commit()
10611041

1062-
# Get the connectivity of the two molecules.
1042+
# Get the original connectivity of the two molecules.
10631043
c0 = molecule0.property("connectivity")
10641044
c1 = molecule1.property("connectivity")
10651045

10661046
# Check that the merge hasn't modified the connectivity.
1067-
1068-
# The checking was blocked when merging a protein
10691047
if roi is None:
10701048
# molecule0
10711049
for x in range(0, molecule0.num_atoms()):
@@ -1083,7 +1061,7 @@ def merge(
10831061
idy_map = mol0_merged_mapping[idy]
10841062

10851063
# Was a ring opened/closed?
1086-
is_ring_broken = _is_ring_broken(c0, conn, idx, idy, idx_map, idy_map)
1064+
is_ring_broken = _is_ring_broken(c0, conn1, idx, idy, idx_map, idy_map)
10871065

10881066
# A ring was broken and it is not allowed.
10891067
if is_ring_broken and not allow_ring_breaking:
@@ -1095,7 +1073,7 @@ def merge(
10951073

10961074
# Did a ring change size?
10971075
is_ring_size_change = _is_ring_size_changed(
1098-
c0, conn, idx, idy, idx_map, idy_map
1076+
c0, conn1, idx, idy, idx_map, idy_map
10991077
)
11001078

11011079
# A ring changed size and it is not allowed.
@@ -1113,7 +1091,7 @@ def merge(
11131091
)
11141092

11151093
# The connectivity has changed.
1116-
if c0.connection_type(idx, idy) != conn.connection_type(
1094+
if c0.connection_type(idx, idy) != conn1.connection_type(
11171095
idx_map, idy_map
11181096
):
11191097
# The connectivity changed for an unknown reason.
@@ -1141,7 +1119,7 @@ def merge(
11411119
idy_map = mol1_merged_mapping[idy]
11421120

11431121
# Was a ring opened/closed?
1144-
is_ring_broken = _is_ring_broken(c1, conn, idx, idy, idx_map, idy_map)
1122+
is_ring_broken = _is_ring_broken(c1, conn0, idx, idy, idx_map, idy_map)
11451123

11461124
# A ring was broken and it is not allowed.
11471125
if is_ring_broken and not allow_ring_breaking:
@@ -1153,7 +1131,7 @@ def merge(
11531131

11541132
# Did a ring change size?
11551133
is_ring_size_change = _is_ring_size_changed(
1156-
c1, conn, idx, idy, idx_map, idy_map
1134+
c1, conn0, idx, idy, idx_map, idy_map
11571135
)
11581136

11591137
# A ring changed size and it is not allowed.
@@ -1171,7 +1149,7 @@ def merge(
11711149
)
11721150

11731151
# The connectivity has changed.
1174-
if c1.connection_type(idx, idy) != conn.connection_type(
1152+
if c1.connection_type(idx, idy) != conn0.connection_type(
11751153
idx_map, idy_map
11761154
):
11771155
# The connectivity changed for an unknown reason.
@@ -1266,90 +1244,95 @@ def merge(
12661244
iterlen = len(molecule1_roi_idx)
12671245
iterrange = molecule1_roi_idx
12681246

1269-
for x in range(0, iterlen):
1247+
for x in range(0, iterlen):
1248+
# Convert to an AtomIdx.
1249+
idx = iterrange[x]
1250+
idx = _SireMol.AtomIdx(idx)
1251+
1252+
# Map the index to its position in the merged molecule.
1253+
idx_map = mol1_merged_mapping[idx]
1254+
1255+
for y in range(x + 1, iterlen):
1256+
idy = iterrange[y]
12701257
# Convert to an AtomIdx.
1271-
idx = iterrange[x]
1272-
idx = _SireMol.AtomIdx(idx)
1258+
idy = _SireMol.AtomIdx(idy)
12731259

12741260
# Map the index to its position in the merged molecule.
1275-
idx_map = mol1_merged_mapping[idx]
1276-
1277-
for y in range(x + 1, iterlen):
1278-
idy = iterrange[y]
1279-
# Convert to an AtomIdx.
1280-
idy = _SireMol.AtomIdx(idy)
1261+
idy_map = mol1_merged_mapping[idy]
12811262

1282-
# Map the index to its position in the merged molecule.
1283-
idy_map = mol1_merged_mapping[idy]
1263+
conn_type = conn0.connection_type(idx_map, idy_map)
1264+
# The atoms aren't bonded.
1265+
if conn_type == 0:
1266+
clj_scale_factor = _SireMM.CLJScaleFactor(1, 1)
1267+
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
12841268

1285-
conn_type = conn0.connection_type(idx_map, idy_map)
1286-
# The atoms aren't bonded.
1287-
if conn_type == 0:
1288-
clj_scale_factor = _SireMM.CLJScaleFactor(1, 1)
1289-
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1269+
# The atoms are part of a dihedral.
1270+
elif conn_type == 4:
1271+
clj_scale_factor = _SireMM.CLJScaleFactor(
1272+
ff.electrostatic14_scale_factor(), ff.vdw14_scale_factor()
1273+
)
1274+
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
12901275

1291-
# The atoms are part of a dihedral.
1292-
elif conn_type == 4:
1293-
clj_scale_factor = _SireMM.CLJScaleFactor(
1294-
ff.electrostatic14_scale_factor(), ff.vdw14_scale_factor()
1295-
)
1296-
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1276+
# The atoms are bonded
1277+
else:
1278+
clj_scale_factor = _SireMM.CLJScaleFactor(0, 0)
1279+
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
12971280

1298-
# The atoms are bonded
1299-
else:
1300-
clj_scale_factor = _SireMM.CLJScaleFactor(0, 0)
1301-
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1281+
# Now copy in all intrascale values from molecule0 into clj_nb_pairs0.
13021282

1303-
# Now copy in all intrascale values from molecule0 into both
1304-
# clj_nb_pairs matrices.
1283+
# Work out the iteration length and range.
13051284
if roi is None:
13061285
iterlen = molecule0.num_atoms()
13071286
iterrange = list(range(molecule0.num_atoms()))
1308-
# When region of interest is defined, perfrom loop from these indices
13091287
else:
13101288
for roi_res in roi:
1311-
# Get atom indices of ROI residue in molecule0
1289+
# Get atom indices of ROI residue in molecule0.
13121290
molecule0_roi = molecule0.residues()[roi_res]
13131291
molecule0_roi_idx = [a.index() for a in molecule0_roi]
13141292
iterlen = len(molecule0_roi_idx)
13151293
iterrange = molecule0_roi_idx
13161294

1317-
# Perform a triangular loop over atoms from molecule0.
1318-
for x in range(0, iterlen):
1319-
# Convert to an AtomIdx.
1320-
idx = iterrange[x]
1321-
idx = _SireMol.AtomIdx(idx)
1295+
# Perform a triangular loop over atoms from molecule0.
1296+
for x in range(0, iterlen):
1297+
# Convert to an AtomIdx.
1298+
idx = iterrange[x]
1299+
idx = _SireMol.AtomIdx(idx)
13221300

1323-
# Map the index to its position in the merged molecule.
1324-
idx_map = mol0_merged_mapping[idx]
1325-
1326-
for y in range(x + 1, iterlen):
1327-
idy = iterrange[y]
1328-
# Convert to an AtomIdx.
1329-
idy = _SireMol.AtomIdx(idy)
1330-
1331-
# Map the index to its position in the merged molecule.
1332-
idy_map = mol0_merged_mapping[idy]
1333-
1334-
conn_type = conn0.connection_type(idx_map, idy_map)
1335-
# The atoms aren't bonded.
1336-
if conn_type == 0:
1337-
clj_scale_factor = _SireMM.CLJScaleFactor(1, 1)
1338-
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1339-
1340-
# The atoms are part of a dihedral.
1341-
elif conn_type == 4:
1342-
clj_scale_factor = _SireMM.CLJScaleFactor(
1343-
ff.electrostatic14_scale_factor(), ff.vdw14_scale_factor()
1344-
)
1345-
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1301+
# Map the index to its position in the merged molecule.
1302+
idx_map = mol0_merged_mapping[idx]
13461303

1347-
# The atoms are bonded
1348-
else:
1349-
clj_scale_factor = _SireMM.CLJScaleFactor(0, 0)
1350-
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1304+
for y in range(x + 1, iterlen):
1305+
idy = iterrange[y]
1306+
# Convert to an AtomIdx.
1307+
idy = _SireMol.AtomIdx(idy)
1308+
1309+
# Map the index to its position in the merged molecule.
1310+
idy_map = mol0_merged_mapping[idy]
1311+
1312+
# Get the connection type between the atoms.
1313+
conn_type = conn0.connection_type(idx_map, idy_map)
1314+
1315+
# The atoms aren't bonded.
1316+
if conn_type == 0:
1317+
clj_scale_factor = _SireMM.CLJScaleFactor(1, 1)
1318+
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1319+
1320+
# The atoms are part of a dihedral.
1321+
elif conn_type == 4:
1322+
clj_scale_factor = _SireMM.CLJScaleFactor(
1323+
ff.electrostatic14_scale_factor(),
1324+
ff.vdw14_scale_factor(),
1325+
)
1326+
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
1327+
1328+
# The atoms are bonded
1329+
else:
1330+
clj_scale_factor = _SireMM.CLJScaleFactor(0, 0)
1331+
clj_nb_pairs0.set(idx_map, idy_map, clj_scale_factor)
13511332

13521333
# Finally, copy the intrascale from molecule1 into clj_nb_pairs1.
1334+
1335+
# Work out the iteration length and range.
13531336
if roi is None:
13541337
iterlen = molecule1.num_atoms()
13551338
iterrange = list(range(molecule1.num_atoms()))
@@ -1361,40 +1344,42 @@ def merge(
13611344
iterlen = len(molecule1_roi_idx)
13621345
iterrange = molecule1_roi_idx
13631346

1364-
# Perform a triangular loop over atoms from molecule1.
1365-
for x in range(0, iterlen):
1366-
# Convert to an AtomIdx.
1367-
idx = iterrange[x]
1368-
idx = _SireMol.AtomIdx(idx)
1347+
# Perform a triangular loop over atoms from molecule1.
1348+
for x in range(0, iterlen):
1349+
# Convert to an AtomIdx.
1350+
idx = iterrange[x]
1351+
idx = _SireMol.AtomIdx(idx)
13691352

1370-
# Map the index to its position in the merged molecule.
1371-
idx = mol1_merged_mapping[idx]
1353+
# Map the index to its position in the merged molecule.
1354+
idx = mol1_merged_mapping[idx]
13721355

1373-
for y in range(x + 1, iterlen):
1374-
idy = iterrange[y]
1375-
# Convert to an AtomIdx.
1376-
idy = _SireMol.AtomIdx(idy)
1356+
for y in range(x + 1, iterlen):
1357+
idy = iterrange[y]
1358+
# Convert to an AtomIdx.
1359+
idy = _SireMol.AtomIdx(idy)
13771360

1378-
# Map the index to its position in the merged molecule.
1379-
idy = mol1_merged_mapping[idy]
1361+
# Map the index to its position in the merged molecule.
1362+
idy = mol1_merged_mapping[idy]
13801363

1381-
conn_type = conn1.connection_type(idx, idy)
1364+
# Get the connection type between the atoms.
1365+
conn_type = conn1.connection_type(idx, idy)
13821366

1383-
if conn_type == 0:
1384-
clj_scale_factor = _SireMM.CLJScaleFactor(1, 1)
1385-
clj_nb_pairs1.set(idx, idy, clj_scale_factor)
1367+
if conn_type == 0:
1368+
clj_scale_factor = _SireMM.CLJScaleFactor(1, 1)
1369+
clj_nb_pairs1.set(idx, idy, clj_scale_factor)
13861370

1387-
# The atoms are part of a dihedral.
1388-
elif conn_type == 4:
1389-
clj_scale_factor = _SireMM.CLJScaleFactor(
1390-
ff.electrostatic14_scale_factor(), ff.vdw14_scale_factor()
1391-
)
1392-
clj_nb_pairs1.set(idx, idy, clj_scale_factor)
1371+
# The atoms are part of a dihedral.
1372+
elif conn_type == 4:
1373+
clj_scale_factor = _SireMM.CLJScaleFactor(
1374+
ff.electrostatic14_scale_factor(),
1375+
ff.vdw14_scale_factor(),
1376+
)
1377+
clj_nb_pairs1.set(idx, idy, clj_scale_factor)
13931378

1394-
# The atoms are bonded
1395-
else:
1396-
clj_scale_factor = _SireMM.CLJScaleFactor(0, 0)
1397-
clj_nb_pairs1.set(idx, idy, clj_scale_factor)
1379+
# The atoms are bonded
1380+
else:
1381+
clj_scale_factor = _SireMM.CLJScaleFactor(0, 0)
1382+
clj_nb_pairs1.set(idx, idy, clj_scale_factor)
13981383

13991384
# Store the two molecular components.
14001385
edit_mol.set_property("molecule0", molecule0)

0 commit comments

Comments
 (0)