Beispiel #1
0
def get_axes_and_atoms_i_seqs(pdb_hierarchy, mon_lib_srv):
    get_class = iotbx.pdb.common_residue_names_get_class
    axes_and_atoms_i_seqs = []
    for model in pdb_hierarchy.models():
        for chain in model.chains():
            for residue_group in chain.residue_groups():
                for conformer in residue_group.conformers():
                    for residue in conformer.residues():
                        if (get_class(residue.resname) == "common_amino_acid"):
                            aaa = rotatable_bonds.axes_and_atoms_aa_specific(
                                residue=residue, mon_lib_srv=mon_lib_srv)
                            if (aaa is not None):
                                for aaa_ in aaa:
                                    tmp_ = []
                                    axis = flex.size_t()
                                    moving = flex.size_t()
                                    axis_ = aaa_[0]
                                    atoms_ = aaa_[1]
                                    for i_seq, atom in enumerate(
                                            residue.atoms()):
                                        if (i_seq in axis_):
                                            axis.append(atom.i_seq)
                                        elif (i_seq in atoms_):
                                            moving.append(atom.i_seq)
                                    assert len(axis) == 2
                                    assert len(moving) > 0
                                    tmp_.append([axis, moving])
                                    axes_and_atoms_i_seqs.append(tmp_)
    return axes_and_atoms_i_seqs
 def change_residue_rotamer_in_place(self,sites_cart, residue,
     m_chis, r_chis, mon_lib_srv):
   assert m_chis.count(None) == 0
   assert r_chis.count(None) == 0
   axis_and_atoms_to_rotate= \
     rotatable_bonds.axes_and_atoms_aa_specific(
         residue=residue,
         mon_lib_srv=mon_lib_srv,
         remove_clusters_with_all_h=True,
         log=None)
   if axis_and_atoms_to_rotate is None:
     return
   assert len(m_chis) == len(axis_and_atoms_to_rotate)
   assert len(r_chis) >= len(m_chis)
   counter = 0
   residue_iselection = residue.atoms().extract_i_seq()
   sites_cart_residue = sites_cart.select(residue_iselection)
   for aa in axis_and_atoms_to_rotate:
     axis = aa[0]
     atoms = aa[1]
     residue.atoms().set_xyz(new_xyz=sites_cart_residue)
     new_xyz = flex.vec3_double()
     angle_deg = r_chis[counter] - m_chis[counter]
     if angle_deg < 0:
       angle_deg += 360.0
     for atom in atoms:
       new_xyz = rotate_point_around_axis(
                   axis_point_1=sites_cart_residue[axis[0]],
                   axis_point_2=sites_cart_residue[axis[1]],
                   point=sites_cart_residue[atom],
                   angle=angle_deg, deg=True)
       sites_cart_residue[atom] = new_xyz
     sites_cart = sites_cart.set_selected(
           residue_iselection, sites_cart_residue)
     counter += 1
Beispiel #3
0
 def change_residue_rotamer_in_place(self,sites_cart, residue,
     m_chis, r_chis, mon_lib_srv):
   assert m_chis.count(None) == 0
   assert r_chis.count(None) == 0
   axis_and_atoms_to_rotate= \
     rotatable_bonds.axes_and_atoms_aa_specific(
         residue=residue,
         mon_lib_srv=mon_lib_srv,
         remove_clusters_with_all_h=True,
         log=None)
   if axis_and_atoms_to_rotate is None:
     return
   assert len(m_chis) == len(axis_and_atoms_to_rotate)
   assert len(r_chis) >= len(m_chis)
   counter = 0
   residue_iselection = residue.atoms().extract_i_seq()
   sites_cart_residue = sites_cart.select(residue_iselection)
   for aa in axis_and_atoms_to_rotate:
     axis = aa[0]
     atoms = aa[1]
     residue.atoms().set_xyz(new_xyz=sites_cart_residue)
     new_xyz = flex.vec3_double()
     angle_deg = r_chis[counter] - m_chis[counter]
     if angle_deg < 0:
       angle_deg += 360.0
     for atom in atoms:
       new_xyz = rotate_point_around_axis(
                   axis_point_1=sites_cart_residue[axis[0]],
                   axis_point_2=sites_cart_residue[axis[1]],
                   point=sites_cart_residue[atom],
                   angle=angle_deg, deg=True)
       sites_cart_residue[atom] = new_xyz
     sites_cart = sites_cart.set_selected(
           residue_iselection, sites_cart_residue)
     counter += 1
Beispiel #4
0
def get_axes_and_atoms_i_seqs(pdb_hierarchy, mon_lib_srv):
  get_class = iotbx.pdb.common_residue_names_get_class
  axes_and_atoms_i_seqs = []
  for model in pdb_hierarchy.models():
    for chain in model.chains():
      for residue_group in chain.residue_groups():
        for conformer in residue_group.conformers():
          for residue in conformer.residues():
            if(get_class(residue.resname) == "common_amino_acid"):
              aaa = rotatable_bonds.axes_and_atoms_aa_specific(
                residue = residue, mon_lib_srv = mon_lib_srv)
              if(aaa is not None):
                for aaa_ in aaa:
                  tmp_ = []
                  axis = flex.size_t()
                  moving = flex.size_t()
                  axis_ = aaa_[0]
                  atoms_ = aaa_[1]
                  for i_seq, atom in enumerate(residue.atoms()):
                    if(i_seq in axis_): axis.append(atom.i_seq)
                    elif(i_seq in atoms_): moving.append(atom.i_seq)
                  assert len(axis) == 2
                  assert len(moving) > 0
                  tmp_.append([axis, moving])
                  axes_and_atoms_i_seqs.append(tmp_)
  return axes_and_atoms_i_seqs
