Skip to content

Commit

Permalink
Debugging evaluate_as_nitrosyl and assign_charges
Browse files Browse the repository at this point in the history
  • Loading branch information
choglass committed Nov 10, 2024
1 parent 669856d commit 7397a04
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 58 deletions.
6 changes: 3 additions & 3 deletions cell2mol/charge_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ def get_possible_charge_state(spec: object, debug: int=0):
### After collecting charge states, then best ones are selected
if spec.subtype == "ligand":
if spec.is_nitrosyl:
if spec.NO_type == "Linear": possible_cs = charge_states[2] ## When Nitrosyl, we sistematically get the correct charge_distribution in [2] (charge = 1)and [0] (charge = 0)for Linear and Bent respectively
elif spec.NO_type == "Bent": possible_cs = charge_states[0]
if spec.NO_type == "Linear": possible_cs = [charge_states[2]] ## When Nitrosyl, we sistematically get the correct charge_distribution in [2] (charge = 1)and [0] (charge = 0)for Linear and Bent respectively
elif spec.NO_type == "Bent": possible_cs = [charge_states[0]]
else:
# spec.get_connected_atoms()
# if [a.label for a in spec.connected_atoms] == ['S', 'S'] :
# possible_cs = [charge_states[0], charge_states[3]] # charge 0 and 2
# else :
possible_cs = select_charge_distr(charge_states, debug=debug) ## For ligands other than nitrosyl
else: possible_cs = select_charge_distr(charge_states, debug=debug) ## For organic molecules

print(f"GET_POSSIBLE_CHARGE_STATE: {spec.formula} ({spec.subtype}) {spec.cov_factor=} {possible_cs=}")
### Return possible charge states
if len(possible_cs) == 0: return None
else: return possible_cs
Expand Down
51 changes: 34 additions & 17 deletions cell2mol/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ def get_protonation_states(self, debug: int=0):
# if not hasattr(self,"groups"): self.split_ligand()
if not hasattr(self, "is_haptic"): self.get_hapticity()
if not hasattr(self, "denticity"): self.get_denticity()
if not hasattr(self, "is_nitrosyl"): self.evaluate_as_nitrosyl()
self.protonation_states = get_protonation_states_specie(self, debug=debug)
else:
if not hasattr(self,"is_haptic"): self.get_hapticity()
Expand Down Expand Up @@ -436,7 +437,7 @@ def split_complex(self, debug: int=0):
newligand.origin = "split_complex"
# Define the molecule as parent of the ligand. Bottom-Up hierarchy
newligand.add_parent(self, indices=lig_indices)

if self.check_parent("unitcell"):
cell_indices = [a.get_parent_index("unitcell") for a in lig_atoms]
newligand.add_parent(self.get_parent("unitcell"), indices=cell_indices)
Expand All @@ -452,6 +453,7 @@ def split_complex(self, debug: int=0):
# Inherit the adjacencies from molecule
newligand.inherit_adjmatrix("molecule")
# Add ligand to the list. Top-Down hierarchy
# newligand.evaluate_as_nitrosyl()
self.ligands.append(newligand)

