Skip to content

Commit

Permalink
Debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
choglass committed Jun 4, 2024
1 parent 9b8b7bf commit 5f528b4
Show file tree
Hide file tree
Showing 8 changed files with 780 additions and 137 deletions.
84 changes: 43 additions & 41 deletions cell2mol/charge_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import sys
from cell2mol.hungarian import reorder
from cell2mol.xyz2mol import xyz2mol

from cell2mol.new_charge_assignment import get_charge
elemdatabase = ElementData()

#############################
Expand Down Expand Up @@ -370,13 +370,15 @@ def get_protonation_states_specie(specie: object, debug: int=0) -> list:
if a.connec == 1:
elemlist[idx] = "H"
addedlist[idx] = 1
elif a.connec > 1:
elif a.connec == 2:
needs_nonlocal = True
non_local_groups += 1
if debug >= 2: print(f" GET_PROTONATION_STATES: will be sent to nonlocal due to {a.label} atom")
# block[idx] = 1
# elemlist[idx] = "H"
# addedlist[idx] = 1
else:
block[idx] = 1
# Hydrides
elif a.label == "H":
if a.connec == 0:
Expand Down Expand Up @@ -584,45 +586,45 @@ def get_protonation_states_specie(specie: object, debug: int=0) -> list:
return protonation_states

#######################################################
def get_charge(ich: int, prot: object, allow: bool=True, debug: int=0):
## Generates the connectivity of a molecule given a desired charge (ich).
# The molecule is described by a protonation states that has labels, and the atomic cartesian coordinates "coords"
# The adjacency matrix is also provided in the protonation state(adjmat)
#:return charge_state which is an object with the necessary information for other functions to handle the result

natoms = prot.natoms
atnums = prot.atnums

##########################
# xyz2mol is called here #
##########################
# use_graph is called for a faster generation
# allow_charged_fragments is necessary for non-neutral molecules
# embed_chiral shouldn't ideally be necessary, but it runs a sanity check that improves the proposed connectivity
# use_huckel false means that the xyz2mol adjacency will be generated based on atom distances and vdw radii.
# instead of use_huckel, we provide the adjacency matrix

mols = xyz2mol(atnums, prot.coords, prot.adjmat, prot.cov_factor, charge=ich, use_graph=True,allow_charged_fragments=allow,embed_chiral=True,use_huckel=False)
if len(mols) > 1: print("WARNING: More than 1 mol received from xyz2mol for initcharge:", ich)

# Smiles are generated with rdkit
smiles = Chem.MolToSmiles(mols[0])
if debug >= 2: print(f"GET_CHARGE. {smiles=}")
# Gets the resulting charges
atom_charge = []
total_charge = 0
for i in range(natoms):
a = mols[0].GetAtomWithIdx(i) # Returns a particular Atom
atom_charge.append(a.GetFormalCharge())
total_charge += a.GetFormalCharge()

# Connectivity is checked
iscorrect = check_rdkit_obj_connectivity(mols[0], prot.natoms, ich, debug=debug)

# Charge_state is initiated
ch_state = charge_state(iscorrect, total_charge, atom_charge, mols[0], smiles, ich, allow, prot)

return ch_state
# def get_charge(ich: int, prot: object, allow: bool=True, debug: int=0):
# ## Generates the connectivity of a molecule given a desired charge (ich).
# # The molecule is described by a protonation states that has labels, and the atomic cartesian coordinates "coords"
# # The adjacency matrix is also provided in the protonation state(adjmat)
# #:return charge_state which is an object with the necessary information for other functions to handle the result

# natoms = prot.natoms
# atnums = prot.atnums

# ##########################
# # xyz2mol is called here #
# ##########################
# # use_graph is called for a faster generation
# # allow_charged_fragments is necessary for non-neutral molecules
# # embed_chiral shouldn't ideally be necessary, but it runs a sanity check that improves the proposed connectivity
# # use_huckel false means that the xyz2mol adjacency will be generated based on atom distances and vdw radii.
# # instead of use_huckel, we provide the adjacency matrix

