예제 #1
0
def from_data(formula_sublayer,
              main_sublayer_dct=None,
              charge_sublayer_dct=None,
              stereo_sublayer_dct=None,
              isotope_sublayer_dct=None):
    """ calculate an inchi string from layers
    """
    main_dct = dict_.empty_if_none(main_sublayer_dct)
    char_dct = dict_.empty_if_none(charge_sublayer_dct)
    ste_dct = dict_.empty_if_none(stereo_sublayer_dct)
    iso_dct = dict_.empty_if_none(isotope_sublayer_dct)

    fml_slyr = formula_sublayer
    main_slyrs = [
        pfx + slyr for pfx, slyr in zip(
            MAIN_PFXS, dict_.values_by_key(main_dct, MAIN_PFXS)) if slyr
    ]
    char_slyrs = [
        pfx + slyr for pfx, slyr in zip(
            CHAR_PFXS, dict_.values_by_key(char_dct, CHAR_PFXS)) if slyr
    ]
    ste_slyrs = [
        pfx + slyr
        for pfx, slyr in zip(STE_PFXS, dict_.values_by_key(ste_dct, STE_PFXS))
        if slyr
    ]
    iso_slyrs = [
        pfx + slyr
        for pfx, slyr in zip(ISO_PFXS, dict_.values_by_key(iso_dct, ISO_PFXS))
        if slyr
    ]

    ich = '/'.join(['InChI=1', fml_slyr] + main_slyrs + char_slyrs +
                   ste_slyrs + iso_slyrs)
    return ich
예제 #2
0
def inchi_with_sort_from_coordinates(gra, atm_xyz_dct=None):
    """ connectivity graph => inchi conversion

    (if coordinates are passed in, they are used to determine stereo)
    """
    gra = automol.graph.without_dummy_atoms(gra)
    gra = automol.graph.dominant_resonance(gra)
    atm_keys = list(automol.graph.atom_keys(gra))
    bnd_keys = list(automol.graph.bond_keys(gra))
    atm_syms = dict_.values_by_key(automol.graph.atom_symbols(gra), atm_keys)
    atm_bnd_vlcs = dict_.values_by_key(
        automol.graph.atom_bond_valences(gra), atm_keys)
    atm_rad_vlcs = dict_.values_by_key(
        automol.graph.atom_unsaturated_valences(gra), atm_keys)
    bnd_ords = dict_.values_by_key(automol.graph.bond_orders(gra), bnd_keys)
    atm_xyzs = (None if atm_xyz_dct is None else
                dict_.values_by_key(atm_xyz_dct, atm_keys))
    mlf, key_map_inv = _molfile.from_data(
        atm_keys, bnd_keys, atm_syms, atm_bnd_vlcs, atm_rad_vlcs, bnd_ords,
        atm_xyzs=atm_xyzs)
    rdm = _rdkit.from_molfile(mlf)
    ich, aux_info = _rdkit.to_inchi(rdm, with_aux_info=True)
    nums = _parse_sort_order_from_aux_info(aux_info)
    nums = tuple(map(key_map_inv.__getitem__, nums))
    return ich, nums
예제 #3
0
def heuristic_geometry(xgr):
    """ heuristic geometry for this molecular graph
    """
    xgr = _explicit(xgr)
    atm_keys = sorted(_atom_keys(xgr))
    syms = dict_.values_by_key(_atom_symbols(xgr), atm_keys)
    xyzs = dict_.values_by_key(atom_stereo_coordinates(xgr), atm_keys)
    geo = automol.create.geom.from_data(syms, xyzs)
    return geo
예제 #4
0
def geometry(gra):
    """ graph => geometry
    """
    gra = automol.graph.explicit(gra)
    atm_keys = sorted(automol.graph.atom_keys(gra))
    atm_syms = dict_.values_by_key(automol.graph.atom_symbols(gra), atm_keys)
    atm_xyzs = dict_.values_by_key(
        automol.graph.atom_stereo_coordinates(gra), atm_keys)
    geo = automol.create.geom.from_data(atm_syms, atm_xyzs)
    return geo
