Example #1
0
        def _gen3(ich):
            if has_stereo(ich):
                raise ValueError

            gra = graph(ich, stereo=False)
            gra = automol.graph.explicit(gra)
            geo = automol.graph.embed.geometry(gra)
            return geo
Example #2
0
def hydrogen_bonded_idxs(geo, dist_thresh=5.3, angle_thresh=1.92, grxn=None):
    """ Compare bond lengths in structure to determine if there
        is a hydrogen bond.

        :param geo: geometry object
        :type geo: geo object (tuple of tuples)
        :param grxn: reaction object (geo indexing)
        :type grxn: automol.reac.Reaction object
        :param dist_thresh: cutoff value for hbond length (Bohr)
        :type dist_thresh: float
        :param angle_thresh: cutoff value for hbond angle (Radian)
        :type angle_thresh: float
        :rtype: tuple
    """
    # Initialize the hydrogen bond list to None
    hydrogen_bond = None
    if count(geo) > 1:
        # Get the forming/breaking bond idxs if possible
        if grxn is not None:
            frm_bnd_keys = automol.graph.ts.forming_bond_keys(
                grxn.forward_ts_graph)
            brk_bnd_keys = automol.graph.ts.breaking_bond_keys(
                grxn.forward_ts_graph)
            rxn_keys = set()
            for key in frm_bnd_keys:
                rxn_keys = rxn_keys | key
            for key in brk_bnd_keys:
                rxn_keys = rxn_keys | key
            rxn_h_idxs = tuple(rxn_keys)
        else:
            rxn_h_idxs = ()

        # Get all potential indices for HB interactions
        gra = graph(geo)
        dist_mat = distance_matrix(geo)
        adj_atm_dct = automol.graph.atoms_neighbor_atom_keys(gra)
        h_idxs = automol.graph.atom_keys(gra, sym='H')
        acceptor_idxs = list(
            automol.graph.resonance_dominant_radical_atom_keys(gra))
        acceptor_idxs.extend(list(automol.graph.atom_keys(gra, sym='O')))
        # Loop over indices, ignoring H-idxs in reacting bonds
        hb_idxs = tuple(idx for idx in h_idxs if idx not in rxn_h_idxs)
        for h_idx in hb_idxs:
            for acceptor_idx in acceptor_idxs:
                donor_idx = list(adj_atm_dct[h_idx])[0]
                if acceptor_idx in adj_atm_dct[donor_idx]:
                    continue
                if dist_mat[h_idx][acceptor_idx] < dist_thresh:
                    ang = central_angle(geo, donor_idx, h_idx, acceptor_idx)
                    if ang > angle_thresh:
                        hydrogen_bond = (
                            donor_idx,
                            h_idx,
                            acceptor_idx,
                        )
                        dist_thresh = dist_mat[h_idx][acceptor_idx]
    return hydrogen_bond
Example #3
0
def components_graph(geo, stereo=True):
    """ Generate a list of molecular graphs where each element is a graph that
        consists of fully connected (bonded) atoms. Stereochemistry is included
        if requested.
        :param geo: molecular geometry
        :type geo: automol geometry data structure
        :param stereo: parameter to include stereochemistry information
        :type stereo: bool
        :rtype: automol molecular graph data structure
    """
    return automol.graph.connected_components(graph(geo, stereo=stereo))
Example #4
0
def expand_stereo(ich):
    """ Obtain all possible stereoisomers compatible with an InChI string.

        :param ich: InChI string
        :type ich: str
        :rtype: list[str]
    """
    gra = graph(ich)
    sgrs = automol.graph.stereomers(gra)
    ste_ichs = [automol.graph.stereo_inchi(sgr) for sgr in sgrs]
    return ste_ichs
Example #5
0
def is_complete(ich):
    """ Determine if the InChI string is complete
        (has all stereo-centers assigned).

        Currently only checks species that does not have any
        resonance structures.

        :param ich: InChI string
        :type ich: str
        :rtype: bool
    """

    gra = graph(ich, stereo=False)
    ste_atm_keys = automol.graph.stereogenic_atom_keys(gra)
    ste_bnd_keys = automol.graph.stereogenic_bond_keys(gra)
    graph_has_stereo = bool(ste_atm_keys or ste_bnd_keys)

    _complete = equivalent(
        ich, standard_form(ich)) and not (has_stereo(ich) ^ graph_has_stereo)

    return _complete
