Ejemplo n.º 1
0
def calculate_residue_phi_psi_angles(prev, current, next, deg=True):
    """Calculate phi-psi angles for a set of three residues. Returns (phi, psi)."""
    phi = dihedral_angle(sites=extract_phi_sites(prev=prev, current=current),
                         deg=deg)
    psi = dihedral_angle(sites=extract_psi_sites(current=current, next=next),
                         deg=deg)
    return (phi, psi)
def should_be_flipped(residue_1, residue_2):
  """ are these residues in similar flip orientation?"""
  # assert residue_1.resname == residue_2.resname, "%s %s" % (
  #     residue_1.id_str(), residue_2.id_str())
  if residue_1.resname != residue_2.resname:
    # e.g. 1u54, 3srv: PTR mutation of TYR residues
    return False
  if residue_1.resname in flippable_sidechains:
    tor_1_sites = []
    for aname in flippable_sidechains[residue_1.resname][:4]:
      a = residue_1.find_atom_by(name=aname)
      if a is None:
        return False
      else:
        tor_1_sites.append(a.xyz)
    tor_23_sites = []
    for aname in flippable_sidechains[residue_1.resname][:5]:
      a = residue_2.find_atom_by(name=aname)
      if a is None:
        return False
      else:
        tor_23_sites.append(a.xyz)
    tor1 = dihedral_angle(
      sites=tor_1_sites,
      deg=True)
    tor2 = dihedral_angle(
      sites=tor_23_sites[:4],
      deg=True)
    tor3 = dihedral_angle(
      sites=tor_23_sites[:3]+[tor_23_sites[4]],
      deg=True)
    if tor1 is None or tor2 is None or tor3 is None:
      return False
    return abs(tor1-tor2) > abs(tor1-tor3)+5
  return False
Ejemplo n.º 3
0
def should_be_flipped(residue_1, residue_2):
  """ are these residues in similar flip orientation?"""
  # assert residue_1.resname == residue_2.resname, "%s %s" % (
  #     residue_1.id_str(), residue_2.id_str())
  if residue_1.resname != residue_2.resname:
    # e.g. 1u54, 3srv: PTR mutation of TYR residues
    return False
  if residue_1.resname in flippable_sidechains:
    tor_1_sites = []
    for aname in flippable_sidechains[residue_1.resname][:4]:
      a = residue_1.find_atom_by(name=aname)
      if a is None:
        return False
      else:
        tor_1_sites.append(a.xyz)
    tor_23_sites = []
    for aname in flippable_sidechains[residue_1.resname][:5]:
      a = residue_2.find_atom_by(name=aname)
      if a is None:
        return False
      else:
        tor_23_sites.append(a.xyz)
    tor1 = dihedral_angle(
      sites=tor_1_sites,
      deg=True)
    tor2 = dihedral_angle(
      sites=tor_23_sites[:4],
      deg=True)
    tor3 = dihedral_angle(
      sites=tor_23_sites[:3]+[tor_23_sites[4]],
      deg=True)
    if tor1 is None or tor2 is None or tor3 is None:
      return False
    return abs(tor1-tor2) > abs(tor1-tor3)+5
  return False
def should_be_flipped(residue_1, residue_2):
  """ are these residues in similar flip orientation?"""
  assert residue_1.resname == residue_2.resname
  if residue_1.resname in flippable_sidechains:

    tor_1_sites = []
    for aname in flippable_sidechains[residue_1.resname][:4]:
      a = residue_1.find_atom_by(name=aname)
      if a is None:
        return False
      else:
        tor_1_sites.append(a.xyz)

    tor_23_sites = []
    for aname in flippable_sidechains[residue_1.resname][:5]:
      a = residue_2.find_atom_by(name=aname)
      if a is None:
        return False
      else:
        tor_23_sites.append(a.xyz)

    tor1 = dihedral_angle(
      sites=tor_1_sites,
      deg=True)
    tor2 = dihedral_angle(
      sites=tor_23_sites[:4],
      deg=True)
    tor3 = dihedral_angle(
      sites=tor_23_sites[:3]+[tor_23_sites[4]],
      deg=True)

    return abs(tor1-tor2) > abs(tor1-tor3)+5
  return False
Ejemplo n.º 5
0
def get_peptide_bond_type(prev_Ca, prev_C, curr_N, curr_Ca):
    "Return the type of peptide bond"

    assert prev_Ca.name.strip() == 'CA'
    assert prev_C.name.strip() == 'C'
    assert curr_N.name.strip() == 'N'
    assert curr_Ca.name.strip() == 'CA'

    ang = dihedral_angle(
        sites=[a.xyz for a in (prev_Ca, prev_C, curr_N, curr_Ca)], deg=True)
    ang = numpy.round(ang, 2)

    if curr_N.parent().resname == 'PRO':
        cis, trans = ('PCIS', 'PTRANS')
    else:
        cis, trans = ('CIS', 'TRANS')

    # Use lenient angle tolerances to detect CIS or TRANS
    if angle_difference(a1=0, a2=ang, deg=True, abs_val=True) < 45:
        bond_type = cis
    elif angle_difference(a1=180, a2=ang, deg=True, abs_val=True) < 45:
        bond_type = trans
    else:
        print 'WARNING: BOND IS NOT CIS OR TRANS (angle {:7}) for link between {} and {} - DEFAULTING TO TRANS'.format(
            ang, prev_C.id_str(), curr_N.id_str())
        bond_type = trans

    return bond_type
Ejemplo n.º 6
0
 def find_third_neighbors(self, dihedral_proxies):
     """ Loop through dihedral angle proxies to find third neighbor
 Fill in neighbors.b1 with iseq and angle proxy"""
     for dp in dihedral_proxies:
         for i_test in dp.i_seqs:
             if (self.h_connectivity[i_test] is None
                     and not self.hd_sel[i_test]):
                 continue
             ih = i_test
             i1, i2, i3, i4 = dp.i_seqs
             if (ih == i1):
                 i_third = i4
             if (ih == i4):
                 i_third = i1
             dihedral = dihedral_angle(sites=[
                 self.sites_cart[i1], self.sites_cart[i2],
                 self.sites_cart[i3], self.sites_cart[i4]
             ])
             if dihedral is None:
                 return
             dihedral_id = dp.angle_ideal
             delta = geometry_restraints.angle_delta_deg(
                 angle_1=math.degrees(dihedral),
                 angle_2=dihedral_id,
                 periodicity=dp.periodicity)
             dihedral_ideal = math.degrees(dihedral) + delta
             b1 = {'iseq': i_third, 'dihedral_ideal': dihedral_ideal}
             self.h_connectivity[ih].b1 = b1
             self.assign_b1_for_H_atom_groups(ih=ih, i_third=i_third)
Ejemplo n.º 7
0
 def get_omega_value(
     self,
     omega_cdl=False,
 ):
     #
     # this is very poor! there needs to be a better way to check for cis-
     #
     for i, residue in enumerate(self):
         if i == 0: continue
         if omega_cdl:
             if len(self) == 3:
                 if i == 1: continue
         else:
             if i == 2: continue
         ccn1, outl1 = get_c_ca_n(residue, return_subset=True)
         ccn2, outl2 = get_c_ca_n(self[i - 1], return_subset=True)
         ca1 = ccn1[1]
         n = ccn1[2]
         c = ccn2[0]
         ca2 = ccn2[1]
         omega_atoms = [ca1, n, c, ca2]
         if None in omega_atoms: return None
         omega = dihedral_angle(sites=[atom.xyz for atom in omega_atoms],
                                deg=True)
         return omega