## Arranges Metals
Expand Down Expand Up @@ -488,7 +490,7 @@ def __init__(self, labels: list, coord: list, frac_coord: list=None, radii: list
self.subtype = "ligand"
if frac_coord is not None: self.frac_coord = frac_coord
specie.__init__(self, labels, coord, frac_coord, radii)
self.evaluate_as_nitrosyl()
#self.evaluate_as_nitrosyl() ### move to the split_complexes function

#######################################################
def __repr__(self):
Expand Down Expand Up @@ -1332,13 +1334,14 @@ def get_reference_molecules(self, ref_labels: list, ref_fracs: list, cov_factor:
refcell.get_subtype("reference")
# Get reference molecules
blocklist = split_species(ref_labels, ref_pos, cov_factor=cov_factor)

print(blocklist)
self.refmoleclist = []
for b in blocklist:
mol_labels = extract_from_list(b, ref_labels, dimension=1)
mol_coord = extract_from_list(b, ref_pos, dimension=1)
mol_frac_coord = extract_from_list(b, ref_fracs, dimension=1)
newmolec = molecule(mol_labels, mol_coord, mol_frac_coord)
print(newmolec)
newmolec.add_parent(self, indices=b)
newmolec.add_parent(refcell, indices=b)
newmolec.set_adjacency_parameters(cov_factor, metal_factor)
Expand Down Expand Up @@ -1550,6 +1553,7 @@ def get_selected_cs(self, debug: int=0):

self.selected_cs = []
for specie in self.unique_species:
print("Get possible charge states for unique specie", specie.formula)
tmp = specie.get_possible_cs(debug=debug)
if tmp is None:
self.selected_cs.append(None)
Expand Down Expand Up @@ -1614,34 +1618,41 @@ def assign_charges (self, debug: int=0):
cs = specie.possible_cs[idx]
specie.set_charge(cs)
for specie in self.unique_species:
print("Unique Species final charges")
if (specie.subtype == "molecule" and specie.iscomplex == False) or (specie.subtype == "ligand"):
print(specie.formula, specie.charge_state, specie.totcharge, specie.smiles)
print(specie.formula, specie.totcharge)
elif specie.subtype == "metal" :
print(specie.formula, specie.charge)

for idx, ref in enumerate(self.refmoleclist):
print(f"Refenrence Molecule {idx}: {ref.formula}")
if ref.iscomplex:
for jdx, lig in enumerate(ref.ligands):
for specie in self.unique_species:
for kdx, specie in enumerate(self.unique_species):
if specie.subtype == "ligand":
issame = compare_species(lig, specie)
if issame:
set_charge_state (specie, lig, mode=1, debug=debug)
print(lig.formula, specie.formula, issame)
print(lig.formula, specie.formula, lig.totcharge, specie.totcharge, issame)
print("Check Error", f"{idx=}, {jdx=}, {kdx=}", lig.formula, specie.formula, issame)
# print(f"{lig.smiles=}")
# print(f"{specie.smiles=}")

for met in ref.metals:
for specie in self.unique_species:
if specie.subtype == "metal":
issame = compare_metals(met, specie)
if issame:
met.set_charge(specie.charge)
print(met.formula, specie.formula, issame)
print(met.formula, specie.formula, met.charge, specie.charge, issame)
prepare_mol(ref)
else:
for specie in self.unique_species:
if specie.subtype == "molecule":
issame = compare_species(ref, specie)
if issame:
set_charge_state (specie, ref, mode=1, debug=debug)
print(ref.formula, specie.formula, issame)
print(ref.formula, specie.formula, ref.totcharge, specie.totcharge, issame)

for idx, mol in enumerate(self.moleclist):
print(f"Unit cell Molecule {idx}: {mol.formula}")
Expand All @@ -1651,20 +1662,30 @@ def assign_charges (self, debug: int=0):
issame = compare_reference_indices(ref, mol, debug=debug)
if issame:
set_charge_state (ref, mol, mode=2, debug=debug)
print(mol.formula, ref.formula, issame)
print(mol.formula, ref.formula, mol.totcharge, ref.totcharge, issame)
else:
for ref in self.refmoleclist:
if ref.iscomplex:
for lig in mol.ligands:
for ref_lig in ref.ligands:
for jdx, lig in enumerate(mol.ligands):
for kdx, ref_lig in enumerate(ref.ligands):
issame = compare_reference_indices(ref_lig, lig, debug=debug)
if issame:
set_charge_state (ref_lig, lig, mode=2, debug=debug)
print(lig.formula, ref_lig.formula, issame)
print(lig.formula, ref_lig.formula, lig.totcharge, ref_lig.totcharge, lig.smiles, ref_lig.smiles, issame)
else :
issame_2 = compare_species(lig, ref_lig)
if issame_2:
set_charge_state (ref_lig, lig, mode=1, debug=debug)
print("Check Error", f"{idx=} {jdx=} {kdx}", lig.formula, ref_lig.formula, issame)
for met in mol.metals:
for ref_met in ref.metals:
if ref_met.get_parent_index("reference") == met.get_parent_index("reference"):
met.set_charge(ref_met.charge)
print(met.formula, ref_met.formula, met.charge, ref_met.charge, issame)
else :
issame_2 = compare_metals(met, ref_met)
if issame_2:
met.set_charge(ref_met.charge)
prepare_mol(mol)

#######################################################
Expand Down Expand Up @@ -1770,11 +1791,7 @@ def assign_charges_old (self, debug: int=0) -> object:
else: # Only one possible charge distribution -> getcharge for the repeated species
self.error_multiple_distrib = False
self.error_empty_distrib = False
if debug >= 1:
print(f"\nFINAL Charge Distribution: {final_charge_distribution}\n")
print("#########################################")
print("Assigning Charges and Preparing Molecules")
print("#########################################")

self.moleclist, self.error_prepare_mols = prepare_mols (self.moleclist, self.unique_indices, self.unique_species, final_charge_distribution[0], debug=debug)

if self.error_prepare_mols:
Expand Down
4 changes: 2 additions & 2 deletions cell2mol/missingH.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def check_missingH(refmoleclist: list, debug: int=0):
Warning = False

# List of Metal Atoms for which O atoms might appear connected directly.
Exceptions_for_CoordWater = ["Re", "V", "Mo", "W"]
Exceptions_for_CoordWater = ["Re", "V", "Mo", "W", "Fe"]

if debug >= 2: print("")
if debug >= 2: print("##################")
Expand Down Expand Up @@ -141,7 +141,7 @@ def check_missingH(refmoleclist: list, debug: int=0):
else:
for jdx, lig in enumerate(ref.ligands):
if lig.natoms == 1 and "O" in lig.labels and lig.denticity <= 1:
if any(m.label in Exceptions_for_CoordWater for m in lig.metalatoms): pass
if any(m.label in Exceptions_for_CoordWater for m in lig.metals): pass
else:
Missing_H_in_CoordWater = True
if debug >= 2: print("")
Expand Down
2 changes: 1 addition & 1 deletion cell2mol/new_cell_reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def modify_cov_factor_due_to_possible_charges (refcell, debug: int=0):
else :
temp_selection.append(specie.possible_cs)

if debug >= 1: print(f"Covalent factor decreases: {cov_factor=}")
if debug >= 1: print(f"Covalent factor : {cov_factor=}")
refcell.assess_errors(mode="hydrogens")
if refcell.error_case == 0:
if debug >= 1: print(f"OK with decreasing cov_factor {cov_factor=}")
Expand Down
9 changes: 6 additions & 3 deletions cell2mol/new_charge_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def assign_charge_state_for_unique_species(unique_species, final_charges_tuple,
specie.set_charges(cs.corr_total_charge, cs.corr_atom_charges, cs.smiles, cs.rdkit_obj)
elif specie.subtype == "metal" :
charge_list = specie.possible_cs
# idx = charge_list.index(final_charge)
idx = charge_list.index(final_charge)
cs = specie.possible_cs[idx]
specie.set_charge(cs)
for specie in unique_species:
Expand Down Expand Up @@ -112,8 +112,10 @@ def set_charge_state(reference, target, mode, debug: int=0):
if target.formula in ["O4-Cl", "N3", "I3"]:
cs = get_charge_manual(target, debug=debug)
else :
#if not hasattr(target, "possible_cs"): target.get_possible_cs(debug=debug)
target.get_possible_cs(debug=debug)
charge_list = [cs.corr_total_charge for cs in target.possible_cs]
print(charge_list, final_charge, target.possible_cs)
idx = charge_list.index(final_charge)
cs = target.possible_cs[idx]

Expand Down Expand Up @@ -148,12 +150,13 @@ def set_charge_state(reference, target, mode, debug: int=0):
target.charge_state = cs
if final_charge != cs.corr_total_charge:
print(f"SET_CHARGE_STATE: WARNING!!! {target.formula=} {final_charge=} {cs.corr_total_charge=} final_charge != cs.corr_total_charge")
print("SET_CHARGE_STATE!!!!", f"{mode=}", cs, cs.smiles)
target.set_charges(cs.corr_total_charge, cs.corr_atom_charges, cs.smiles, cs.rdkit_obj)
print(f"SET_CHARGE_STATE:{target.formula=} {target.totcharge=} {target.smiles=}")

######################################################
def prepare_mol (mol):
tmp_atcharge = np.zeros((mol.natoms))
tmp_atcharge = np.zeros((mol.natoms), dtype=int)
tmp_smiles = []

for lig in mol.ligands:
Expand All @@ -164,7 +167,7 @@ def prepare_mol (mol):

for met in mol.metals:
parent_index = met.get_parent_index("molecule")
tmp_atcharge[parent_index] = met.charge
tmp_atcharge[parent_index] = met.charge

mol.set_charges(int(sum(tmp_atcharge)), atomic_charges=tmp_atcharge, smiles=tmp_smiles)

Expand Down
2 changes: 1 addition & 1 deletion cell2mol/refcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def get_unique_species_in_reference (refcell, debug):
if debug >= 1:
print(f"Unique species: {[specie.formula for specie in refcell.unique_species]}")
print(f"Species list: {[specie.formula for specie in refcell.species_list]}\n")

refcell = modify_cov_factor_due_to_possible_charges(refcell, debug=debug)
refcell.get_selected_cs(debug=debug)
refcell.assess_errors(mode="possible_charges")
Expand Down
5 changes: 4 additions & 1 deletion cell2mol/spin.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,13 @@ def assign_spin_complexes (mol:object, debug: int=0) -> None:
"""
for metal in mol.metals:
if not hasattr(metal,"spin"): metal.get_spin(debug=debug)
for ligand in mol.ligands:
if not hasattr(ligand, "is_nitrosyl"): ligand.evaluate_as_nitrosyl()

metals_spin = [metal.spin for metal in mol.metals]
if debug >=2: print(f"ASSIGN_SPIN_COMPLEXES: {metals_spin=}")

if any(ligand.is_nitrosyl for ligand in mol.ligands): return None
if any([ligand.is_nitrosyl for ligand in mol.ligands]): return None
else :
if None in metals_spin : return None
elif len(metals_spin) == 1: return metals_spin[0] # Mononuclear complex
Expand Down
Loading

0 comments on commit 7397a04

Please sign in to comment.