예제 #5
0
def is_stereo_compatible(tra, sgr1, sgr2):
    """ is this transformation compatible with the reactant/product stereo
    assignments?
    """
    cgr1 = without_stereo_parities(sgr1)
    cgr2 = without_stereo_parities(sgr2)
    atm_key_dct = full_isomorphism(apply(tra, cgr1), cgr2)

    # determine the stereo centers which are preserved in the transformation
    sgr1 = _relabel(sgr1, atm_key_dct)
    atm_keys = sorted(atom_stereo_keys(sgr1) & atom_stereo_keys(sgr2))
    bnd_keys = sorted(bond_stereo_keys(sgr1) & bond_stereo_keys(sgr2))

    atm_pars1 = dict_.values_by_key(atom_stereo_parities(sgr1), atm_keys)
    atm_pars2 = dict_.values_by_key(atom_stereo_parities(sgr2), atm_keys)
    bnd_pars1 = dict_.values_by_key(bond_stereo_parities(sgr1), bnd_keys)
    bnd_pars2 = dict_.values_by_key(bond_stereo_parities(sgr2), bnd_keys)

    atm_ngb_keys_dct1 = atom_neighbor_keys(sgr1)
    atm_ngb_keys_dct2 = atom_neighbor_keys(sgr2)

    ret = True

    for atm_key, par1, par2 in zip(atm_keys, atm_pars1, atm_pars2):
        atm_ngb_keys1 = stereo_sorted_atom_neighbor_keys(
            sgr1, atm_key, atm_ngb_keys_dct1[atm_key])
        atm_ngb_keys2 = stereo_sorted_atom_neighbor_keys(
            sgr2, atm_key, atm_ngb_keys_dct2[atm_key])

        if _permutation_parity(atm_ngb_keys1, atm_ngb_keys2):
            ret &= (par1 == par2)
        else:
            ret &= (par1 != par2)

    for bnd_key, par1, par2 in zip(bnd_keys, bnd_pars1, bnd_pars2):
        atm1_key, atm2_key = bnd_key

        atm1_ngb_key1 = stereo_sorted_atom_neighbor_keys(
            sgr1, atm1_key, atm_ngb_keys_dct1[atm1_key] - {atm2_key})[0]
        atm2_ngb_key1 = stereo_sorted_atom_neighbor_keys(
            sgr1, atm2_key, atm_ngb_keys_dct1[atm2_key] - {atm1_key})[0]
        atm1_ngb_key2 = stereo_sorted_atom_neighbor_keys(
            sgr2, atm1_key, atm_ngb_keys_dct2[atm1_key] - {atm2_key})[0]
        atm2_ngb_key2 = stereo_sorted_atom_neighbor_keys(
            sgr2, atm2_key, atm_ngb_keys_dct2[atm2_key] - {atm1_key})[0]

        if not ((atm1_ngb_key1 != atm1_ngb_key2) ^
                (atm2_ngb_key1 != atm2_ngb_key2)):
            ret &= (par1 == par2)
        else:
            ret &= (par1 != par2)

    return ret
예제 #6
0
def add_atom_implicit_hydrogen_valences(xgr, inc_atm_imp_hyd_vlc_dct):
    """ add atom imlicit hydrogen valences

    (increments can be positive or negative)
    """
    atm_keys = list(inc_atm_imp_hyd_vlc_dct.keys())
    atm_imp_hyd_vlcs = numpy.add(
        dict_.values_by_key(atom_implicit_hydrogen_valences(xgr), atm_keys),
        dict_.values_by_key(inc_atm_imp_hyd_vlc_dct, atm_keys))
    assert all(atm_imp_hyd_vlc >= 0 for atm_imp_hyd_vlc in atm_imp_hyd_vlcs)
    atm_imp_hyd_vlc_dct = dict_.transform_values(
        dict(zip(atm_keys, atm_imp_hyd_vlcs)), int)
    return set_atom_implicit_hydrogen_valences(xgr, atm_imp_hyd_vlc_dct)
