Skip to content

Commit 25912e4

Browse files
committed
merge existing exclusions and don't write redundant exclusions
1 parent 985b52d commit 25912e4

File tree

3 files changed

+121
-263
lines changed

3 files changed

+121
-263
lines changed

src/kimmdy/coordinates.py

+15-19
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import MDAnalysis as mda
1212
import numpy as np
1313

14-
from kimmdy.constants import DEFAULT_EDISSOC, REACTIVE_MOLECULEYPE, FFFUNC
14+
from kimmdy.constants import DEFAULT_EDISSOC, FFFUNC
1515
from kimmdy.parsing import read_plumed, write_plumed
1616
from kimmdy.recipe import Place
1717
from kimmdy.tasks import TaskFiles
@@ -209,6 +209,7 @@ def merge(self) -> MoleculeType:
209209
self.merge_bonds()
210210
self.merge_angles()
211211
self.merge_dihedrals()
212+
self.merge_exclusions()
212213

213214
if not self.morse_only:
214215
self.merge_pairs()
@@ -221,6 +222,14 @@ def merge(self) -> MoleculeType:
221222
key=lambda item: (int(item[0][0]), int(item[0][1])),
222223
)
223224
)
225+
# sort exclusions after adding helper pairs because they
226+
# come with their own exclusions
227+
self.mol_b.exclusions = dict(
228+
sorted(
229+
self.mol_b.exclusions.items(),
230+
key=lambda item: [int(i) for i in item[0]],
231+
)
232+
)
224233
else:
225234
# same as in (keysA - keysB) in v1
226235
for key in self.affected_interactions.bonds.removed:
@@ -936,6 +945,11 @@ def merge_pairs(self):
936945
self.mol_b.pairs = {}
937946
for key, pair in new_pairs.items():
938947
self.mol_b.pairs[key] = pair
948+
949+
def merge_exclusions(self):
950+
"""Merge exclusions by adding the exclusions from the A state to the B state"""
951+
logger.info("Merging exclusions")
952+
for key in self.mol_a.exclusions.keys():
939953
self.mol_b.exclusions[key] = Exclusion(*key)
940954

941955
def add_helper_pairs(self):
@@ -950,7 +964,6 @@ def add_helper_pairs(self):
950964
# pairs that stem from bonds breaking or forming
951965
# collected by looking at the changing bonds, angles and dihedrals (=higher order interactions)
952966
self.helper_pairs: dict[tuple[str, str], Pair] = {}
953-
self.helper_exclusions: set[tuple[str, str]] = set()
954967

955968
# a bond is either added or removed, but can't be both.
956969
# but for higher order interactions the end-atoms (of the angle or dihedral) can be involved
@@ -996,10 +1009,6 @@ def add_helper_pairs(self):
9961009
morphing_dihedrals = self.affected_interactions.dihedrals.morphed
9971010

9981011
for pair_key in added_bonds:
999-
if pair_key in removed_angles:
1000-
# the bond is added, but the atoms where in an angle in A
1001-
# so they where excluded before and will be excluded again
1002-
self.helper_exclusions.add(pair_key)
10031012
if pair_key in removed_dihedrals:
10041013
# the bond is added, but the atoms where in a dihedral in A
10051014
# so they had 1-4 interactions in A and will be excluded in B
@@ -1040,9 +1049,6 @@ def add_helper_pairs(self):
10401049
self.helper_pairs[pairkey] = self._make_pair(
10411050
*pairkey, transition=PairTransition.Vanish, from_1_4=True
10421051
)
1043-
if pairkey in removed_bonds:
1044-
# atoms where in a bond together and will be in an angle together, so they are just excluded
1045-
self.helper_exclusions.add(pairkey)
10461052
if (
10471053
pairkey
10481054
not in removed_bonds
@@ -1067,11 +1073,6 @@ def add_helper_pairs(self):
10671073
*pairkey, transition=PairTransition.Create
10681074
)
10691075

1070-
# atoms involved in angles that stay involved in angles but the parameters or atomtypes my change
1071-
for pairkey in swapping_angles | morphing_angles:
1072-
# we just want the exclusion
1073-
self.helper_exclusions.add(pairkey)
1074-
10751076
# atoms that end up with a dihedral between them where there was none before
10761077
for pairkey in added_dihedrals:
10771078
if pairkey in removed_bonds | removed_angles:
@@ -1128,11 +1129,6 @@ def add_helper_pairs(self):
11281129
# add general exclusions for each pair
11291130
self.mol_b.exclusions[key] = Exclusion(*key)
11301131

1131-
# add additional exclusions for atoms we know should be excluded
1132-
# just in case
1133-
for key in self.helper_exclusions:
1134-
self.mol_b.exclusions[key] = Exclusion(*key)
1135-
11361132

11371133
def merge_top_slow_growth(
11381134
top_a: Topology,

tests/test_coordinates.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,8 @@ def test_merge_hat_top(arranged_tmp_path, caplog):
298298
top_merge_ref = Topology(read_top(Path("topol_FEP.top")))
299299
top_merge = merge_top_slow_growth(top_a=top_a, top_b=top_b)
300300

301-
write_top(top_merge.to_dict(), Path("/tmp/kimmdtests_topol_merge.top"))
301+
# for debugging
302+
# write_top(top_merge.to_dict(), Path("/tmp/kimmdtests_topol_merge.top"))
302303

303304
assert top_merge.bonds[("19", "27")].funct == "3"
304305
assert top_merge.bonds[("26", "27")].funct == "3"
@@ -402,14 +403,11 @@ def test_merge_small_hat_details(arranged_tmp_path, caplog):
402403
assert len(removed_dihedrals) == 4
403404

404405
assert len(merger.helper_pairs) > 0
405-
assert len(merger.helper_exclusions) > 0
406406

407407
# the atoms of the changing bond still stay in an angle
408408
# so they keep being excluded
409409
assert ("8", "9") not in merger.helper_pairs
410410
assert ("7", "8") not in merger.helper_pairs
411-
assert ("8", "9") in merger.helper_exclusions
412-
assert ("7", "8") in merger.helper_exclusions
413411

414412

415413
def test_merge_small_hat_with_more_overlaps(arranged_tmp_path, caplog):

0 commit comments

Comments
 (0)