Skip to content

Commit

Permalink
Define ring and puckering info for confs
Browse files Browse the repository at this point in the history
  • Loading branch information
JintaoWu98 committed Dec 8, 2024
1 parent 84898ee commit b016dce
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
46 changes: 46 additions & 0 deletions arc/species/conformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,12 @@ def generate_conformers(mol_list: Union[List[Molecule], Molecule],
mol_list=mol_list, label=label, xyzs=xyzs, torsion_num=len(torsions), charge=charge, multiplicity=multiplicity,
num_confs=num_confs_to_generate, force_field=force_field)

rings, rings_indices = determine_rings(mol_list)
lowest_confs = list()
if len(conformers):
conformers = determine_dihedrals(conformers, torsions)
if len(rings):
conformers = determine_puckering(conformers, rings_indices)

new_conformers, symmetries = deduce_new_conformers(
label, conformers, torsions, tops, mol_list, smeared_scan_res, plot_path=plot_path,
Expand Down Expand Up @@ -887,6 +890,49 @@ def determine_dihedrals(conformers, torsions):
return conformers


def determine_rings(mol_list):
"""
Determine the rings in the molecule.
Args:
mol_list (list): Localized structures (Molecule objects) by which all rotors will be determined.
Returns:
Tuple[list, list]:
- A list of ring atoms.
- A list of ring atom indices.
"""
rings, rings_indexes = list(), list()
for mol in mol_list:
rings = mol.get_deterministic_sssr()
rings_indexes = [[mol.atoms.index(atom) for atom in ring] for ring in rings]
return rings, rings_indexes


def determine_puckering(conformers, rings_indices):
"""
For each conformer in `conformers` determine the respective puckering angles.
Args:
conformers (list): Entries are conformer dictionaries.
rings_indices (list): Entries are lists of ring atom indices.
Returns:
list: Entries are conformer dictionaries.
"""
for conformer in conformers:
if isinstance(conformer['xyz'], str):
xyz = converter.str_to_xyz(conformer['xyz'])
else:
xyz = conformer['xyz']
if 'puckering' not in conformer or not conformer['puckering']:
conformer['puckering'] = dict()
for i, ring in enumerate(rings_indices):
theta = vectors.calculate_ring_dihedral_angles(coords=xyz['coords'], ring=ring, index=0)
conformer['puckering'][tuple((ring[i%len(ring)], ring[(i + 1)%len(ring)], ring[(i + 2)%len(ring)], ring[(i + 3)%len(ring)]) for i in range(len(ring)))] = theta
return conformers


def determine_torsion_sampling_points(label, torsion_angles, smeared_scan_res=None, symmetry=1):
"""
Determine how many points to consider in each well of a torsion for conformer combinations.
Expand Down
21 changes: 20 additions & 1 deletion arc/species/vectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def calculate_dihedral_angle(coords: Union[list, tuple, dict],
"""
if isinstance(coords, dict) and 'coords' in coords:
coords = coords['coords']
if not isinstance(coords, (list, tuple)):
if not isinstance(coords, (list, tuple, np.ndarray)):
raise TypeError(f'coords must be a list or a tuple, got\n{coords}\nwhich is a {type(coords)}')
if index not in [0, 1]:
raise VectorsError(f'index must be either 0 or 1, got {index}')
Expand All @@ -232,6 +232,25 @@ def calculate_dihedral_angle(coords: Union[list, tuple, dict],
return get_dihedral(v1, v2, v3, units=units)


def calculate_ring_dihedral_angles(coords: Union[list, tuple, dict],
ring: list,
index: int = 0
) -> list:
if isinstance(coords, dict) and 'coords' in coords:
coords = coords['coords']
if not isinstance(coords, (list, tuple)):
raise TypeError(f'coords must be a list or a tuple, got {type(coords)}')

coords = np.array(coords, dtype=np.float32)
ring = [atom - index for atom in ring] # Adjusting for zero-indexed
angles = []
for i in range(len(ring)):
angle_deg = calculate_dihedral_angle(coords, [ring[i%len(ring)], ring[(i + 1)%len(ring)], ring[(i + 2)%len(ring)], ring[(i + 3)%len(ring)]])
angles.append(angle_deg)

return angles


def calculate_param(coords: Union[list, tuple, dict],
atoms: list,
index: int = 0,
Expand Down

0 comments on commit b016dce

Please sign in to comment.