# mols = xyz2mol(atnums, prot.coords, prot.adjmat, prot.cov_factor, charge=ich, use_graph=True,allow_charged_fragments=allow,embed_chiral=True,use_huckel=False)
# if len(mols) > 1: print("WARNING: More than 1 mol received from xyz2mol for initcharge:", ich)

# # Smiles are generated with rdkit
# smiles = Chem.MolToSmiles(mols[0])
# if debug >= 2: print(f"GET_CHARGE. {smiles=}")
# # Gets the resulting charges
# atom_charge = []
# total_charge = 0
# for i in range(natoms):
# a = mols[0].GetAtomWithIdx(i) # Returns a particular Atom
# atom_charge.append(a.GetFormalCharge())
# total_charge += a.GetFormalCharge()

# # Connectivity is checked
# iscorrect = check_rdkit_obj_connectivity(mols[0], prot.natoms, ich, debug=debug)

# # Charge_state is initiated
# ch_state = charge_state(iscorrect, total_charge, atom_charge, mols[0], smiles, ich, allow, prot)

# return ch_state

#######################################################
def check_rdkit_obj_connectivity(mol: object, natoms: int, ich: int, debug: int=0):
Expand Down
2 changes: 1 addition & 1 deletion cell2mol/connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def get_radii(labels: list) -> np.ndarray:
for l in labels:
if l[-1].isdigit(): label = l[:-1]
else: label = l

# radii.append(elemdatabase.CovalentRadius3[label])
if elemdatabase.elementgroup[label] == 1 and label != "H":
radii.append(elemdatabase.CovalentRadius2[label])
else:
Expand Down
7 changes: 5 additions & 2 deletions cell2mol/new_c2m_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@
### PREPARES THE REFERENCE CELL OBJECT ###
##########################################
cov_factor = 1.3

print(f"{cov_factor=}")
metal_factor = 1.0
# Get reference molecules
# labels, pos, ref_labels, ref_fracs, cellvec, cell_param = readinfo(infopath)
Expand All @@ -101,7 +103,7 @@
# Create reference cell object
refcell = cell(name, ref_labels, ref_pos, ref_fracs, cell_vector, cell_param)
refcell.get_subtype("reference")
refcell.get_reference_molecules(ref_labels, ref_fracs, debug=debug)
refcell.get_reference_molecules(ref_labels, ref_fracs, cov_factor=cov_factor, debug=debug)

if not refcell.has_isolated_H:
refcell.check_missing_H(debug=debug)
Expand All @@ -114,7 +116,8 @@
print(f"Covalent factor increases: {cov_factor=}")
refcell.check_missing_H(debug=debug)
refcell.assess_errors(mode="hydrogens")

refcell.save(ref_cell_fname)

if refcell.error_case == 0:
# Get unique species for the reference cell
refcell.get_unique_species(debug=debug) # Get unique_species, unique_indices, and species_list
Expand Down
10 changes: 5 additions & 5 deletions cell2mol/new_cell_reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def find_row_indices(source, target):
# Iterate over each row in the source array with enumeration to track the index
for index, row in enumerate(source):
# Check if any row in the target array matches the current row
if any(np.allclose(row, target_row, atol=1e-6, rtol=1e-4) for target_row in target):
if any(np.allclose(row, target_row, atol=1e-4, rtol=1e-2) for target_row in target):
found_indices.append(index)
found_rows.append(row)
else :
Expand All @@ -58,7 +58,7 @@ def find_row_index_from_matrix (matrix, query_row):

# Check each row for equality with the query_row
for index, row in enumerate(matrix):
if np.allclose(row, query_row, atol=1e-6, rtol=1e-4):
if np.allclose(row, query_row, atol=1e-4, rtol=1e-2):
return index
return -1

