@@ -213,6 +213,31 @@ def copy(self):
213213 other .is_forward = self .is_forward
214214
215215 return other
216+
217+ def check_if_spin_allowed (self ):
218+ # get the combined spin for reactants and products
219+ reactants_combined_spin , products_combined_spin = self .calculate_combined_spin ()
220+ # check if there are any matches for combined spin between reactants and products
221+ if reactants_combined_spin .intersection (products_combined_spin ) != set ([]):
222+ return True
223+ else :
224+ logging .debug (f"Reactants combined spin is { reactants_combined_spin } , but the products combined spin is { products_combined_spin } " )
225+ return False
226+
227+ def calculate_combined_spin (self ):
228+ if len (self .reactants ) == 1 :
229+ reactant_combined_spin = {self .reactants [0 ].multiplicity }
230+ elif len (self .reactants ) == 2 :
231+ reactant_combined_spin = set ([self .reactants [0 ].multiplicity + self .reactants [1 ].multiplicity - 1 , np .abs (self .reactants [0 ].multiplicity - self .reactants [1 ].multiplicity )+ 1 ])
232+ else :
233+ return None
234+ if len (self .products ) == 1 :
235+ product_combined_spin = {self .products [0 ].multiplicity }
236+ elif len (self .products ) == 2 :
237+ product_combined_spin = set ([self .products [0 ].multiplicity + self .products [1 ].multiplicity - 1 , np .abs (self .products [0 ].multiplicity - self .products [1 ].multiplicity )+ 1 ])
238+ else :
239+ return None
240+ return reactant_combined_spin , product_combined_spin
216241
217242 def apply_solvent_correction (self , solvent ):
218243 """
@@ -1678,7 +1703,7 @@ def is_molecule_forbidden(self, molecule):
16781703
16791704 return False
16801705
1681- def _create_reaction (self , reactants , products , is_forward ):
1706+ def _create_reaction (self , reactants , products , is_forward , check_spin = True ):
16821707 """
16831708 Create and return a new :class:`Reaction` object containing the
16841709 provided `reactants` and `products` as lists of :class:`Molecule`
@@ -1713,7 +1738,11 @@ def _create_reaction(self, reactants, products, is_forward):
17131738 for key , species_list in zip (['reactants' , 'products' ], [reaction .reactants , reaction .products ]):
17141739 for species in species_list :
17151740 reaction .labeled_atoms [key ] = dict (reaction .labeled_atoms [key ], ** species .get_all_labeled_atoms ())
1716-
1741+ if check_spin :
1742+ if not reaction .check_if_spin_allowed ():
1743+ logging .warn ("Did not create the following reaction, which violates conservation of spin..." )
1744+ logging .warn (str (reaction ))
1745+ return None
17171746 return reaction
17181747
17191748 def _match_reactant_to_template (self , reactant , template_reactant ):
0 commit comments