def generate_sidechain_clusters(residue, mon_lib_srv):
    """
  Extract Chi angle indices (including rotation axis) from the atom_group
  """
    from mmtbx.refinement.real_space import fit_residue
    from mmtbx.utils import rotatable_bonds
    from scitbx.array_family import flex
    atoms = residue.atoms()
    axes_and_atoms_aa_specific = \
        rotatable_bonds.axes_and_atoms_aa_specific(residue = residue,
          mon_lib_srv = mon_lib_srv)
    result = []
    if (axes_and_atoms_aa_specific is not None):
        for i_aa, aa in enumerate(axes_and_atoms_aa_specific):
            n_heavy = 0
            #for i_seq in aa[1] :
            #  if (atoms[i_seq].element.strip() != "H"):
            #    n_heavy += 1
            #if (n_heavy == 0) : continue
            if (i_aa == len(axes_and_atoms_aa_specific) - 1):
                result.append(
                    mmtbx.refinement.real_space.cluster(axis=aa[0],
                                                        atoms_to_rotate=aa[1],
                                                        selection=flex.size_t(
                                                            aa[1]),
                                                        vector=None))  # XXX
            else:
                result.append(
                    mmtbx.refinement.real_space.cluster(axis=aa[0],
                                                        atoms_to_rotate=aa[1],
                                                        selection=flex.size_t(
                                                            [aa[1][0]]),
                                                        vector=None))  # XXX
    return result
Beispiel #6
0
def generate_sidechain_clusters (residue, mon_lib_srv) :
  """
  Extract Chi angle indices (including rotation axis) from the atom_group
  """
  from mmtbx.refinement.real_space import fit_residue
  from mmtbx.utils import rotatable_bonds
  from scitbx.array_family import flex
  atoms = residue.atoms()
  axes_and_atoms_aa_specific = \
      rotatable_bonds.axes_and_atoms_aa_specific(residue = residue,
        mon_lib_srv = mon_lib_srv)
  result = []
  if(axes_and_atoms_aa_specific is not None):
    for i_aa, aa in enumerate(axes_and_atoms_aa_specific):
      n_heavy = 0
      for i_seq in aa[1] :
        if (atoms[i_seq].element.strip() != "H") :
          n_heavy += 1
      if (n_heavy == 0) : continue
      if(i_aa == len(axes_and_atoms_aa_specific)-1):
        result.append(mmtbx.refinement.real_space.cluster(
          axis=aa[0],
          atoms_to_rotate=aa[1],
          selection=flex.size_t(aa[1]),
          vector=None)) # XXX
      else:
        result.append(mmtbx.refinement.real_space.cluster(
          axis=aa[0],
          atoms_to_rotate=aa[1],
          selection=flex.size_t([aa[1][0]]),
          vector=None)) # XXX
  return result
Beispiel #7
0
 def helper_1(residue, mon_lib_srv, log, result, psel):
   fr = rotatable_bonds.axes_and_atoms_aa_specific(
     residue=residue, mon_lib_srv=mon_lib_srv,
     remove_clusters_with_all_h=False, log=log)
   if(fr is not None):
     r = analyze_group_aa_specific(g=fr, atoms=residue.atoms(), psel=psel)
     if(r is not None):
       for r_ in r: result.append(r_)
Beispiel #8
0
 def __init__(self,
              residue,
              mon_lib_srv,
              backbone_sample):
   self.clusters = []
   atom_names = residue.atoms().extract_name()
   if(backbone_sample):
     backrub_axis  = []
     backrub_atoms_to_rotate = []
     backrub_atoms_to_evaluate = []
     counter = 0 # XXX DOES THIS RELY ON ORDER?
     for atom in residue.atoms():
       if(atom.name.strip().upper() in ["N", "C"]):
         backrub_axis.append(counter)
       else:
         backrub_atoms_to_rotate.append(counter)
       if(atom.name.strip().upper() in ["CA", "O", "CB"]):
         backrub_atoms_to_evaluate.append(counter)
       counter += 1
     if(len(backrub_axis)==2 and len(backrub_atoms_to_evaluate)>0):
       self.clusters.append(cluster(
         axis            = flex.size_t(backrub_axis),
         atom_names      = atom_names,
         atoms_to_rotate = flex.size_t(backrub_atoms_to_rotate),
         selection       = flex.size_t(backrub_atoms_to_evaluate)))
   self.axes_and_atoms_aa_specific = \
     rotatable_bonds.axes_and_atoms_aa_specific(
       residue = residue, mon_lib_srv = mon_lib_srv)
   if(self.axes_and_atoms_aa_specific is not None):
     for i_aa, aa in enumerate(self.axes_and_atoms_aa_specific):
       if(i_aa == len(self.axes_and_atoms_aa_specific)-1):
         selection = flex.size_t(aa[1])
       else:
         selection = flex.size_t([aa[1][0]])
       self.clusters.append(cluster(
         axis            = flex.size_t(aa[0]),
         atom_names      = atom_names,
         atoms_to_rotate = flex.size_t(aa[1]),
         selection       = flex.size_t(selection)))
     vector_selections = []
     if(len(self.clusters)>0):
       for i_aa, aa in enumerate(self.axes_and_atoms_aa_specific):
         for aa_ in aa[0]:
           if(not aa_ in vector_selections):
             vector_selections.append(aa_)
       vector_selections.append(
         self.clusters[len(self.clusters)-1].atoms_to_rotate)
       for cl in self.clusters:
         cl.vector = vector_selections
Beispiel #9
0
 def __init__(self,
              residue,
              mon_lib_srv,
              backbone_sample):
   self.clusters = []
   atom_names = residue.atoms().extract_name()
   if(backbone_sample):
     backrub_axis  = []
     backrub_atoms_to_rotate = []
     backrub_atoms_to_evaluate = []
     counter = 0 # XXX DOES THIS RELY ON ORDER?
     for atom in residue.atoms():
       if(atom.name.strip().upper() in ["N", "C"]):
         backrub_axis.append(counter)
       else:
         backrub_atoms_to_rotate.append(counter)
       if(atom.name.strip().upper() in ["CA", "O", "CB"]):
         backrub_atoms_to_evaluate.append(counter)
       counter += 1
     if(len(backrub_axis)==2 and len(backrub_atoms_to_evaluate)>0):
       self.clusters.append(cluster(
         axis            = flex.size_t(backrub_axis),
         atom_names      = atom_names,
         atoms_to_rotate = flex.size_t(backrub_atoms_to_rotate),
         selection       = flex.size_t(backrub_atoms_to_evaluate)))
   self.axes_and_atoms_aa_specific = \
     rotatable_bonds.axes_and_atoms_aa_specific(
       residue = residue, mon_lib_srv = mon_lib_srv)
   if(self.axes_and_atoms_aa_specific is not None):
     for i_aa, aa in enumerate(self.axes_and_atoms_aa_specific):
       if(i_aa == len(self.axes_and_atoms_aa_specific)-1):
         selection = flex.size_t(aa[1])
       else:
         selection = flex.size_t([aa[1][0]])
       self.clusters.append(cluster(
         axis            = flex.size_t(aa[0]),
         atom_names      = atom_names,
         atoms_to_rotate = flex.size_t(aa[1]),
         selection       = flex.size_t(selection)))
     vector_selections = []
     if(len(self.clusters)>0):
       for i_aa, aa in enumerate(self.axes_and_atoms_aa_specific):
         for aa_ in aa[0]:
           if(not aa_ in vector_selections):
             vector_selections.append(aa_)
       vector_selections.append(
         self.clusters[len(self.clusters)-1].atoms_to_rotate)
       for cl in self.clusters:
         cl.vector = vector_selections