Ejemplo n.º 8
0
def add_c_terminal_oxygens_to_atom_group(ag,
                                         use_capping_hydrogens=False,
                                         append_to_end_of_model=False,
                                         c_ca_n=None,
                                        ):
  #
  # do we need ANISOU
  #
  rc = []
  atom_name=' OXT'
  atom_element = 'O'
  bond_length=1.231
  if use_capping_hydrogens:
    if ag.get_atom(atom_name.strip()): return []
    atom_name=" HC "
    atom_element="H"
    bond_length=1.
  if ag.get_atom(atom_name.strip()): return []
  if c_ca_n is not None:
    c, ca, n = c_ca_n
  else:
    c = ag.get_atom("C")
    if c is None: return
    ca = ag.get_atom("CA")
    if ca is None: return
    n = ag.get_atom("N")
    if n is None: return
  atom = ag.get_atom('O')
  dihedral = dihedral_angle(sites=[atom.xyz,
                                   c.xyz,
                                   ca.xyz,
                                   n.xyz,
                                 ],
                            deg=True)
  ro2 = construct_xyz(c, bond_length,
                      ca, 120.,
                      n, dihedral,
                      period=2,
                     )
  oxys = [' O  ', atom_name]
  for i in range(0,2):
    name = oxys[i]
    atom = ag.get_atom(name.strip())
    if atom:
      pass #atom.xyz = ro2[i]
    else:
      atom = iotbx.pdb.hierarchy.atom()
      atom.name = name
      atom.element = atom_element
      atom.occ = c.occ
      atom.b = c.b
      atom.segid = ' '*4
      atom.xyz = ro2[i]
      if append_to_end_of_model:
        chain = _add_atom_to_chain(atom, ag)
        rc.append(chain)
      else:
        # add the atom to the hierarchy
        ag.append_atom(atom)
  return rc
def add_side_chain_acid_hydrogens_to_atom_group(
    atom_group,
    anchors=None,
    configuration_index=0,
    bond_length=0.95,
    element='H',
):
    """Add hydrogen atoms to side-chain acid in place

  Args:
      atom_group (TYPE): Atom group
      anchors (None, optional): Atoms that specify the acids moeity
      configuration_index (int, optional): Configuration to return

  """
    assert element in ['H', 'D']
    c, o1, o2 = anchors
    if configuration_index >= 2:
        tmp = o1.name
        o1.name = o2.name
        o2.name = tmp
        tmp = o1
        o1 = o2
        o2 = tmp
        configuration_index = configuration_index % 2
    if o2.name == ' OD2':
        name = ' HD2'
        atom = atom_group.get_atom('CB')
    elif o2.name == ' OE2':
        name = ' HE2'
        atom = atom_group.get_atom('CG')
    else:
        assert 0
    if element == 'D': name = name.replace('H', 'D')
    dihedral = dihedral_angle(sites=[
        atom.xyz,
        c.xyz,
        o1.xyz,
        o2.xyz,
    ],
                              deg=True)
    ro2 = construct_xyz(
        o2,
        bond_length,
        c,
        120.,
        o1,
        dihedral,
        period=2,
    )
    i = configuration_index
    atom = atom_group.get_atom(name.strip())
    if atom:
        pass  #atom.xyz = ro2[i]
    else:
        atom = new_atom_with_inheritance(name, element, ro2[i], o2)
        atom_group.append_atom(atom)
Ejemplo n.º 10
0
def get_dihedral_angle(atoms, round_coords=False):
  # round here is to emulate rounding when dumping to pdb, to get more
  # consistent result for rama outliers inside program and when calculating
  # from resulted pdb file.
  sites = []
  if round_coords:
    for x in atoms:
      sites.append((round(x.xyz[0], 3), round(x.xyz[1], 3), round(x.xyz[2], 3)))
  else:
    sites = [x.xyz for x in atoms]
  return dihedral_angle(
      sites = sites,
      deg=True)
Ejemplo n.º 11
0
def get_torsion(ag1, ag2, an1, an2, limits='-180-180'):
    from scitbx.math import dihedral_angle
    atoms = _get_atoms(ag1, an1) + _get_atoms(ag2, an2)
    omega = dihedral_angle(sites=[atom.xyz for atom in atoms], deg=True)
    if limits == '-180-180':
        if omega > 180:
            print(omega, limits)
            assert 0
    elif limits == '0-360':
        if omega < 0:
            omega += 360
    # for atom in atoms: print atom.quote()
    return omega
Ejemplo n.º 12
0
def add_main_chain_o_to_atom_group(ag, c_ca_n=None):
    # cetral functuon
    if c_ca_n is not None:
        c, ca, n = c_ca_n
    else:
        c = ag.get_atom("C")
        if c is None: return
        ca = ag.get_atom("CA")
        if ca is None: return
        n = ag.get_atom("N")
        if n is None: return
    atom = ag.get_atom('O')
    dihedral = dihedral_angle(sites=[
        atom.xyz,
        c.xyz,
        ca.xyz,
        n.xyz,
    ],
                              deg=True)
    ro2 = construct_xyz(
        c,
        bond_length,
        ca,
        120.,
        n,
        dihedral,
        period=2,
    )
    oxys = [' O  ', atom_name]
    for i in range(0, 2):
        name = oxys[i]
        atom = ag.get_atom(name.strip())
        if atom:
            pass  #atom.xyz = ro2[i]
        else:
            atom = iotbx.pdb.hierarchy.atom()
            atom.name = name
            atom.element = atom_element
            atom.occ = c.occ
            atom.b = c.b
            atom.segid = ' ' * 4
            atom.xyz = ro2[i]
            if append_to_end_of_model:
                chain = _add_atom_to_chain(atom, ag)
                rc.append(chain)
            else:
                # add the atom to the hierarchy
                ag.append_atom(atom)

    #for
    assert atom
Ejemplo n.º 13
0
def get_dihedral_angle(atoms, round_coords=False):
    # round here is to emulate rounding when dumping to pdb, to get more
    # consistent result for rama outliers inside program and when calculating
    # from resulted pdb file.
    if atoms is None:
        return None
    sites = []
    if round_coords:
        for x in atoms:
            sites.append((round(x.xyz[0], 3), round(x.xyz[1],
                                                    3), round(x.xyz[2], 3)))
    else:
        sites = [x.xyz for x in atoms]
    return dihedral_angle(sites=sites, deg=True)
Ejemplo n.º 14
0
 def check_for_plane_proxy(self, ih):
   neighbors = self.h_connectivity[ih]
   a0 = neighbors.a0['iseq']
   a1 = neighbors.a1['iseq']
   b1 = neighbors.b1['iseq']
   if (neighbors.h1 and not neighbors.h2): # if there is only 1 H atom as second neighbor
     ih2 = neighbors.h1['iseq']
     if ('dihedral_ideal' not in neighbors.b1 or
         'dihedral_ideal' not in self.h_connectivity[ih2].b1):
       if ih in self.plane_h:
         dihedral = dihedral_angle(
               sites = [self.sites_cart[ih], self.sites_cart[a0],
               self.sites_cart[a1],self.sites_cart[b1]])
         neighbors.b1['dihedral_ideal'] = math.degrees(dihedral)
Ejemplo n.º 15
0
def get_omega_value(residue1, residue2, verbose=False):
    ccn1, outl1 = get_c_ca_n(residue1, return_subset=True)
    ccn2, outl2 = get_c_ca_n(residue2, return_subset=True)
    ca1 = ccn1[1]
    n = ccn1[2]
    c = ccn2[0]
    ca2 = ccn2[1]
    omega_atoms = [ca1, n, c, ca2]
    if verbose:
        for atom in omega_atoms:
            print(atom.quote())
    if None in omega_atoms: return None
    omega = dihedral_angle(sites=[atom.xyz for atom in omega_atoms], deg=True)
    return omega
Ejemplo n.º 16
0
def get_ca_dihedrals(residues, verbose=False):
    assert len(residues) >= 4
    dihedrals = []
    atoms = []
    for residue in residues:
        atoms.append(residue.find_atom_by(name=' CA '))
        if len(atoms) == 4:
            if verbose:
                print('CAs')
                for atom in atoms:
                    print(atom.quote())
            dihedrals.append(
                dihedral_angle(sites=[atom.xyz for atom in atoms], deg=True))
            del atoms[0]
    return dihedrals
