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
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
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
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
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_)
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
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
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)
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
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
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
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