schrodinger.comparison.struc module

class schrodinger.comparison.struc.LabeledCentroidCoords(xyz: ndarray, ids: ndarray)

Bases: object

Read-only dataclass that holds coordinates of centroids of molecules in a crystal and the ASU component ids of those molecules.

Molecules with the same ASU component ID are images of each other under space group operations.

Parameters:
  • xyz – M x 3 array with coordinates of the centroids of a set of M molecules.

  • ids – M x 1 array holding the ASU component IDs of the same set of molecules.

xyz: ndarray
ids: ndarray
classmethod from_mol_aids(st: Structure, per_mol_aids: Iterable[Iterable[int]]) Self

Create an instance from a structure and a collection of atom IDs for a subset of molecules in that structure.

Assumes ASU component IDs have been set on st.

Parameters:
  • st – Strcutre containing molecules to be described

  • per_mol_aids – collection of iterables of 0-indexed atom IDs, one for each molecule in st to be included.

reassign_ids(id_map: dict[int, int]) Self

Map each molecule’s ASU component ID to a new value. Returns a copy.

Parameters:

id_map – dict mapping old to new ASU component IDs.

Returns:

Copy with each ASU component ID mapped to a new value. Original object is unmodified.

__init__(xyz: ndarray, ids: ndarray) None
schrodinger.comparison.struc.chorus_to_lower_triangle(struct)

Update chorus properties and with them atom coordinates so that upper triangle of the lattice vectors are all zeros. This is needed so that maestro displays structure correctly.

Parameters:

struct (Structure) – Structure to update

Return type:

Structure

Returns:

Updated structure (not a copy!!)

schrodinger.comparison.struc.atom_indices_are_contiguous(st: Structure) bool

Determine if atom indices of each molecule are contiguous. This is to guard against DFT making hydrogen transfers.

schrodinger.comparison.struc.set_component_id(mol: _AtomCollection, component_id: int)

Label a molecule as belonging to a given component of the ASU.

The ASU component ID is a label for molecules in the ASU, but our API doesn’t implement molecule-level properties, so it’s implemented in terms of an atom-level property set on all atoms in the molecule. :param mol: The molecule(s) to label :param component_id: the ASU component label to assign

schrodinger.comparison.struc.get_component_id(mol: _AtomCollection) int

Get the ASU component ID assigned to a molecule.

Uses -1 as a sentinel value if no label has been assigned. Molecules with the same ASU component ID are images of each other under space group operations. :param mol: The molecule to retrieve the label from. :return: The 1-indexed component ID of that molecule

schrodinger.comparison.struc.has_component_id(mol: _AtomCollection) bool

Return True if the ASU component ID has been set on mol.

The ASU component ID is a label for molecules in the ASU, but our API doesn’t implement molecule-level properties, so it’s implemented in terms of an atom-level property set on all atoms in the molecule.

schrodinger.comparison.struc.get_asu_component_ids(st: Structure) dict[int, int]

Get the ASU component ID assignments of all molecules in st.

Molecules with the same ASU component ID are images of each other under space group operations. :param st: Structure to read IDs from. :return: dict mapping molecule index to ASU component (both 1-indexed.)

schrodinger.comparison.struc.get_asu_id_array(st: Structure, mol_atom_0idxs: Iterable[Iterable[int]]) ndarray

Get the ASU component ID assignments of molecules in st, in a form suited to spherical cluster alignment.

Molecules with the same ASU component ID are images of each other under space group operations.

Parameters:
  • st – Structure to read IDs from.

  • mol_atom_0idxs – 2D array (or list of lists) of 0-indexed atom indexes, e.g. indices into a the coordinate array of st.

Returns:

1D array; indices are molecule indices in st (0-indexed), values are component IDs (1-indexed by convention).

schrodinger.comparison.struc.get_asu_component_name(mol: _AtomCollection) str

Return a string labeling the ASU component ID: “A” for 1, etc.

Parameters:

mol – The molecule get the name from

Returns:

“A” for 1, etc., or empty string if the component ID isn’t set.