예제 #7
0
def _add_pi_bonds(rgr, bnd_ord_inc_dct):
    """ add pi bonds to this graph
    """
    bnd_keys = _bond_keys(rgr)
    assert set(bnd_ord_inc_dct.keys()) <= bnd_keys

    bnd_keys = list(bnd_keys)
    bnd_ords = dict_.values_by_key(_bond_orders(rgr), bnd_keys)
    bnd_ord_incs = dict_.values_by_key(bnd_ord_inc_dct, bnd_keys, fill_val=0)
    new_bnd_ords = numpy.add(bnd_ords, bnd_ord_incs)
    bnd_ord_dct = dict(zip(bnd_keys, new_bnd_ords))
    rgr = _set_bond_orders(rgr, bnd_ord_dct)
    return rgr
예제 #8
0
 def _is_valid(bnd_ord_inc_dct):
     # check if pi bonds exceed unsaturated valences
     def __tally(atm_bnd_keys):
         return sum(dict_.values_by_key(bnd_ord_inc_dct, atm_bnd_keys))
     atm_unsat_vlc_decs = tuple(map(__tally, atm_bnd_keys_lst))
     enough_elecs = numpy.all(
         numpy.less_equal(atm_unsat_vlc_decs, atm_unsat_vlcs))
     # check if all bond orders are less than 4 (should only affect C2)
     bnd_inc_keys = bnd_ord_inc_dct.keys()
     bnd_incs = dict_.values_by_key(bnd_ord_inc_dct, bnd_inc_keys)
     bnd_ords = dict_.values_by_key(bnd_ord_dct, bnd_inc_keys)
     new_bnd_ords = numpy.add(bnd_ords, bnd_incs)
     not_too_many = numpy.all(numpy.less(new_bnd_ords, 4))
     return enough_elecs and not_too_many
예제 #9
0
def atom_unsaturated_valences(xgr, bond_order=True):
    """ unsaturated valences, by atom

    (element valences minus bonding valences -- pi sites and radical electrons)
    """
    atm_keys = list(atom_keys(xgr))
    if not bond_order:
        xgr = without_bond_orders(xgr)

    atm_bnd_vlcs = dict_.values_by_key(atom_bond_valences(xgr), atm_keys)
    atm_tot_vlcs = dict_.values_by_key(atom_element_valences(xgr), atm_keys)
    atm_rad_vlcs = numpy.subtract(atm_tot_vlcs, atm_bnd_vlcs)
    atm_unsat_vlc_dct = dict_.transform_values(
        dict(zip(atm_keys, atm_rad_vlcs)), int)
    return atm_unsat_vlc_dct
예제 #10
0
def frozen(xgr):
    """ hashable, sortable, immutable container of graph data
    """
    atm_keys = sorted(atom_keys(xgr))
    bnd_keys = sorted(bond_keys(xgr), key=sorted)

    # make it sortable by replacing Nones with -infinity
    atm_vals = numpy.array(dict_.values_by_key(atoms(xgr), atm_keys))
    bnd_vals = numpy.array(dict_.values_by_key(bonds(xgr), bnd_keys))
    atm_vals[numpy.equal(atm_vals, None)] = -numpy.inf
    bnd_vals[numpy.equal(bnd_vals, None)] = -numpy.inf

    frz_atms = tuple(zip(atm_keys, map(tuple, atm_vals)))
    frz_bnds = tuple(zip(bnd_keys, map(tuple, bnd_vals)))
    return (frz_atms, frz_bnds)
예제 #11
0
def atom_hybridizations(rgr):
    """ atom hybridizations, by atom
    """
    atm_keys = list(_atom_keys(rgr))
    atm_unsat_vlc_dct = _atom_unsaturated_valences(rgr, bond_order=True)
    atm_bnd_vlc_dct = _atom_bond_valences(rgr, bond_order=False)     # note!!
    atm_unsat_vlcs = numpy.array(
        dict_.values_by_key(atm_unsat_vlc_dct, atm_keys))
    atm_bnd_vlcs = numpy.array(dict_.values_by_key(atm_bnd_vlc_dct, atm_keys))
    atm_lpcs = numpy.array(
        dict_.values_by_key(_atom_lone_pair_counts(rgr), atm_keys))
    atm_hybs = atm_unsat_vlcs + atm_bnd_vlcs + atm_lpcs - 1
    atm_hyb_dct = dict_.transform_values(
        dict(zip(atm_keys, atm_hybs)), int)
    return atm_hyb_dct
