3232 rmg_mol_from_dict_repr ,
3333 rmg_mol_to_dict_repr ,
3434 timedelta_from_str ,
35+ sort_atoms_in_decending_label_order ,
3536 )
3637from arc .exceptions import InputError , RotorError , SpeciesError , TSError
3738from arc .imports import settings
@@ -248,6 +249,7 @@ class ARCSpecies(object):
248249 rxn_index (int): The reaction index which is the respective key to the Scheduler rxn_dict.
249250 arkane_file (str): Path to the Arkane Species file generated in processor.
250251 yml_path (str): Path to an Arkane YAML file representing a species (for loading the object).
252+ keep_mol (bool): Label to prevent the generation of a new Molecule object.
251253 checkfile (str): The local path to the latest checkfile by Gaussian for the species.
252254 external_symmetry (int): The external symmetry of the species (not including rotor symmetries).
253255 optical_isomers (int): Whether (=2) or not (=1) the species has chiral center/s.
@@ -317,6 +319,7 @@ def __init__(self,
317319 ts_number : Optional [int ] = None ,
318320 xyz : Optional [Union [list , dict , str ]] = None ,
319321 yml_path : Optional [str ] = None ,
322+ keep_mol : bool = False ,
320323 ):
321324 self .t1 = None
322325 self .ts_number = ts_number
@@ -347,6 +350,7 @@ def __init__(self,
347350 self .checkfile = checkfile
348351 self .transport_data = TransportData ()
349352 self .yml_path = yml_path
353+ self .keep_mol = keep_mol
350354 self .fragments = fragments
351355 self .original_label = None
352356 self .chosen_ts = None
@@ -1543,7 +1547,8 @@ def mol_from_xyz(self,
15431547 f'{ self .mol .copy (deep = True ).to_smiles ()} \n '
15441548 f'{ self .mol .copy (deep = True ).to_adjacency_list ()} ' )
15451549 raise SpeciesError (f'XYZ and the 2D graph representation for { self .label } are not compliant.' )
1546- self .mol = perceived_mol
1550+ if not self .keep_mol :
1551+ self .mol = perceived_mol
15471552 else :
15481553 mol_s , mol_b = molecules_from_xyz (xyz , multiplicity = self .multiplicity , charge = self .charge )
15491554 if mol_b is not None and len (mol_b .atoms ) == self .number_of_atoms :
@@ -1764,13 +1769,25 @@ def check_xyz_isomorphism(self,
17641769 logger .warning ('Allowing nonisomorphic 2D' )
17651770 return isomorphic
17661771
1767- def scissors (self ) -> list :
1772+ def label_atoms (self ):
1773+ """
1774+ Labels atoms in order.
1775+ The label is stored in the atom.label property.
1776+ """
1777+ for index , atom in enumerate (self .mol .atoms ):
1778+ atom .label = str (index )
1779+
1780+ def scissors (self ,
1781+ sort_atom_labels : bool = False ) -> list :
17681782 """
17691783 Cut chemical bonds to create new species from the original one according to the .bdes attribute,
17701784 preserving the 3D geometry other than the scissioned bond.
17711785 If one of the scission-resulting species is a hydrogen atom, it will be returned last, labeled as 'H'.
17721786 Other species labels will be <original species label>_BDE_index1_index2_X, where "X" is either "A" or "B",
17731787 and the indices are 1-indexed.
1788+
1789+ Args:
1790+ sort_atom_labels (bool, optional): Boolean flag, dettermines whether or not sorting is required.
17741791
17751792 Returns: list
17761793 The scission-resulting species.
@@ -1794,21 +1811,26 @@ def scissors(self) -> list:
17941811 atom_indices_reverse = (atom_indices [1 ], atom_indices [0 ])
17951812 if atom_indices not in self .bdes and atom_indices_reverse not in self .bdes :
17961813 self .bdes .append (atom_indices )
1814+ if sort_atom_labels :
1815+ self .label_atoms ()
17971816 resulting_species = list ()
17981817 for index_tuple in self .bdes :
1799- new_species_list = self ._scissors (indices = index_tuple )
1818+ new_species_list = self ._scissors (indices = index_tuple , sort_atom_labels = sort_atom_labels )
18001819 for new_species in new_species_list :
18011820 if new_species .label not in [existing_species .label for existing_species in resulting_species ]:
18021821 # Mainly checks that the H species doesn't already exist.
18031822 resulting_species .append (new_species )
18041823 return resulting_species
18051824
1806- def _scissors (self , indices : tuple ) -> list :
1825+ def _scissors (self ,
1826+ indices : tuple ,
1827+ sort_atom_labels : bool = True ) -> list :
18071828 """
18081829 Cut a chemical bond to create two new species from the original one, preserving the 3D geometry.
18091830
18101831 Args:
18111832 indices (tuple): The atom indices between which to cut (1-indexed, atoms must be bonded).
1833+ sort_atom_labels (bool, optional): Boolean flag, dettermines whether or not sorting is required.
18121834
18131835 Returns: list
18141836 The scission-resulting species, a list of either one or two species, if the scissored location is linear,
@@ -1860,6 +1882,10 @@ def _scissors(self, indices: tuple) -> list:
18601882 logger .warning (f'Scissors were requested to remove a non-single bond in { self .label } .' )
18611883 mol_copy .remove_bond (bond )
18621884 mol_splits = mol_copy .split ()
1885+ if sort_atom_labels :
1886+ for split in mol_splits :
1887+ sort_atoms_in_decending_label_order (split )
1888+
18631889 if len (mol_splits ) == 1 : # If cutting leads to only one split, then the split is cyclic.
18641890 spc1 = ARCSpecies (label = self .label + '_BDE_' + str (indices [0 ] + 1 ) + '_' + str (indices [1 ] + 1 ) + '_cyclic' ,
18651891 mol = mol_splits [0 ],
@@ -1902,8 +1928,8 @@ def _scissors(self, indices: tuple) -> list:
19021928 else :
19031929 raise SpeciesError (f'Could not figure out which atom should gain a radical '
19041930 f'due to scission in { self .label } ' )
1905- mol1 .update (raise_atomtype_exception = False )
1906- mol2 .update (raise_atomtype_exception = False )
1931+ mol1 .update (log_species = False , raise_atomtype_exception = False , sort_atoms = False )
1932+ mol2 .update (log_species = False , raise_atomtype_exception = False , sort_atoms = False )
19071933
19081934 # match xyz to mol:
19091935 if len (mol1 .atoms ) != len (mol2 .atoms ):
@@ -1934,7 +1960,8 @@ def _scissors(self, indices: tuple) -> list:
19341960 multiplicity = mol1 .multiplicity ,
19351961 charge = mol1 .get_net_charge (),
19361962 compute_thermo = False ,
1937- e0_only = True )
1963+ e0_only = True ,
1964+ keep_mol = True )
19381965 spc1 .generate_conformers ()
19391966 spc1 .rotors_dict = None
19401967 spc2 = ARCSpecies (label = label2 ,
@@ -1943,7 +1970,8 @@ def _scissors(self, indices: tuple) -> list:
19431970 multiplicity = mol2 .multiplicity ,
19441971 charge = mol2 .get_net_charge (),
19451972 compute_thermo = False ,
1946- e0_only = True )
1973+ e0_only = True ,
1974+ keep_mol = True )
19471975 spc2 .generate_conformers ()
19481976 spc2 .rotors_dict = None
19491977
0 commit comments