Beispiel #10
0
 def helper_2(atoms, restraints_manager):
     elements = atoms.extract_element()
     names = atoms.extract_name()
     # create tardy_model
     iselection = atoms.extract_i_seq()
     sites_cart = atoms.extract_xyz()
     masses = [1] * sites_cart.size()
     labels = list(range(sites_cart.size()))
     grm_i = restraints_manager.select(iselection)
     bps, asu = grm_i.geometry.get_all_bond_proxies(sites_cart=sites_cart)
     edge_list = []
     for bp in bps:
         edge_list.append(bp.i_seqs)
     fixed_vertex_lists = []
     tmp_r = []
     # try all possible edges (bonds) as potential fixed vertices and
     # accept only non-redundant
     for bp in bps:
         tardy_tree = scitbx.graph.tardy_tree.construct(
             sites=sites_cart,
             edge_list=edge_list,
             fixed_vertex_lists=[bp.i_seqs])
         tardy_model = scitbx.rigid_body.tardy_model(labels=labels,
                                                     sites=sites_cart,
                                                     masses=masses,
                                                     tardy_tree=tardy_tree,
                                                     potential_obj=None)
         fr = rotatable_bonds.axes_and_atoms_aa_specific(
             residue=residue,
             mon_lib_srv=mon_lib_srv,
             remove_clusters_with_all_h=False,
             log=None,
             tardy_model=tardy_model)
         if (fr is not None):
             r = analyze_group_general(g=fr,
                                       atoms=atoms,
                                       bps=bps,
                                       psel=psel)
             if (r is not None and len(r) > 0):
                 for r_ in r:
                     if (not r_ in tmp_r):
                         if (not r_ in tmp_r): tmp_r.append(r_)
     for r in tmp_r:
         if (not r in result):
             result.append(r)
Beispiel #11
0
def rotatable(pdb_hierarchy, mon_lib_srv, restraints_manager, log):
    """
  General tool to identify rotatable H, such as C-O-H, C-H3, in any molecule.
  """
    result = []

    def analyze_group_aa_specific(g, atoms):
        result = []
        for gi in g:
            assert len(gi[0]) == 2  # because this is axis
            assert len(
                gi[1]) > 0  # because these are atoms rotating about this axis
            # condition 1: axis does not contain H or D
            a1, a2 = atoms[gi[0][0]], atoms[gi[0][1]]
            e1 = a1.element.strip().upper()
            e2 = a2.element.strip().upper()
            condition_1 = [e1, e2].count("H") == 0 and [e1, e2].count("D") == 0
            # condition 2: all atoms to rotate are H or D
            condition_2 = True
            rot_atoms = []
            for gi1i in gi[1]:
                if (not atoms[gi1i].element.strip().upper() in ["H", "D"]):
                    condition_2 = False
                    break
            rot_atoms = []
            axis = None
            if (condition_1 and condition_2):
                axis = [a1.i_seq, a2.i_seq]
                for gi1i in gi[1]:
                    rot_atoms.append(atoms[gi1i].i_seq)
                result.append([axis, rot_atoms])
        if (len(result) > 0 is not None): return result
        else: return None

    def analyze_group_general(g, atoms, bps, psel):
        result = []
        for gi in g:
            condition_1, condition_2, condition_3 = None, None, None
            assert len(gi[0]) == 2  # because this is axis
            assert len(
                gi[1]) > 0  # because these are atoms rotating about this axis
            # condition 1: axis does not contain H or D
            a1, a2 = atoms[gi[0][0]], atoms[gi[0][1]]
            e1 = a1.element.strip().upper()
            e2 = a2.element.strip().upper()
            condition_1 = [e1, e2].count("H") == 0 and [e1, e2].count("D") == 0
            s1 = set(gi[1])
            if (condition_1):
                # condition 2: all atoms to rotate are H or D
                condition_2 = True
                for gi1i in gi[1]:
                    if (not atoms[gi1i].element.strip().upper() in ["H", "D"]):
                        condition_2 = False
                        break
                if (condition_2):
                    # condition 3: one of axis atoms is terminal (bonded to another axis
                    #              atom and hydrogens
                    condition_3 = False
                    for gia in gi[0]:
                        bonds_involved_into = []
                        for bp in bps:
                            if (gia in bp.i_seqs):
                                for i_seq in bp.i_seqs:
                                    if (atoms[i_seq].element.strip().upper()
                                            in ["H", "D"]):
                                        bonds_involved_into.append(i_seq)
                        s2 = set(bonds_involved_into)
                        s = list(s1 & s2)
                        if (len(s) > 0): condition_3 = True
                    #
                    if (condition_1 and condition_2 and condition_3):
                        axis = [a1.i_seq, a2.i_seq]
                        rot_atoms = []
                        in_plane = False
                        for i in bonds_involved_into:
                            if (atoms[i].i_seq in psel): in_plane = True
                            rot_atoms.append(atoms[i].i_seq)
                        if (not in_plane): result.append([axis, rot_atoms])
        if (len(result) > 0 is not None): return result
        else: return None

    if (restraints_manager is not None):
        psel = flex.size_t()
        for p in restraints_manager.geometry.planarity_proxies:
            psel.extend(p.i_seqs)
    # very handy for debugging: do not remove
    #NAMES = pdb_hierarchy.atoms().extract_name()
    #
    get_class = iotbx.pdb.common_residue_names_get_class
    import scitbx.graph.tardy_tree
    for model in pdb_hierarchy.models():
        for chain in model.chains():
            residue_groups = chain.residue_groups()
            n_residues = len(residue_groups)
            for i_rg, residue_group in enumerate(residue_groups):
                first_or_last = i_rg == 0 or i_rg + 1 == n_residues
                conformers = residue_group.conformers()
                for conformer in residue_group.conformers():
                    for residue in conformer.residues():
                        if (residue.resname.strip().upper() == "PRO"): continue
                        atoms = residue.atoms()
                        if (get_class(name=residue.resname) == "common_water"
                                and len(atoms) == 1):
                            continue
                        if (get_class(name=residue.resname)
                                == "common_amino_acid" and not first_or_last):
                            fr = rotatable_bonds.axes_and_atoms_aa_specific(
                                residue=residue,
                                mon_lib_srv=mon_lib_srv,
                                remove_clusters_with_all_h=False,
                                log=log)
                            if (fr is not None):
                                r = analyze_group_aa_specific(g=fr,
                                                              atoms=atoms)
                                if (r is not None):
                                    for r_ in r:
                                        result.append(r_)
                        elif (restraints_manager is not None):
                            elements = atoms.extract_element()
                            names = atoms.extract_name()
                            # create tardy_model
                            iselection = atoms.extract_i_seq()
                            sites_cart = atoms.extract_xyz()
                            masses = [1] * sites_cart.size()
                            labels = range(sites_cart.size())
                            grm_i = restraints_manager.select(iselection)
                            bps, asu = grm_i.geometry.get_all_bond_proxies(
                                sites_cart=sites_cart)
                            edge_list = []
                            for bp in bps:
                                edge_list.append(bp.i_seqs)
                            fixed_vertex_lists = []
                            tmp_r = []
                            # try all possible edges (bonds) as potential fixed vertices and
                            # accept only non-redundant
                            for bp in bps:
                                tardy_tree = scitbx.graph.tardy_tree.construct(
                                    sites=sites_cart,
                                    edge_list=edge_list,
                                    fixed_vertex_lists=[bp.i_seqs])
                                tardy_model = scitbx.rigid_body.tardy_model(
                                    labels=labels,
                                    sites=sites_cart,
                                    masses=masses,
                                    tardy_tree=tardy_tree,
                                    potential_obj=None)
                                fr = rotatable_bonds.axes_and_atoms_aa_specific(
                                    residue=residue,
                                    mon_lib_srv=mon_lib_srv,
                                    remove_clusters_with_all_h=False,
                                    log=None,
                                    tardy_model=tardy_model)
                                if (fr is not None):
                                    r = analyze_group_general(g=fr,
                                                              atoms=atoms,
                                                              bps=bps,
                                                              psel=psel)
                                    if (r is not None and len(r) > 0):
                                        for r_ in r:
                                            if (not r_ in tmp_r):
                                                if (not r_ in tmp_r):
                                                    tmp_r.append(r_)
                            for r in tmp_r:
                                result.append(r)
    # very handy for debugging: do not remove
    #for r_ in result:
    #  print "  analyze_group:", r_, \
    #    [NAMES[i] for i in r_[0]], [NAMES[i] for i in r_[1]], residue.resname
    return result