Expand Down Expand Up @@ -367,9 +367,9 @@ def get_updated_indices(sp_idx, new, cell_labels, cell_pos, cell_fracs, debug: i

for jdx, (n_l, n_p, n_f) in enumerate(zip(new_labels, new_pos, new_fracs)):
for kdx, (l, p, f) in enumerate(zip(cell_labels, cell_pos, cell_fracs)):
if n_l == l and np.allclose(n_p, p, atol=1e-5, rtol=1e-3):
if np.allclose(np.remainder(n_f, 1), np.remainder(f, 1), atol=1e-5, rtol=1e-3):
if debug > 2:
if n_l == l and np.allclose(n_p, p, atol=1e-4, rtol=1e-2):
if np.allclose(np.remainder(n_f, 1), np.remainder(f, 1), atol=1e-4, rtol=1e-2):
if debug >= 2:
print(f"symmtry operation {sp_idx}:", f"atom of new (index: {jdx})", n_l, n_p, n_f, \
f"is the same as the atom of the unit cell (index: {kdx})", l, p, f)
indices_lists.append((jdx, kdx))
Expand Down
18 changes: 13 additions & 5 deletions cell2mol/new_charge_assignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def set_charge_state(reference, target, mode, debug: int=0):
print(f"SET_CHARGE_STATE:{target.formula=} {target.totcharge=} {target.smiles=}")

######################################################
def get_charge(charge: int, prot: object, allow: bool=True, debug: int=0):
def get_charge(charge: int, prot: object, allow: bool=True, embed_chiral: bool=True, debug: int=0):
## Generates the connectivity of a molecule given a desired charge (charge).
# The molecule is described by a protonation states that has labels, and the atomic cartesian coordinates "coords"
# The adjacency matrix is also provided in the protonation state(adjmat)
Expand Down Expand Up @@ -285,8 +285,12 @@ def create_bonds_specie (specie, debug: int=0):
if debug >=1 :
print(f"\tBONDS", [(bd.atom1.label, bd.atom2.label, bd.order, round(bd.distance,3)) for bd in specie.atoms[idx].bonds])
else:
if debug >=1: print(f"\tNO BONDS for {specie.atoms[idx].label} with {specie.subtype} RDKit object index {idx}. Please check the RDKit object.")
return False # return False if no bonds are created
if specie.natoms == 1:
if debug >=1: print(f"\tNO BONDS CREATED for {specie.atoms[idx].label} because it is the only atom in {specie.subtype} object")
pass
else:
if debug >=1: print(f"\tNO BONDS for {specie.atoms[idx].label} with {specie.subtype} RDKit object index {idx}. Please check the RDKit object.")
return False # return False if no bonds are created
else:
if debug >= 1: print(f"\tNumber of atoms in {specie.subtype} object and RDKit object are different: {n_atoms} {n_atoms_rdkit}")
if debug >= 2: print(f"\t{[(i, atom.label) for i, atom in enumerate(specie.atoms)]}")
Expand Down Expand Up @@ -324,8 +328,12 @@ def create_bonds_specie (specie, debug: int=0):
if debug >=2:
print(f"\tBONDS", [(bd.atom1.label, bd.atom2.label, bd.order, round(bd.distance,3)) for bd in specie.atoms[idx].bonds])
else:
if debug >=1: print(f"\tNO BONDS for {specie.atoms[idx].label} with {specie.subtype} RDKit object index {idx}. Please check the RDKit object.")
return False # return False if no bonds are created
if specie.natoms == 1:
if debug >=1: print(f"\tNO BONDS CREATED for {specie.atoms[idx].label} because it is the only atom in {specie.subtype} object")
pass
else:
if debug >=1: print(f"\tNO BONDS for {specie.atoms[idx].label} with {specie.subtype} RDKit object index {idx}. Please check the RDKit object.")
return False # return False if no bonds are created
else :
if debug >=1: print(f"\tNO BONDS for {rdkit_atom.GetSymbol()} with {specie.subtype} RDKit object index {idx} because it is an added atom")

Expand Down
Loading

0 comments on commit 5f528b4

Please sign in to comment.