Skip to content

Commit 1a4b736

Browse files
committed
Merge branch 'master' into forced-swap
2 parents fca1f0a + 5b7c6cd commit 1a4b736

File tree

10 files changed

+529
-607
lines changed

10 files changed

+529
-607
lines changed

ensemble_md/cli/run_REXEE.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def main():
104104
os.mkdir(f'{REXEE.working_dir}/sim_{i}')
105105
os.mkdir(f'{REXEE.working_dir}/sim_{i}/iteration_0')
106106
MDP = REXEE.initialize_MDP(i)
107-
MDP.write(f"{REXEE.working_dir}/sim_{i}/iteration_0/expanded.mdp", skipempty=True)
107+
MDP.write(f"{REXEE.working_dir}/sim_{i}/iteration_0/{REXEE.mdp}", skipempty=True)
108108
if REXEE.modify_coords == 'default' and (not os.path.exists('residue_connect.csv') or not os.path.exists('residue_swap_map.csv')): # noqa: E501
109109
REXEE.process_top()
110110

@@ -263,8 +263,8 @@ def main():
263263
os.mkdir(f'{REXEE.working_dir}/sim_{j}/iteration_{i}')
264264
if REXEE.fixed_weights is True:
265265
counts = None # So that this should work also for GROMACS version < 2022.5
266-
MDP = REXEE.update_MDP(f"sim_{j}/iteration_{i - 1}/expanded.mdp", j, i, states, wl_delta, weights, counts) # modify with a new template # noqa: E501
267-
MDP.write(f"{REXEE.working_dir}/sim_{j}/iteration_{i}/expanded.mdp", skipempty=True)
266+
MDP = REXEE.update_MDP(f"sim_{j}/iteration_{i - 1}/{REXEE.mdp}", j, i, states, wl_delta, weights, counts) # modify with a new template # noqa: E501
267+
MDP.write(f"{REXEE.working_dir}/sim_{j}/iteration_{i}/{REXEE.mdp}", skipempty=True)
268268
# In run_REXEE(i, swap_pattern), where the tpr files will be generated, we use the top file at the
269269
# level of the simulation (the file that will be shared by all simulations). For the gro file, we
270270
# pass swap_pattern to the function to figure it out internally.
@@ -313,6 +313,10 @@ def main():
313313
gro_2 = f'{REXEE.working_dir}/sim_{swap_list[j][1]}/iteration_{i-1}/confout.gro'
314314
print(f' - {gro_1}\n - {gro_2}')
315315

316+
# Check that swap was not performed before checkpoint was created
317+
if os.path.exists(gro_1.split('.gro')[0] + '_backup.gro') and os.path.exists(gro_2.split('.gro')[0] + '_backup.gro'): # noqa: E501
318+
print('\nSwap already performed')
319+
else:
316320
# Now we rename gro_1 and gro_2 to back them up
317321
gro_1_backup = gro_1.split('.gro')[0] + '_backup.gro'
318322
gro_2_backup = gro_2.split('.gro')[0] + '_backup.gro'

ensemble_md/replica_exchange_EE.py

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ def set_params(self, analysis):
418418

419419
# 7-5. A list of sets of state indices
420420
start_idx = [i * self.s for i in range(self.n_sim)]
421-
self.state_ranges = [list(np.arange(i, i + self.n_sub)) for i in start_idx]
421+
self.state_ranges = [list(np.arange(i, i + self.n_sub, dtype=np.int32)) for i in start_idx]
422422

423423
# 7-6. A list of time it took to get the weights equilibrated
424424
self.equil = [-1 for i in range(self.n_sim)] # -1 means unequilibrated
@@ -1649,6 +1649,7 @@ def default_coords_fn(self, molA_file_name, molB_file_name, swap_index):
16491649
# Load the coordinate swapping map
16501650
connection_map = pd.read_csv('residue_connect.csv')
16511651
swap_map = pd.read_csv('residue_swap_map.csv')
1652+
atom_mapping = pd.read_csv('atom_name_mapping.csv')
16521653