Beispiel #12
0
 def __init__(self,
              residue,
              mon_lib_srv,
              backbone_sample):
   self.clusters               = []
   atoms                       = residue.atoms()
   atoms_as_list               = list(atoms)
   atom_names                  = atoms.extract_name()
   self.weights                = flex.double()
   self.clash_eval_selection   = flex.size_t()
   self.clash_eval_h_selection = flex.bool(len(atoms_as_list), False)
   self.rsr_eval_selection     = flex.size_t()
   # Backbone sample
   backrub_axis  = []
   backrub_atoms_to_rotate = []
   backrub_atoms_to_evaluate = []
   counter = 0 # XXX DOES THIS RELY ON ORDER?
   for atom in atoms:
     an = atom.name.strip().upper()
     ae = atom.element.strip().upper()
     if(ae in ["H","D"]):
       self.clash_eval_h_selection[counter]=True
     if(an in ["N", "C"]):
       backrub_axis.append(counter)
     else:
       backrub_atoms_to_rotate.append(counter)
     if(an in ["CA", "O", "CB"]):
       backrub_atoms_to_evaluate.append(counter)
     if(not an in ["CA", "O", "CB", "C", "N", "HA", "H"]):
       self.clash_eval_selection.append(counter)
       if(not ae in ["H","D"]):
         self.rsr_eval_selection.append(counter)
     std_lbl = eltbx.xray_scattering.get_standard_label(
       label=ae, exact=True, optional=True)
     self.weights.append(tiny_pse.table(std_lbl).weight())
     #
     counter += 1
   #
   if(backbone_sample):
     if(len(backrub_axis)==2 and len(backrub_atoms_to_evaluate)>0):
       self.clusters.append(cluster(
         axis            = flex.size_t(backrub_axis),
         atom_names      = atom_names,
         atoms_to_rotate = flex.size_t(backrub_atoms_to_rotate),
         selection       = flex.size_t(backrub_atoms_to_evaluate)))
   self.axes_and_atoms_aa_specific = \
     rotatable_bonds.axes_and_atoms_aa_specific(
       residue = residue, mon_lib_srv = mon_lib_srv)
   if(self.axes_and_atoms_aa_specific is not None):
     for i_aa, aa in enumerate(self.axes_and_atoms_aa_specific):
       if(i_aa == len(self.axes_and_atoms_aa_specific)-1):
         selection = flex.size_t(aa[1])
       else:
         selection = flex.size_t([aa[1][0]])
       # Exclude pure H or D rotatable groups
       elements_to_rotate = flex.std_string()
       for etr in aa[1]:
         elements_to_rotate.append(atoms_as_list[etr].element.strip())
       c_H = elements_to_rotate.count("H")
       c_D = elements_to_rotate.count("D")
       etr_sz = elements_to_rotate.size()
       if(c_H==etr_sz or c_D==etr_sz or c_H+c_D==etr_sz):
         continue
       #
       self.clusters.append(cluster(
         axis            = flex.size_t(aa[0]),
         atom_names      = atom_names,
         atoms_to_rotate = flex.size_t(aa[1]),
         selection       = flex.size_t(selection)))
     vector_selections = []
     if(len(self.clusters)>0):
       for i_aa, aa in enumerate(self.axes_and_atoms_aa_specific):
         for aa_ in aa[0]:
           if(not aa_ in vector_selections):
             vector_selections.append(aa_)
       vector_selections.append(
         self.clusters[len(self.clusters)-1].atoms_to_rotate)
       for cl in self.clusters:
         cl.vector = vector_selections