Example #6
0
def torsional_symmetry_numbers(zma,
                               tors_names,
                               frm_bnd_key=None,
                               brk_bnd_key=None):
    """ symmetry numbers for torsional dihedrals
    """
    dih_edg_key_dct = _dihedral_edge_keys(zma)
    assert set(tors_names) <= set(dih_edg_key_dct.keys())
    edg_keys = tuple(map(dih_edg_key_dct.__getitem__, tors_names))

    gra = graph(zma, stereo=False)
    bnd_sym_num_dct = automol.graph.bond_symmetry_numbers(
        gra, frm_bnd_key, brk_bnd_key)
    tors_sym_nums = []
    for edg_key in edg_keys:
        if edg_key in bnd_sym_num_dct.keys():
            sym_num = bnd_sym_num_dct[edg_key]
        else:
            sym_num = 1
        tors_sym_nums.append(sym_num)

    tors_sym_nums = tuple(tors_sym_nums)
    return tors_sym_nums
Example #7
0
def torsion_leading_atom(zma, key1, key2, zgra=None):
    """ Obtain the leading atom for a torsion coordinate about a torsion axis.

        The leading atom is the atom whose dihedral defines the torsional
        coordinate, which must always be the first dihedral coordinate
        for this bond.

        A bond is properly decoupled if all other dihedrals along this
        bond depend on the leading atom.

        :param zma: the z-matrix
        :type zma: automol Z-Matrix data structure
        :param key1: the first key in the torsion axis (rotational bond)
        :type key1: int
        :param key2: the second key in the torsion axis (rotational bond)
        :type key2: int
        :param gra: an automol graph data structure, aligned to the z-matrix;
            used to check connectivity when necessary
        :rtype: int
    """

    key_mat = key_matrix(zma)
    krs1 = [(key, row) for key, row in enumerate(key_mat)
            if row[:2] == (key1, key2)]
    krs2 = [(key, row) for key, row in enumerate(key_mat)
            if row[:2] == (key2, key1)]

    lead_key_candidates = []

    for krs in (krs1, krs2):
        if krs:
            keys, rows = zip(*krs)
            start_key = keys[0]
            assert all(row[-1] == start_key for row in rows[1:]), (
                "Torsion coordinate along bond {:d}-{:d} not decoupled:\n{}"
                .format(key1, key2, string(zma, one_indexed=False)))
            if rows[0][-1] is not None:
                lead_key_candidates.append(start_key)

    if not lead_key_candidates:
        lead_key = None
    elif len(lead_key_candidates) == 1:
        lead_key = lead_key_candidates[0]
    else:
        # If we get to this point, then the z-matrix includes dihedrals across
        # the key1-key2 bond in both directions and we have to choose which
        # dihedral to use. This mans there will be two lead_key_candidates.
        zgra = graph(zma) if zgra is None else zgra

        # Let key0 be the lead key and let (key1, key2, key3) be its key row in
        # the z-matrix. For the torsion coordinate, key0-key1-key2-key3 should
        # all be connected in a line. For subsidiary dihedral coordinates, key3
        # will be connected to key1 instead of key2.
        # A simple solution is therefore to choose the lead key based on
        # whether or not key2 and key3 are connected, which is what this code
        # does.
        bnd_keys = automol.graph.bond_keys(zgra)
        lead_key = next((k for k in lead_key_candidates if
                         frozenset(key_mat[k][-2:]) in bnd_keys), None)

        # If that fails, choose the key that appears earlier. It's possible
        # that it would be better to choose the later one, in which case we
        # would replace the min() here with a max().
        if lead_key is None:
            lead_key = min(lead_key_candidates)

    return lead_key