16531654
# Step 1: Read the GRO input coordinate files and open temporary Output files
16541655
molA_file = open(molA_file_name, 'r').readlines() # open input file
@@ -1662,7 +1663,7 @@ def default_coords_fn(self, molA_file_name, molB_file_name, swap_index):
16621663
residue_options = swap_map['Swap A'].to_list() + swap_map['Swap B'].to_list()
16631664
nameA = coordinate_swap.identify_res(molA.topology, residue_options)
16641665
nameB = coordinate_swap.identify_res(molB.topology, residue_options)
1665-
df_atom_swap = coordinate_swap.find_common(molA_file, molB_file, nameA, nameB)
1666+
df_atom_swap = coordinate_swap.extract_missing(nameA, nameB, swap_map)
16661667

16671668
# Step 3: Fix break if present for solvated systems only
16681669
if len(molA.topology.select('water')) != 0:
@@ -1672,30 +1673,46 @@ def default_coords_fn(self, molA_file_name, molB_file_name, swap_index):
16721673
molB = coordinate_swap.fix_break(molB, nameB, B_dimensions, connection_map[connection_map['Resname'] == nameB]) # noqa: E501
16731674

16741675
# Step 4: Determine coordinates of atoms which need to be reconstructed as we swap coordinates between molecules # noqa: E501
1675-
miss_B = df_atom_swap[(df_atom_swap['Swap'] == 'B2A') & (df_atom_swap['Direction'] == 'miss')]['Name'].to_list() # noqa: E501
1676-
miss_A = df_atom_swap[(df_atom_swap['Swap'] == 'A2B') & (df_atom_swap['Direction'] == 'miss')]['Name'].to_list() # noqa: E501
1677-
if len(miss_B) != 0:
1678-
df_atom_swap = coordinate_swap.get_miss_coord(molB, molA, nameB, nameA, df_atom_swap, 'B2A', swap_map[(swap_map['Swap A'] == nameB) & (swap_map['Swap B'] == nameA)]) # noqa: E501
1679-
if len(miss_A) != 0:
1680-
df_atom_swap = coordinate_swap.get_miss_coord(molA, molB, nameA, nameB, df_atom_swap, 'A2B', swap_map[(swap_map['Swap A'] == nameA) & (swap_map['Swap B'] == nameB)]) # noqa: E501
1676+
df_atom_swap = coordinate_swap.get_miss_coord(molB, molA, nameB, nameA, df_atom_swap, 'A2B', swap_map[(swap_map['Swap A'] == nameB) & (swap_map['Swap B'] == nameA)]) # noqa: E501
1677+
df_atom_swap = coordinate_swap.get_miss_coord(molA, molB, nameA, nameB, df_atom_swap, 'B2A', swap_map[(swap_map['Swap A'] == nameA) & (swap_map['Swap B'] == nameB)]) # noqa: E501
16811678

16821679
# Step 5: Parse Current file to ensure atoms are added in the correct order
16831680
atom_order_A = gmx_parser.deter_atom_order(molA_file, nameA)
16841681
atom_order_B = gmx_parser.deter_atom_order(molB_file, nameB)
16851682

16861683
# Step 6: Write the new file
16871684
# Reprint preamble text
1688-
line_start = coordinate_swap.print_preamble(molA_file, molB_new, len(miss_B), len(miss_A))
1685+
line_start = coordinate_swap.print_preamble(molA_file, molB_new, len(df_atom_swap[df_atom_swap['Swap'] == 'A2B']), len(df_atom_swap[df_atom_swap['Swap'] == 'B2A'])) # noqa: E501
1686+
1687+
# Print up until we reach the residue to modify
1688+
line_restart, atom_num_restart = coordinate_swap.write_unmodified(line_start, molA_file, molB_new, nameA, 1, line_start, copy.deepcopy(molA.xyz[0])) # noqa: E501
16891689