예제 #12
0
def branch_bond_keys(gra, atm_key, bnd_key):
    """ bond keys for branch extending along `bnd_key` away from `atm_key`
    """

    # bnd_key is the set of atom indices for the bond of interest
    # atm_bnd_keys_dct is a dictionary of atoms that are connected to each atom
    bnd_key = frozenset(bnd_key)
    assert atm_key in bnd_key

    atm_bnd_keys_dct = atom_bond_keys(gra)

    bnch_bnd_keys = {bnd_key}
    seen_bnd_keys = set()
    excl_bnd_keys = atm_bnd_keys_dct[atm_key] - {bnd_key}

    new_bnd_keys = {bnd_key}

    bnd_ngb_keys_dct = bond_neighbor_keys(gra)

    while new_bnd_keys:
        new_bnd_ngb_keys = set(
            itertools.chain(
                *dict_.values_by_key(bnd_ngb_keys_dct, new_bnd_keys)))
        bnch_bnd_keys.update(new_bnd_ngb_keys - excl_bnd_keys)
        seen_bnd_keys.update(new_bnd_keys)
        new_bnd_keys = bnch_bnd_keys - seen_bnd_keys

    return frozenset(bnch_bnd_keys)
예제 #13
0
def resonance_dominant_bond_orders(rgr):
    """ resonance-dominant bond orders, by bond
    """
    bnd_keys = list(_bond_keys(rgr))
    bnd_ords_by_res = [
        dict_.values_by_key(_bond_orders(dom_rgr), bnd_keys)
        for dom_rgr in dominant_resonances(rgr)]
    bnd_ords_lst = list(map(frozenset, zip(*bnd_ords_by_res)))
    bnd_dom_res_ords_dct = dict(zip(bnd_keys, bnd_ords_lst))
    return bnd_dom_res_ords_dct
예제 #14
0
def resonance_dominant_atom_hybridizations(rgr):
    """ resonance-dominant atom hybridizations, by atom
    """
    atm_keys = list(_atom_keys(rgr))
    atm_hybs_by_res = [
        dict_.values_by_key(atom_hybridizations(dom_rgr), atm_keys)
        for dom_rgr in dominant_resonances(rgr)]
    atm_hybs = [min(hybs) for hybs in zip(*atm_hybs_by_res)]
    atm_hyb_dct = dict(zip(atm_keys, atm_hybs))
    return atm_hyb_dct
예제 #15
0
def sing_res_dom_radical_atom_keys(rgr):
    """ resonance-dominant radical atom keys,for one resonance
    """
    atm_keys = list(_atom_keys(rgr))
    atm_rad_vlcs_by_res = [
        dict_.values_by_key(_atom_unsaturated_valences(dom_rgr), atm_keys)
        for dom_rgr in dominant_resonances(rgr)]
    first_atm_rad_val = [atm_rad_vlcs_by_res[0]]
    atm_rad_vlcs = [max(rad_vlcs) for rad_vlcs in zip(*first_atm_rad_val)]
    atm_rad_keys = frozenset(atm_key for atm_key, atm_rad_vlc
                             in zip(atm_keys, atm_rad_vlcs) if atm_rad_vlc)
    return atm_rad_keys
예제 #16
0
def resonance_avg_bond_orders(rgr):
    """ resonance-dominant bond orders, by bond
    """
    bnd_keys = list(_bond_keys(rgr))
    bnd_ords_by_res = [
        dict_.values_by_key(_bond_orders(dom_rgr), bnd_keys)
        for dom_rgr in dominant_resonances(rgr)]
    nres = len(bnd_ords_by_res)
    bnd_ords_lst = zip(*bnd_ords_by_res)
    avg_bnd_ord_lst = [sum(bnd_ords)/nres for bnd_ords in bnd_ords_lst]
    avg_bnd_ord_dct = dict(zip(bnd_keys, avg_bnd_ord_lst))
    return avg_bnd_ord_dct