Example #8
0
def rot_permutated_geoms(geo, frm_bnd_keys=(), brk_bnd_keys=()):
    """ Convert an input geometry to a list of geometries
        corresponding to the rotational permuations of all the terminal groups.
        :param geo: molecular geometry
        :type geo: automol molecular geometry data structure
        :param frm_bnd_keys: keys denoting atoms forming bond in TS
        :type frm_bnd_keys: frozenset(int)
        :param brk_bnd_keys: keys denoting atoms breaking bond in TS
        :type brk_bnd_keys: frozenset(int)
        :rtype: tuple(automol geom data structure)
    """

    # Set saddle based on frm and brk keys existing
    saddle = bool(frm_bnd_keys or brk_bnd_keys)

    gra = graph(geo, stereo=False)
    term_atms = {}
    all_hyds = []
    neighbor_dct = automol.graph.atoms_neighbor_atom_keys(gra)
    ts_atms = []
    for bnd_ in frm_bnd_keys:
        ts_atms.extend(list(bnd_))
    for bnd_ in brk_bnd_keys:
        ts_atms.extend(list(bnd_))

    # determine if atom is a part of a double bond
    unsat_atms = automol.graph.unsaturated_atom_keys(gra)
    if not saddle:
        rad_atms = automol.graph.sing_res_dom_radical_atom_keys(gra)
        res_rad_atms = automol.graph.resonance_dominant_radical_atom_keys(gra)
        rad_atms = [atm for atm in rad_atms if atm not in res_rad_atms]
    else:
        rad_atms = []

    gra = gra[0]
    for atm in gra:
        if gra[atm][0] == 'H':
            all_hyds.append(atm)
    for atm in gra:
        if atm in unsat_atms and atm not in rad_atms:
            pass
        else:
            if atm not in ts_atms:
                nonh_neighs = []
                h_neighs = []
                neighs = neighbor_dct[atm]
                for nei in neighs:
                    if nei in all_hyds:
                        h_neighs.append(nei)
                    else:
                        nonh_neighs.append(nei)
                if len(nonh_neighs) < 2 and len(h_neighs) > 1:
                    term_atms[atm] = h_neighs
    geo_final_lst = [geo]
    for hyds in term_atms.values():
        geo_lst = []
        for geom in geo_final_lst:
            geo_lst.extend(_swap_for_one(geom, hyds))
        geo_final_lst = geo_lst

    return geo_final_lst
Example #9
0
def end_group_symmetry_factor(geo, frm_bnd_keys=(), brk_bnd_keys=()):
    """ Determine sym factor for terminal groups in a geometry
        :param geo: molecular geometry
        :type geo: automol molecular geometry data structure
        :param frm_bnd_keys: keys denoting atoms forming bond in TS
        :type frm_bnd_keys: frozenset(int)
        :param brk_bnd_keys: keys denoting atoms breaking bond in TS
        :type brk_bnd_keys: frozenset(int)
        :rtype: (automol geom data structure, float)
    """

    # Set saddle based on frm and brk keys existing
    saddle = bool(frm_bnd_keys or brk_bnd_keys)

    gra = graph(geo, stereo=False)
    term_atms = {}
    all_hyds = []
    neighbor_dct = automol.graph.atoms_neighbor_atom_keys(gra)

    ts_atms = []
    for bnd_ in frm_bnd_keys:
        ts_atms.extend(list(bnd_))
    for bnd_ in brk_bnd_keys:
        ts_atms.extend(list(bnd_))
    # determine if atom is a part of a double bond
    unsat_atms = automol.graph.unsaturated_atom_keys(gra)
    if not saddle:
        rad_atms = automol.graph.sing_res_dom_radical_atom_keys(gra)
        res_rad_atms = automol.raph.resonance_dominant_radical_atom_keys(gra)
        rad_atms = [atm for atm in rad_atms if atm not in res_rad_atms]
    else:
        rad_atms = []

    gra = gra[0]
    for atm in gra:
        if gra[atm][0] == 'H':
            all_hyds.append(atm)
    for atm in gra:
        if atm in unsat_atms and atm not in rad_atms:
            pass
        else:
            if atm not in ts_atms:
                nonh_neighs = []
                h_neighs = []
                neighs = neighbor_dct[atm]
                for nei in neighs:
                    if nei in all_hyds:
                        h_neighs.append(nei)
                    else:
                        nonh_neighs.append(nei)
                if len(nonh_neighs) == 1 and len(h_neighs) > 1:
                    term_atms[atm] = h_neighs
                    print('terminal atom accepted:', atm, h_neighs)
    factor = 1.
    remove_atms = []
    for atm in term_atms:
        hyds = term_atms[atm]
        if len(hyds) > 1:
            factor *= len(hyds)
            remove_atms.extend(hyds)
    geo = remove(geo, remove_atms)

    return geo, factor, remove_atms