Ejemplo n.º 17
0
def get_phi_psi_angles(residues, verbose=False):
    assert len(residues) >= 3
    dihedrals = []
    for i in range(len(residues)):
        if i < 2: continue
        atoms = get_phi_psi_atoms(*tuple(residues[i - 2:i + 1]),
                                  verbose=verbose)
        if atoms is None: return None
        for dihedral in atoms:
            phi_or_psi = dihedral_angle(sites=[atom.xyz for atom in dihedral],
                                        deg=True)
            dihedrals.append(phi_or_psi)
    if verbose:
        print('dihedrals')
        for phi_or_psi in dihedrals:
            print('phi_or_psi', phi_or_psi)
    return dihedrals
Ejemplo n.º 18
0
 def get_phi_psi_angles(self,
                        only_psi_phi_pairs=True,
                        force_plus_one=False,
                        omega_cdl=False,
                        verbose=False,
                        ):
   atoms = self.get_phi_psi_atoms(only_psi_phi_pairs=only_psi_phi_pairs,
                                  force_plus_one=force_plus_one,
                                  omega_cdl=omega_cdl,
                                 )
   dihedrals = []
   for dihedral in atoms:
     phi_or_psi=dihedral_angle(sites=[atom.xyz for atom in dihedral], deg=True)
     dihedrals.append(phi_or_psi)
   if verbose:
     for phi_or_psi in dihedrals:
       print 'phi_or_psi',phi_or_psi
   return dihedrals
Ejemplo n.º 19
0
 def get_phi_psi_angles(self,
                        only_psi_phi_pairs=True,
                        force_plus_one=False,
                        omega_cdl=False,
                        verbose=False,
                        ):
   atoms = self.get_phi_psi_atoms(only_psi_phi_pairs=only_psi_phi_pairs,
                                  force_plus_one=force_plus_one,
                                  omega_cdl=omega_cdl,
                                 )
   if atoms is None: return None
   dihedrals = []
   for dihedral in atoms:
     phi_or_psi=dihedral_angle(sites=[atom.xyz for atom in dihedral], deg=True)
     dihedrals.append(phi_or_psi)
   if verbose:
     for phi_or_psi in dihedrals:
       print 'phi_or_psi',phi_or_psi
   return dihedrals
Ejemplo n.º 20
0
 def cis_group(self, limit=45., verbose=False):
   cis_peptide_bond = False
   for i, residue in enumerate(self):
     if i==0: continue
     if i==2: continue # only check the middle omega angle
     ccn1, outl1 = get_c_ca_n(residue)
     ccn2, outl2 = get_c_ca_n(self[i-1])
     ca1 = ccn1[1]
     n = ccn1[2]
     c = ccn2[0]
     ca2 = ccn2[1]
     omega_atoms = [ca1, n, c, ca2]
     omega = dihedral_angle(sites=[atom.xyz for atom in omega_atoms], deg=True)
     if (180.-abs(omega))>limit:
       cis_peptide_bond = True
       break
   if verbose:
     if cis_peptide_bond:
       print 'cis peptide bond', cis_peptide_bond, omega
       print self
   return cis_peptide_bond
Ejemplo n.º 21
0
 def get_omega_value(self,
                     omega_cdl=False,
                    ):
   #
   # this is very poor! there needs to be a better way to check for cis-
   #
   for i, residue in enumerate(self):
     if i==0: continue
     if omega_cdl:
       if len(self)==3:
         if i==1: continue
     else:
       if i==2: continue
     ccn1, outl1 = get_c_ca_n(residue, return_subset=True)
     ccn2, outl2 = get_c_ca_n(self[i-1], return_subset=True)
     ca1 = ccn1[1]
     n = ccn1[2]
     c = ccn2[0]
     ca2 = ccn2[1]
     omega_atoms = [ca1, n, c, ca2]
     if None in omega_atoms: return None
     omega = dihedral_angle(sites=[atom.xyz for atom in omega_atoms], deg=True)
     return omega
 def process_1_neighbor(self, neighbors):
     ih = neighbors.ih
     # if used for hydrogenate, make sure that first we use the H with dihedral angle
     # However, this needs some tweaking for neutron H/D situations
     if (neighbors.number_h_neighbors == 2):
         i_h1, i_h2 = neighbors.h1['iseq'], neighbors.h2['iseq']
         if ('dihedral_ideal' in neighbors.b1):
             neighbors = self.h_connectivity[ih]
         elif ('dihedral_ideal' in self.h_connectivity[i_h1].b1):
             if self.h_parameterization[i_h1] is None:
                 neighbors = self.h_connectivity[i_h1]
         elif ('dihedral_ideal' in self.h_connectivity[i_h2].b1):
             if self.h_parameterization[i_h2] is None:
                 neighbors = self.h_connectivity[i_h2]
     ih = neighbors.ih
     #print(self.site_labels[ih])
     i_a0 = neighbors.a0['iseq']
     rh = matrix.col(self.sites_cart[ih])
     r0 = matrix.col(self.sites_cart[i_a0])
     if self.use_ideal_bonds_angles:
         disth = neighbors.a0['dist_ideal']
     else:
         disth = (r0 - rh).length()
     if (not neighbors.a1 or not neighbors.b1):
         self.unk_list.append(ih)
         return
     i_a1 = neighbors.a1['iseq']
     i_b1 = neighbors.b1['iseq']
     r1 = matrix.col(self.sites_cart[i_a1])
     rb1 = matrix.col(self.sites_cart[i_b1])
     self.check_if_atoms_superposed(rh, r0, ih, i_a0)
     self.check_if_atoms_superposed(r1, r0, i_a1, i_a0)
     uh0 = (rh - r0).normalize()
     u10 = (r1 - r0).normalize()
     dihedral = dihedral_angle(sites=[
         self.sites_cart[ih], self.sites_cart[i_a0], self.sites_cart[i_a1],
         self.sites_cart[i_b1]
     ])
     if self.use_ideal_bonds_angles:
         alpha = math.radians(neighbors.a1['angle_ideal'])
         #allow for rotation even for idealize = True
         phi = dihedral
         if self.use_ideal_dihedral:
             #phi = math.radians(b1.dihedral_ideal)
             if 'dihedral_ideal' in neighbors.b1:
                 phi = math.radians(neighbors.b1['dihedral_ideal'])
     else:
         alpha = (u10).angle(uh0)
         phi = dihedral
     #print(math.degrees(phi))
     u1 = (r0 - r1).normalize()
     rb10 = rb1 - r1
     # TODO check needed?
     u2 = (rb10 - ((rb10).dot(u1)) * u1).normalize()
     u3 = u1.cross(u2)
     if (neighbors.number_h_neighbors == 0):
         self.h_parameterization[ih] = riding_coefficients(htype='alg1b',
                                                           ih=ih,
                                                           a0=i_a0,
                                                           a1=i_a1,
                                                           a2=i_b1,
                                                           a3=-1,
                                                           a=alpha,
                                                           b=phi,
                                                           h=0,
                                                           n=0,
                                                           disth=disth)
     if (neighbors.number_h_neighbors == 2):
         i_h1, i_h2 = neighbors.h1['iseq'], neighbors.h2['iseq']
         i_h1, i_h2 = self.check_propeller_order(i_a0=i_a0,
                                                 i_a1=i_a1,
                                                 ih=ih,
                                                 i_h1=i_h1,
                                                 i_h2=i_h2)
         for nprop, hprop in zip([0, 1, 2], [ih, i_h1, i_h2]):
             self.h_parameterization[hprop] = riding_coefficients(
                 htype='prop',
                 ih=hprop,
                 a0=i_a0,
                 a1=i_a1,
                 a2=i_b1,
                 a3=-1,
                 a=alpha,
                 n=nprop,
                 b=phi,
                 h=0,
                 disth=disth)
 def process_1_neighbor_type_arg(self, neighbors):
     """
   alg1a: X-H2 planar groups, such as in ARG, ASN, GLN
   requires that dihedral angle restraint exists for at least one H atom
 """
     ih = neighbors.ih
     i_h1 = neighbors.h1['iseq']
     i_a0 = neighbors.a0['iseq']
     rh = matrix.col(self.sites_cart[ih])
     r0 = matrix.col(self.sites_cart[i_a0])
     if self.use_ideal_bonds_angles:
         disth = neighbors.a0['dist_ideal']
     else:
         disth = (r0 - rh).length()
     i_a1 = neighbors.a1['iseq']
     r1 = matrix.col(self.sites_cart[i_a1])
     if ('dihedral_ideal' in neighbors.b1):
         ih_dihedral = ih
         ih_no_dihedral = i_h1
     else:
         if ('dihedral_ideal' in self.h_connectivity[i_h1].b1):
             ih_dihedral = i_h1
             ih_no_dihedral = ih
         else:
             self.unk_list.append(ih)
             return
     i_b1 = self.h_connectivity[ih_dihedral].b1['iseq']
     rb1 = matrix.col(self.sites_cart[i_b1])
     # check if angle is typical for propeller
     # catches case of missing propeller atom
     if (neighbors.h1['angle_ideal'] > 107
             and neighbors.h1['angle_ideal'] < 111):
         self.unk_list.append(ih)
     else:
         dihedral = dihedral_angle(sites=[
             self.sites_cart[i_b1], self.sites_cart[i_a1],
             self.sites_cart[i_a0], self.sites_cart[ih_dihedral]
         ])
         self.check_if_atoms_superposed(rh, r0, ih, i_a0)
         self.check_if_atoms_superposed(r1, r0, i_a1, i_a0)
         uh0 = (rh - r0).normalize()
         u10 = (r1 - r0).normalize()
         if self.use_ideal_bonds_angles:
             alpha = math.radians(neighbors.a1['angle_ideal'])
             phi = math.radians(
                 self.h_connectivity[ih_dihedral].b1['dihedral_ideal'])
         else:
             alpha = (u10).angle(uh0)
             phi = dihedral
         u1 = (r0 - r1).normalize()
         rb10 = rb1 - r1
         # TODO check needed?
         u2 = (rb10 - ((rb10).dot(u10)) * u10).normalize()
         u3 = u1.cross(u2)
         for ih_alg1a, phi_alg1a in zip([ih_dihedral, ih_no_dihedral],
                                        [phi, phi + math.pi]):
             if self.h_parameterization[ih_alg1a] is None:
                 self.h_parameterization[ih_alg1a] = riding_coefficients(
                     htype='alg1a',
                     ih=ih_alg1a,
                     a0=i_a0,
                     a1=i_a1,
                     a2=i_b1,
                     a3=-1,
                     a=alpha,
                     b=phi_alg1a,
                     n=0,
                     h=0,
                     disth=disth)