예제 #17
0
def subresonances(rgr):
    """ this connected graph and its lower-spin (more pi-bonded) resonances
    """
    def _inc_range(bnd_cap):
        return tuple(range(0, bnd_cap+1))

    add_pi_bonds_ = functools.partial(_add_pi_bonds, rgr)

    atm_keys = list(_atom_keys(rgr))
    bnd_keys = list(_bond_keys(rgr))
    atm_unsat_vlcs = dict_.values_by_key(
        _atom_unsaturated_valences(rgr), atm_keys)
    atm_bnd_keys_lst = dict_.values_by_key(_atom_bond_keys(rgr), atm_keys)
    bnd_caps = dict_.values_by_key(_bond_capacities(rgr), bnd_keys)
    bnd_ord_dct = _bond_orders(rgr)

    def _is_valid(bnd_ord_inc_dct):
        # check if pi bonds exceed unsaturated valences
        def __tally(atm_bnd_keys):
            return sum(dict_.values_by_key(bnd_ord_inc_dct, atm_bnd_keys))
        atm_unsat_vlc_decs = tuple(map(__tally, atm_bnd_keys_lst))
        enough_elecs = numpy.all(
            numpy.less_equal(atm_unsat_vlc_decs, atm_unsat_vlcs))
        # check if all bond orders are less than 4 (should only affect C2)
        bnd_inc_keys = bnd_ord_inc_dct.keys()
        bnd_incs = dict_.values_by_key(bnd_ord_inc_dct, bnd_inc_keys)
        bnd_ords = dict_.values_by_key(bnd_ord_dct, bnd_inc_keys)
        new_bnd_ords = numpy.add(bnd_ords, bnd_incs)
        not_too_many = numpy.all(numpy.less(new_bnd_ords, 4))
        return enough_elecs and not_too_many

    def _bond_value_dictionary(bnd_vals):
        return dict(zip(bnd_keys, bnd_vals))

    bnd_ord_incs_itr = itertools.product(*map(_inc_range, bnd_caps))
    bnd_ord_inc_dct_itr = map(_bond_value_dictionary, bnd_ord_incs_itr)
    bnd_ord_inc_dct_itr = filter(_is_valid, bnd_ord_inc_dct_itr)
    rgrs = tuple(sorted(map(add_pi_bonds_, bnd_ord_inc_dct_itr), key=_frozen))
    return rgrs
예제 #18
0
def bonds_from_data(bond_keys, bond_orders=None, bond_stereo_parities=None):
    """ construct bond dictionary graph from data

    format:
        bnd_dct := {bnd_key: (bnd_ord, bnd_ste_par), ...}
        [where bnd_key := frozenset({atm1_key, atm2_key})]

    :param bond_keys: bond keys
    :type bond_keys: set
    :param bond_orders: bond orders, by bond key
    :type bond_orders: dict
    :param bond_stereo_parities: bond stereo parities, by bond key
    :type bond_stereo_parities: dict
    """
    keys = sorted(bond_keys)
    assert all(len(key) == 2 for key in keys)
    ords = dict_.values_by_key(dict_.empty_if_none(bond_orders),
                               keys,
                               fill_val=1)
    pars = dict_.values_by_key(dict_.empty_if_none(bond_stereo_parities),
                               keys,
                               fill_val=None)

    nbnds = len(keys)

    ords = [1] * nbnds if ords is None else list(ords)
    pars = [None] * nbnds if pars is None else list(pars)

    assert len(ords) == nbnds
    assert len(pars) == nbnds

    keys = list(map(frozenset, keys))
    ords = list(map(int, ords))

    assert all(par in (None, False, True) for par in pars)
    pars = [bool(par) if par is not None else par for par in pars]

    bnd_dct = dict(zip(keys, zip(ords, pars)))
    return bnd_dct
예제 #19
0
def resonance_dominant_radical_atom_keys(rgr):
    """ resonance-dominant radical atom keys

    (keys of resonance-dominant radical sites)
    """
    atm_keys = list(_atom_keys(rgr))
    atm_rad_vlcs_by_res = [
        dict_.values_by_key(_atom_unsaturated_valences(dom_rgr), atm_keys)
        for dom_rgr in dominant_resonances(rgr)]
    atm_rad_vlcs = [max(rad_vlcs) for rad_vlcs in zip(*atm_rad_vlcs_by_res)]
    atm_rad_keys = frozenset(atm_key for atm_key, atm_rad_vlc
                             in zip(atm_keys, atm_rad_vlcs) if atm_rad_vlc)
    return atm_rad_keys
