def refit_residues(pdb_hierarchy, cif_objects, fmodel, use_rotamers=True, anneal=False, verbose=True, allow_modified_residues=False, out=sys.stdout): """ Use real-space refinement tools to fit newly extended residues. """ from mmtbx.refinement.real_space import fit_residue from mmtbx.rotamer import rotamer_eval import mmtbx.monomer_library.server from mmtbx import building from scitbx.array_family import flex mon_lib_srv = mmtbx.monomer_library.server.server() rotamer_manager = rotamer_eval.RotamerEval() ppdb_out = box_out = out if (not verbose): ppdb_out = null_out() box_out = null_out() make_sub_header("Processing new model", out=ppdb_out) processed_pdb = building.reprocess_pdb( pdb_hierarchy=pdb_hierarchy, crystal_symmetry=fmodel.f_obs().crystal_symmetry(), cif_objects=cif_objects, out=ppdb_out) print("", file=ppdb_out) hierarchy = processed_pdb.all_chain_proxies.pdb_hierarchy xrs = processed_pdb.xray_structure() grm_geometry = processed_pdb.geometry_restraints_manager() make_sub_header("Fitting residues", out=out) target_map = fmodel.map_coefficients( map_type="2mFo-DFc", exclude_free_r_reflections=True).fft_map( resolution_factor=0.25).apply_sigma_scaling().real_map_unpadded() unit_cell = xrs.unit_cell() for chain in hierarchy.only_model().chains(): if (not chain.is_protein()) and (not allow_modified_residues): continue residue_groups = chain.residue_groups() for i_rg, residue_group in enumerate(residue_groups): prev_res = next_res = None atom_groups = residue_group.atom_groups() if (len(atom_groups) > 1): continue residue = atom_groups[0] atoms = residue.atoms() atoms.reset_tmp() segids = atoms.extract_segid() if (segids.all_eq("XXXX")): sites_start = atoms.extract_xyz() def get_two_fofc_mean(residue): sum = 0 n_atoms = 0 for atom in residue.atoms(): if (not atom.element.strip() in ["H", "D"]): site_frac = unit_cell.fractionalize( site_cart=atom.xyz) sum += target_map.eight_point_interpolation( site_frac) n_atoms += 1 assert (n_atoms > 0) return sum / n_atoms sites_start = atoms.extract_xyz().deep_copy() two_fofc_mean_start = get_two_fofc_mean(residue) refit = fit_residue.run_with_minimization( target_map=target_map, residue=residue, xray_structure=xrs, mon_lib_srv=mon_lib_srv, rotamer_manager=rotamer_manager, geometry_restraints_manager=grm_geometry, real_space_gradients_delta=fmodel.f_obs().d_min() * 0.25, rms_bonds_limit=0.01, rms_angles_limit=1.0, backbone_sample_angle=20, allow_modified_residues=allow_modified_residues) two_fofc_mean_end = get_two_fofc_mean(residue) sites_end = atoms.extract_xyz() flag = "" if (two_fofc_mean_end > two_fofc_mean_start): flag = " <-- keep" xrs = refit.xray_structure else: atoms.set_xyz(sites_start) for atom in atoms: atom.tmp = 1 print(" residue '%s' : rmsd=%5.3f 2fofc_start=%5.3f 2fofc_end=%5.3f%s" \ % (residue.id_str(), sites_end.rms_difference(sites_start), two_fofc_mean_start, two_fofc_mean_end, flag), file=out) return hierarchy, xrs
def real_space_refine ( pdb_hierarchy, fmodel, cif_objects, params, out, nproc=None, max_cycles=100, # arbitrarily large remediate=False) : from scitbx.array_family import flex i_cycle = 0 while (i_cycle < max_cycles) : print >> out, " Cycle %d:" % (i_cycle+1) # this keeps track of which residues were split in the previous cycle - # we only refine segments that have had residues added rebuilt_flags = pdb_hierarchy.atoms().extract_tmp_as_size_t() processed_pdb_file = building.reprocess_pdb( pdb_hierarchy=pdb_hierarchy, cif_objects=cif_objects, crystal_symmetry=fmodel.xray_structure, out=null_out()) # get the 2mFo-DFc map without new alternates! #two_fofc_map = fmodel.two_fofc_map(exclude_free_r_reflections=True) pdb_hierarchy = processed_pdb_file.all_chain_proxies.pdb_hierarchy pdb_atoms = pdb_hierarchy.atoms() xray_structure = processed_pdb_file.xray_structure() geometry_restraints_manager = \ processed_pdb_file.geometry_restraints_manager(show_energies=False) fmodel.update_xray_structure(xray_structure) sele_cache = pdb_hierarchy.atom_selection_cache() # FIXME very inefficient when looping! # this will include both the newly built residues and the original atoms, # including residues split to allow for backbone flexibility. sele_split = sele_cache.selection(alt_confs.SELECTION_MODIFIED) sele_main_conf = sele_cache.selection(alt_confs.SELECTION_OLD) assert (len(sele_split) > 0) k = 0 fragments = [] while (k < len(sele_split)) : if (sele_split[k]) : current_fragment = flex.size_t() while (sele_split[k]) : current_fragment.append(k) k += 1 atom_start = pdb_atoms[current_fragment[0]].fetch_labels() atom_end = pdb_atoms[current_fragment[-1]].fetch_labels() frag_selection = flex.bool(sele_split.size(), current_fragment) if (i_cycle > 0) : flags = rebuilt_flags.select(frag_selection) if flags.all_eq(0) : continue fragments.append(current_fragment) else : k += 1 if (len(fragments) == 0) : pass refine_fragments = rsr_fragments_parallel( pdb_hierarchy=pdb_hierarchy, fmodel=fmodel, processed_pdb_file=processed_pdb_file, sele_main_conf=sele_main_conf, rsr_fofc_map_target=(i_cycle==0 and params.cleanup.rsr_fofc_map_target)) refined = easy_mp.pool_map( fixed_func=refine_fragments, iterable=fragments, processes=nproc) sites_refined = pdb_atoms.extract_xyz() for result in refined : assert (result is not None) result.show(out=out, prefix=" ") sites_refined.set_selected(result.selection, result.sites_cart) pdb_atoms.set_xyz(sites_refined) xray_structure.set_sites_cart(sites_refined) fmodel.update_xray_structure(xray_structure) if (not remediate) or (max_cycles == 1) : break else : for atom in pdb_hierarchy.atoms() : if (atom.segid == alt_confs.SEGID_NEW_SPLIT) : atom.segid = alt_confs.SEGID_NEW_REBUILT print >> out, " checking for conformational strain..." n_split = alt_confs.spread_alternates( pdb_hierarchy=pdb_hierarchy, new_occupancy=params.residue_fitting.expected_occupancy, split_all_adjacent=False, selection=alt_confs.SELECTION_NEW_REBUILT) if (n_split > 0) : print >> out, " split another %d residue(s) - will re-run RSR" % \ n_split else : break i_cycle += 1 xray_structure = pdb_hierarchy.extract_xray_structure( crystal_symmetry=fmodel.xray_structure) fmodel.update_xray_structure(xray_structure, update_f_mask=True, update_f_calc=True) #fmodel.info().show_targets(out=out, text="After real-space refinement") t2 = time.time() return pdb_hierarchy
def real_space_refine( pdb_hierarchy, fmodel, cif_objects, params, out, nproc=None, max_cycles=100, # arbitrarily large remediate=False): from scitbx.array_family import flex i_cycle = 0 while (i_cycle < max_cycles): print(" Cycle %d:" % (i_cycle + 1), file=out) # this keeps track of which residues were split in the previous cycle - # we only refine segments that have had residues added rebuilt_flags = pdb_hierarchy.atoms().extract_tmp_as_size_t() processed_pdb_file = building.reprocess_pdb( pdb_hierarchy=pdb_hierarchy, cif_objects=cif_objects, crystal_symmetry=fmodel.xray_structure, out=null_out()) # get the 2mFo-DFc map without new alternates! #two_fofc_map = fmodel.two_fofc_map(exclude_free_r_reflections=True) pdb_hierarchy = processed_pdb_file.all_chain_proxies.pdb_hierarchy pdb_atoms = pdb_hierarchy.atoms() xray_structure = processed_pdb_file.xray_structure() geometry_restraints_manager = \ processed_pdb_file.geometry_restraints_manager(show_energies=False) fmodel.update_xray_structure(xray_structure) sele_cache = pdb_hierarchy.atom_selection_cache() # FIXME very inefficient when looping! # this will include both the newly built residues and the original atoms, # including residues split to allow for backbone flexibility. sele_split = sele_cache.selection(alt_confs.SELECTION_MODIFIED) sele_main_conf = sele_cache.selection(alt_confs.SELECTION_OLD) assert (len(sele_split) > 0) k = 0 fragments = [] while (k < len(sele_split)): if (sele_split[k]): current_fragment = flex.size_t() while (sele_split[k]): current_fragment.append(k) k += 1 atom_start = pdb_atoms[current_fragment[0]].fetch_labels() atom_end = pdb_atoms[current_fragment[-1]].fetch_labels() frag_selection = flex.bool(sele_split.size(), current_fragment) if (i_cycle > 0): flags = rebuilt_flags.select(frag_selection) if flags.all_eq(0): continue fragments.append(current_fragment) else: k += 1 if (len(fragments) == 0): pass refine_fragments = rsr_fragments_parallel( pdb_hierarchy=pdb_hierarchy, fmodel=fmodel, processed_pdb_file=processed_pdb_file, sele_main_conf=sele_main_conf, rsr_fofc_map_target=(i_cycle == 0 and params.cleanup.rsr_fofc_map_target)) refined = easy_mp.pool_map(fixed_func=refine_fragments, iterable=fragments, processes=nproc) sites_refined = pdb_atoms.extract_xyz() for result in refined: assert (result is not None) result.show(out=out, prefix=" ") sites_refined.set_selected(result.selection, result.sites_cart) pdb_atoms.set_xyz(sites_refined) xray_structure.set_sites_cart(sites_refined) fmodel.update_xray_structure(xray_structure) if (not remediate) or (max_cycles == 1): break else: for atom in pdb_hierarchy.atoms(): if (atom.segid == alt_confs.SEGID_NEW_SPLIT): atom.segid = alt_confs.SEGID_NEW_REBUILT print(" checking for conformational strain...", file=out) n_split = alt_confs.spread_alternates( pdb_hierarchy=pdb_hierarchy, new_occupancy=params.residue_fitting.expected_occupancy, split_all_adjacent=False, selection=alt_confs.SELECTION_NEW_REBUILT) if (n_split > 0): print(" split another %d residue(s) - will re-run RSR" % \ n_split, file=out) else: break i_cycle += 1 xray_structure = pdb_hierarchy.extract_xray_structure( crystal_symmetry=fmodel.xray_structure) fmodel.update_xray_structure(xray_structure, update_f_mask=True, update_f_calc=True) #fmodel.info().show_targets(out=out, text="After real-space refinement") t2 = time.time() return pdb_hierarchy
def refit_residues ( pdb_hierarchy, cif_objects, fmodel, use_rotamers=True, anneal=False, verbose=True, allow_modified_residues=False, out=sys.stdout) : """ Use real-space refinement tools to fit newly extended residues. """ from mmtbx.refinement.real_space import fit_residue from mmtbx.rotamer import rotamer_eval import mmtbx.monomer_library.server from mmtbx import building from scitbx.array_family import flex mon_lib_srv = mmtbx.monomer_library.server.server() rotamer_manager = rotamer_eval.RotamerEval() ppdb_out = box_out = out if (not verbose) : ppdb_out = null_out() box_out = null_out() make_sub_header("Processing new model", out=ppdb_out) processed_pdb = building.reprocess_pdb( pdb_hierarchy=pdb_hierarchy, crystal_symmetry=fmodel.f_obs().crystal_symmetry(), cif_objects=cif_objects, out=ppdb_out) print >> ppdb_out, "" hierarchy = processed_pdb.all_chain_proxies.pdb_hierarchy xrs = processed_pdb.xray_structure() grm_geometry = processed_pdb.geometry_restraints_manager() make_sub_header("Fitting residues", out=out) target_map = fmodel.map_coefficients( map_type="2mFo-DFc", exclude_free_r_reflections=True).fft_map( resolution_factor=0.25).apply_sigma_scaling().real_map_unpadded() unit_cell = xrs.unit_cell() for chain in hierarchy.only_model().chains() : if (not chain.is_protein()) and (not allow_modified_residues) : continue residue_groups = chain.residue_groups() for i_rg, residue_group in enumerate(residue_groups) : prev_res = next_res = None atom_groups = residue_group.atom_groups() if (len(atom_groups) > 1) : continue residue = atom_groups[0] atoms = residue.atoms() atoms.reset_tmp() segids = atoms.extract_segid() if (segids.all_eq("XXXX")) : sites_start = atoms.extract_xyz() def get_two_fofc_mean (residue) : sum = 0 n_atoms = 0 for atom in residue.atoms() : if (not atom.element.strip() in ["H","D"]) : site_frac = unit_cell.fractionalize(site_cart=atom.xyz) sum += target_map.eight_point_interpolation(site_frac) n_atoms += 1 assert (n_atoms > 0) return sum / n_atoms sites_start = atoms.extract_xyz().deep_copy() two_fofc_mean_start = get_two_fofc_mean(residue) refit = fit_residue.run_with_minimization( target_map=target_map, residue=residue, xray_structure=xrs, mon_lib_srv=mon_lib_srv, rotamer_manager=rotamer_manager, geometry_restraints_manager=grm_geometry, real_space_gradients_delta=fmodel.f_obs().d_min()*0.25, rms_bonds_limit=0.01, rms_angles_limit=1.0, backbone_sample_angle=20, allow_modified_residues=allow_modified_residues) two_fofc_mean_end = get_two_fofc_mean(residue) sites_end = atoms.extract_xyz() flag = "" if (two_fofc_mean_end > two_fofc_mean_start) : flag = " <-- keep" xrs = refit.xray_structure else : atoms.set_xyz(sites_start) for atom in atoms : atom.tmp = 1 print >> out, \ " residue '%s' : rmsd=%5.3f 2fofc_start=%5.3f 2fofc_end=%5.3f%s" \ % (residue.id_str(), sites_end.rms_difference(sites_start), two_fofc_mean_start, two_fofc_mean_end, flag) return hierarchy, xrs