Ejemplo n.º 24
0
def determine_H_neighbors(geometry_restraints, bond_proxies, angle_proxies,
  dihedral_proxies, hd_selection, sites_cart, atoms):
  fsc2=geometry_restraints.shell_sym_tables[2].full_simple_connectivity()
  fsc1=geometry_restraints.shell_sym_tables[1].full_simple_connectivity()
  #fsc0=geometry_restraints.shell_sym_tables[0].full_simple_connectivity()
  # Maybe there is better way to get number of atoms?
  n_atoms = len(sites_cart)
  connectivity = {}
  # loop through bond proxies to find H atom and parent atom
  for bproxy in bond_proxies:
    i_seq, j_seq = bproxy.i_seqs
    is_i_hd = hd_selection[i_seq]
    is_j_hd = hd_selection[j_seq]
    if(not is_i_hd and not is_j_hd): continue
    elif(is_i_hd and is_j_hd):       assert 0
    else:
      if  (is_i_hd): ih, i_parent = i_seq, j_seq
      elif(is_j_hd): ih, i_parent = j_seq, i_seq
      else:
        raise Sorry("Something went wrong in bond proxies")
    rh = matrix.col(sites_cart[ih])
    r0 = matrix.col(sites_cart[i_parent])
    dist = (r0 - rh).length()
    parent = atom_info(
      iseq       = i_parent,
      dist_ideal = bproxy.distance_ideal,
      dist       = dist)
    altloc_h = atoms[ih].parent().altloc
    connectivity[ih]=[parent]
    # this is connectivity[ih][1] --> list of second non-H neighbours
    connectivity[ih].append([])
    # this is connectivity[ih][2] --> list of second H/D neighbours
    connectivity[ih].append([])
    # find second neighbors
    second_neighbors = list(fsc1[ih])
    count_H = 0
    altconf_dict = {}
    for i_second in second_neighbors:
      iselection = flex.size_t([ih,i_parent,i_second])
      ap = angle_proxies.proxy_select(
        n_seq      = n_atoms,
        iselection = iselection)
      # check if angle proxy exists = check that list ap is not empty
      if ap:
        altloc_i_second = atoms[i_second].parent().altloc
        #rint atoms[i_second].name, atoms[i_second].parent().altloc, atoms[i_second].parent().parent().resseq
        #ag_isecond = atoms[i_second].parent().parent().atom_groups()
        if ((altloc_i_second != altloc_h and altloc_i_second != 'A') and altloc_h ==''):
          continue
        neighbor = atom_info(
          iseq = i_second,
          angle_ideal = ap[0].angle_ideal)
        if (hd_selection[i_second]):
          connectivity[ih][2].append(neighbor)
          count_H = count_H + 1
        else:
          connectivity[ih][1].append(neighbor)
    (connectivity[ih][0]).count_H = count_H
    # find third neighbors, if necessary
    if (len(connectivity[ih][1]) == 1):
      connectivity[ih].append([])
      i_second = ((connectivity[ih][1])[0]).iseq
      third_neighbors = list(fsc2[ih])
      third_no_dihedrals = []
      for i_third in third_neighbors:
        if (not hd_selection[i_third]):
          iselection = flex.size_t([i_parent,i_second,i_third])
          ap = angle_proxies.proxy_select(
            n_seq      = n_atoms,
            iselection = iselection)
          if ap:
            iselection_dihe = flex.size_t([ih,i_parent,i_second,i_third])
            dp = dihedral_proxies.proxy_select(
              n_seq      = n_atoms,
              iselection = iselection_dihe)
            if dp:
              dihedral_id = dp[0].angle_ideal
              dihedral = dihedral_angle(
                sites=[sites_cart[i_third], sites_cart[i_second],
                sites_cart[i_parent],sites_cart[ih]])
              sites_cart_dihe = sites_cart.select(iselection_dihe).deep_copy()
              delta = dp.deltas(sites_cart=sites_cart_dihe)[0]
              dihedral_ideal = math.degrees(dihedral) + delta
              neighbor = atom_info(
                iseq           = i_third,
                dihedral       = dihedral,
                dihedral_ideal = dihedral_ideal)
              #print dihedral_id, delta, math.degrees(dihedral), dihedral_ideal
              connectivity[ih][3].append(neighbor)
            else:
              neighbor = atom_info(
                iseq = i_third)
              third_no_dihedrals.append(neighbor)
      if (not connectivity[ih][3]):
        connectivity[ih][3] = third_no_dihedrals
    if (len(connectivity[ih][1]) == 2):
      reduced_neighbs = connectivity[ih][1]
      ix = i_parent
      iy = (reduced_neighbs[0]).iseq
      iz = (reduced_neighbs[1]).iseq
      iselection = flex.size_t([ix,iy,iz])
      (connectivity[ih][0]).angle_ideal =  angle_proxies.proxy_select(
        n_seq      = n_atoms,
        iselection = iselection)[0].angle_ideal
    if (len(connectivity[ih][1]) == 3):
    # for tetrahedral, all 3 ideal angles are needed
      reduced_neighbs = connectivity[ih][1]
      angles = []
      ix = i_parent
      _list = [(0,1),(1,2),(2,0)]
      for _i,_j in _list:
        iy = (reduced_neighbs[_i]).iseq
        iz = (reduced_neighbs[_j]).iseq
        iselection = flex.size_t([ix,iy,iz])
        ap = angle_proxies.proxy_select(
          n_seq      = n_atoms,
          iselection = iselection)
        if ap:
          angles.append(ap[0].angle_ideal)
        (connectivity[ih][0]).angle_ideal = angles
  return connectivity