예제 #20
0
def atom_bond_valences(xgr, bond_order=True):
    """ bond count (bond valence), by atom
    """
    atm_keys = list(atom_keys(xgr))
    xgr = explicit(xgr)
    if not bond_order:
        xgr = without_bond_orders(xgr)

    atm_nbhs = dict_.values_by_key(atom_neighborhoods(xgr), atm_keys)
    atm_bnd_vlcs = [sum(bond_orders(nbh).values()) for nbh in atm_nbhs]
    atm_bnd_vlc_dct = dict_.transform_values(dict(zip(atm_keys, atm_bnd_vlcs)),
                                             int)
    return atm_bnd_vlc_dct
예제 #21
0
def atoms_from_data(atom_symbols,
                    atom_implicit_hydrogen_valences=None,
                    atom_stereo_parities=None):
    """ construct atom dictionary from data

    format:
        atm_dct := {atm_key: (atm_sym, atm_imp_hyd_vlc, atm_ste_par), ...}

    :param atom_symbols: atomic symbols, by atom key
    :type atom_symbols: dict
    :param atom_implicit_hydrogen_valences: the number of implicit hydrogens
        associated with each atom, by atom key
    :type atom_implicit_hydrogen_valences: dict
    :param atom_stereo_parities: atom stereo parities, by atom key
    :type atom_stereo_parities: dict
    """
    keys = sorted(atom_symbols.keys())
    syms = dict_.values_by_key(atom_symbols, keys)
    vlcs = dict_.values_by_key(
        dict_.empty_if_none(atom_implicit_hydrogen_valences), keys, fill_val=0)
    pars = dict_.values_by_key(dict_.empty_if_none(atom_stereo_parities),
                               keys,
                               fill_val=None)

    natms = len(syms)
    vlcs = [0] * natms if vlcs is None else list(vlcs)
    pars = [None] * natms if pars is None else list(pars)

    assert len(vlcs) == natms
    assert len(pars) == natms

    syms = list(map(pt.to_E, syms))
    vlcs = list(map(int, vlcs))

    assert all(par in (None, False, True) for par in pars)
    pars = [bool(par) if par is not None else par for par in pars]

    atm_dct = dict(zip(keys, zip(syms, vlcs, pars)))
    return atm_dct
예제 #22
0
def inchi_with_sort_from_geometry(gra, geo=None, geo_idx_dct=None):
    """ connectivity graph => inchi conversion

    (if coordinates are passed in, they are used to determine stereo)
    """
    gra = automol.graph.without_dummy_atoms(gra)
    gra = automol.graph.dominant_resonance(gra)
    atm_keys = sorted(automol.graph.atom_keys(gra))
    bnd_keys = list(automol.graph.bond_keys(gra))
    atm_syms = dict_.values_by_key(automol.graph.atom_symbols(gra), atm_keys)
    atm_bnd_vlcs = dict_.values_by_key(automol.graph.atom_bond_valences(gra),
                                       atm_keys)
    atm_rad_vlcs = dict_.values_by_key(
        automol.graph.atom_unsaturated_valences(gra), atm_keys)
    bnd_ords = dict_.values_by_key(automol.graph.bond_orders(gra), bnd_keys)

    #print('geo test print:', automol.geom.string(automol.graph.geometry(gra)))

    if geo is not None:
        assert geo_idx_dct is not None
        atm_xyzs = automol.geom.coordinates(geo)
        atm_xyzs = [atm_xyzs[geo_idx_dct[atm_key]] for atm_key in atm_keys]
    else:
        atm_xyzs = None

    mlf, key_map_inv = _molfile.from_data(atm_keys,
                                          bnd_keys,
                                          atm_syms,
                                          atm_bnd_vlcs,
                                          atm_rad_vlcs,
                                          bnd_ords,
                                          atm_xyzs=atm_xyzs)
    rdm = _rdkit.from_molfile(mlf)
    ich, aux_info = _rdkit.to_inchi(rdm, with_aux_info=True)
    nums = _parse_sort_order_from_aux_info(aux_info)
    nums = tuple(map(key_map_inv.__getitem__, nums))
    return ich, nums
