@@ -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
0 commit comments