Beispiel #13
0
    def search(self, atom_group, all_dict, m_chis, r_chis, rotamer,
               sites_cart_moving, xray_structure, key):
        include_ca_hinge = False
        axis_and_atoms_to_rotate, tardy_labels= \
          rotatable_bonds.axes_and_atoms_aa_specific(
              residue=atom_group,
              mon_lib_srv=self.mon_lib_srv,
              remove_clusters_with_all_h=True,
              include_labels=True,
              log=None)
        if (axis_and_atoms_to_rotate is None):
            print >> self.log, "Skipped %s rotamer (TARDY error)" % key
            return False
        assert len(m_chis) == len(r_chis)
        #exclude H-only clusters if necessary
        while len(axis_and_atoms_to_rotate) > len(m_chis):
            axis_and_atoms_to_rotate = \
              axis_and_atoms_to_rotate[:-1]
        assert len(m_chis) == len(axis_and_atoms_to_rotate)
        counter = 0
        residue_iselection = atom_group.atoms().extract_i_seq()
        cur_ca = None
        ca_add = None
        ca_axes = []
        for atom in atom_group.atoms():
            if atom.name == " CA ":
                cur_ca = atom.i_seq
        if cur_ca is not None:
            cur_c_alpha_hinges = self.c_alpha_hinges.get(cur_ca)
            if cur_c_alpha_hinges is not None:
                residue_length = len(tardy_labels)
                for ca_pt in cur_c_alpha_hinges[0]:
                    residue_iselection.append(ca_pt)
                    tardy_labels.append(self.name_hash[ca_pt][0:4])
                for bb_pt in cur_c_alpha_hinges[1]:
                    residue_iselection.append(bb_pt)
                    tardy_labels.append(self.name_hash[bb_pt][0:4])
                end_pts = (residue_length, residue_length + 1)
                group = []
                for i, value in enumerate(tardy_labels):
                    if i not in end_pts:
                        group.append(i)
                ca_add = [end_pts, group]
                ca_axes.append(ca_add)
                for ax in axis_and_atoms_to_rotate:
                    ca_axes.append(ax)
        sites_cart_residue = \
          sites_cart_moving.select(residue_iselection)
        sites_cart_residue_start = sites_cart_residue.deep_copy()
        selection = flex.bool(len(sites_cart_moving), residue_iselection)
        rev_first_atoms = []

        rev_start = rotamer_evaluator(
            sites_cart_start=sites_cart_residue_start,
            unit_cell=self.unit_cell,
            two_mfo_dfc_map=self.target_map_data,
            mfo_dfc_map=self.residual_map_data)

        sidechain_only_iselection = flex.size_t()
        for i_seq in residue_iselection:
            atom_name = self.name_hash[i_seq][0:4]
            if atom_name not in [' N  ', ' CA ', ' C  ', ' O  ']:
                sidechain_only_iselection.append(i_seq)
        sites_cart_sidechain = \
          sites_cart_moving.select(sidechain_only_iselection)
        sites_frac_residue = self.unit_cell.fractionalize(sites_cart_sidechain)
        sigma_cutoff = 1.0
        sigma_residue = []
        for rsf in sites_frac_residue:
            if self.target_map_data.eight_point_interpolation(
                    rsf) < sigma_cutoff:
                sigma_residue.append(False)
            else:
                sigma_residue.append(True)
        sigma_count_start = 0
        for sigma_state in sigma_residue:
            if sigma_state:
                sigma_count_start += 1
            else:
                break

        for aa in axis_and_atoms_to_rotate:
            axis = aa[0]
            atoms = aa[1]
            new_xyz = flex.vec3_double()
            angle_deg = r_chis[counter] - m_chis[counter]
            #skip angle rotations that are close to zero
            if math.fabs(angle_deg) < 0.01:
                counter += 1
                continue
            if angle_deg < 0:
                angle_deg += 360.0
            for atom in atoms:
                new_xyz = rotate_point_around_axis(
                    axis_point_1=sites_cart_residue[axis[0]],
                    axis_point_2=sites_cart_residue[axis[1]],
                    point=sites_cart_residue[atom],
                    angle=angle_deg,
                    deg=True)
                sites_cart_residue[atom] = new_xyz
            counter += 1

        #***** TEST *****
        sites_cart_moving.set_selected(residue_iselection, sites_cart_residue)
        cur_rotamer, cur_chis, cur_value = rotalyze.evaluate_rotamer(
            atom_group=atom_group,
            sidechain_angles=self.sa,
            rotamer_evaluator=self.rotamer_evaluator,
            rotamer_id=self.rotamer_id,
            all_dict=all_dict,
            sites_cart=sites_cart_moving)
        assert rotamer == cur_rotamer
        #****************

        if len(ca_axes) == 0:
            eval_axes = axis_and_atoms_to_rotate
        else:
            eval_axes = ca_axes
            include_ca_hinge = True
        for i_aa, aa in enumerate(eval_axes):
            if (i_aa == len(eval_axes) - 1):
                sites_aa = flex.vec3_double()
                for aa_ in aa[1]:
                    sites_aa.append(sites_cart_residue[aa_])
            elif i_aa == 0 and include_ca_hinge:
                sites_aa = flex.vec3_double()
                for aa_ in aa[1]:
                    sites_aa.append(sites_cart_residue[aa_])
            else:
                sites_aa = flex.vec3_double([sites_cart_residue[aa[1][0]]])
            rev_i = rotamer_evaluator(sites_cart_start=sites_aa,
                                      unit_cell=self.unit_cell,
                                      two_mfo_dfc_map=self.target_map_data,
                                      mfo_dfc_map=self.residual_map_data)
            rev_first_atoms.append(rev_i)

        rev = rotamer_evaluator(sites_cart_start=sites_cart_residue,
                                unit_cell=self.unit_cell,
                                two_mfo_dfc_map=self.target_map_data,
                                mfo_dfc_map=self.residual_map_data)

        residue_sites_best = sites_cart_residue.deep_copy()
        residue_sites_best, rotamer_id_best = \
          torsion_search(
            residue_evaluator=rev,
            cluster_evaluators=rev_first_atoms,
            axes_and_atoms_to_rotate=eval_axes,
            rotamer_sites_cart=sites_cart_residue,
            rotamer_id_best=rotamer,
            residue_sites_best=residue_sites_best,
            params = self.torsion_params,
            rotamer_id = rotamer,
            include_ca_hinge = include_ca_hinge)
        sites_cart_moving.set_selected(residue_iselection, residue_sites_best)
        xray_structure.set_sites_cart(sites_cart_moving)
        cur_rotamer, cur_chis, cur_value = rotalyze.evaluate_rotamer(
            atom_group=atom_group,
            sidechain_angles=self.sa,
            rotamer_evaluator=self.rotamer_evaluator,
            rotamer_id=self.rotamer_id,
            all_dict=all_dict,
            sites_cart=sites_cart_moving)
        rotamer_match = (cur_rotamer == rotamer)
        if rev_start.is_better(sites_cart=residue_sites_best,
                               percent_cutoff=0.15, verbose=True) and \
           rotamer_match:
            sidechain_only_iselection = flex.size_t()
            for i_seq in residue_iselection:
                atom_name = self.name_hash[i_seq][0:4]
                if atom_name not in [
                        ' N  ', ' CA ', ' C  ', ' O  ', ' OXT', ' H  ', ' HA '
                ]:
                    sidechain_only_iselection.append(i_seq)
            selection = flex.bool(len(sites_cart_moving),
                                  sidechain_only_iselection)
            selection_within = xray_structure.selection_within(
                radius=1.0, selection=selection)
            #check for bad steric clashes
            created_clash = False
            for i, state in enumerate(selection_within):
                if state:
                    if i not in sidechain_only_iselection:
                        #print >> self.log, "atom clash: ", self.name_hash[i]
                        created_clash = True
            if created_clash:
                sites_cart_moving.set_selected(residue_iselection,
                                               sites_cart_residue_start)
                xray_structure.set_sites_cart(sites_cart_moving)
                return False

            sidechain_only_iselection = flex.size_t()
            for i_seq in residue_iselection:
                atom_name = self.name_hash[i_seq][0:4]
                if atom_name not in [' N  ', ' CA ', ' C  ', ' O  ']:
                    sidechain_only_iselection.append(i_seq)
            sites_cart_sidechain = \
              sites_cart_moving.select(sidechain_only_iselection)
            sites_frac_residue = self.unit_cell.fractionalize(
                sites_cart_sidechain)
            sigma_cutoff = 1.0
            sigma_residue = []
            for rsf in sites_frac_residue:
                if self.target_map_data.eight_point_interpolation(
                        rsf) < sigma_cutoff:
                    sigma_residue.append(False)
                else:
                    sigma_residue.append(True)
            sigma_count = 0
            for sigma_state in sigma_residue:
                if sigma_state:
                    sigma_count += 1
                else:
                    break
            if sigma_count < sigma_count_start:
                sites_cart_moving.set_selected(residue_iselection,
                                               sites_cart_residue_start)
                xray_structure.set_sites_cart(sites_cart_moving)
                return False
            return True
        else:
            sites_cart_moving.set_selected(residue_iselection,
                                           sites_cart_residue_start)
            xray_structure.set_sites_cart(sites_cart_moving)
            return False
  def search(
        self,
        atom_group,
        all_dict,
        m_chis,
        r_chis,
        rotamer,
        sites_cart_moving,
        xray_structure,
        key):
    include_ca_hinge = False
    axis_and_atoms_to_rotate, tardy_labels= \
      rotatable_bonds.axes_and_atoms_aa_specific(
          residue=atom_group,
          mon_lib_srv=self.mon_lib_srv,
          remove_clusters_with_all_h=True,
          include_labels=True,
          log=None)
    if (axis_and_atoms_to_rotate is None) :
      print >> self.log, "Skipped %s rotamer (TARDY error)" % key
      return False
    assert len(m_chis) == len(r_chis)
    #exclude H-only clusters if necessary
    while len(axis_and_atoms_to_rotate) > len(m_chis):
      axis_and_atoms_to_rotate = \
        axis_and_atoms_to_rotate[:-1]
    assert len(m_chis) == len(axis_and_atoms_to_rotate)
    counter = 0
    residue_iselection = atom_group.atoms().extract_i_seq()
    cur_ca = None
    ca_add = None
    ca_axes = []
    for atom in atom_group.atoms():
      if atom.name == " CA ":
        cur_ca = atom.i_seq
    if cur_ca is not None:
      cur_c_alpha_hinges = self.c_alpha_hinges.get(cur_ca)
      if cur_c_alpha_hinges is not None:
        residue_length = len(tardy_labels)
        for ca_pt in cur_c_alpha_hinges[0]:
          residue_iselection.append(ca_pt)
          tardy_labels.append(self.name_hash[ca_pt][0:4])
        for bb_pt in cur_c_alpha_hinges[1]:
          residue_iselection.append(bb_pt)
          tardy_labels.append(self.name_hash[bb_pt][0:4])
        end_pts = (residue_length, residue_length+1)
        group = []
        for i, value in enumerate(tardy_labels):
          if i not in end_pts:
            group.append(i)
        ca_add = [end_pts, group]
        ca_axes.append(ca_add)
        for ax in axis_and_atoms_to_rotate:
          ca_axes.append(ax)
    sites_cart_residue = \
      sites_cart_moving.select(residue_iselection)
    sites_cart_residue_start = sites_cart_residue.deep_copy()
    selection = flex.bool(
                  len(sites_cart_moving),
                  residue_iselection)
    rev_first_atoms = []

    rev_start = fit_rotamers.rotamer_evaluator(
      sites_cart_start = sites_cart_residue_start,
      unit_cell        = self.unit_cell,
      two_mfo_dfc_map  = self.target_map_data,
      mfo_dfc_map      = self.residual_map_data)

    sidechain_only_iselection = flex.size_t()
    for i_seq in residue_iselection:
      atom_name = self.name_hash[i_seq][0:4]
      if atom_name not in [' N  ', ' CA ', ' C  ', ' O  ']:
        sidechain_only_iselection.append(i_seq)
    sites_cart_sidechain = \
      sites_cart_moving.select(sidechain_only_iselection)
    sites_frac_residue = self.unit_cell.fractionalize(sites_cart_sidechain)
    sigma_cutoff = 1.0
    sigma_residue = []
    for rsf in sites_frac_residue:
      if self.target_map_data.eight_point_interpolation(rsf) < sigma_cutoff:
        sigma_residue.append(False)
      else:
        sigma_residue.append(True)
    sigma_count_start = 0
    for sigma_state in sigma_residue:
      if sigma_state:
        sigma_count_start += 1
      else:
        break

    for aa in axis_and_atoms_to_rotate:
      axis = aa[0]
      atoms = aa[1]
      new_xyz = flex.vec3_double()
      angle_deg = r_chis[counter] - m_chis[counter]
      #skip angle rotations that are close to zero
      if math.fabs(angle_deg) < 0.01:
        counter += 1
        continue
      if angle_deg < 0:
        angle_deg += 360.0
      for atom in atoms:
        new_xyz = rotate_point_around_axis(
                    axis_point_1=sites_cart_residue[axis[0]],
                    axis_point_2=sites_cart_residue[axis[1]],
                    point=sites_cart_residue[atom],
                    angle=angle_deg, deg=True)
        sites_cart_residue[atom] = new_xyz
      counter += 1

    #***** TEST *****
    sites_cart_moving.set_selected(
      residue_iselection, sites_cart_residue)
    cur_rotamer, cur_chis, cur_value = rotalyze.evaluate_rotamer(
      atom_group=atom_group,
      sidechain_angles=self.sa,
      rotamer_evaluator=self.rotamer_evaluator,
      rotamer_id=self.rotamer_id,
      all_dict=all_dict,
      sites_cart=sites_cart_moving)
    assert rotamer == cur_rotamer
    #****************

    if len(ca_axes) == 0:
      eval_axes = axis_and_atoms_to_rotate
    else:
      eval_axes = ca_axes
      include_ca_hinge = True
    for i_aa, aa in enumerate(eval_axes):
      if(i_aa == len(eval_axes)-1):
        sites_aa = flex.vec3_double()
        for aa_ in aa[1]:
          sites_aa.append(sites_cart_residue[aa_])
      elif i_aa == 0 and include_ca_hinge:
        sites_aa = flex.vec3_double()
        for aa_ in aa[1]:
          sites_aa.append(sites_cart_residue[aa_])
      else:
        sites_aa = flex.vec3_double([sites_cart_residue[aa[1][0]]])
      rev_i = fit_rotamers.rotamer_evaluator(
        sites_cart_start = sites_aa,
        unit_cell        = self.unit_cell,
        two_mfo_dfc_map  = self.target_map_data,
        mfo_dfc_map      = self.residual_map_data)
      rev_first_atoms.append(rev_i)

    rev = fit_rotamers.rotamer_evaluator(
      sites_cart_start = sites_cart_residue,
      unit_cell        = self.unit_cell,
      two_mfo_dfc_map  = self.target_map_data,
      mfo_dfc_map      = self.residual_map_data)

    residue_sites_best = sites_cart_residue.deep_copy()
    residue_sites_best, rotamer_id_best = \
      fit_rotamers.torsion_search(
        residue_evaluator=rev,
        cluster_evaluators=rev_first_atoms,
        axes_and_atoms_to_rotate=eval_axes,
        rotamer_sites_cart=sites_cart_residue,
        rotamer_id_best=rotamer,
        residue_sites_best=residue_sites_best,
        params = self.torsion_params,
        rotamer_id = rotamer,
        include_ca_hinge = include_ca_hinge)
    sites_cart_moving.set_selected(
        residue_iselection, residue_sites_best)
    xray_structure.set_sites_cart(sites_cart_moving)
    cur_rotamer, cur_chis, cur_value = rotalyze.evaluate_rotamer(
      atom_group=atom_group,
      sidechain_angles=self.sa,
      rotamer_evaluator=self.rotamer_evaluator,
      rotamer_id=self.rotamer_id,
      all_dict=all_dict,
      sites_cart=sites_cart_moving)
    rotamer_match = (cur_rotamer == rotamer)
    if rev_start.is_better(sites_cart=residue_sites_best,
                           percent_cutoff=0.15, verbose=True) and \
       rotamer_match:
      sidechain_only_iselection = flex.size_t()
      for i_seq in residue_iselection:
        atom_name = self.name_hash[i_seq][0:4]
        if atom_name not in [' N  ', ' CA ', ' C  ', ' O  ',
                             ' OXT', ' H  ', ' HA ']:
          sidechain_only_iselection.append(i_seq)
      selection = flex.bool(
                    len(sites_cart_moving),
                    sidechain_only_iselection)
      selection_within = xray_structure.selection_within(
      radius    = 1.0,
      selection = selection)
      #check for bad steric clashes
      created_clash = False
      for i, state in enumerate(selection_within):
        if state:
          if i not in sidechain_only_iselection:
            #print >> self.log, "atom clash: ", self.name_hash[i]
            created_clash = True
      if created_clash:
        sites_cart_moving.set_selected(
          residue_iselection, sites_cart_residue_start)
        xray_structure.set_sites_cart(sites_cart_moving)
        return False

      sidechain_only_iselection = flex.size_t()
      for i_seq in residue_iselection:
        atom_name = self.name_hash[i_seq][0:4]
        if atom_name not in [' N  ', ' CA ', ' C  ', ' O  ']:
          sidechain_only_iselection.append(i_seq)
      sites_cart_sidechain = \
        sites_cart_moving.select(sidechain_only_iselection)
      sites_frac_residue = self.unit_cell.fractionalize(sites_cart_sidechain)
      sigma_cutoff = 1.0
      sigma_residue = []
      for rsf in sites_frac_residue:
        if self.target_map_data.eight_point_interpolation(rsf) < sigma_cutoff:
          sigma_residue.append(False)
        else:
          sigma_residue.append(True)
      sigma_count = 0
      for sigma_state in sigma_residue:
        if sigma_state:
          sigma_count += 1
        else:
          break
      if sigma_count < sigma_count_start:
        sites_cart_moving.set_selected(
          residue_iselection, sites_cart_residue_start)
        xray_structure.set_sites_cart(sites_cart_moving)
        return False
      return True
    else:
      sites_cart_moving.set_selected(
        residue_iselection, sites_cart_residue_start)
      xray_structure.set_sites_cart(sites_cart_moving)
      return False