Ejemplo n.º 25
0
def get_h_parameterization(h_connectivity, sites_cart, use_ideal_bonds_angles):
    h_parameterization = {}
    n_atoms = len(sites_cart)
    for ih in h_connectivity.keys():
        #if (ih != 22):
        #  continue
        #for debugging
        #print 'atom:', names[ih]+' ('+str(ih)+ ') residue:', \
        #  atoms_list[ih].resseq, 'chain', atoms_list[ih].chain_id
        # if entry exists already, skip it
        if ih in h_parameterization.keys():
            continue
        a0 = h_connectivity[ih][0]
        count_H = a0.count_H
        reduced_neighbs = h_connectivity[ih][1]
        n_red_neigbs = len(reduced_neighbs)
        rh = matrix.col(sites_cart[ih])
        r0 = matrix.col(sites_cart[a0.iseq])
        if use_ideal_bonds_angles:
            dist_h = a0.dist_ideal
        else:
            dist_h = (r0 - rh).length()
    # alg2a, 2tetra, 2neigbs
        if (n_red_neigbs == 2):
            a1, a2 = reduced_neighbs[0], reduced_neighbs[1]
            # if H is second neighbor, gets its index
            if (count_H == 1):
                hlist = h_connectivity[ih][2]
                if hlist:
                    ih2 = (hlist[0])
                    i_h2 = (hlist[0]).iseq
            else:
                ih2 = None
            sumang, a, b, h, root = get_coefficients(
                ih=ih,
                a0=a0,
                a1=a1,
                a2=a2,
                ih2=ih2,
                use_ideal_bonds_angles=use_ideal_bonds_angles,
                sites_cart=sites_cart,
                typeh='alg2')
            h_parameterization[ih] = parameterization_info(a0=a0.iseq,
                                                           a1=a1.iseq,
                                                           a2=a2.iseq,
                                                           a=a,
                                                           b=b,
                                                           dist_h=dist_h)
            # alg2a
            if (sumang > (2 * math.pi + 0.05) and root < 0):
                h_parameterization[ih].htype = 'unk_ideal'
            elif (sumang < (2 * math.pi + 0.05)
                  and (sumang > 2 * math.pi - 0.05)):
                h_parameterization[ih].htype = 'flat_2neigbs'
            else:
                if (count_H == 1):
                    # 2 tetragonal geometry
                    h_parameterization[ih].htype = '2tetra'
                    h_parameterization[ih].alpha = h
                    h_parameterization[i_h2] = parameterization_info(
                        a0=a0.iseq,
                        a1=a1.iseq,
                        a2=a2.iseq,
                        a=a,
                        b=b,
                        alpha=-h,
                        dist_h=dist_h,
                        htype='2tetra')
                else:
                    # 2neigbs
                    h_parameterization[ih].h = h
                    h_parameterization[ih].htype = '2neigbs'
        # tetragonal geometry: 3neigbs
        elif (n_red_neigbs == 3 and count_H == 0):
            a1, a2, a3 = reduced_neighbs[0], reduced_neighbs[
                1], reduced_neighbs[2]
            a, b, h = get_coefficients_alg3(
                rh=rh,
                a0=a0,
                a1=a1,
                a2=a2,
                a3=a3,
                use_ideal_bonds_angles=use_ideal_bonds_angles,
                sites_cart=sites_cart)
            h_parameterization[ih] = parameterization_info(a0=a0.iseq,
                                                           a1=a1.iseq,
                                                           a2=a2.iseq,
                                                           a3=a3.iseq,
                                                           a=a,
                                                           b=b,
                                                           h=h,
                                                           dist_h=dist_h,
                                                           htype='3neigbs')
        # alg1a: X-H2 planar groups, such as in ARG, ASN, GLN
        # requires that dihedral angle restraint exists for at least one H atom
        elif (n_red_neigbs == 1 and count_H == 1
              and len(h_connectivity[ih]) == 4):
            b1 = None
            a1 = reduced_neighbs[0]
            r1 = matrix.col(sites_cart[a1.iseq])
            hlist = h_connectivity[ih][2]
            ih_2 = hlist[0].iseq
            for b1_test in h_connectivity[ih][3]:
                if (b1_test.dihedral_ideal is None):
                    continue
                else:
                    b1 = b1_test
            if (b1 == None):
                for b1_test in h_connectivity[ih_2][3]:
                    if (b1_test.dihedral_ideal is None):
                        continue
                    else:
                        b1 = b1_test
                        ih, ih_2 = ih_2, ih
            if (b1 == None):
                h_parameterization[ih] = parameterization_info(htype='unk',
                                                               a0=a0.iseq)
                continue
            # check if angle is typical for propeller
            # catches case of missing propeller atom
            if (hlist[0].angle_ideal > 107 and hlist[0].angle_ideal < 111):
                h_parameterization[ih] = parameterization_info(htype='unk',
                                                               a0=a0.iseq)
                h_parameterization[ih_2] = parameterization_info(htype='unk',
                                                                 a0=a0.iseq)
                continue
            dihedral = dihedral_angle(sites=[
                sites_cart[b1.iseq], sites_cart[a1.iseq], sites_cart[a0.iseq],
                sites_cart[ih]
            ])
            #print 'dihedrals', a0.dihedral, dihedral, a0.dihedral_ideal
            rb1 = matrix.col(sites_cart[b1.iseq])
            uh0 = (rh - r0).normalize()
            u10 = (r1 - r0).normalize()
            if use_ideal_bonds_angles:
                alpha = math.radians(a1.angle_ideal)
                phi = math.radians(b1.dihedral_ideal)
                #phi = dihedral
            else:
                alpha = (u10).angle(uh0)
                #phi = a0.dihedral
                phi = dihedral
            u1 = (r0 - r1).normalize()
            rb10 = rb1 - r1
            u2 = (rb10 - ((rb10).dot(u10)) * u10).normalize()
            u3 = u1.cross(u2)
            #print names[ih], names[b1.iseq], names[a1.iseq]
            if ih not in h_parameterization:
                h_parameterization[ih] = parameterization_info(htype='alg1a',
                                                               a0=a0.iseq,
                                                               a1=a1.iseq,
                                                               a2=b1.iseq,
                                                               phi=phi,
                                                               n=0,
                                                               alpha=alpha,
                                                               dist_h=dist_h)
            if ih_2 not in h_parameterization:
                h_parameterization[ih_2] = parameterization_info(htype='alg1a',
                                                                 a0=a0.iseq,
                                                                 a1=a1.iseq,
                                                                 a2=b1.iseq,
                                                                 phi=phi +
                                                                 math.pi,
                                                                 n=0,
                                                                 alpha=alpha,
                                                                 dist_h=dist_h)
        # case 1b


# a0.dihedral = dihedral angle between angle ideal and actual position
        elif (n_red_neigbs == 1 and (count_H == 0 or count_H == 2)):
            if (len(h_connectivity[ih]) != 4):
                continue
            a1 = reduced_neighbs[0]
            b1 = (h_connectivity[ih][3])[0]
            r1 = matrix.col(sites_cart[a1.iseq])
            rb1 = matrix.col(sites_cart[b1.iseq])
            uh0 = (rh - r0).normalize()
            u10 = (r1 - r0).normalize()
            dihedral = dihedral_angle(sites=[
                sites_cart[ih], sites_cart[a0.iseq], sites_cart[a1.iseq],
                sites_cart[b1.iseq]
            ])
            if use_ideal_bonds_angles:
                alpha = math.radians(a1.angle_ideal)
                #phi = math.radians(b1.dihedral_ideal)
                #allow for rotation even for idealize = True
                phi = dihedral
            else:
                alpha = (u10).angle(uh0)
                phi = dihedral
            u1 = (r0 - r1).normalize()
            rb10 = rb1 - r1
            u2 = (rb10 - ((rb10).dot(u1)) * u1).normalize()
            u3 = u1.cross(u2)
            h_parameterization[ih] = parameterization_info(htype='alg1b',
                                                           a0=a0.iseq,
                                                           a1=a1.iseq,
                                                           a2=b1.iseq,
                                                           phi=phi,
                                                           n=0,
                                                           alpha=alpha,
                                                           dist_h=dist_h)
            if (count_H == 2):
                h_parameterization[ih].htype = 'prop'
                hlist = h_connectivity[ih][2]
                ih_2, ih_3 = hlist[0].iseq, hlist[1].iseq
                h_parameterization[ih_2] = parameterization_info(htype='prop',
                                                                 a0=a0.iseq,
                                                                 a1=a1.iseq,
                                                                 a2=b1.iseq,
                                                                 phi=phi,
                                                                 n=1,
                                                                 alpha=alpha,
                                                                 dist_h=dist_h)
                # check if order is reversed
                ih_2_coord = compute_H_position(sites_cart=sites_cart,
                                                ih=ih_2,
                                                hp=h_parameterization[ih_2])
                h_parameterization[ih_3] = parameterization_info(htype='prop',
                                                                 a0=a0.iseq,
                                                                 a1=a1.iseq,
                                                                 a2=b1.iseq,
                                                                 phi=phi,
                                                                 n=2,
                                                                 alpha=alpha,
                                                                 dist_h=dist_h)
                if ((ih_2_coord - matrix.col(sites_cart[ih_3])).length() <
                    (ih_2_coord - matrix.col(sites_cart[ih_2])).length()):
                    h_parameterization[ih_2].n = 2
                    h_parameterization[ih_3].n = 1
        else:
            h_parameterization[ih] = parameterization_info(htype='unk',
                                                           a0=a0.iseq)
    return h_parameterization
