Esempio n. 1
0
def inchi(gra, stereo=False):
    """ Generate an InChI string from a molecular graph.

        :param gra: molecular graph
        :type gra: automol graph data structure
        :param stereo: parameter to include stereochemistry information
        :type stereo: bool
        :rtype: str
    """

    ich = automol.inchi.base.hardcoded_object_to_inchi_by_key('graph',
                                                              gra,
                                                              comp=_compare)

    if ich is None:
        if not stereo or not has_stereo(gra):
            ich, _ = inchi_with_sort_from_geometry(gra)
            ich = automol.inchi.base.standard_form(ich, stereo=stereo)
        else:
            gra = explicit(gra)
            geo, geo_idx_dct = automol.graph.embed.fake_stereo_geometry(gra)
            ich, _ = inchi_with_sort_from_geometry(gra,
                                                   geo=geo,
                                                   geo_idx_dct=geo_idx_dct)

    return ich
Esempio n. 2
0
def _connected_inchi_with_graph_stereo(ich, gra, nums):
    """ For a connected inchi/graph, check if the inchi is missing stereo; If so,
    add stereo based on the graph.

    Currently only checks for missing bond stereo, since this is all we have
    seen so far, but could be generalized.

    :param ich: the inchi string
    :param gra: the graph
    :param nums: graph indices to backbone atoms in canonical inchi order
    :type nums: tuple[int]
    """
    # First, do a check to see if the InChI is missing bond stereo
    # relative to the graph.
    ich_ste_keys = automol.inchi.stereo_bonds(ich)
    our_ste_keys = bond_stereo_keys(gra)

    miss_ich_ste_keys = automol.inchi.unassigned_stereo_bonds(ich)

    if len(ich_ste_keys) > len(our_ste_keys):
        raise Exception("Our code is missing stereo bonds")

    if len(ich_ste_keys) < len(our_ste_keys) or miss_ich_ste_keys:
        # Convert to implicit graph and relabel based on InChI sort
        atm_key_dct = dict(map(reversed, enumerate(nums)))
        gra = relabel(gra, atm_key_dct)
        gra = explicit(gra)
        exp_h_keys = explicit_hydrogen_keys(gra)
        exp_h_key_dct = {k: -k for k in exp_h_keys}
        gra = relabel(gra, exp_h_key_dct)

        # Translate internal stereo parities into InChI stereo parities
        # and generate the appropriate b-layer string for the InChI
        ste_dct = bond_stereo_parities(gra)
        ste_keys = tuple(
            sorted(tuple(reversed(sorted(k))) for k in bond_stereo_keys(gra)))
        blyr_strs = []
        for atm1_key, atm2_key in ste_keys:
            our_par = ste_dct[frozenset({atm1_key, atm2_key})]
            our_srt1, our_srt2 = bond_stereo_sorted_neighbor_atom_keys(
                gra, atm1_key, atm2_key)
            ich_srt1 = tuple(reversed(sorted(our_srt1)))
            ich_srt2 = tuple(reversed(sorted(our_srt2)))
            if not ((our_srt1 != ich_srt1) ^ (our_srt2 != ich_srt2)):
                ich_par = our_par
            else:
                ich_par = not our_par

            blyr_strs.append(
                f"{atm1_key+1}-{atm2_key+1}{'-' if ich_par else '+'}")

        # After forming the b-layer string, generate the new InChI
        blyr_str = ','.join(blyr_strs)
        ste_dct = {'b': blyr_str}
        # print(ste_dct)
        ich = automol.inchi.standard_form(ich, ste_dct=ste_dct)
        # print('out:', ich)

    return ich
Esempio n. 3
0
def geometry(gra, keys=None, ntries=5, max_dist_err=0.2):
    """ sample a qualitatively-correct stereo geometry

    :param gra: the graph, which may or may not have stereo
    :param keys: graph keys, in the order in which they should appear in the
        geometry
    :param ntries: number of tries for finding a valid geometry
    :param max_dist_err: maximum distance error convergence threshold

    Qualitatively-correct means it has the right connectivity and the right
    stero parities, but its bond lengths and bond angles may not be
    quantitatively realistic
    """
    assert gra == explicit(gra), (
        "Graph => geometry conversion requires explicit hydrogens!\n"
        "Use automol.graph.explicit() to convert to an explicit graph.")

    # 0. Get keys and symbols
    symb_dct = atom_symbols(gra)

    keys = sorted(atom_keys(gra)) if keys is None else keys
    symbs = tuple(map(symb_dct.__getitem__, keys))

    # 1. Generate bounds matrices
    lmat, umat = distance_bounds_matrices(gra, keys)
    chi_dct = chirality_constraint_bounds(gra, keys)
    pla_dct = planarity_constraint_bounds(gra, keys)
    conv1_ = qualitative_convergence_checker_(gra, keys)
    conv2_ = embed.distance_convergence_checker_(lmat, umat, max_dist_err)

    def conv_(xmat, err, grad):
        return conv1_(xmat, err, grad) & conv2_(xmat, err, grad)

    # 2. Generate coordinates with correct stereo, trying a few times
    for _ in range(ntries):
        xmat = embed.sample_raw_distance_coordinates(lmat, umat, dim4=True)
        xmat, conv = embed.cleaned_up_coordinates(xmat,
                                                  lmat,
                                                  umat,
                                                  pla_dct=pla_dct,
                                                  chi_dct=chi_dct,
                                                  conv_=conv_)
        if conv:
            break

    if not conv:
        raise error.FailedGeometryGenerationError(f'Bad gra {string(gra)}')

    # 3. Generate a geometry data structure from the coordinates
    xyzs = xmat[:, :3]
    geo = automol.geom.base.from_data(symbs, xyzs, angstrom=True)

    return geo
Esempio n. 4
0
def geometry(gra):
    """ Convert a molecular graph to a molecular geometry.

        :param gra: molecular graph
        :type gra: automol graph data structure
        :rtype: automol molecular geometry data structure
    """

    symbs = atom_symbols(gra)
    if len(symbs) != 1:
        gra = explicit(gra)
        geo = automol.graph.embed.geometry(gra)
    else:
        symb = list(symbs.values())[0]
        # symb = list(symbs.keys())[0]
        geo = ((symb, (0.00, 0.00, 0.00)),)

    return geo