예제 #1
0
def bond_with_H_length(heavy, geom):
    element = heavy.element.name
    if element == "C":
        if geom == 4:
            return 1.09
        if geom == 3:
            return 1.08
        if geom == 2:
            return 1.056
    elif element == "N":
        return N_H
    elif element == "O":
        # can't rely on water being in chain "water" anymore...
        if heavy.num_bonds == 0 or heavy.num_bonds == 2 \
        and len([nb for nb in heavy.neighbors if nb.element.number > 1]) == 0:
            return 0.9572
        return 0.96
    elif element == "S":
        return 1.336
    from chimerax.atomic import Element
    return Element.bond_length(heavy.element, Element.get_element(1))
예제 #2
0
def hyd_positions(heavy, include_lone_pairs=False):
    """Return list of positions for hydrogens attached to this atom.
       If a hydrogen could be in one of several positions, don't return any of those.
    """

    # first, find known attached atoms
    bonded_heavys = []
    hyds = []
    for atom in heavy.neighbors:
        if atom.element.number > 1:
            bonded_heavys.append(atom)
        else:
            hyds.append(atom)

    # convert to Points
    hyd_locs = []
    for hyd in hyds:
        hyd_locs.append(hyd._hb_coord)

    if hyd_locs and not include_lone_pairs:
        # explicit hydrogens "win" over atom types
        return hyd_locs

    if heavy.idatm_type in type_info:
        info = type_info[heavy.idatm_type]
        geom = info.geometry
        if include_lone_pairs:
            subs = geom
        else:
            subs = info.substituents
        bonded_locs = hyd_locs[:]
        for b_heavy in bonded_heavys:
            bonded_locs.append(b_heavy._hb_coord)
    else:
        return hyd_locs

    known_subs = len(bonded_locs)
    if known_subs >= subs or known_subs == 0:
        return hyd_locs
    # above eliminates 'single' geometry

    if known_subs == 1 and geom == tetrahedral:
        # rotamer
        return hyd_locs

    max_subs = geom
    if max_subs - subs > 0:
        # the "empty" bond could be anywhere
        return hyd_locs

    heavy_loc = heavy._hb_coord
    bond_len = Element.bond_length(heavy.element, "H")

    if geom == planar:
        coplanar = []
        for b_heavy in bonded_heavys:
            try:
                bh_geom = type_info[b_heavy.idatm_type].geometry
            except KeyError:
                bh_geom = None
            if bh_geom != planar:
                continue
            for atom in b_heavy.neighbors:
                if atom != heavy:
                    coplanar.append(atom._hb_coord)

    else:
        coplanar = None

    hyd_locs = hyd_locs + list(
        bond_positions(heavy_loc, geom, bond_len, bonded_locs, coplanar=coplanar))
    return hyd_locs
예제 #3
0
def _find_donors(structure, d_params, limited_donors, generic_don_info):
    don_atoms = []
    don_data = []
    std_donors = {}
    for dp in d_params:
        group_key, donorIndex, geom_type, tau_sym, arg_list, test_dist = dp

        if group_key:
            groups = find_group(group_key, [structure])
        else:
            # generic donors
            groups = []
            for atom in structure.atoms:
                if atom in std_donors:
                    continue
                if atom.element.number not in [7, 8, 16]:
                    continue
                if limited_donors and atom not in limited_donors:
                    continue
                # oxygen, nitrogen, or sulfur
                try:
                    expect_bonds = type_info[atom.idatm_type].substituents
                except KeyError:
                    expect_bonds = 0
                num_bonds = atom.num_bonds
                # screen out the partial terminal N that AddH can leave, since the geometry is
                # problematic and the H direction isn't really determined
                if atom.idatm_type == "Npl" and num_bonds == 2 \
                and 1 in [n.element.number for n in atom.neighbors]:
                    continue
                if num_bonds < expect_bonds:
                    groups.append([atom])
                    continue
                for bonded in atom.neighbors:
                    if bonded.element.number == 1:
                        groups.append([atom])
                        break
            if verbose:
                for g in groups:
                    print("generic donor:", g[0])

        if groups and geom_type == theta_tau:
            # extend probe distance by H-bond length so that all relevant acceptors will be found
            test_dist = test_dist + Element.bond_length(
                groups[0][donorIndex].element, 'H')
        for group in groups:
            donor_atom = group[donorIndex]
            if limited_donors and donor_atom not in limited_donors:
                continue
            if donor_atom in std_donors:
                if group_key != std_donors[donor_atom] and not (
                        # conflicts of non-ring groups with ring
                        # groups not considered a problem (non-ring
                        # groups "win")
                        group_key[0] in _ring_funcs
                        and std_donors[donor_atom][0] not in _ring_funcs):
                    global _problem
                    _problem = ("donor", donor_atom, std_donors[donor_atom],
                                group_key)
                continue
            if donor_atom.is_missing_heavy_template_neighbors(
                    no_template_okay=True):
                global _truncated
                _truncated.add(donor_atom)
                continue
            std_donors[donor_atom] = group_key
            don_atoms.append(donor_atom)
            don_data.append((geom_type, tau_sym, arg_list, test_dist))
    return don_atoms, don_data
예제 #4
0
#    index of donor in group,
#    type of donor geometry
#    degree of tau symmetry
#    argument tuple used when geometry-check function is called
#
#    in argument tuple, conversions will occur before function gets called.
#    namely:
#        positive floats are assumed to be distances, and will be squared
#        integers are assumed to be angles in degrees, and will be
#            converted to radians

import sys
water = sys.intern("water")
theta_tau = sys.intern('theta_tau')
upsilon_tau = sys.intern('upsilon_tau')
OH_bond_dist = Element.bond_length("O", "H")

donor_params = [
    # neutral carboxylic acid
    [[['O3', ['Cac', H]], [1, 1, 0]], 0, upsilon_tau, 2,
     (2.87, 103, -128, 140, -30, 2.87, 103, -128, 155, -30, 150, 2.87, 103,
      -128, 140, -30, 150)],
    # protonated nitrogen double-bonded to carbon
    [
        [['Npl', [['C2', [explicit_single_bond, explicit_single_bond]], H, H]],
         [1, 1, 0, 0, 0, 0]],
        0,
        upsilon_tau,
        4,
        (
            3.17,