16901690
# Print new coordinates to file for molB
1691-
coordinate_swap.write_new_file(df_atom_swap, 'A2B', 'B2A', line_start, molA_file, molB_new, nameA, nameB, copy.deepcopy(molA.xyz[0]), miss_A, atom_order_B) # noqa: E501
1691+
line_restart, atom_num_restart = coordinate_swap.write_modified(df_atom_swap, 'A2B', line_start, molA_file, molB_new, atom_num_restart, nameA, nameB, copy.deepcopy(molA.xyz[0]), atom_mapping, atom_order_B, atom_order_A) # noqa: E501
1692+
1693+
if line_restart is not None:
1694+
# Print rest of file after modified residue
1695+
coordinate_swap.write_unmodified(line_restart, molA_file, molB_new, nameA, atom_num_restart, line_start, copy.deepcopy(molA.xyz[0])) # noqa: E501
1696+
1697+
# Print box size
1698+
molB_new.write(molA_file[-1])
16921699

16931700
# Print new coordinates to file
16941701
# Reprint preamble text
1695-
line_start = coordinate_swap.print_preamble(molB_file, molA_new, len(miss_A), len(miss_B))
1702+
line_start = coordinate_swap.print_preamble(molB_file, molA_new, len(df_atom_swap[df_atom_swap['Swap'] == 'B2A']), len(df_atom_swap[df_atom_swap['Swap'] == 'A2B'])) # noqa: E501
1703+
1704+
# Print up until we reach the residue to modify
1705+
line_restart, atom_num_restart = coordinate_swap.write_unmodified(line_start, molB_file, molA_new, nameB, 1, line_start, copy.deepcopy(molB.xyz[0])) # noqa: E501
1706+
1707+
# Print new coordinates to file for molA
1708+
line_restart, atom_num_restart = coordinate_swap.write_modified(df_atom_swap, 'B2A', line_start, molB_file, molA_new, atom_num_restart, nameB, nameA, copy.deepcopy(molB.xyz[0]), atom_mapping, atom_order_A, atom_order_B) # noqa: E501
16961709

1697-
# Print new coordinates for molA
1698-
coordinate_swap.write_new_file(df_atom_swap, 'B2A', 'A2B', line_start, molB_file, molA_new, nameB, nameA, copy.deepcopy(molB.xyz[0]), miss_B, atom_order_A) # noqa: E501
1710+
if line_restart is not None:
1711+
# Print rest of file after modified residue
1712+
coordinate_swap.write_unmodified(line_restart, molB_file, molA_new, nameB, atom_num_restart, line_start, copy.deepcopy(molB.xyz[0])) # noqa: E501
1713+
1714+
# Print box size
1715+
molA_new.write(molB_file[-1])
16991716