Beispiel #15
0
def rotatable(pdb_hierarchy, mon_lib_srv, restraints_manager, log):
  """
  General tool to identify rotatable H, such as C-O-H, C-H3, in any molecule.
  """
  result = []
  def analyze_group_aa_specific(g, atoms):
    result = []
    for gi in g:
      assert len(gi[0])==2 # because this is axis
      assert len(gi[1])>0  # because these are atoms rotating about this axis
      # condition 1: axis does not contain H or D
      a1, a2 = atoms[gi[0][0]], atoms[gi[0][1]]
      e1 = a1.element.strip().upper()
      e2 = a2.element.strip().upper()
      condition_1 = [e1,e2].count("H")==0 and [e1,e2].count("D")==0
      # condition 2: all atoms to rotate are H or D
      condition_2 = True
      rot_atoms = []
      for gi1i in gi[1]:
        if(not atoms[gi1i].element.strip().upper() in ["H","D"]):
          condition_2 = False
          break
      rot_atoms = []
      axis = None
      if(condition_1 and condition_2):
        axis = [a1.i_seq, a2.i_seq]
        for gi1i in gi[1]:
          rot_atoms.append(atoms[gi1i].i_seq)
        result.append([axis, rot_atoms])
    if(len(result)>0 is not None): return result
    else: return None
  def analyze_group_general(g, atoms, bps, psel):
    result = []
    for gi in g:
      condition_1, condition_2, condition_3 = None,None,None
      assert len(gi[0])==2 # because this is axis
      assert len(gi[1])>0  # because these are atoms rotating about this axis
      # condition 1: axis does not contain H or D
      a1, a2 = atoms[gi[0][0]], atoms[gi[0][1]]
      e1 = a1.element.strip().upper()
      e2 = a2.element.strip().upper()
      condition_1 = [e1,e2].count("H")==0 and [e1,e2].count("D")==0
      s1 = set(gi[1])
      if(condition_1):
        # condition 2: all atoms to rotate are H or D
        condition_2 = True
        for gi1i in gi[1]:
          if(not atoms[gi1i].element.strip().upper() in ["H","D"]):
            condition_2 = False
            break
        if(condition_2):
          # condition 3: one of axis atoms is terminal (bonded to another axis
          #              atom and hydrogens
          condition_3 = False
          for gia in gi[0]:
            bonds_involved_into = []
            for bp in bps:
              if(gia in bp.i_seqs):
                for i_seq in bp.i_seqs:
                  if(atoms[i_seq].element.strip().upper() in ["H","D"]):
                    bonds_involved_into.append(i_seq)
            s2 = set(bonds_involved_into)
            s = list(s1 & s2)
            if(len(s)>0): condition_3 = True
          #
          if(condition_1 and condition_2 and condition_3):
            axis = [a1.i_seq, a2.i_seq]
            rot_atoms = []
            in_plane = False
            for i in bonds_involved_into:
              if(atoms[i].i_seq in psel): in_plane = True
              rot_atoms.append(atoms[i].i_seq)
            if(not in_plane): result.append([axis, rot_atoms])
    if(len(result)>0 is not None): return result
    else: return None
  if(restraints_manager is not None):
    psel = flex.size_t()
    for p in restraints_manager.geometry.planarity_proxies:
      psel.extend(p.i_seqs)
  # very handy for debugging: do not remove
  #NAMES = pdb_hierarchy.atoms().extract_name()
  #
  get_class = iotbx.pdb.common_residue_names_get_class
  import scitbx.graph.tardy_tree
  for model in pdb_hierarchy.models():
    for chain in model.chains():
      residue_groups = chain.residue_groups()
      n_residues = len(residue_groups)
      for i_rg, residue_group in enumerate(residue_groups):
        first_or_last = i_rg == 0 or i_rg+1 == n_residues
        conformers = residue_group.conformers()
        for conformer in residue_group.conformers():
          for residue in conformer.residues():
            if(residue.resname.strip().upper() == "PRO"): continue
            atoms = residue.atoms()
            if(get_class(name=residue.resname)=="common_water" and
               len(atoms)==1):
                 continue
            if(get_class(name=residue.resname)=="common_amino_acid" and
               not first_or_last):
              fr = rotatable_bonds.axes_and_atoms_aa_specific(
                residue=residue, mon_lib_srv=mon_lib_srv,
                remove_clusters_with_all_h=False, log=log)
              if(fr is not None):
                r = analyze_group_aa_specific(g=fr, atoms=atoms)
                if(r is not None):
                  for r_ in r: result.append(r_)
            elif(restraints_manager is not None):
              elements = atoms.extract_element()
              names = atoms.extract_name()
              # create tardy_model
              iselection = atoms.extract_i_seq()
              sites_cart = atoms.extract_xyz()
              masses     = [1]*sites_cart.size()
              labels     = range(sites_cart.size())
              grm_i = restraints_manager.select(iselection)
              bps = grm_i.geometry.pair_proxies(
                sites_cart = sites_cart).bond_proxies.simple
              edge_list = []
              for bp in bps: edge_list.append(bp.i_seqs)
              fixed_vertex_lists = []
              tmp_r = []
              # try all possible edges (bonds) as potential fixed vertices and
              # accept only non-redundant
              for bp in bps:
                tardy_tree = scitbx.graph.tardy_tree.construct(
                  sites              = sites_cart,
                  edge_list          = edge_list,
                  fixed_vertex_lists = [bp.i_seqs])
                tardy_model = scitbx.rigid_body.tardy_model(
                  labels        = labels,
                  sites         = sites_cart,
                  masses        = masses,
                  tardy_tree    = tardy_tree,
                  potential_obj = None)
                fr = rotatable_bonds.axes_and_atoms_aa_specific(
                  residue=residue, mon_lib_srv=mon_lib_srv,
                  remove_clusters_with_all_h=False, log=None,
                  tardy_model = tardy_model)
                if(fr is not None):
                  r = analyze_group_general(g=fr, atoms=atoms,bps=bps,psel=psel)
                  if(r is not None and len(r)>0):
                    for r_ in r:
                      if(not r_ in tmp_r):
                        if(not r_ in tmp_r): tmp_r.append(r_)
              for r in tmp_r:
                result.append(r)
  # very handy for debugging: do not remove
  #for r_ in result:
  #  print "  analyze_group:", r_, \
  #    [NAMES[i] for i in r_[0]], [NAMES[i] for i in r_[1]], residue.resname
  return result