def get_h_parameterization(connectivity, sites_cart, idealize):
  h_parameterization = {}
  for ih in connectivity.keys():
   #for debugging
    #print 'atom:', names[ih]+' ('+str(ih)+ ') residue:', \
    #  atoms_list[ih].resseq, 'chain', atoms_list[ih].chain_id
    # if entry exists already, skip it
    if ih in h_parameterization:
      continue
    a0 = connectivity[ih][0]
    count_H  = a0.count_H
    reduced_neighbs = connectivity[ih][1]
    n_red_neigbs = len(reduced_neighbs)
    rh = matrix.col(sites_cart[ih])
    r0 = matrix.col(sites_cart[a0.iseq])
    if idealize:
      dist_h = a0.dist_ideal
    else:
      dist_h = (r0 - rh).length()
  # alg2a, 2tetra, 2neigbs
    if(n_red_neigbs == 2):
      a1, a2  = reduced_neighbs[0], reduced_neighbs[1]
      # if H is second neighbor, gets its index
      if (count_H == 1):
        hlist = connectivity[ih][2]
        if hlist:
          ih2 = (hlist[0])
          i_h2 = (hlist[0]).iseq
      else:
        ih2 = None
      sumang, a, b, h, root = get_coefficients(
        ih         = ih,
        a0         = a0,
        a1         = a1,
        a2         = a2,
        ih2        = ih2,
        idealize   = idealize,
        sites_cart = sites_cart,
        typeh      = 'alg2')
      h_parameterization[ih] = parameterization_info(
        a0     = a0.iseq,
        a1     = a1.iseq,
        a2     = a2.iseq,
        a      = a,
        b      = b,
        dist_h = dist_h)
      # alg2a
      if (sumang > (2*math.pi + 0.05) and root < 0):
        h_parameterization[ih].htype = 'unk_ideal'
      elif (sumang < (2*math.pi + 0.05) and (sumang > 2*math.pi - 0.05)):
        h_parameterization[ih].htype = 'flat_2neigbs'
      else:
        if (count_H == 1):
        # 2 tetragonal geometry
          h_parameterization[ih].htype = '2tetra'
          h_parameterization[ih].alpha = h
          h_parameterization[i_h2] = parameterization_info(
            a0     = a0.iseq,
            a1     = a1.iseq,
            a2     = a2.iseq,
            a      = a,
            b      = b,
            alpha  = -h,
            dist_h = dist_h,
            htype  = '2tetra')
        else:
          # 2neigbs
          h_parameterization[ih].h = h
          h_parameterization[ih].htype = '2neigbs'
    # tetragonal geometry: 3neigbs
    elif (n_red_neigbs == 3 and count_H == 0):
      a1, a2, a3  = reduced_neighbs[0], reduced_neighbs[1], reduced_neighbs[2]
      a, b, h = get_coefficients_alg3(
        rh         = rh,
        a0         = a0,
        a1         = a1,
        a2         = a2,
        a3         = a3,
        idealize   = idealize,
        sites_cart = sites_cart)
      h_parameterization[ih] = parameterization_info(
        a0     = a0.iseq,
        a1     = a1.iseq,
        a2     = a2.iseq,
        a3     = a3.iseq,
        a      = a,
        b      = b,
        h      = h,
        dist_h = dist_h,
        htype  = '3neigbs')
    # alg1a: X-H2 planar groups, such as in ARG, ASN, GLN
    # requires that dihedral angle restraint exists
    elif(n_red_neigbs == 1 and count_H == 1 and len(connectivity[ih])==4):
      a1 = reduced_neighbs[0]
      r1 = matrix.col(sites_cart[a1.iseq])
      hlist = connectivity[ih][2]
      ih_2 = hlist[0].iseq
      #if(len(connectivity[ih])!=4):
      #  continue
      b1 = (connectivity[ih][3])[0]
      if (b1.dihedral_ideal == None):
        continue
      #iseq_b1 = b1.iseq
      dihedral = dihedral_angle(
        sites=[sites_cart[b1.iseq], sites_cart[a1.iseq],
        sites_cart[a0.iseq],sites_cart[ih]])
      #print 'dihedrals', a0.dihedral, dihedral, a0.dihedral_ideal
      rb1 = matrix.col(sites_cart[b1.iseq])
      uh0 = (rh - r0).normalize()
      u10 = (r1 - r0).normalize()
      if idealize:
        alpha = math.radians(a1.angle_ideal)
        phi = math.radians(b1.dihedral_ideal)
        #phi = dihedral
      else:
        alpha = (u10).angle(uh0)
        #phi = a0.dihedral
        phi = dihedral
      u1 = (r0 - r1).normalize()
      rb10 = rb1 - r1
      u2 = (rb10 - ((rb10).dot(u10)) * u10).normalize()
      u3 = u1.cross(u2)
      h_parameterization[ih] = parameterization_info(
        htype  = 'alg1a',
        a0     = a0.iseq,
        a1     = a1.iseq,
        a2     = b1.iseq,
        phi    = phi,
        n      = 0,
        alpha  = alpha,
        dist_h = dist_h)
      h_parameterization[ih_2] = parameterization_info(
        htype  = 'alg1a',
        a0     = a0.iseq,
        a1     = a1.iseq,
        a2     = b1.iseq,
        phi    = phi+math.pi,
        n      = 0,
        alpha  = alpha,
        dist_h = dist_h)
    # case 1b
# a0.dihedral = dihedral angle between angle ideal and actual position
    elif(n_red_neigbs == 1 and (count_H == 0 or count_H ==2)):
      #if(count_H == 0 and len(connectivity[ih])!=4):
      #  print 'the culprit is ', ih, names[ih], atoms_list[ih].resseq
      if (len(connectivity[ih])!=4):
        continue
      a1 = reduced_neighbs[0]
      b1 = (connectivity[ih][3])[0]
      r1 = matrix.col(sites_cart[a1.iseq])
      rb1 = matrix.col(sites_cart[b1.iseq])
      uh0 = (rh - r0).normalize()
      u10 = (r1 - r0).normalize()
      dihedral = dihedral_angle(
        sites=[sites_cart[ih], sites_cart[a0.iseq],
        sites_cart[a1.iseq],sites_cart[b1.iseq]])
      if idealize:
        alpha = math.radians(a1.angle_ideal)
        #phi = math.radians(b1.dihedral_ideal)
        #allow for rotation even for idealize = True
        phi = dihedral
      else:
        alpha = (u10).angle(uh0)
        phi = dihedral
      u1 = (r0 - r1).normalize()
      rb10 = rb1 - r1
      u2 = (rb10 - ((rb10).dot(u1)) * u1).normalize()
      u3 = u1.cross(u2)
      h_parameterization[ih] = parameterization_info(
        htype  = 'alg1b',
        a0     = a0.iseq,
        a1     = a1.iseq,
        a2     = b1.iseq,
        phi    = phi,
        n      = 0,
        alpha  = alpha,
        dist_h = dist_h)
      if (count_H == 2):
        h_parameterization[ih].htype = 'prop'
        hlist = connectivity[ih][2]
        # TO DO: Can the order be reversed? To be kept in mind!!
        ih_2, ih_3 = hlist[0].iseq, hlist[1].iseq
        h_parameterization[ih_2] = parameterization_info(
          htype  = 'prop',
          a0     = a0.iseq,
          a1     = a1.iseq,
          a2     = b1.iseq,
          phi    = phi,
          n      = 1,
          alpha  = alpha,
          dist_h = dist_h)
        ih_2_coord = generate_H_positions(
          sites_cart        = sites_cart,
          ih                = ih_2,
          para_info         = h_parameterization[ih_2]).rH_gen
        h_parameterization[ih_3] = parameterization_info(
          htype  = 'prop',
          a0     = a0.iseq,
          a1     = a1.iseq,
          a2     = b1.iseq,
          phi    = phi,
          n      = 2,
          alpha  = alpha,
          dist_h = dist_h)
        if ((ih_2_coord - matrix.col(sites_cart[ih_3])).length() <
          (ih_2_coord - matrix.col(sites_cart[ih_2])).length() ):
          h_parameterization[ih_2].n = 2
          h_parameterization[ih_3].n = 1
    else:
      a1 = reduced_neighbs[0]
      h_parameterization[ih] = parameterization_info(
        htype  = 'unk',
        a0     = a0.iseq,
        a1     = a1.iseq)
  return h_parameterization