schrodinger.comparison.struc.get_pymatgen_mol(ct)
schrodinger.comparison.struc.get_pointgroup_symmetry_ops(st, mol_index=1, include_H=False)

Determine point group symmetry ops using pymatgen. These symmetry operations are given at the origin.

Parameters:
  • st – Structure

  • mol_index – index of molecule to perform point group analysis on assumed to be the ASU

  • include_H – if True include hydrogens

Returns:

list of SymmOp instances representing symmetry operations

schrodinger.comparison.struc.rotate_pointgroup_symmetry_ops(symmetry_ops, U)

transform point group symmetry ops due to a rotation of the molecule for which the symmetry operations belong

Parameters:
  • symmetry_ops – list of SymmOp

  • U – 3x3 unitary transformation

Returns:

list of SymmOp

schrodinger.comparison.struc.apply_pointgroup_symmetry_op(op, st, asu_atom_indices)

apply point group symmetry operation to structure This will translate the asu (assumed to be the first molecule) to the origin, apply the symmetry operation and translate back

Parameters:
  • op – SymmOp

  • st – Structure to transform

  • asu_atom_indices – list of atom indices of the asu

Returns:

transformed cartesian coordinates

schrodinger.comparison.struc.get_op_trans_idx(op, st, asu_atom_indices)

calculates the transformation of indices that occurs under the application of the given symmetry operation

Parameters:
  • op – SymmOp

  • st – Structure to transform

  • asu_atom_indices – list of atom indices of the asu

Returns:

transformed cartesian coordinates

schrodinger.comparison.struc.is_better_match(n_matched: int, rmsd: float, best_n: int, best_rmsd: float, n_thresh: int = 20)

Logic for comparing two different RMSD-n values from spherical cluster alignment.

When matched molecules are greater than n_thresh, focus on the rmsd improvement only.

schrodinger.comparison.struc.center_com(st: Structure)

Move center of mass to origin.

schrodinger.comparison.struc.estimate_size(st: Structure) float

Return the largest projection along its principal directions

schrodinger.comparison.struc.get_bbox_vectors(st: Structure, make_isometric=False) ndarray

Return basis vectors of a bounding box for the input structure. Their lengths correspond to the st dimension along these directions. The moment of inertia eigenvalues are in ascending order.

Parameters:

st – The input structure should have its center of mass at origin.

schrodinger.comparison.struc.align_st_by_mol(st: Structure, st_indices: ndarray, ref_st: Structure, ref_indices: ndarray, allow_reflection=False) Tuple[ndarray, ndarray]

Transform st such that its molecule mol_id is aligned to molecule ref_mol_id in ref_st. Only heavy atoms are considered.

Parameters:
  • st – test structure to align

  • st_indices – list of atom indices to align (zero based)

  • ref_st – reference structure to align on

  • ref_indices – list of atom indices to align on (zero based)

  • allow_reflection – allow improper rotations in alignment

Returns:

translation vector and rotation matrix for the alignment

schrodinger.comparison.struc.get_RMSDn(st: Structure, ref: Structure, matching_cutoff: float = 2, with_alignment=True, allow_reflection=True) Tuple[int, float, Tuple[int, int]]

Return number of matched molecules matched and their RMSD. The input cluster st0 will be aligned with respect to ref as side effect,

Parameters:

matching_cutoff – If the center of mass of a molecule is within the radius of another molecule from a different cluster, it is considered as matched.

schrodinger.comparison.struc.reorder_cluster_atoms(st, ref, allow_reflection, align=True, use_chirality=False) Structure

Re-order atoms in st to match ref according to alignment. New order is generated by matching the first molecule in st and ref and applied to all other molecules in st.

Parameters:
  • st – Structure to re-order atoms of

  • ref – Reference Structure

  • allow_reflection – whether or not to allow reflection when optimizing rmsd in scoring method

  • align – if True align for rmsd in scoring atom maps

Returns:

the renumbered structure

schrodinger.comparison.struc.reorder_zprime2_cluster(st: Structure) Structure

Ensure that when the conformation of A and B are close, they would have the same atom orderings.

It (probably) will error out if A and B are different tautamers.

