@@ -89,6 +89,7 @@ def merge(
8989 merged : Sire.Mol.Molecule
9090 The merged molecule.
9191 """
92+ from sire .legacy import CAS as _SireCAS
9293 from sire .legacy import Mol as _SireMol
9394 from sire .legacy import Base as _SireBase
9495 from sire .legacy import MM as _SireMM
@@ -1027,45 +1028,29 @@ def merge(
10271028 "or 'allow_ring_size_change' options."
10281029 )
10291030
1030- # Create the connectivity object.
1031- conn = _SireMol .Connectivity (edit_mol .info ()).edit ()
1032-
10331031 # Connectivity in the merged molecule.
10341032 conn0 = _SireMol .Connectivity (edit_mol .info ()).edit ()
10351033 conn1 = _SireMol .Connectivity (edit_mol .info ()).edit ()
10361034
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 ()
1035+ # Connect the bonded atoms in both end states.
1036+ for bond in edit_mol .property ("bond0" ).potentials ():
1037+ # Only connect bonds with non-zero force constants.
1038+ ab = _SireMM .AmberBond (bond .function (), _SireCAS .Symbol ("r" ))
1039+ if ab .k () != 0.0 :
1040+ conn0 .connect (bond .atom0 (), bond .atom1 ())
10591041 conn0 = conn0 .commit ()
1042+ for bond in edit_mol .property ("bond1" ).potentials ():
1043+ # Only connect bonds with non-zero force constants.
1044+ ab = _SireMM .AmberBond (bond .function (), _SireCAS .Symbol ("r" ))
1045+ if ab .k () != 0.0 :
1046+ conn1 .connect (bond .atom0 (), bond .atom1 ())
10601047 conn1 = conn1 .commit ()
10611048
1062- # Get the connectivity of the two molecules.
1049+ # Get the original connectivity of the two molecules.
10631050 c0 = molecule0 .property ("connectivity" )
10641051 c1 = molecule1 .property ("connectivity" )
10651052
10661053 # Check that the merge hasn't modified the connectivity.
1067-
1068- # The checking was blocked when merging a protein
10691054 if roi is None :
10701055 # molecule0
10711056 for x in range (0 , molecule0 .num_atoms ()):
@@ -1083,7 +1068,7 @@ def merge(
10831068 idy_map = mol0_merged_mapping [idy ]
10841069
10851070 # Was a ring opened/closed?
1086- is_ring_broken = _is_ring_broken (c0 , conn , idx , idy , idx_map , idy_map )
1071+ is_ring_broken = _is_ring_broken (c0 , conn1 , idx , idy , idx_map , idy_map )
10871072
10881073 # A ring was broken and it is not allowed.
10891074 if is_ring_broken and not allow_ring_breaking :
@@ -1095,7 +1080,7 @@ def merge(
10951080
10961081 # Did a ring change size?
10971082 is_ring_size_change = _is_ring_size_changed (
1098- c0 , conn , idx , idy , idx_map , idy_map
1083+ c0 , conn1 , idx , idy , idx_map , idy_map
10991084 )
11001085
11011086 # A ring changed size and it is not allowed.
@@ -1113,7 +1098,7 @@ def merge(
11131098 )
11141099
11151100 # The connectivity has changed.
1116- if c0 .connection_type (idx , idy ) != conn .connection_type (
1101+ if c0 .connection_type (idx , idy ) != conn1 .connection_type (
11171102 idx_map , idy_map
11181103 ):
11191104 # The connectivity changed for an unknown reason.
@@ -1141,7 +1126,7 @@ def merge(
11411126 idy_map = mol1_merged_mapping [idy ]
11421127
11431128 # Was a ring opened/closed?
1144- is_ring_broken = _is_ring_broken (c1 , conn , idx , idy , idx_map , idy_map )
1129+ is_ring_broken = _is_ring_broken (c1 , conn0 , idx , idy , idx_map , idy_map )
11451130
11461131 # A ring was broken and it is not allowed.
11471132 if is_ring_broken and not allow_ring_breaking :
@@ -1153,7 +1138,7 @@ def merge(
11531138
11541139 # Did a ring change size?
11551140 is_ring_size_change = _is_ring_size_changed (
1156- c1 , conn , idx , idy , idx_map , idy_map
1141+ c1 , conn0 , idx , idy , idx_map , idy_map
11571142 )
11581143
11591144 # A ring changed size and it is not allowed.
@@ -1171,7 +1156,7 @@ def merge(
11711156 )
11721157
11731158 # The connectivity has changed.
1174- if c1 .connection_type (idx , idy ) != conn .connection_type (
1159+ if c1 .connection_type (idx , idy ) != conn0 .connection_type (
11751160 idx_map , idy_map
11761161 ):
11771162 # The connectivity changed for an unknown reason.
@@ -1266,90 +1251,95 @@ def merge(
12661251 iterlen = len (molecule1_roi_idx )
12671252 iterrange = molecule1_roi_idx
12681253
1269- for x in range (0 , iterlen ):
1254+ for x in range (0 , iterlen ):
1255+ # Convert to an AtomIdx.
1256+ idx = iterrange [x ]
1257+ idx = _SireMol .AtomIdx (idx )
1258+
1259+ # Map the index to its position in the merged molecule.
1260+ idx_map = mol1_merged_mapping [idx ]
1261+
1262+ for y in range (x + 1 , iterlen ):
1263+ idy = iterrange [y ]
12701264 # Convert to an AtomIdx.
1271- idx = iterrange [x ]
1272- idx = _SireMol .AtomIdx (idx )
1265+ idy = _SireMol .AtomIdx (idy )
12731266
12741267 # 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 )
1268+ idy_map = mol1_merged_mapping [idy ]
12811269
1282- # Map the index to its position in the merged molecule.
1283- idy_map = mol1_merged_mapping [idy ]
1270+ conn_type = conn0 .connection_type (idx_map , idy_map )
1271+ # The atoms aren't bonded.
1272+ if conn_type == 0 :
1273+ clj_scale_factor = _SireMM .CLJScaleFactor (1 , 1 )
1274+ clj_nb_pairs0 .set (idx_map , idy_map , clj_scale_factor )
12841275
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 )
1276+ # The atoms are part of a dihedral.
1277+ elif conn_type == 4 :
1278+ clj_scale_factor = _SireMM .CLJScaleFactor (
1279+ ff .electrostatic14_scale_factor (), ff .vdw14_scale_factor ()
1280+ )
1281+ clj_nb_pairs0 .set (idx_map , idy_map , clj_scale_factor )
12901282
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 )
1283+ # The atoms are bonded
1284+ else :
1285+ clj_scale_factor = _SireMM .CLJScaleFactor (0 , 0 )
1286+ clj_nb_pairs0 .set (idx_map , idy_map , clj_scale_factor )
12971287
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 )
1288+ # Now copy in all intrascale values from molecule0 into clj_nb_pairs0.
13021289
1303- # Now copy in all intrascale values from molecule0 into both
1304- # clj_nb_pairs matrices.
1290+ # Work out the iteration length and range.
13051291 if roi is None :
13061292 iterlen = molecule0 .num_atoms ()
13071293 iterrange = list (range (molecule0 .num_atoms ()))
1308- # When region of interest is defined, perfrom loop from these indices
13091294 else :
13101295 for roi_res in roi :
1311- # Get atom indices of ROI residue in molecule0
1296+ # Get atom indices of ROI residue in molecule0.
13121297 molecule0_roi = molecule0 .residues ()[roi_res ]
13131298 molecule0_roi_idx = [a .index () for a in molecule0_roi ]
13141299 iterlen = len (molecule0_roi_idx )
13151300 iterrange = molecule0_roi_idx
13161301
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 )
1302+ # Perform a triangular loop over atoms from molecule0.
1303+ for x in range (0 , iterlen ):
1304+ # Convert to an AtomIdx.
1305+ idx = iterrange [x ]
1306+ idx = _SireMol .AtomIdx (idx )
13221307
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 )
1308+ # Map the index to its position in the merged molecule.
1309+ idx_map = mol0_merged_mapping [idx ]
13461310
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 )
1311+ for y in range (x + 1 , iterlen ):
1312+ idy = iterrange [y ]
1313+ # Convert to an AtomIdx.
1314+ idy = _SireMol .AtomIdx (idy )
1315+
1316+ # Map the index to its position in the merged molecule.
1317+ idy_map = mol0_merged_mapping [idy ]
1318+
1319+ # Get the connection type between the atoms.
1320+ conn_type = conn0 .connection_type (idx_map , idy_map )
1321+
1322+ # The atoms aren't bonded.
1323+ if conn_type == 0 :
1324+ clj_scale_factor = _SireMM .CLJScaleFactor (1 , 1 )
1325+ clj_nb_pairs0 .set (idx_map , idy_map , clj_scale_factor )
1326+
1327+ # The atoms are part of a dihedral.
1328+ elif conn_type == 4 :
1329+ clj_scale_factor = _SireMM .CLJScaleFactor (
1330+ ff .electrostatic14_scale_factor (),
1331+ ff .vdw14_scale_factor (),
1332+ )
1333+ clj_nb_pairs0 .set (idx_map , idy_map , clj_scale_factor )
1334+
1335+ # The atoms are bonded
1336+ else :
1337+ clj_scale_factor = _SireMM .CLJScaleFactor (0 , 0 )
1338+ clj_nb_pairs0 .set (idx_map , idy_map , clj_scale_factor )
13511339
13521340 # Finally, copy the intrascale from molecule1 into clj_nb_pairs1.
1341+
1342+ # Work out the iteration length and range.
13531343 if roi is None :
13541344 iterlen = molecule1 .num_atoms ()
13551345 iterrange = list (range (molecule1 .num_atoms ()))
@@ -1361,40 +1351,42 @@ def merge(
13611351 iterlen = len (molecule1_roi_idx )
13621352 iterrange = molecule1_roi_idx
13631353
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 )
1354+ # Perform a triangular loop over atoms from molecule1.
1355+ for x in range (0 , iterlen ):
1356+ # Convert to an AtomIdx.
1357+ idx = iterrange [x ]
1358+ idx = _SireMol .AtomIdx (idx )
13691359
1370- # Map the index to its position in the merged molecule.
1371- idx = mol1_merged_mapping [idx ]
1360+ # Map the index to its position in the merged molecule.
1361+ idx = mol1_merged_mapping [idx ]
13721362
1373- for y in range (x + 1 , iterlen ):
1374- idy = iterrange [y ]
1375- # Convert to an AtomIdx.
1376- idy = _SireMol .AtomIdx (idy )
1363+ for y in range (x + 1 , iterlen ):
1364+ idy = iterrange [y ]
1365+ # Convert to an AtomIdx.
1366+ idy = _SireMol .AtomIdx (idy )
13771367
1378- # Map the index to its position in the merged molecule.
1379- idy = mol1_merged_mapping [idy ]
1368+ # Map the index to its position in the merged molecule.
1369+ idy = mol1_merged_mapping [idy ]
13801370
1381- conn_type = conn1 .connection_type (idx , idy )
1371+ # Get the connection type between the atoms.
1372+ conn_type = conn1 .connection_type (idx , idy )
13821373
1383- if conn_type == 0 :
1384- clj_scale_factor = _SireMM .CLJScaleFactor (1 , 1 )
1385- clj_nb_pairs1 .set (idx , idy , clj_scale_factor )
1374+ if conn_type == 0 :
1375+ clj_scale_factor = _SireMM .CLJScaleFactor (1 , 1 )
1376+ clj_nb_pairs1 .set (idx , idy , clj_scale_factor )
13861377
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 )
1378+ # The atoms are part of a dihedral.
1379+ elif conn_type == 4 :
1380+ clj_scale_factor = _SireMM .CLJScaleFactor (
1381+ ff .electrostatic14_scale_factor (),
1382+ ff .vdw14_scale_factor (),
1383+ )
1384+ clj_nb_pairs1 .set (idx , idy , clj_scale_factor )
13931385
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 )
1386+ # The atoms are bonded
1387+ else :
1388+ clj_scale_factor = _SireMM .CLJScaleFactor (0 , 0 )
1389+ clj_nb_pairs1 .set (idx , idy , clj_scale_factor )
13981390
13991391 # Store the two molecular components.
14001392 edit_mol .set_property ("molecule0" , molecule0 )
0 commit comments