Ejemplo n.º 27
0
def get_dihedral_angle(atoms):
  from scitbx.math import dihedral_angle
  return dihedral_angle(
      sites = [x.xyz for x in atoms],
      deg=True)
Ejemplo n.º 28
0
def add_n_terminal_hydrogens_to_atom_group(ag,
                                           use_capping_hydrogens=False,
                                           append_to_end_of_model=False,
                                           retain_original_hydrogens=True,
                                           n_ca_c=None,
                                          ):
  rc=[]
  if n_ca_c is not None:
    n, ca, c = n_ca_c
  else:
    n = ag.get_atom("N")
    if n is None: return 'no N'
    ca = ag.get_atom("CA")
    if ca is None: return 'no CA'
    c = ag.get_atom("C")
    if c is None: return 'no C'
  atom = ag.get_atom('H')
  dihedral=120.
  if atom:
    dihedral = dihedral_angle(sites=[atom.xyz,
                                     n.xyz,
                                     ca.xyz,
                                     c.xyz,
                                   ],
                              deg=True)
  if retain_original_hydrogens: pass
  else:
    if ag.get_atom("H"): # maybe needs to be smarter or actually work
      ag.remove_atom(ag.get_atom('H'))
  #if use_capping_hydrogens and 0:
  #  for i, atom in enumerate(ag.atoms()):
  #    if atom.name == ' H3 ':
  #      ag.remove_atom(i)
  #      break
  # add H1
  rh3 = construct_xyz(n, 0.9,
                      ca, 109.5,
                      c, dihedral,
                     )
  # this could be smarter
  possible = ['H', 'H1', 'H2', 'H3', 'HT1', 'HT2']
  h_count = 0
  for h in possible:
    if ag.get_atom(h): h_count+=1
  number_of_hydrogens=3
  if use_capping_hydrogens:
    number_of_hydrogens-=1
    #if ag.atoms()[0].parent().resname=='PRO':
    #  number_of_hydrogens=-1
    #  # should name the hydrogens correctly
  if h_count>=number_of_hydrogens: return []
  for i in range(0, number_of_hydrogens):
    name = " H%d " % (i+1)
    if retain_original_hydrogens:
      if i==0 and ag.get_atom('H'): continue
    if ag.get_atom(name.strip()): continue
    if ag.resname=='PRO':
      if i==0:
        continue
    atom = iotbx.pdb.hierarchy.atom()
    atom.name = name
    atom.element = "H"
    atom.xyz = rh3[i]
    atom.occ = n.occ
    atom.b = n.b
    atom.segid = ' '*4
    if append_to_end_of_model and i+1==number_of_hydrogens:
      rg = _add_atom_to_chain(atom, ag)
      rc.append(rg)
    else:
      ag.append_atom(atom)
  return rc
Ejemplo n.º 29
0
def determine_H_neighbors(geometry_restraints, pdb_hierarchy):
    atoms = pdb_hierarchy.atoms()
    sites_cart = atoms.extract_xyz()
    bond_proxies_simple, asu = geometry_restraints.get_all_bond_proxies(
        sites_cart=sites_cart)
    angle_proxies = geometry_restraints.get_all_angle_proxies()
    dihedral_proxies = geometry_restraints.dihedral_proxies  # this should be function in GRM, like previous
    fsc2 = geometry_restraints.shell_sym_tables[2].full_simple_connectivity()
    fsc1 = geometry_restraints.shell_sym_tables[1].full_simple_connectivity()
    #fsc0=geometry_restraints.shell_sym_tables[0].full_simple_h_connectivity()
    # Maybe there is better way to get number of atoms?
    n_atoms = len(sites_cart)
    h_connectivity = {}
    double_H = {}
    number_h = 0
    # -------------------------------------------------------------
    # loop through bond proxies to find H atom and parent atom (A0)
    # -------------------------------------------------------------
    for bproxy in bond_proxies_simple:
        i_seq, j_seq = bproxy.i_seqs
        is_i_hd = atoms[i_seq].element_is_hydrogen()
        is_j_hd = atoms[j_seq].element_is_hydrogen()
        if (not is_i_hd and not is_j_hd): continue
        elif (is_i_hd and is_j_hd): assert 0
        else:
            if (is_i_hd): ih, i_parent = i_seq, j_seq
            elif (is_j_hd): ih, i_parent = j_seq, i_seq
            else:
                raise Sorry("Something went wrong in bond proxies")
        rh = matrix.col(sites_cart[ih])
        r0 = matrix.col(sites_cart[i_parent])
        dist = (r0 - rh).length()
        parent = atom_info(iseq=i_parent,
                           dist_ideal=bproxy.distance_ideal,
                           dist=dist)
        altloc_h = atoms[ih].parent().altloc
        #print 'atom:', atoms[ih].name+' ('+str(ih)+ ') residue:', \
        #  atoms[ih].parent().parent().resseq
        i_parent_altloc = atoms[i_parent].parent().altloc
        #    number_h = number_h + 1
        # ---------------------------------------------------------
        # if entry exists already == H has two bonds
        # use the first atom encountered, ignore all others
        if (ih in h_connectivity):
            double_H[ih] = [(h_connectivity[ih][0]).iseq, i_parent]
            continue