17001717
# Rename temp files
17011718
os.rename('A_hybrid_swap.gro', molB_dir + '/confout.gro')
@@ -1706,6 +1723,12 @@ def process_top(self):
17061723
Processes the input topologies in order to determine the atoms for alignment in the default GRO swapping
17071724
function. Output as csv files to prevent needing to re-run this step.
17081725
"""
1726+
if not os.path.exists('atom_name_mapping.csv'):
1727+
coordinate_swap.create_atom_map(self.gro, self.resname_list, self.swap_rep_pattern)
1728+
atom_name_mapping = pd.read_csv('atom_name_mapping.csv')
1729+
else:
1730+
atom_name_mapping = pd.read_csv('atom_name_mapping.csv')
1731+
17091732
if not os.path.exists('residue_connect.csv'):
17101733
df_top = pd.DataFrame()
17111734
for f, file_name in enumerate(self.top):
@@ -1745,17 +1768,23 @@ def process_top(self):
17451768
# Determine atoms not present in both molecules
17461769
X, Y = [int(swap[0][0]), int(swap[1][0])]
17471770
lam = {X: int(swap[0][1]), Y: int(swap[1][1])}
1771+
swap_name_match = atom_name_mapping[(atom_name_mapping['resname A'].isin([self.resname_list[X], self.resname_list[Y]])) & (atom_name_mapping['resname B'].isin([self.resname_list[X], self.resname_list[Y]]))] # noqa: E501
17481772
for A, B in zip([X, Y], [Y, X]):
1773+
# Swapping coordinates from B to A
17491774
input_A = gmx_parser.read_top(self.top[A], self.resname_list[A])
17501775
start_line, A_name, A_num, state = coordinate_swap.get_names(input_A, self.resname_list[A])
17511776
input_B = gmx_parser.read_top(self.top[B], self.resname_list[B])
17521777
start_line, B_name, B_num, state = coordinate_swap.get_names(input_B, self.resname_list[B])
17531778

1754-
A_only = [x for x in A_name if x not in B_name]
1755-
B_only = [x for x in B_name if x not in A_name]
1779+
# Determine shared atom names
1780+
if len(swap_name_match[swap_name_match['resname A'] == self.resname_list[A]]) != 0:
1781+
common_atoms_A = list(swap_name_match['atom name A'].values)
1782+
else:
1783+
common_atoms_A = list(swap_name_match['atom name B'].values)
1784+
A_only = [x for x in A_name if x not in common_atoms_A]
17561785

17571786
# Seperate real to dummy switches
1758-
df = coordinate_swap.determine_connection(A_only, B_only, self.resname_list[A], self.resname_list[B], df_top, lam[A]) # noqa: E501
1787+
df = coordinate_swap.determine_connection(A_only, swap_name_match, self.resname_list[A], self.resname_list[B], df_top, lam[A]) # noqa: E501
17591788

17601789
df_map = pd.concat([df_map, df])
17611790

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
,resname A,resname B,atomid A,atom name A,atomid B,atom name B
2+
0,A2B,B2C,1,S1,1,S1
3+
1,A2B,B2C,1,S1,1,S1
4+
2,A2B,B2C,2,C2,2,C2
5+
3,A2B,B2C,2,C2,2,C2
6+
4,A2B,B2C,3,N3,3,N3
7+
5,A2B,B2C,3,N3,3,N3
8+
6,A2B,B2C,4,C4,4,C4
9+
7,A2B,B2C,4,C4,4,C4
10+
8,A2B,B2C,5,C5,5,C5
11+
9,A2B,B2C,5,C5,5,C5
12+
10,A2B,B2C,6,C6,6,C6
13+
11,A2B,B2C,6,C6,6,C6
14+
12,A2B,B2C,7,H1,8,H1
15+
13,A2B,B2C,7,H1,8,H1
16+
14,A2B,B2C,8,H2,9,H2
17+
15,A2B,B2C,8,H2,9,H2
18+
16,A2B,B2C,9,H3,10,H3
19+
17,A2B,B2C,9,H3,10,H3
20+
18,A2B,B2C,10,H4,11,H4
21+
19,A2B,B2C,10,H4,11,H4
22+
20,A2B,B2C,12,DC7,7,C7
23+
21,A2B,B2C,13,HV5,12,H5
24+
22,A2B,B2C,14,HV6,13,H6
25+
23,A2B,B2C,15,HV7,14,H7
26+
0,B2C,C2D,1,S1,1,S1
27+
1,B2C,C2D,1,S1,1,S1
28+
2,B2C,C2D,2,C2,2,C2
29+
3,B2C,C2D,2,C2,2,C2
30+
4,B2C,C2D,3,N3,3,N3
31+
5,B2C,C2D,3,N3,3,N3
32+
6,B2C,C2D,4,C4,4,C4
33+
7,B2C,C2D,4,C4,4,C4
34+
8,B2C,C2D,5,C5,5,C5
35+
9,B2C,C2D,5,C5,5,C5
36+
10,B2C,C2D,6,C6,6,C6
37+
11,B2C,C2D,6,C6,6,C6
38+
12,B2C,C2D,7,C7,7,C7
39+
13,B2C,C2D,7,C7,7,C7
40+
14,B2C,C2D,8,H1,9,H1
41+
15,B2C,C2D,8,H1,9,H1
42+
16,B2C,C2D,9,H2,10,H2
43+
17,B2C,C2D,9,H2,10,H2
44+
18,B2C,C2D,10,H3,11,H3
45+
19,B2C,C2D,10,H3,11,H3
46+
20,B2C,C2D,11,H4,12,H4
47+
21,B2C,C2D,11,H4,12,H4
48+
22,B2C,C2D,12,H5,19,HV5
49+
23,B2C,C2D,13,H6,13,H6
50+
24,B2C,C2D,13,H6,13,H6
51+
25,B2C,C2D,14,H7,14,H7
52+
26,B2C,C2D,14,H7,14,H7
53+
27,B2C,C2D,15,DC8,8,C8
54+
28,B2C,C2D,16,HV8,15,H8
55+
29,B2C,C2D,17,HV9,16,H9
56+
30,B2C,C2D,18,HV10,17,H10
57+
0,C2D,D2E,1,S1,1,S1
58+
1,C2D,D2E,1,S1,1,S1
59+
2,C2D,D2E,2,C2,2,C2
60+
3,C2D,D2E,2,C2,2,C2
61+
4,C2D,D2E,3,N3,3,N3
62+
5,C2D,D2E,3,N3,3,N3
63+
6,C2D,D2E,4,C4,4,C4
64+
7,C2D,D2E,4,C4,4,C4
65+
8,C2D,D2E,5,C5,5,C5
66+
9,C2D,D2E,5,C5,5,C5
67+
10,C2D,D2E,6,C6,6,C6
68+
11,C2D,D2E,6,C6,6,C6
69+
12,C2D,D2E,7,C7,7,C7
70+
13,C2D,D2E,7,C7,7,C7
71+
14,C2D,D2E,8,C8,18,DC8
72+
15,C2D,D2E,9,H1,9,H1
73+
16,C2D,D2E,9,H1,9,H1
74+
17,C2D,D2E,10,H2,10,H2
75+
18,C2D,D2E,10,H2,10,H2
76+
19,C2D,D2E,11,H3,11,H3
77+
20,C2D,D2E,11,H3,11,H3
78+
21,C2D,D2E,13,H6,13,H6
79+
22,C2D,D2E,13,H6,13,H6
80+
23,C2D,D2E,14,H7,14,H7
81+
24,C2D,D2E,14,H7,14,H7
82+
25,C2D,D2E,15,H8,19,HV8
83+
26,C2D,D2E,16,H9,20,HV9
84+
27,C2D,D2E,17,H10,21,HV10
85+
28,C2D,D2E,18,DC9,8,C9
86+
29,C2D,D2E,19,HV5,12,H5
87+
30,C2D,D2E,20,HV11,15,H11
88+
31,C2D,D2E,21,HV12,16,H12
89+
32,C2D,D2E,22,HV13,17,H13
90+
0,D2E,E2F,1,S1,1,S1
91+
1,D2E,E2F,1,S1,1,S1
92+
2,D2E,E2F,2,C2,2,C2
93+
3,D2E,E2F,2,C2,2,C2
94+
4,D2E,E2F,3,N3,3,N3
95+
5,D2E,E2F,3,N3,3,N3
96+
6,D2E,E2F,4,C4,4,C4
97+
7,D2E,E2F,4,C4,4,C4
98+
8,D2E,E2F,5,C5,5,C5
99+
9,D2E,E2F,5,C5,5,C5
100+
10,D2E,E2F,6,C6,6,C6
101+
11,D2E,E2F,6,C6,6,C6
102+
12,D2E,E2F,7,C7,7,C7
103+
13,D2E,E2F,7,C7,7,C7
104+
14,D2E,E2F,8,C9,9,C9
105+
15,D2E,E2F,8,C9,9,C9
106+
16,D2E,E2F,9,H1,10,H1
107+
17,D2E,E2F,9,H1,10,H1
108+
18,D2E,E2F,10,H2,11,H2
109+
19,D2E,E2F,10,H2,11,H2
110+
20,D2E,E2F,11,H3,12,H3
111+
21,D2E,E2F,11,H3,12,H3
112+
22,D2E,E2F,13,H6,13,H6
113+
23,D2E,E2F,13,H6,13,H6
114+
24,D2E,E2F,14,H7,14,H7
115+
25,D2E,E2F,14,H7,14,H7
116+
26,D2E,E2F,15,H11,18,H11
117+
27,D2E,E2F,15,H11,18,H11
118+
28,D2E,E2F,16,H12,19,H12
119+
29,D2E,E2F,16,H12,19,H12
120+
30,D2E,E2F,17,H13,20,H13
121+
31,D2E,E2F,17,H13,20,H13
122+
32,D2E,E2F,18,DC8,8,C8
123+
33,D2E,E2F,19,HV8,15,H8
124+
34,D2E,E2F,20,HV9,16,H9
125+
35,D2E,E2F,21,HV10,17,H10
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
,resname A,resname B,atomid A,atom name A,atomid B,atom name B
2+
0,I2J,J2K,1,O,1,O
3+
1,I2J,J2K,2,C1,2,C1
4+
2,I2J,J2K,3,C2,3,C2
5+
3,I2J,J2K,4,C3,4,C3
6+
4,I2J,J2K,5,C4,5,C4
7+
5,I2J,J2K,6,CV5,6,C5
8+
6,I2J,J2K,7,CV6,7,C6
9+
7,I2J,J2K,8,H1,10,H1
10+
8,I2J,J2K,9,H2,11,H2
11+
9,I2J,J2K,10,H3,12,H3
12+
10,I2J,J2K,11,H4,13,H4
13+
11,I2J,J2K,12,H5,14,H5
14+
12,I2J,J2K,13,H6,15,H6
15+
13,I2J,J2K,14,H7,16,H7
16+
14,I2J,J2K,16,HV9,17,H9
17+
15,I2J,J2K,17,HV10,18,H10
18+
16,I2J,J2K,18,HV11,19,H11
19+
17,I2J,J2K,19,HV12,20,H12
20+
18,I2J,J2K,20,HV13,21,H13
Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
1-
,index,Name,Atom Name Number,Element,Direction,Swap,File line,Final Type,X Coordinates,Y Coordinates,Z Coordinates
2-
0,0,H5,5,H,miss,A2B,13,real,0.09260503947734833,1.6340194940567017,0.3355029225349426
3-
1,1,DC8,8,C,D2R,A2B,19,real,,,
4-
2,2,HV8,8,H,D2R,A2B,20,real,,,
5-
3,3,HV9,9,H,D2R,A2B,21,real,,,
6-
4,4,HV10,10,H,D2R,A2B,22,real,,,
7-
5,0,C8,8,C,R2D,B2A,9,dummy,,,
8-
6,1,H8,8,H,R2D,B2A,16,dummy,,,
9-
7,2,H9,9,H,R2D,B2A,17,dummy,,,
10-
8,3,H10,10,H,R2D,B2A,18,dummy,,,
11-
9,4,DC10,10,C,miss,B2A,22,dummy,2.620028495788574,1.403925895690918,2.7885396480560303
12-
10,5,HV4,4,H,miss,B2A,23,dummy,2.3651702404022217,1.4678032398223877,2.8239073753356934
13-
11,6,HV14,14,H,miss,B2A,24,dummy,2.678273916244507,1.464888095855713,2.8585944175720215
14-
12,7,HV15,15,H,miss,B2A,25,dummy,2.6814169883728027,1.340580940246582,2.7234597206115723
15-
13,8,HV16,16,H,miss,B2A,26,dummy,2.5583090782165527,1.3370134830474854,2.8496134281158447
1+
,Name,Swap,X Coordinates,Y Coordinates,Z Coordinates
2+
0,DC10,A2B,2.620028018951416,1.4039266109466553,2.7885406017303467
3+
1,HV14,A2B,2.6782684326171875,1.4648889303207397,2.8585996627807617
4+
2,HV15,A2B,2.6814215183258057,1.3405863046646118,2.723461389541626
5+
3,HV16,A2B,2.5583088397979736,1.3370097875595093,2.849609851837158
6+
4,HV4,A2B,2.3651702404022217,1.4678034782409668,2.8239071369171143
7+
5,H5,B2A,0.09260530769824982,1.6340194940567017,0.33550316095352173
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
,Name,Swap
2+
0,DC10,A2B
3+
1,HV14,A2B
4+
2,HV15,A2B
5+
3,HV16,A2B
6+
4,HV4,A2B
7+
5,H5,B2A

ensemble_md/tests/data/coord_swap/find_common.csv

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)