def get_fixed_moving_parts(pdb_hierarchy, out_res_num, n_following, n_previous): # limitation: only one chain in pdb_hierarchy!!! original_pdb_h = pdb_hierarchy.deep_copy() start_res_num, end_res_num = get_res_nums_around( pdb_hierarchy, out_res_num, n_following, n_previous) xrs = original_pdb_h.extract_xray_structure() truncate_to_poly_gly(pdb_hierarchy, start_res_num, end_res_num) cache = pdb_hierarchy.atom_selection_cache() # print "selectioin:", "resid %d through %d" % (start_res_num, end_res_num) m_selection = cache.iselection("(name N or name CA or name C or name O) and resid %s through %s" % (start_res_num, end_res_num)) moving_h = pdb_hierarchy.select(m_selection) moving_h.reset_atom_i_seqs() # print dir(moving_h) # STOP() m_cache = moving_h.atom_selection_cache() # print "len inp h atoms", pdb_hierarchy.atoms().size() # print "len moving_h atoms", moving_h.atoms().size() moving_ref_atoms_iseqs = [] # here we need N, CA, C atoms from the end_res_num residue eff_end_resnum = end_res_num sel = m_cache.selection("resid %s" % end_res_num) while len(moving_h.select(sel).atoms()) == 0: eff_end_resnum -= 1 sel = m_cache.selection("resid %s" % eff_end_resnum) sel = m_cache.selection("resid %s and name N" % eff_end_resnum) a = moving_h.select(sel).atoms()[0] moving_ref_atoms_iseqs.append(a.i_seq) fixed_N = a.detached_copy() sel = m_cache.selection("resid %s and name CA" % eff_end_resnum) a = moving_h.select(sel).atoms()[0] moving_ref_atoms_iseqs.append(a.i_seq) fixed_CA = a.detached_copy() sel = m_cache.selection("resid %s and name C" % eff_end_resnum) a = moving_h.select(sel).atoms()[0] moving_ref_atoms_iseqs.append(a.i_seq) fixed_C = a.detached_copy() fixed_ref_atoms = [fixed_N, fixed_CA, fixed_C] return moving_h, moving_ref_atoms_iseqs, fixed_ref_atoms, m_selection
def secondary_structure_from_sequence(pdb_str, sequence=None, pdb_hierarchy_template=None, rotamer_manager=None): """ Return pdb.hierarchy with secondary structure according to sequence or reference hierarcy. If reference hierarchy provided, the resulting hierarchy will be rigid body aligned to it. Residue numbers will start from 1. pdb_str - "ideal" structure at least 2 residues long. sequence - string with sequence (one-letter codes) pdb_hierarchy_template - reference hierarchy. """ if rotamer_manager is None: rotamer_manager = RotamerEval() pht = pdb_hierarchy_template assert [sequence, pht].count(None) == 1 if pht is not None: lk = len(pht.altloc_indices().keys()) if lk ==0: raise Sorry( "Hierarchy template in secondary_structure_from_sequence is empty") else: assert len(pht.altloc_indices().keys()) == 1, \ "Alternative conformations are not supported" number_of_residues = len(sequence) if sequence!=None else \ len(pht.models()[0].chains()[0].conformers()[0].residues()) if number_of_residues<1: raise Sorry('sequence should contain at least one residue.') ideal_res_dict = idealized_aa.residue_dict() real_res_list = None if pht: real_res_list = pht.models()[0].chains()[0].residue_groups() pdb_hierarchy = iotbx.pdb.input(source_info=None, lines=pdb_str).\ construct_hierarchy() truncate_to_poly_gly(pdb_hierarchy) chain = pdb_hierarchy.models()[0].chains()[0] current_gly_ag = chain.residue_groups()[0].atom_groups()[0] new_chain = iotbx.pdb.hierarchy.chain(id="A") new_chain.pre_allocate_residue_groups(number_of_additional_residue_groups=\ number_of_residues) r, t = get_r_t_matrices_from_structure(pdb_str) for j in range(number_of_residues): # put ALA rg = iotbx.pdb.hierarchy.residue_group(icode="") rg.resseq = j+1 new_chain.append_residue_group(residue_group=rg) ag_to_place = current_gly_ag.detached_copy() rg.append_atom_group(atom_group=ag_to_place) current_gly_ag.atoms().set_xyz( r.elems*current_gly_ag.atoms().extract_xyz()+t.elems) current_reference_ag = real_res_list[j].atom_groups()[0] if pht else \ ideal_res_dict[three_one[sequence[j]].lower()].models()[0].chains()[0].\ residue_groups()[0].atom_groups()[0] side_chain_placement(ag_to_place, current_reference_ag, rotamer_manager) new_pdb_h = iotbx.pdb.hierarchy.new_hierarchy_from_chain(new_chain) # align to real if pht != None: fixed_sites, moving_sites = get_matching_sites_cart_in_both_h(pht, new_pdb_h) assert len(fixed_sites) == len(moving_sites) lsq_fit_obj = superpose.least_squares_fit(reference_sites = fixed_sites, other_sites = moving_sites) new_pdb_h.atoms().set_xyz( lsq_fit_obj.r.elems*new_pdb_h.atoms().extract_xyz()+lsq_fit_obj.t.elems) return new_pdb_h
def get_fixed_moving_parts(pdb_hierarchy, out_res_num_list, n_following, n_previous, ss_annotation=None, direction_forward=True, log=None): # limitation: only one chain in pdb_hierarchy!!! if log is None: log = StringIO() original_pdb_h = pdb_hierarchy.deep_copy() # print >> log, " out_res_num, n_following, n_previous", out_res_num_list, n_following, n_previous start_res_num, end_res_num = get_res_nums_around(pdb_hierarchy, out_res_num_list, n_following, n_previous, include_intermediate=False, avoid_ss_annot=ss_annotation) print >> log, " start_res_num, end_res_num", start_res_num, end_res_num xrs = original_pdb_h.extract_xray_structure() truncate_to_poly_gly(pdb_hierarchy, start_res_num, end_res_num) cache = pdb_hierarchy.atom_selection_cache() # print "POSSIBLE ERROR:", "selectioin:", "(name N or name CA or name C or name O) and resid %s through %s" % ( # start_res_num, end_res_num) m_selection = cache.iselection( "(name N or name CA or name C or name O) and resid %s through %s" % ( start_res_num, end_res_num)) # Somewhere here would be the place to tweak n_following, n_previous to # exclude SS parts. It would be nice to increase n_prev in case # we need to cut on n_following etc. # If no ss_annotation is provided, don't filter. contains_ss_element = False if ss_annotation is not None: ss_selection_str = ss_annotation.overall_selection() ss_selection = cache.iselection(ss_selection_str) intersect = flex.size_t(sorted(list(set(ss_selection) & set(m_selection)))) if intersect.size() > 0: intersect_h = pdb_hierarchy.select(intersect) print >> log, "Hitting SS element" print >> log, intersect_h.as_pdb_string() contains_ss_element = False assert intersect_h.atoms_size() > 0, "Wrong atom count in SS intersection" # assert 0, "hitting SS element!" moving_h = pdb_hierarchy.select(m_selection) moving_h.reset_atom_i_seqs() # print dir(moving_h) # STOP() m_cache = moving_h.atom_selection_cache() # print "len inp h atoms", pdb_hierarchy.atoms_size() # print "len moving_h atoms", moving_h.atoms_size() # here we need N, CA, C atoms from the end_res_num residue eff_end_resnum = end_res_num if not direction_forward: eff_end_resnum = start_res_num sel = m_cache.selection("resid %s" % end_res_num) int_eff_resnum = hy36decode(4,eff_end_resnum) while len(moving_h.select(sel).atoms()) == 0: if direction_forward: int_eff_resnum -= 1 else: int_eff_resnum += 1 sel = m_cache.selection("resid %d" % int_eff_resnum) eff_end_resnum = hy36encode(4, int_eff_resnum) anchor_present = True moving_ref_atoms_iseqs = [] fixed_ref_atoms = [] # print "fixed_ref_atoms:" base_sel = "resid %s and name " % eff_end_resnum for ssel in ["N", "CA", "C"]: sel = m_cache.selection(base_sel+ssel) atoms = moving_h.select(sel).atoms() if atoms.size() > 0: moving_ref_atoms_iseqs.append(atoms[0].i_seq) fixed_ref_atoms.append(atoms[0].detached_copy()) else: anchor_present = False # print " ", atoms[0].id_str() print "anchor_present", anchor_present return (moving_h, moving_ref_atoms_iseqs, fixed_ref_atoms, m_selection, contains_ss_element, anchor_present)
def get_fixed_moving_parts(pdb_hierarchy, out_res_num, n_following, n_previous, ss_annotation=None): # limitation: only one chain in pdb_hierarchy!!! original_pdb_h = pdb_hierarchy.deep_copy() start_res_num, end_res_num = get_res_nums_around(pdb_hierarchy, out_res_num, n_following, n_previous) xrs = original_pdb_h.extract_xray_structure() truncate_to_poly_gly(pdb_hierarchy, start_res_num, end_res_num) cache = pdb_hierarchy.atom_selection_cache() # print "selectioin:", "resid %d through %d" % (start_res_num, end_res_num) m_selection = cache.iselection( "(name N or name CA or name C or name O) and resid %s through %s" % (start_res_num, end_res_num)) # Somewhere here would be the place to tweak n_following, n_previous to # exclude SS parts. It would be nice to increase n_prev in case # we need to cut on n_following etc. # If no ss_annotation is provided, don't filter. contains_ss_element = False if ss_annotation is not None: ss_selection_str = ss_annotation.overall_selection() ss_selection = cache.iselection(ss_selection_str) intersect = flex.size_t( sorted(list(set(ss_selection) & set(m_selection)))) if intersect.size > 0: intersect_h = pdb_hierarchy.select(intersect) print "Hitting SS element" print intersect_h.as_pdb_string() contains_ss_element = True # assert 0, "hitting SS element!" moving_h = pdb_hierarchy.select(m_selection) moving_h.reset_atom_i_seqs() # print dir(moving_h) # STOP() m_cache = moving_h.atom_selection_cache() # print "len inp h atoms", pdb_hierarchy.atoms_size() # print "len moving_h atoms", moving_h.atoms_size() moving_ref_atoms_iseqs = [] # here we need N, CA, C atoms from the end_res_num residue eff_end_resnum = end_res_num sel = m_cache.selection("resid %s" % end_res_num) while len(moving_h.select(sel).atoms()) == 0: eff_end_resnum -= 1 sel = m_cache.selection("resid %s" % eff_end_resnum) sel = m_cache.selection("resid %s and name N" % eff_end_resnum) a = moving_h.select(sel).atoms()[0] moving_ref_atoms_iseqs.append(a.i_seq) fixed_N = a.detached_copy() sel = m_cache.selection("resid %s and name CA" % eff_end_resnum) a = moving_h.select(sel).atoms()[0] moving_ref_atoms_iseqs.append(a.i_seq) fixed_CA = a.detached_copy() sel = m_cache.selection("resid %s and name C" % eff_end_resnum) a = moving_h.select(sel).atoms()[0] moving_ref_atoms_iseqs.append(a.i_seq) fixed_C = a.detached_copy() fixed_ref_atoms = [fixed_N, fixed_CA, fixed_C] return moving_h, moving_ref_atoms_iseqs, fixed_ref_atoms, m_selection, contains_ss_element