# ---------------------------------------------------------
        number_h = number_h + 1
        # h_connectivity[ih][0] --> parent atom
        h_connectivity[ih] = [parent]
        # h_connectivity[ih][1] --> list of second non-H neighbours
        h_connectivity[ih].append([])
        # h_connectivity[ih][2] --> list of second H/D neighbours
        h_connectivity[ih].append([])
        # compute total list of second neighbors
        second_neighbors = list(fsc1[ih])
        count_H = 0
        altloc_dict = {}

        # loop to find second neighbors (ignore those where angle proxies don't
        # exist, and choose same altloc for all second neighbors)
        for i_second in second_neighbors:
            iselection = flex.size_t([ih, i_parent, i_second])
            ap = angle_proxies.proxy_select(n_seq=n_atoms,
                                            iselection=iselection)
            if (ap):
                angle_ideal = ap[0].angle_ideal
                if (i_second in altloc_dict.keys()):
                    continue
                altloc_dict_temp = {}
                i_second_altloc = atoms[i_second].parent().altloc
                # make sure that all second neighbors belong to same altloc
                if (h_connectivity[ih][1] and atoms[
                    (h_connectivity[ih][1])[0].iseq].parent().altloc != ''):
                    iseq_previous = (h_connectivity[ih][1])[0].iseq
                    overall_altloc = atoms[iseq_previous].parent().altloc
                    if (i_second_altloc != '' and altloc_h == ''
                            and i_second_altloc != overall_altloc):
                        continue
                # if no previous altloc, chose that which has highest occ
                elif (i_second_altloc != '' and altloc_h == ''
                      and i_parent_altloc != i_second_altloc):
                    altloc_dict_temp = make_altloc_dict(
                        atoms=atoms,
                        index=i_second,
                        altloc_dict_temp=altloc_dict_temp,
                        neighbors=second_neighbors,
                        altloc=i_second_altloc)
                if (i_second in altloc_dict_temp.keys()):
                    i_second = max(altloc_dict_temp,
                                   key=lambda k: altloc_dict_temp[k])
                    iselection = flex.size_t([ih, i_parent, i_second])
                    ap = angle_proxies.proxy_select(n_seq=n_atoms,
                                                    iselection=iselection)
                    if ap:
                        angle_ideal = ap[0].angle_ideal
                altloc_dict.update(altloc_dict_temp)
                neighbor = atom_info(iseq=i_second, angle_ideal=angle_ideal)
                is_same_hd = is_same_element(iseq1=ih,
                                             iseq2=i_second,
                                             atoms=atoms)
                if ((atoms[i_second].element_is_hydrogen() and is_same_hd)
                        or (atoms[i_second].element_is_hydrogen()
                            and i_second_altloc == '')):
                    h_connectivity[ih][2].append(neighbor)
                    count_H = count_H + 1
                elif (not atoms[i_second].element_is_hydrogen()):
                    h_connectivity[ih][1].append(neighbor)
        (h_connectivity[ih][0]).count_H = count_H
        # ---------------------------------------------------------
        # find third neighbors, if necessary
        # ---------------------------------------------------------
        # possibly, code for second and third neighbors can be transformed
        # to a function  - TODO
        if (len(h_connectivity[ih][1]) == 1):
            h_connectivity[ih].append([])
            i_second = ((h_connectivity[ih][1])[0]).iseq
            third_neighbors = list(fsc2[ih])
            altloc_dict_third = {}
            for i_third in third_neighbors:
                if (not atoms[i_third].element_is_hydrogen()):
                    iselection = flex.size_t([i_parent, i_second, i_third])
                    ap = angle_proxies.proxy_select(n_seq=n_atoms,
                                                    iselection=iselection)
                    if ap:
                        if (i_third in altloc_dict_third.keys()):
                            continue
                        altloc_dict_third_temp = {}
                        i_third_altloc = atoms[i_third].parent().altloc
                        # make sure that all third neighbors belong to the same altloc
                        if (h_connectivity[ih][3]
                                and atoms[(h_connectivity[ih][3]
                                           )[0].iseq].parent().altloc != ''):
                            iseq_previous_third = (
                                h_connectivity[ih][3])[0].iseq
                            overall_altloc_third = atoms[
                                iseq_previous_third].parent().altloc
                            if (i_third_altloc != '' and altloc_h == '' and
                                    i_third_altloc != overall_altloc_third):
                                continue
                        elif (i_third_altloc != '' and altloc_h == ''):
                            altloc_dict_third_temp = make_altloc_dict(
                                atoms=atoms,
                                index=i_third,
                                altloc_dict_temp=altloc_dict_third_temp,
                                neighbors=third_neighbors,
                                altloc=i_third_altloc)
                        if (i_third in altloc_dict_third_temp.keys()):
                            i_third = max(
                                altloc_dict_third_temp,
                                key=lambda k: altloc_dict_third_temp[k])
                        altloc_dict_third.update(altloc_dict_third_temp)
                        # get dihedral angle between H, A0, A1 and third neighbor(B1, B2)
                        iselection_dihe = flex.size_t(
                            [ih, i_parent, i_second, i_third])
                        dp = dihedral_proxies.proxy_select(
                            n_seq=n_atoms, iselection=iselection_dihe)
                        dihedral = dihedral_angle(sites=[
                            sites_cart[i_third], sites_cart[i_second],
                            sites_cart[i_parent], sites_cart[ih]
                        ])
                        sites_cart_dihe = sites_cart.select(
                            iselection_dihe).deep_copy()
                        if dp:
                            dihedral_id = dp[0].angle_ideal
                            delta = dp.deltas(sites_cart=sites_cart_dihe)[0]
                            dihedral_ideal = math.degrees(dihedral) + delta
                        else:
                            dihedral_ideal = None
                        neighbor = atom_info(iseq=i_third,
                                             dihedral=dihedral,
                                             dihedral_ideal=dihedral_ideal)
                        h_connectivity[ih][3].append(neighbor)
        # get ideal angles involving parent and other non-H second neighbors
        n_sec_neigbs = len(h_connectivity[ih][1])
        if (n_sec_neigbs == 2 or n_sec_neigbs == 3):
            reduced_neighbs = h_connectivity[ih][1]
            angles = []
            ix = i_parent
            if (n_sec_neigbs == 2):
                _list = [(0, 1)]
            else:
                _list = [(0, 1), (1, 2), (2, 0)]
            for _i, _j in _list:
                iy = (reduced_neighbs[_i]).iseq
                iz = (reduced_neighbs[_j]).iseq
                iselection = flex.size_t([ix, iy, iz])
                ap = angle_proxies.proxy_select(n_seq=n_atoms,
                                                iselection=iselection)
                if ap:
                    angles.append(ap[0].angle_ideal)
                else:
                    raise Sorry("Expected ideal angles are missing. \
            Second neigbs - parent atom.")
                (h_connectivity[ih][0]).angle_ideal = angles
    #
    return group_args(h_connectivity=h_connectivity,
                      double_H=double_H,
                      number_h=number_h)
Ejemplo n.º 30
0
 def process_1_neighbor(self, neighbors):
     ih = neighbors.ih
     i_a0 = neighbors.a0['iseq']
     rh = matrix.col(self.sites_cart[ih])
     r0 = matrix.col(self.sites_cart[i_a0])
     if self.use_ideal_bonds_angles:
         disth = neighbors.a0['dist_ideal']
     else:
         disth = (r0 - rh).length()
     i_a1 = neighbors.a1['iseq']
     i_b1 = neighbors.b1['iseq']
     r1 = matrix.col(self.sites_cart[i_a1])
     rb1 = matrix.col(self.sites_cart[i_b1])
     uh0 = (rh - r0).normalize()
     u10 = (r1 - r0).normalize()
     dihedral = dihedral_angle(sites=[
         self.sites_cart[ih], self.sites_cart[i_a0], self.sites_cart[i_a1],
         self.sites_cart[i_b1]
     ])
     if self.use_ideal_bonds_angles:
         alpha = math.radians(neighbors.a1['angle_ideal'])
         #allow for rotation even for idealize = True
         #phi = math.radians(b1.dihedral_ideal)
         phi = dihedral
     else:
         alpha = (u10).angle(uh0)
         phi = dihedral
     u1 = (r0 - r1).normalize()
     rb10 = rb1 - r1
     u2 = (rb10 - ((rb10).dot(u1)) * u1).normalize()
     u3 = u1.cross(u2)
     if (neighbors.number_h_neighbors == 0):
         self.h_parameterization[ih] = riding_coefficients(htype='alg1b',
                                                           ih=ih,
                                                           a0=i_a0,
                                                           a1=i_a1,
                                                           a2=i_b1,
                                                           a3=0,
                                                           a=alpha,
                                                           b=phi,
                                                           h=0,
                                                           n=0,
                                                           disth=disth)
     if (neighbors.number_h_neighbors == 2):
         i_h1, i_h2 = neighbors.h1['iseq'], neighbors.h2['iseq']
         i_h1, i_h2 = self.check_propeller_order(i_a0=i_a0,
                                                 i_a1=i_a1,
                                                 ih=ih,
                                                 i_h1=i_h1,
                                                 i_h2=i_h2)
         for nprop, hprop in zip([0, 1, 2], [ih, i_h1, i_h2]):
             self.h_parameterization[hprop] = riding_coefficients(
                 htype='prop',
                 ih=hprop,
                 a0=i_a0,
                 a1=i_a1,
                 a2=i_b1,
                 a3=0,
                 a=alpha,
                 n=nprop,
                 b=phi,
                 h=0,
                 disth=disth)