Skip to content

Commit

Permalink
Fix error in charge assignment and spin
Browse files Browse the repository at this point in the history
  • Loading branch information
choglass committed Jan 7, 2025
1 parent 6eecc9d commit e035d31
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 23 deletions.
35 changes: 21 additions & 14 deletions cell2mol/charge_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_possible_charge_state(spec: object, debug: int=0):
if spec.protonation_states is None:
return None

if spec.formula in ["O4-Cl", "N3", "I3"]:
if spec.formula in ["O4-Cl", "N3", "I3", "N2"]:
ch_state = get_charge_manual(spec, debug=debug)
possible_cs = [ch_state]
return possible_cs
Expand Down Expand Up @@ -437,7 +437,8 @@ def get_protonation_states_specie(specie: object, debug: int=0) -> list:
addedlist[idx] = 1
else:
# nitrogen with at least 3 adjacencies doesnt need H
if a.connec >= 3:
# if a.connec >= 3:
if (a.connec - a.mconnec) >= 3 :
block[idx] = 1
# needs_nonlocal = True
# non_local_groups += 1
Expand Down Expand Up @@ -700,7 +701,11 @@ def get_charge_manual(spec, debug: int=0):
break # Found the target atom, no need to check further

if debug >= 2: print(f"I3: new_order={new_order}")

elif spec.formula == "N2":
smiles = "N#N"
charge = 0
order = [0, 1]
new_order = order

temp_mol = Chem.MolFromSmiles(smiles, sanitize=False)
mol = Chem.RenumberAtoms(temp_mol, new_order)
Expand Down Expand Up @@ -943,9 +948,9 @@ def get_metal_poscharges(metal: object, debug: int=0) -> list:
at_charge[23] = [1, 2, 3, 4, 5] # V
at_charge[24] = [0, 2, 3] # Cr ; including 5 leads to worse results
at_charge[25] = [1, 2, 3] # Mn
at_charge[26] = [2, 3] # Fe
at_charge[26] = [0, 2, 3] # Fe
at_charge[27] = [1, 2, 3] # Co
at_charge[28] = [2, 3] # Ni
at_charge[28] = [0, 2, 3] # Ni
at_charge[29] = [1, 2] # Cu
at_charge[30] = [2] # Zn
# 2nd-row transition metals.
Expand All @@ -954,7 +959,7 @@ def get_metal_poscharges(metal: object, debug: int=0) -> list:
at_charge[41] = [1, 3, 4, 5] # Nb
at_charge[42] = [0, 2, 4, 5, 6] # Mo
at_charge[43] = [1, 2, 3, 4, 5] # Tc
at_charge[44] = [2, 3, 4] # Ru
at_charge[44] = [0, 2, 3, 4] # Ru
at_charge[45] = [1, 2, 3] # Rh
at_charge[46] = [0, 2] # Pd
at_charge[47] = [1] # Ag
Expand All @@ -971,14 +976,14 @@ def get_metal_poscharges(metal: object, debug: int=0) -> list:
at_charge[80] = [2] # Hg

# post-transition metals
at_charge[13] = [0, 3] # Al
at_charge[31] = [0, 3] # Ga
at_charge[32] = [0, 2, 4] # Ge
at_charge[49] = [0, 3] # In
at_charge[50] = [0, 2, 4] # Sn
at_charge[81] = [0, 1, 3] # Tl
at_charge[82] = [0, 2, 4] # Pb
at_charge[83] = [0, 3] # Bi
at_charge[13] = [3] # Al
at_charge[31] = [3] # Ga
at_charge[32] = [2, 4] # Ge
at_charge[49] = [3] # In
at_charge[50] = [2, 4] # Sn
at_charge[81] = [1, 3] # Tl
at_charge[82] = [2, 4] # Pb
at_charge[83] = [3] # Bi

# Lanthanides (atomic numbers 57 to 71)
at_charge[57] = [3] # La
Expand Down Expand Up @@ -1227,6 +1232,8 @@ def correct_smiles_ligand(ligand: object, debug: int=0) -> Tuple[str, object]:
ismetal_2 = elemdatabase.elementblock[b.atom2.label] == "d" or elemdatabase.elementblock[b.atom2.label] == "f"
if ismetal_1 or ismetal_2:
pass
elif len(get_non_transition_metal_idxs([b.atom1.label, b.atom2.label])) > 0:
pass
else:
begin_idx = b.atom1.get_parent_index("ligand")
end_idx = b.atom2.get_parent_index("ligand")
Expand Down
20 changes: 12 additions & 8 deletions cell2mol/spin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,18 @@ def assign_spin_metal (metal:object, debug: int=0) -> None:
elif valence_elec in [1, 9]: return 2
elif valence_elec in [2, 3] and metal.get_parent("molecule").is_haptic == False : return (valence_elec + 1)
elif valence_elec in [4, 5, 6, 7, 8] or (valence_elec in [2, 3] and metal.get_parent("molecule").is_haptic == True) :
# Predict spin multiplicity of metal based on Random forest model
feature = generate_feature_vector (metal, target_prop="spin", debug=debug)
path_rf = os.path.join( os.path.abspath(os.path.dirname(__file__)), "total_spin_3131.pkl")
ramdom_forest = pickle.load(open(path_rf, 'rb'))
predictions = ramdom_forest.predict(feature)
spin_rf = predictions[0]
print(f"ASSIGN_SPIN_METAL: Spin multiplicity of the metal {metal.label} is predicted as {spin_rf} using Random Forest model")
return spin_rf
if hasattr(metal, "coord_geometry") and metal.coord_geometry != "Undefined":
# Predict spin multiplicity of metal based on Random forest model
feature = generate_feature_vector (metal, target_prop="spin", debug=debug)
path_rf = os.path.join( os.path.abspath(os.path.dirname(__file__)), "total_spin_3131.pkl")
ramdom_forest = pickle.load(open(path_rf, 'rb'))
predictions = ramdom_forest.predict(feature)
spin_rf = predictions[0]
print(f"ASSIGN_SPIN_METAL: Spin multiplicity of the metal {metal.label} is predicted as {spin_rf} using Random Forest model")
return spin_rf
else:
print("ASSIGN_SPIN_METAL: Error! Coordination geometry of the metal is not defined.")
return None
else :
print("ASSIGN_SPIN_METAL: Error! Spin multiplicity could not be assigned to the metal with valence electrons: ", valence_elec)
return None
Expand Down
2 changes: 1 addition & 1 deletion cell2mol/xyz2mol.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ def AC2BO(AC, atoms, charge, allow_charged_fragments=True, use_graph=True):
and valences_not_too_large(BO, valences)
and charge_OK
):
print(f"\tAC2BO: status", status, "BO.sum()", BO.sum(), "best_BO.sum()", best_BO.sum())
#print(f"\tAC2BO: status", status, "BO.sum()", BO.sum(), "best_BO.sum()", best_BO.sum())
best_BO = BO.copy()

count += 1
Expand Down

0 comments on commit e035d31

Please sign in to comment.