@@ -1544,6 +1544,7 @@ def default_coords_fn(self, molA_file_name, molB_file_name):
15441544 # Load the coordinate swapping map
15451545 connection_map = pd .read_csv ('residue_connect.csv' )
15461546 swap_map = pd .read_csv ('residue_swap_map.csv' )
1547+ atom_mapping = pd .read_csv ('atom_name_mapping.csv' )
15471548
15481549 # Step 1: Read the GRO input coordinate files and open temporary Output files
15491550 molA_file = open (molA_file_name , 'r' ).readlines () # open input file
@@ -1557,7 +1558,7 @@ def default_coords_fn(self, molA_file_name, molB_file_name):
15571558 residue_options = swap_map ['Swap A' ].to_list () + swap_map ['Swap B' ].to_list ()
15581559 nameA = coordinate_swap .identify_res (molA .topology , residue_options )
15591560 nameB = coordinate_swap .identify_res (molB .topology , residue_options )
1560- df_atom_swap = coordinate_swap .find_common ( molA_file , molB_file , nameA , nameB )
1561+ df_atom_swap = coordinate_swap .extract_missing ( nameA , nameB , swap_map )
15611562
15621563 # Step 3: Fix break if present for solvated systems only
15631564 if len (molA .topology .select ('water' )) != 0 :
@@ -1567,30 +1568,46 @@ def default_coords_fn(self, molA_file_name, molB_file_name):
15671568 molB = coordinate_swap .fix_break (molB , nameB , B_dimensions , connection_map [connection_map ['Resname' ] == nameB ]) # noqa: E501
15681569
15691570 # Step 4: Determine coordinates of atoms which need to be reconstructed as we swap coordinates between molecules # noqa: E501
1570- miss_B = df_atom_swap [(df_atom_swap ['Swap' ] == 'B2A' ) & (df_atom_swap ['Direction' ] == 'miss' )]['Name' ].to_list () # noqa: E501
1571- miss_A = df_atom_swap [(df_atom_swap ['Swap' ] == 'A2B' ) & (df_atom_swap ['Direction' ] == 'miss' )]['Name' ].to_list () # noqa: E501
1572- if len (miss_B ) != 0 :
1573- 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
1574- if len (miss_A ) != 0 :
1575- 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
1571+ 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
1572+ 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
15761573
15771574 # Step 5: Parse Current file to ensure atoms are added in the correct order
15781575 atom_order_A = gmx_parser .deter_atom_order (molA_file , nameA )
15791576 atom_order_B = gmx_parser .deter_atom_order (molB_file , nameB )
15801577
15811578 # Step 6: Write the new file
15821579 # Reprint preamble text
1583- line_start = coordinate_swap .print_preamble (molA_file , molB_new , len (miss_B ), len (miss_A ))
1580+ 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
1581+
1582+ # Print up until we reach the residue to modify
1583+ 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
15841584
15851585 # Print new coordinates to file for molB
1586- 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
1586+ 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
1587+
1588+ if line_restart is not None :
1589+ # Print rest of file after modified residue
1590+ coordinate_swap .write_unmodified (line_restart , molA_file , molB_new , nameA , atom_num_restart , line_start , copy .deepcopy (molA .xyz [0 ])) # noqa: E501
1591+
1592+ # Print box size
1593+ molB_new .write (molA_file [- 1 ])
15871594
15881595 # Print new coordinates to file
15891596 # Reprint preamble text
1590- line_start = coordinate_swap .print_preamble (molB_file , molA_new , len (miss_A ), len (miss_B ))
1597+ 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
1598+
1599+ # Print up until we reach the residue to modify
1600+ 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
1601+
1602+ # Print new coordinates to file for molA
1603+ 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
15911604
1592- # Print new coordinates for molA
1593- 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
1605+ if line_restart is not None :
1606+ # Print rest of file after modified residue
1607+ coordinate_swap .write_unmodified (line_restart , molB_file , molA_new , nameB , atom_num_restart , line_start , copy .deepcopy (molB .xyz [0 ])) # noqa: E501
1608+
1609+ # Print box size
1610+ molA_new .write (molB_file [- 1 ])
15941611
15951612 # Rename temp files
15961613 os .rename ('A_hybrid_swap.gro' , molB_dir + '/confout.gro' )
@@ -1601,6 +1618,12 @@ def process_top(self):
16011618 Processes the input topologies in order to determine the atoms for alignment in the default GRO swapping
16021619 function. Output as csv files to prevent needing to re-run this step.
16031620 """
1621+ if not os .path .exists ('atom_name_mapping.csv' ):
1622+ coordinate_swap .create_atom_map (self .gro , self .resname_list , self .swap_rep_pattern )
1623+ atom_name_mapping = pd .read_csv ('atom_name_mapping.csv' )
1624+ else :
1625+ atom_name_mapping = pd .read_csv ('atom_name_mapping.csv' )
1626+
16041627 if not os .path .exists ('residue_connect.csv' ):
16051628 df_top = pd .DataFrame ()
16061629 for f , file_name in enumerate (self .top ):
@@ -1640,17 +1663,23 @@ def process_top(self):
16401663 # Determine atoms not present in both molecules
16411664 X , Y = [int (swap [0 ][0 ]), int (swap [1 ][0 ])]
16421665 lam = {X : int (swap [0 ][1 ]), Y : int (swap [1 ][1 ])}
1666+ 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
16431667 for A , B in zip ([X , Y ], [Y , X ]):
1668+ # Swapping coordinates from B to A
16441669 input_A = gmx_parser .read_top (self .top [A ], self .resname_list [A ])
16451670 start_line , A_name , A_num , state = coordinate_swap .get_names (input_A , self .resname_list [A ])
16461671 input_B = gmx_parser .read_top (self .top [B ], self .resname_list [B ])
16471672 start_line , B_name , B_num , state = coordinate_swap .get_names (input_B , self .resname_list [B ])
16481673
1649- A_only = [x for x in A_name if x not in B_name ]
1650- B_only = [x for x in B_name if x not in A_name ]
1674+ # Determine shared atom names
1675+ if len (swap_name_match [swap_name_match ['resname A' ] == self .resname_list [A ]]) != 0 :
1676+ common_atoms_A = list (swap_name_match ['atom name A' ].values )
1677+ else :
1678+ common_atoms_A = list (swap_name_match ['atom name B' ].values )
1679+ A_only = [x for x in A_name if x not in common_atoms_A ]
16511680
16521681 # Seperate real to dummy switches
1653- df = coordinate_swap .determine_connection (A_only , B_only , self .resname_list [A ], self .resname_list [B ], df_top , lam [A ]) # noqa: E501
1682+ df = coordinate_swap .determine_connection (A_only , swap_name_match , self .resname_list [A ], self .resname_list [B ], df_top , lam [A ]) # noqa: E501
16541683
16551684 df_map = pd .concat ([df_map , df ])
16561685
0 commit comments