def align_model (self, i_model) : from scitbx.array_family import flex from scitbx.math import superpose hierarchy_moving = self.related_chains[i_model].pdb_hierarchy mov_atoms = hierarchy_moving.atoms() mov_atoms.reset_i_seq() sel_cache = hierarchy_moving.atom_selection_cache() mov_atom_selection = sel_cache.selection(self.atom_selection_string) mov_chain = hierarchy_moving.only_model().only_chain() sel_ref = flex.size_t() sel_mov = flex.size_t() for residue_group in mov_chain.residue_groups() : for atom in residue_group.only_atom_group().atoms() : if (not mov_atom_selection[atom.i_seq]) : continue resid = residue_group.resid() ref_name = "%s %s" % (resid, atom.name.strip()) if (ref_name in self.atoms_ref) : sel_mov.append(atom.i_seq) sel_ref.append(self.atoms_ref.index(ref_name)) if (len(sel_ref) == 0) : assert (self.atom_selection_string is not None) return None assert (len(sel_ref) > 0) and (len(sel_ref) == len(sel_mov)) xyz_mov = mov_atoms.extract_xyz() sites_mov = xyz_mov.select(sel_mov) sites_ref = self.reference_sites.select(sel_ref) if (self.sieve_fit) : return superpose.sieve_fit( sites_fixed=sites_ref, sites_moving=sites_mov, frac_discard=self.frac_discard) else : return superpose.least_squares_fit( reference_sites=sites_ref, other_sites=sites_mov)
def align_model(self, i_model): from scitbx.array_family import flex from scitbx.math import superpose hierarchy_moving = self.related_chains[i_model].pdb_hierarchy mov_atoms = hierarchy_moving.atoms() mov_atoms.reset_i_seq() sel_cache = hierarchy_moving.atom_selection_cache() mov_atom_selection = sel_cache.selection(self.atom_selection_string) mov_chain = hierarchy_moving.only_model().only_chain() sel_ref = flex.size_t() sel_mov = flex.size_t() for residue_group in mov_chain.residue_groups(): for atom in residue_group.only_atom_group().atoms(): if (not mov_atom_selection[atom.i_seq]): continue resid = residue_group.resid() ref_name = "%s %s" % (resid, atom.name.strip()) if (ref_name in self.atoms_ref): sel_mov.append(atom.i_seq) sel_ref.append(self.atoms_ref.index(ref_name)) if (len(sel_ref) == 0): assert (self.atom_selection_string is not None) return None assert (len(sel_ref) > 0) and (len(sel_ref) == len(sel_mov)) xyz_mov = mov_atoms.extract_xyz() sites_mov = xyz_mov.select(sel_mov) sites_ref = self.reference_sites.select(sel_ref) if (self.sieve_fit): return superpose.sieve_fit( sites_fixed=sites_ref, sites_moving=sites_mov, frac_discard=self.frac_discard) else : return superpose.least_squares_fit( reference_sites=sites_ref, other_sites=sites_mov)
def morph_models (params, out=None, debug=False) : assert len(params.morph.pdb_file) > 1 assert (len(params.morph.frames) == (len(params.morph.pdb_file) - 1)) if (out is None) : out = sys.stdout from mmtbx.monomer_library import pdb_interpretation, server from iotbx import file_reader pdb_hierarchies = [] for pdb_file in params.morph.pdb_file : pdb_in = file_reader.any_file(pdb_file, force_type="pdb") pdb_in.check_file_type("pdb") hierarchy = pdb_in.file_object.hierarchy pdb_hierarchies.append(hierarchy) new_pdb = homogenize_structures( pdb_hierarchies=pdb_hierarchies, delete_waters=params.morph.delete_waters, debug=debug) mon_lib_srv = server.server() ener_lib = server.ener_lib() for cif_file in params.morph.cif_file : print "Loading CIF file %s" % cif_file cif_object = server.read_cif(file_name=cif_file) mon_lib_serv.process_cif_object(cif_object=cif_object, file_name=cif_file) ener_lib.process_cif_object(cif_object=cif_object, file_name=cif_file) if (params.morph.minimization.interpolate_dihedrals) : params.pdb_interpretation.peptide_link.discard_psi_phi = False processed_pdb_file = pdb_interpretation.process( mon_lib_srv=mon_lib_srv, ener_lib=ener_lib, params=params.pdb_interpretation, pdb_inp=new_pdb[0], substitute_non_crystallographic_unit_cell_if_necessary=True) all_chain_proxies = processed_pdb_file.all_chain_proxies static_coords = [ all_chain_proxies.pdb_hierarchy.atoms().extract_xyz() ] for pdb_inp in new_pdb[1:] : sites = pdb_inp.atoms().extract_xyz() static_coords.append(sites) if (params.morph.fitting.align_atoms is not None) : print >> out, "Superposing on initial structure..." selection_cache = all_chain_proxies.pdb_hierarchy.atom_selection_cache() selection = selection_cache.selection(params.morph.fitting.align_atoms) if (selection.count(True) == 0) : raise Sorry("No atoms in alignment selection!") i_ref = params.morph.fitting.reference_structure sites_fixed = static_coords[i_ref] j = 0 while (j < len(static_coords)) : if (j != i_ref) : sites_moving = static_coords[j] assert (len(sites_moving) == len(sites_fixed) > 0) if (params.morph.fitting.sieve_fit) : from scitbx.math import superpose lsq_fit = superpose.sieve_fit( sites_fixed=sites_fixed, sites_moving=sites_moving, selection=selection) sites_moving_new = lsq_fit.r.elems * sites_moving + lsq_fit.t.elems else : sites_moving_new = fit_sites( sites_fixed=sites_fixed, sites_moving=sites_moving, selection=selection) assert (sites_moving_new.size() == sites_moving.size()) static_coords[j] = sites_moving_new j += 1 print >> out, "Ready to morph" morphs = [] restraints_manager = processed_pdb_file.geometry_restraints_manager() for i in range(len(params.morph.pdb_file) - 1) : morph = adiabatic_mapping( pdb_hierarchy=all_chain_proxies.pdb_hierarchy, restraints_manager=restraints_manager, start_coords = static_coords[i], end_coords = static_coords[i+1], params = params.morph.minimization, nsteps = params.morph.frames[i], out=out) morphs.append(morph) serial = 1 if (params.morph.output_directory is not None) : output_base = os.path.join(params.morph.output_directory, params.morph.output_prefix) else : output_base = params.morph.output_prefix for i, morph in enumerate(morphs) : serial = morph.write_pdb_files( output_base=output_base, serial=serial, serial_format=params.morph.serial_format, pause=params.morph.pause, pause_at_end=(i == (len(morphs) - 1)), log=out) f = open("%s.pml" % output_base, "w") for i in range(1, serial) : format_base = "%s_%s" % (output_base, params.morph.serial_format) print >> f, "load %s.pdb, morph" % (format_base % i) f.close() print >> out, "PyMOL script is %s.pml" % output_base
def find_ncs_operators (pdb_hierarchy, max_rmsd=2.0, try_sieve_fit=True, log=None) : """ Determines all possible NCS transformation matrices for the input structure, based on sequence alignemnt and simple C-alpha superposition. There may be multiple sets of operators but these will eventually become a flat list. :param max_rmsd: maximum allowable RMSD between NCS-related chains for use in ligand superposition :param try_sieve_fit: also perform a sieve fit between chains and use the resulting operator if the RMSD is lower than the global fit :param log: filehandle-like object :returns: list of lists of group_operators objects """ import iotbx.ncs from scitbx.math import superpose from scitbx.array_family import flex ncs_obj = iotbx.ncs.input(hierarchy=pdb_hierarchy) ncs_groups = [] for k,v in ncs_obj.ncs_to_asu_selection.iteritems(): ncs_groups.append([k]+v) if (len(ncs_groups) == 0) : raise Sorry("No NCS present in the input model.") for k, group in enumerate(ncs_groups) : print >> log, "Group %d:" % (k+1) for sele in group : print >> log, " %s" % sele selection_cache = pdb_hierarchy.atom_selection_cache() pdb_atoms = pdb_hierarchy.atoms() sites_cart = pdb_atoms.extract_xyz() operators = [] def get_selection (sele_str) : sele_str = "(%s) and name CA and (altloc ' ' or altloc A)" % sele_str return selection_cache.selection(sele_str).iselection() for restraint_group in ncs_groups : group_ops = [] assert (len(restraint_group) >= 2) # XXX This is currently an all-vs-all loop, which means that each # NCS relationship will be calculated (and stored) twice. Need to figure # out whether this actually matters in practice. for j, sele_str in enumerate(restraint_group) : sele_j = get_selection(sele_str) group = group_operators(sele_j, sele_str, sites_cart) assert (len(sele_j) > 0) calpha_ids = [] for i_seq in sele_j : resid = resid_str(pdb_atoms[i_seq]) if (not resid in calpha_ids) : calpha_ids.append(resid) for k, sele_str_k in enumerate(restraint_group) : if (k == j) : continue sele_k = get_selection(sele_str_k) group_sele = flex.size_t() group_ids = set([]) assert (len(sele_k) > 0) # poor man's sequence alignment for i_seq in sele_k : id_str = resid_str(pdb_atoms[i_seq]) if (id_str in group_ids) : continue group_ids.add(id_str) if (id_str in calpha_ids) : group_sele.append(i_seq) first_sele_copy = flex.size_t() #first_sele.deep_copy() delete_indices = [] for i_seq, id_str in zip(sele_j, calpha_ids) : if (id_str in group_ids) : first_sele_copy.append(i_seq) assert (len(first_sele_copy) == len(group_sele)) assert (len(group_sele) > 0) sites_ref = sites_cart.select(first_sele_copy) sites_group = sites_cart.select(group_sele).deep_copy() lsq_fit = superpose.least_squares_fit( reference_sites=sites_ref, other_sites=sites_group) sites_fit = lsq_fit.r.elems * sites_group + lsq_fit.t.elems rmsd = sites_ref.rms_difference(sites_fit) if (try_sieve_fit) : lsq_fit_2 = superpose.sieve_fit( sites_fixed=sites_ref, sites_moving=sites_group, frac_discard=0.25) sites_fit_2 = lsq_fit_2.r.elems * sites_group + lsq_fit_2.t.elems rmsd_2 = sites_ref.rms_difference(sites_fit) if (rmsd_2 < rmsd) : print >> log, " using sieve fit (RMSD = %.3f, RMSD(all) = %.3f)" %\ (rmsd_2, rmsd) lsq_fit = lsq_fit_2 rmsd = rmsd_2 print >> log, " %d versus %d RMSD = %.3f" % (j+1, k+1, rmsd) if (rmsd <= max_rmsd) : group.add_operator(lsq_fit.rt().inverse(), sele_str_k) else : print >> log, " exceeds cutoff, will not use this operator" group_ops.append(group) operators.append(group_ops) return operators