예제 #23
0
def _connected_heuristic_geometry(gra):
    """ stereo-specific coordinates for a connected molecular geometry
    """
    assert gra == explicit(gra)

    atm_keys = sorted(atom_keys(gra))

    zma, zma_key_dct = connected_heuristic_zmatrix(gra)

    geo = automol.zmatrix.geometry(zma)
    idxs = dict_.values_by_key(zma_key_dct, atm_keys)
    geo = automol.geom.from_subset(geo, idxs)
    geo_idx_dct = {atm_key: idx for idx, atm_key in enumerate(atm_keys)}

    return geo, geo_idx_dct
예제 #24
0
def from_graph(gra):
    """ igraph object from a molecular graph
    """
    atm_labels = sorted(automol.graph.atom_keys(gra))
    bnd_labels = list(sorted(map(sorted, automol.graph.bond_keys(gra))))

    atm_keys = atm_labels
    bnd_keys = list(map(frozenset, bnd_labels))

    atm_vals = dict_.values_by_key(automol.graph.atoms(gra), atm_keys)
    bnd_vals = dict_.values_by_key(automol.graph.bonds(gra), bnd_keys)

    atm_colors = list(itertools.starmap(_encode_vertex_attributes, atm_vals))
    bnd_colors = list(itertools.starmap(_encode_edge_attributes, bnd_vals))

    igr = igraph.Graph(bnd_labels)

    igr.vs['label'] = atm_labels
    igr.es['label'] = bnd_labels

    igr.vs['color'] = atm_colors
    igr.es['color'] = bnd_colors

    return igr
예제 #25
0
def _atom_stereo_parity_from_geometry(gra, atm_key, geo, geo_idx_dct):
    """ get the current stereo parity of an atom from its geometry
    """
    atm_ngb_keys_dct = atom_neighbor_keys(gra)
    atm_ngb_keys = atm_ngb_keys_dct[atm_key]

    # sort the neighbor keys by stereo priority
    atm_ngb_keys = stereo_sorted_atom_neighbor_keys(gra, atm_key, atm_ngb_keys)

    # determine the parity based on the coordinates
    xyzs = automol.geom.coordinates(geo)
    atm_ngb_idxs = dict_.values_by_key(geo_idx_dct, atm_ngb_keys)
    atm_ngb_xyzs = [xyzs[idx] for idx in atm_ngb_idxs]
    det_mat = numpy.ones((4, 4))
    det_mat[:, :3] = atm_ngb_xyzs
    det_val = numpy.linalg.det(det_mat)
    assert det_val != 0.  # for now, assume no four-atom planes
    par = det_val > 0.
    return par
예제 #26
0
def _start_zmatrix_from_ring(gra, rng_atm_keys):
    """ generates a z-matrix for a ring
    """
    # the key dictionary can be constructed immediately
    zma_key_dct = {
        atm_key: zma_key
        for zma_key, atm_key in enumerate(rng_atm_keys)
    }

    # now, build the z-matrix
    natms = len(rng_atm_keys)
    atm_sym_dct = atom_symbols(gra)

    dist_val = 1.5 * qcc.conversion_factor('angstrom', 'bohr')
    ang_val = (natms - 2.) * numpy.pi / natms
    dih_val = 0.

    # 1. construct the z-matrix for a 3-atom system
    key_mat = [[None, None, None], [0, None, None], [1, 0, None]]

    name_mat = [[None, None, None], ['R1', None, None], ['R2', 'A2', None]]

    syms = dict_.values_by_key(atm_sym_dct, rng_atm_keys[:3])

    val_dct = {'R1': dist_val, 'R2': dist_val, 'A2': ang_val}

    zma = automol.zmatrix.from_data(syms, key_mat, name_mat, val_dct)

    # 2. append z-matrix rows for the remaining atoms
    for row, rng_atm_key in enumerate(rng_atm_keys):
        if row > 2:
            sym = atm_sym_dct[rng_atm_key]
            dist_name = automol.zmatrix.new_distance_name(zma)
            ang_name = automol.zmatrix.new_central_angle_name(zma)
            dih_name = automol.zmatrix.new_dihedral_angle_name(zma)

            zma = automol.zmatrix.append(zma, sym, [row - 1, row - 2, row - 3],
                                         [dist_name, ang_name, dih_name],
                                         [dist_val, ang_val, dih_val])

    return zma, zma_key_dct