Assumptions: 1. All AB pair are contiguous with the same ordering 2. A atoms and B atoms separated 3. The first 2 molecules are A and B

These assumptions could be false for DFT output

class schrodinger.comparison.struc.AlignDimerCache(xyz_maps_A: ndarray, xyz_maps_B: ndarray, rmsd_atom_0idxs: list[int])

Bases: NamedTuple

Precomputed data for use in repeated calls to align_dimer.

xyz_maps_A: ndarray

Alias for field number 0

xyz_maps_B: ndarray

Alias for field number 1

rmsd_atom_0idxs: list[int]

Alias for field number 2

classmethod get_cache(dimer: Structure, include_polar_H: bool = True)

Constructor which precomputes information needed by align_dimer.

Parameters:
  • dimer – Any dimer to be aligned. Used as reference for atom mappings; alignment isn’t done.

  • include_polar_H – Flag to include polar hydrogens in the set of graph isomorphisms. If false, only consider remapping heavy atoms.

schrodinger.comparison.struc.align_dimer(ref_dimer: Structure, test_dimer: Structure, cache: AlignDimerCache, *, allow_improper_rotation: bool = True, is_precentered: bool = False) tuple[Structure, float]

Align test_dimer to ref_dimer.

Parameters:
  • test_dimer – Test dimer to be aligned. Not modified.

  • ref_dimer – Reference dimer for the alignment.

  • allow_improper_rotation – If True, allow improper (mirror-image) rotations during alignment.

  • is_precentered – If True, only consider rotations about the origin during alignment.

Returns:

Min-rmsd alignment of test_dimer to ref_dimer,and the min-rmsd value. Atoms may be reordered relative to input test_dimer.

schrodinger.comparison.struc.resolve_conflict(test: List[int], ref: List[int]) Iterator[Tuple[ndarray, ndarray]]

Return all valid mappings even if ref has repeats

schrodinger.comparison.struc.get_mappings(choices: Dict[int, List[int]]) Iterator[Tuple[List[int], List[int]]]

Return mappings without duplicates in values

schrodinger.comparison.struc.get_xyz_matches(test_coords: LabeledCentroidCoords, ref_coords: LabeledCentroidCoords, matching_cutoff: float = 2, matched_cutoff: int = 15, allow_id_reassign: bool = False, zprime: int = 1) Iterator[Tuple[List[int], List[int]]]

Yield candidate mappings between molecules in ref and test, based on rigid-body motions that align molecule centroids with the same ASU component IDs.

Parameters:
  • test_coords – centroids and component IDs from the test structure.

  • ref_coords – centroids and component IDs from the ref structure.

  • matching_cutoff – distance tolerance for two centroids to be considered as matched.

  • matched_cutoff – Number of centroids that must be matched in order for a mapping to be worth evaluating.

  • allow_id_reassign – Set to True if the ASU consists of multiple conformers of the same molecule; we then consider mappings that permute the ASU component IDs.

  • zprime – Number of molecules in ASU.

Yield:

mappings as tuples of lists: 0-indexed indices into the test_coords arrays and the corresponding index for the counterpart molecule in ref_coords.

schrodinger.comparison.struc.get_xyz_RMSDn(test_coords: LabeledCentroidCoords, ref_coords: LabeledCentroidCoords, n_thresh: int = 20, **kwargs) Tuple[int, float]

Return number of matched coordinates and their rmsd.

Parameters:
  • n_thresh – Centroid threshold for comparing centroid alignments on the basis of RMSD only.

  • kwargs – See get_xyz_matches for full documentation, since these arguments are passed through unchanged from the caller.

schrodinger.comparison.struc.get_potential_alignment(centroids1, centroids2, rdv1, rdv2, match_thresh, n_max=5) Iterator[ndarray]

Return potential alignment

Parameters:

n_max – max number of centroids for alignment check, in addition to the origin

schrodinger.comparison.struc.load_cif(fname: str, neutralize=True, mmjag=True) Structure
Parameters:

fname – input file name

schrodinger.comparison.struc.replicate(st: Structure, multiplicity: Union[int, Fraction], copy_cc=True) Structure

Replicate structure with integer or fractional multiples.

Parameters:
  • multiplicity – number of st in the returned structure

  • copy_cc – copy over custom charge if True

schrodinger.comparison.struc.get_niggli_params(lattice_params: List[float]) List[float]

Niggli reduction of the lattice parameters (a, b, c, alpha, beta, gamma)

schrodinger.comparison.struc.get_standard_cell(cell: Structure, to_primitive=False, no_idealize=False, symprec=1e-05) Structure

Fix skewed cell definition Note the new structure won’t carry over bonding information (reassigned), or any CT and atom level properties.

Parameters:
  • symprec – distance tolerance in Cartesian coordinates

  • no_idealize – whether to idealize cell lengths and angles according to crystal symmetry

schrodinger.comparison.struc.niggli_reduce_cell(cell: Structure) Structure

Transform cell with Niggli reduced lattice parameters. Note the new cell may not be in the original space group. It seems only to make sense for triclinic lattices (space groups).

schrodinger.comparison.struc.get_cell_fast(st: Structure, symm_ops: Tuple[ndarray], lattice_params: Optional[Tuple[float]] = None, copy_cc=True, extents: Tuple[int, ...] = (1, 1, 1), asu_input=False) Structure

Generate (a supercell of) the unit cell from a structure containing the ASU.

Supercell box and unit cell lattice parameters are stored in the output structure, as well as ASU component IDs. Assumes Z’=1 unless asu_input=True. :param st: Structure containing the ASU :param symm_ops: Each symmetry operator is a 4x4 numpy array :param lattice_params: if None, read from CT level properties of st :param copy_cc: copy custom charge to the supercell if set :param extents: 3D extension of the unit cell :param asu_input: If False, extract ASU, assuming the first molecule in st is ASU.

schrodinger.comparison.struc.apply_symmetries(st: Structure, vecs: List[array], spg_name: str = '', symm_ops: List[ndarray] = None)

in-place

Parameters:

vecs – a, b, c vectors

schrodinger.comparison.struc.has_clash(cell: Structure, cutoff: float = 0.7, use_pbc: bool = True) bool

The clash detection is based on the contacts between atoms in the structure, including both intra and inter-molecular contacts. The detection is similar to the Maestro ‘bad’ contact detection. The intramolecular clash detect is to be removed with DESMOND JIRA case DESMOND-16188

Parameters:
  • cell – input structure

  • cutoff – contact cutoff

  • use_pbc – whether to use periodic boundary conditions

Returns:

True if there is a clash

schrodinger.comparison.struc.get_asu_from_optresult(r: OptResult) Structure

Extract ASU from packing search result.

Parameters:

r – packing search result

schrodinger.comparison.struc.extract_supercell(r: OptResult, extents=(1, 1, 1), copy_cc=True) Structure

Extract supercell from packing search result.

Parameters:
  • r – packing search result

  • copy_cc – copy over custom charge if True

  • extents – 3D extension of the unit cell

schrodinger.comparison.struc.get_inscribe_extents(lattice_params: List[float], d: float) array

Return supercell extents to inscribe a sphere of diameter d.

Parameters:
  • lattice_params – a, b, c, alpha, beta, gamma

  • d – diameter

schrodinger.comparison.struc.get_ASU_RMSD(st1: Structure, st2: Structure, *, allow_improper_rotation=True, include_H=False, include_polar_H=True, reorder_atoms=True) Tuple[float, Structure]

Return RMSD between st1 and st2 and aligned st1, with potential atom index rearrangement. Here st2 is used as reference.

schrodinger.comparison.struc.get_volume_and_density(st: Structure, vecs=None) Tuple[float, float]

Return density in unit of g/cm^-3. The input st should be a supercell.

schrodinger.comparison.struc.is_chiral(st: Structure) bool
schrodinger.comparison.struc.get_conformer_radial_distance_vector(st: Structure) Tuple[ndarray, ndarray]

Return heavy atom coordinates. Origin is set at centroid