예제 #27
0
def branch_bond_keys(xgr, atm_key, bnd_key, saddle=False, ts_bnd=None):
    """ bond keys for branch extending along `bnd_key` away from `atm_key`
    """

    #bnd_key is the set of atom indices for the bond of interest
    # atm_bnd_keys_dct is a dictionary of atoms that are connected to each atom
    #    atm_bnd_keys_dct = atom_bond_keys(xgr)
    #    print('atm_bnd_keys_dct:', atm_bnd_keys_dct)

    #    bnch_bnd_keys = {bnd_key}
    #    seen_bnd_keys = set()
    # form set of keys of atoms connected to atm_key
    #    excl_bnd_keys = atm_bnd_keys_dct[atm_key]
    #    if bnd_key in excl_bnd_keys:
    #        excl_bnd_keys = excl_bnd_keys - {bnd_key}
    #    print('excl_bnd_keys:', excl_bnd_keys)
    #    new_bnd_keys = {bnd_key}
    #    bnd_ngb_keys_dct = bond_neighbor_keys(xgr)
    #    print('bnd_ngb_keys_dct:', bnd_ngb_keys_dct)
    #    if bnd_key not in bnd_ngb_keys_dct:
    #        for bnd in bnd_ngb_keys_dct:
    #            atmi, atmj = list(bnd)
    #            if atmi in list(ts_bnd) or atmj in list(ts_bnd):
    #                bnds = list(bnd_ngb_keys_dct[bnd])
    #                bnds.append(ts_bnd)
    #                bnd_ngb_keys_dct[bnd] = frozenset(bnds)
    #        bnd_ngb_keys_dct[bnd_key] = bond_neighbor_bonds(bnd_key, xgr)
    #    if saddle and bnd_key != ts_bnd:
    #        for bnd in bnd_ngb_keys_dct:
    #            atmi, atmj = list(bnd)
    #            if atmi in list(ts_bnd) or atmj in list(ts_bnd):
    #                bnds = list(bnd_ngb_keys_dct[bnd])
    #                bnds.append(ts_bnd)
    #                bnd_ngb_keys_dct[bnd] = frozenset(bnds)
    #        bnd_ngb_keys_dct[ts_bnd] = bond_neighbor_bonds(ts_bnd, xgr)
    bnd_key = frozenset(bnd_key)
    assert atm_key in bnd_key
    if not saddle:
        assert bnd_key in bond_keys(xgr)

    #print('xgr test:', xgr)
    #print('atm_key:', atm_key)
    #print('bnd_key:', bnd_key)
    #print('saddle:', saddle)
    #print('ts_bnd:', ts_bnd)

    atm_bnd_keys_dct = atom_bond_keys(xgr)

    bnch_bnd_keys = {bnd_key}
    seen_bnd_keys = set()
    excl_bnd_keys = atm_bnd_keys_dct[atm_key] - {bnd_key}

    new_bnd_keys = {bnd_key}

    #print('new_bnd_keys:', new_bnd_keys)
    bnd_ngb_keys_dct = bond_neighbor_keys(xgr)
    #print('bnd_ngb_keys_dct:', bnd_ngb_keys_dct)
    if ts_bnd:
        bnd_ngb_keys_dct[ts_bnd] = bond_neighbor_bonds(ts_bnd, xgr)
    #print('updated bnd_ngb_keys_dct:', bnd_ngb_keys_dct)
    while new_bnd_keys:
        new_bnd_ngb_keys = set(
            itertools.chain(
                *dict_.values_by_key(bnd_ngb_keys_dct, new_bnd_keys)))
        bnch_bnd_keys.update(new_bnd_ngb_keys - excl_bnd_keys)
        seen_bnd_keys.update(new_bnd_keys)
        new_bnd_keys = bnch_bnd_keys - seen_bnd_keys

    #print('branch bond keys:', bnch_bnd_keys)

    return frozenset(bnch_bnd_keys)
예제 #28
0
 def __tally(atm_bnd_keys):
     return sum(dict_.values_by_key(bnd_ord_inc_dct, atm_bnd_keys))