schrodinger.comparison.struc.get_centroid_radial_distance_vector(cluster: Structure, include_H=False, mol_aids=None) Tuple[ndarray, ndarray, ndarray]

Return the RDV of the centroids, the centroids excluding the 1st molecule, and the alignment vector (including the 1st molecule) in sorted ordering of RDV.

Origin is set at the centroid of the 1st molecules.

The alignment vector is nx N_ATOMS_CENTROID_ALIGNMENT x3 where n is the number of molecules (we should change it to ASU). For each ASU, it includes the coordinates of the centroid and two extra atoms (given N_ATOMS_CENTROID_ALIGNMENT is 3).

schrodinger.comparison.struc.get_torsion_atoms(a2: StructureAtom, a3: StructureAtom) Tuple[int, int, int, int]

Return the atom indices of a torsion angle

schrodinger.comparison.struc.get_torsions(st, indices=None) Tuple[ndarray, List]

Return torsion angles

schrodinger.comparison.struc.get_max_torsion_deviation(st1, st2, ref_tors=None)

The input structures should have the SAME AID ordering

schrodinger.comparison.struc.regenerate_with_box_fix(cell: Structure, old_ext: ndarray, symm_ops, new_ext=(1, 1, 1), asu_input=False) Structure

Regenerate supercell with potential box convention change

schrodinger.comparison.struc.remove_H_atoms(st: Structure) Structure

Return a structure without H atoms

schrodinger.comparison.struc.is_dilute(cell: Structure, asu_volume: Optional[float] = None, asu_atom_total: Optional[int] = None, packing_coeff_cutoff=0.6, density_cutoff=1.0) Tuple[bool, float]

Determine whether a structure is considered dilute using the packing coefficient, when an asu_volume is provided, or the density.

Parameters:
  • cell – Unit cell structure

  • asu_volume – Volume of the asymmetric unit

  • asu_atom_total – Total number of atoms in the asymmetric unit, required if asu_volume is provided

  • packing_coeff_cutoff – Threshold for the packing coefficient, values below this indicate a dilute structure

  • density_cutoff – Threshold for the density (g/cm3), values below this indicate a dilute structure

Returns:

True if structure is dilute, False if it is not, and the value used to determine this

schrodinger.comparison.struc.get_asu_volume(idx: str, vfname: str) float
schrodinger.comparison.struc.get_radial_count(xyz, center: ndarray)
schrodinger.comparison.struc.is_close_packed(xyz, center: ndarray) bool
schrodinger.comparison.struc.asu_iter(supercell: Structure, n: Optional[int] = None, num_atoms: Optional[int] = None) Generator[Structure, None, None]

Yield ASUs in supercell.

The supercell has to have ASU as chunks. Either n or num_atoms must be provided.

Parameters:
  • n – number of ASU copies in supercell

  • num_atoms – number of atoms in ASU

schrodinger.comparison.struc.regenerate_unitcell_from_asu(st: Structure, zprime: int = 1)

Extract the ASU from the st and regenerate the unitcell from ASU. This helps to fix the inconsistence in atom ordering between the molecules in the unit cell, particularly for structures converted to conventional cells after the QRNN/DFT optimizations based on reduced cells.

Parameters:
  • st – the input crystal structure.

  • zprime – Number of molecules in the crystal ASU.

Returns:

Unitcell with consistent atom ordering in all mols, ASU component IDs assigned and all mols translated to first lattice unitcell.

schrodinger.comparison.struc.extract_zprime2_asus(unitcell: Structure, dimer_distance: float = 3.5, save_homo_dimer: bool = False, inscribe_radius: float = 25.0)

extract ASU dimers from Z’=2 crystals

schrodinger.comparison.struc.swap_molecules(st, i: int, j: int) Structure

Swap the identity of two molecules in st.

schrodinger.comparison.struc.get_conventional_unit_cell(input_st: Structure, symprec: float = 0.01) Structure

Get the conventional unit cell from the input crystal structure, which can be primitive cell or non-primitive cell.

Parameters:
  • input_st – input unit cell structure; it can be primitive cell or non-primitive

  • symprec – Symmetry tolerance used for atomic coordinates to assign space group