def __call__(self,
              atom_group,
              log,
              window_size=2,
              backbone_sample_angle=10,
              anneal=False,
              annealing_temperature=1000,
              use_chi1_sampling=False):
     import iotbx.pdb.hierarchy
     from scitbx.array_family import flex
     assert (atom_group is not None)
     pdb_hierarchy = self.pdb_hierarchy.deep_copy()
     xray_structure = self.xray_structure.deep_copy_scatterers()
     geometry_restraints_manager = self.geometry_restraints_manager
     # FIXME this doesn't work - can't recover the atom_group afterwards!
     #hd_sel = xray_structure.hd_selection()
     #n_hydrogen = hd_sel.count(True)
     #if (n_hydrogen > 0):
     #  non_hd_sel = ~hd_sel
     #  pdb_hierarchy = pdb_hierarchy.select(non_hd_sel)
     #  xray_structure = xray_structure.select(non_hd_sel)
     #  geometry_restraints_manager = geometry_restraints_manager.select(
     #    non_hd_sel)
     pdb_atoms = pdb_hierarchy.atoms()
     pdb_atoms.reset_i_seq()
     isel = building.extract_iselection([atom_group])
     atom_group = pdb_atoms[isel[0]].parent()
     atom_group_start = atom_group.detached_copy()
     needs_rebuild = not building.is_stub_residue(atom_group)
     residue_group = atom_group.parent()
     assert (len(residue_group.atom_groups()) == 1)
     sel_residues = building.get_window_around_residue(
         residue=atom_group, window_size=window_size)
     # get rid of sidechains for surrounding residues only
     adjacent_residues = []
     for other_rg in sel_residues:
         if (other_rg != residue_group):
             adjacent_residues.append(other_rg)
     building.remove_sidechain_atoms(adjacent_residues)
     pdb_atoms = pdb_hierarchy.atoms()
     adjacent_trimmed_atom_names = pdb_atoms.extract_name()
     adjacent_trimmed_sel = pdb_atoms.extract_i_seq()
     xrs_adjacent_trimmed = xray_structure.select(adjacent_trimmed_sel)
     grm_adjacent_trimmed = geometry_restraints_manager.select(
         adjacent_trimmed_sel)
     pdb_atoms.reset_i_seq()
     # get rid of central sidechain and refine mainchain for entire window
     truncate = (not atom_group.resname in ["GLY", "ALA"])  # XXX PRO?
     if (truncate):
         building.remove_sidechain_atoms([atom_group])
     pdb_atoms = pdb_hierarchy.atoms()
     all_mc_sel = pdb_atoms.extract_i_seq()
     xrs_mc = xrs_adjacent_trimmed.select(all_mc_sel)
     pdb_atoms.reset_i_seq()
     window_mc_sel = building.extract_iselection(sel_residues)
     selection = flex.bool(pdb_atoms.size(),
                           False).set_selected(window_mc_sel, True)
     restraints_manager = grm_adjacent_trimmed.select(all_mc_sel)
     box = building.box_build_refine_base(
         xray_structure=xrs_mc,
         pdb_hierarchy=pdb_hierarchy,
         selection=selection,
         processed_pdb_file=None,
         target_map=self.target_map,
         geometry_restraints_manager=restraints_manager.geometry,
         d_min=self.d_min,
         out=null_out(),
         debug=True)
     box.restrain_atoms(selection=box.others_in_box, reference_sigma=0.1)
     box.real_space_refine(selection=box.selection_in_box)
     sites_new = box.update_original_coordinates()
     pdb_atoms.set_xyz(sites_new)
     # extend and replace existing residue.  this is done in such a way that
     # the original atom ordering for the central residue is preserved, which
     # allows us to use the pre-existing geometry restraints instead of
     # re-calculating them every time this function is called.
     target_atom_group = self.ideal_dict[atom_group.resname.lower()].\
       only_model().only_chain().only_residue_group().only_atom_group()
     new_atom_group_base = extend_sidechains.extend_residue(
         residue=atom_group,
         target_atom_group=target_atom_group,
         mon_lib_srv=self.mon_lib_srv)
     new_atom_group = iotbx.pdb.hierarchy.atom_group(
         resname=atom_group.resname)
     for atom in atom_group_start.atoms():
         for new_atom in new_atom_group_base.atoms():
             if (new_atom.name == atom.name):
                 new_atom_group.append_atom(new_atom.detached_copy())
     n_atoms_new = len(new_atom_group.atoms())
     n_atoms_start = len(atom_group_start.atoms())
     if (n_atoms_new != n_atoms_start):
         raise RuntimeError(
             ("Inconsistent atom counts for residue %s after " +
              "building (%d versus %d).") %
             (atom_group.id_str(), n_atoms_start, n_atoms_new))
     rg = atom_group.parent()
     rg.remove_atom_group(atom_group)
     rg.append_atom_group(new_atom_group)
     pdb_atoms = pdb_hierarchy.atoms()
     pdb_atoms.reset_i_seq()
     new_names = pdb_atoms.extract_name()
     assert new_names.all_eq(adjacent_trimmed_atom_names)
     # get new box around this residue
     residue_sel = building.extract_iselection([new_atom_group])
     selection = flex.bool(pdb_atoms.size(),
                           False).set_selected(residue_sel, True)
     xrs_adjacent_trimmed.set_sites_cart(pdb_atoms.extract_xyz())
     box = building.box_build_refine_base(
         xray_structure=xrs_adjacent_trimmed,
         pdb_hierarchy=pdb_hierarchy,
         selection=selection,
         processed_pdb_file=None,
         target_map=self.target_map,
         geometry_restraints_manager=grm_adjacent_trimmed.geometry,
         d_min=self.d_min,
         out=null_out(),
         debug=True)
     # place sidechain using mmtbx.refinement.real_space.fit_residue
     if ((atom_group.resname in rotatable_sidechain_atoms)
             and (use_chi1_sampling)):
         fit_chi1_simple(residue=box.only_residue(),
                         unit_cell=box.unit_cell_box,
                         target_map=box.target_map_box,
                         rotamer_eval=self.rotamer_eval)
         box.update_sites_from_pdb_atoms()
     else:
         box.fit_residue_in_box(backbone_sample_angle=backbone_sample_angle)
     if (anneal):
         box.anneal(start_temperature=annealing_temperature)
     #box.real_space_refine()
     sites_new = box.update_original_coordinates()
     pdb_hierarchy.atoms().set_xyz(sites_new)
     return building.atom_group_as_hierarchy(new_atom_group)
def find_alternate_residue (residue,
    pdb_hierarchy,
    fmodel,
    restraints_manager,
    params,
    verbose=False,
    debug=None,
    log=None) :
  if (log is None) :
    log = null_out()
  t1 = time.time()
  from scitbx.array_family import flex
  selection = flex.size_t()
  window = building.get_window_around_residue(residue,
    window_size=params.window_size)
  for pdb_object in window :
    selection.extend(pdb_object.atoms().extract_i_seq())
  assert (len(selection) > 0) and (not selection.all_eq(0))
  occupancies = []
  if (params.expected_occupancy is not None) :
    assert (0.0 <= params.expected_occupancy <= 1.0)
    occupancies = [ params.expected_occupancy ]
  else :
    occupancies = [ 0.2, 0.3, 0.4, 0.5 ]
  trials = []
  sites_start_1d = pdb_hierarchy.atoms().extract_xyz().as_double()
  from mmtbx.rotamer import rotamer_eval
  rotamer_manager = rotamer_eval.RotamerEval(data_version="8000")
  id_str = residue.id_str()
  delete_selection = None
  if (params.omit_waters) :
    delete_selection = building.get_nearby_water_selection(
      pdb_hierarchy=pdb_hierarchy,
      xray_structure=fmodel.xray_structure,
      selection=selection)
  for occupancy in occupancies :
    prefix = "%s_%.2f" % (id_str.replace(" ", "_"), occupancy)
    map_file_name = None
    if (debug > 1) :
      map_file_name = prefix + ".mtz"
    two_fofc_map, fofc_map = alt_confs.get_partial_omit_map(
      fmodel=fmodel.deep_copy(),
      selection=selection,
      selection_delete=delete_selection,
      negate_surrounding=True,
      map_file_name=map_file_name,
      partial_occupancy=1.0 - occupancy)
    rebuild = rebuild_residue(
      target_map=fofc_map,
      pdb_hierarchy=pdb_hierarchy,
      xray_structure=fmodel.xray_structure,
      geometry_restraints_manager=restraints_manager,
      rotamer_eval=rotamer_manager,
      d_min=fmodel.f_obs().d_min())
    new_hierarchy = rebuild(atom_group=residue,
      window_size=params.window_size,
      backbone_sample_angle=params.backbone_sample_angle,
      anneal=params.anneal,
      annealing_temperature=params.annealing_temperature,
      use_chi1_sampling=params.simple_chi1_sampling,
      log=log)
    trial = residue_trial(
      residue=residue,
      new_hierarchy=new_hierarchy,
      occupancy=occupancy,
      rotamer_eval=rotamer_manager,
      fmodel=fmodel,
      two_fofc_map=two_fofc_map,
      fofc_map=fofc_map)
    trials.append(trial)
    if (debug > 1) :
      open("%s.pdb" % prefix, "w").write(trial.new_hierarchy.as_pdb_string())
  sites_end_1d = pdb_hierarchy.atoms().extract_xyz().as_double()
  assert sites_start_1d.all_eq(sites_end_1d)
  t2 = time.time()
  if (debug > 1) :
    print >> log, "  %d build trials (%s): %.3fs" % (len(occupancies),
      residue.id_str(), t2 - t1)
  return trials
def find_alternate_residue(residue,
                           pdb_hierarchy,
                           fmodel,
                           restraints_manager,
                           params,
                           verbose=False,
                           debug=None,
                           log=None):
    if (log is None):
        log = null_out()
    t1 = time.time()
    from scitbx.array_family import flex
    selection = flex.size_t()
    window = building.get_window_around_residue(residue,
                                                window_size=params.window_size)
    for pdb_object in window:
        selection.extend(pdb_object.atoms().extract_i_seq())
    assert (len(selection) > 0) and (not selection.all_eq(0))
    occupancies = []
    if (params.expected_occupancy is not None):
        assert (0.0 <= params.expected_occupancy <= 1.0)
        occupancies = [params.expected_occupancy]
    else:
        occupancies = [0.2, 0.3, 0.4, 0.5]
    trials = []
    sites_start_1d = pdb_hierarchy.atoms().extract_xyz().as_double()
    from mmtbx.rotamer import rotamer_eval
    rotamer_manager = rotamer_eval.RotamerEval(data_version="8000")
    id_str = residue.id_str()
    delete_selection = None
    if (params.omit_waters):
        delete_selection = building.get_nearby_water_selection(
            pdb_hierarchy=pdb_hierarchy,
            xray_structure=fmodel.xray_structure,
            selection=selection)
    for occupancy in occupancies:
        prefix = "%s_%.2f" % (id_str.replace(" ", "_"), occupancy)
        map_file_name = None
        if (debug > 1):
            map_file_name = prefix + ".mtz"
        two_fofc_map, fofc_map = alt_confs.get_partial_omit_map(
            fmodel=fmodel.deep_copy(),
            selection=selection,
            selection_delete=delete_selection,
            negate_surrounding=True,
            map_file_name=map_file_name,
            partial_occupancy=1.0 - occupancy)
        rebuild = rebuild_residue(
            target_map=fofc_map,
            pdb_hierarchy=pdb_hierarchy,
            xray_structure=fmodel.xray_structure,
            geometry_restraints_manager=restraints_manager,
            rotamer_eval=rotamer_manager,
            d_min=fmodel.f_obs().d_min())
        new_hierarchy = rebuild(
            atom_group=residue,
            window_size=params.window_size,
            backbone_sample_angle=params.backbone_sample_angle,
            anneal=params.anneal,
            annealing_temperature=params.annealing_temperature,
            use_chi1_sampling=params.simple_chi1_sampling,
            log=log)
        trial = residue_trial(residue=residue,
                              new_hierarchy=new_hierarchy,
                              occupancy=occupancy,
                              rotamer_eval=rotamer_manager,
                              fmodel=fmodel,
                              two_fofc_map=two_fofc_map,
                              fofc_map=fofc_map)
        trials.append(trial)
        if (debug > 1):
            open("%s.pdb" % prefix,
                 "w").write(trial.new_hierarchy.as_pdb_string())
    sites_end_1d = pdb_hierarchy.atoms().extract_xyz().as_double()
    assert sites_start_1d.all_eq(sites_end_1d)
    t2 = time.time()
    if (debug > 1):
        print("  %d build trials (%s): %.3fs" %
              (len(occupancies), residue.id_str(), t2 - t1),
              file=log)
    return trials
 def __call__ (self,
     atom_group,
     log,
     window_size=2,
     backbone_sample_angle=10,
     anneal=False,
     annealing_temperature=1000,
     use_chi1_sampling=False) :
   import iotbx.pdb.hierarchy
   from scitbx.array_family import flex
   assert (atom_group is not None)
   pdb_hierarchy = self.pdb_hierarchy.deep_copy()
   xray_structure = self.xray_structure.deep_copy_scatterers()
   geometry_restraints_manager = self.geometry_restraints_manager
   # FIXME this doesn't work - can't recover the atom_group afterwards!
   #hd_sel = xray_structure.hd_selection()
   #n_hydrogen = hd_sel.count(True)
   #if (n_hydrogen > 0) :
   #  non_hd_sel = ~hd_sel
   #  pdb_hierarchy = pdb_hierarchy.select(non_hd_sel)
   #  xray_structure = xray_structure.select(non_hd_sel)
   #  geometry_restraints_manager = geometry_restraints_manager.select(
   #    non_hd_sel)
   pdb_atoms = pdb_hierarchy.atoms()
   pdb_atoms.reset_i_seq()
   isel = building.extract_iselection([atom_group])
   atom_group = pdb_atoms[isel[0]].parent()
   atom_group_start = atom_group.detached_copy()
   needs_rebuild = not building.is_stub_residue(atom_group)
   residue_group = atom_group.parent()
   assert (len(residue_group.atom_groups()) == 1)
   sel_residues = building.get_window_around_residue(
     residue=atom_group,
     window_size=window_size)
   # get rid of sidechains for surrounding residues only
   adjacent_residues = []
   for other_rg in sel_residues :
     if (other_rg != residue_group) :
       adjacent_residues.append(other_rg)
   building.remove_sidechain_atoms(adjacent_residues)
   pdb_atoms = pdb_hierarchy.atoms()
   adjacent_trimmed_atom_names = pdb_atoms.extract_name()
   adjacent_trimmed_sel = pdb_atoms.extract_i_seq()
   xrs_adjacent_trimmed = xray_structure.select(adjacent_trimmed_sel)
   grm_adjacent_trimmed = geometry_restraints_manager.select(
     adjacent_trimmed_sel)
   pdb_atoms.reset_i_seq()
   # get rid of central sidechain and refine mainchain for entire window
   truncate = (not atom_group.resname in ["GLY","ALA"]) # XXX PRO?
   if (truncate) :
     building.remove_sidechain_atoms([ atom_group ])
   pdb_atoms = pdb_hierarchy.atoms()
   all_mc_sel = pdb_atoms.extract_i_seq()
   xrs_mc = xrs_adjacent_trimmed.select(all_mc_sel)
   pdb_atoms.reset_i_seq()
   window_mc_sel = building.extract_iselection(sel_residues)
   selection = flex.bool(pdb_atoms.size(), False).set_selected(window_mc_sel,
     True)
   restraints_manager = grm_adjacent_trimmed.select(all_mc_sel)
   box = building.box_build_refine_base(
     xray_structure=xrs_mc,
     pdb_hierarchy=pdb_hierarchy,
     selection=selection,
     processed_pdb_file=None,
     target_map=self.target_map,
     geometry_restraints_manager=restraints_manager.geometry,
     d_min=self.d_min,
     out=null_out(),
     debug=True)
   box.restrain_atoms(
     selection=box.others_in_box,
     reference_sigma=0.1)
   box.real_space_refine(selection=box.selection_in_box)
   sites_new = box.update_original_coordinates()
   pdb_atoms.set_xyz(sites_new)
   # extend and replace existing residue.  this is done in such a way that
   # the original atom ordering for the central residue is preserved, which
   # allows us to use the pre-existing geometry restraints instead of
   # re-calculating them every time this function is called.
   new_atom_group_base = extend_sidechains.extend_residue(
     residue=atom_group,
     ideal_dict=self.ideal_dict,
     hydrogens=False,
     mon_lib_srv=self.mon_lib_srv,
     match_conformation=True)
   new_atom_group = iotbx.pdb.hierarchy.atom_group(resname=atom_group.resname)
   for atom in atom_group_start.atoms() :
     for new_atom in new_atom_group_base.atoms() :
       if (new_atom.name == atom.name) :
         new_atom_group.append_atom(new_atom.detached_copy())
   n_atoms_new = len(new_atom_group.atoms())
   n_atoms_start = len(atom_group_start.atoms())
   if (n_atoms_new != n_atoms_start) :
     raise RuntimeError(("Inconsistent atom counts for residue %s after "+
       "building (%d versus %d).") % (atom_group.id_str(), n_atoms_start,
       n_atoms_new))
   rg = atom_group.parent()
   rg.remove_atom_group(atom_group)
   rg.append_atom_group(new_atom_group)
   pdb_atoms = pdb_hierarchy.atoms()
   pdb_atoms.reset_i_seq()
   new_names = pdb_atoms.extract_name()
   assert new_names.all_eq(adjacent_trimmed_atom_names)
   # get new box around this residue
   residue_sel = building.extract_iselection([ new_atom_group ])
   selection = flex.bool(pdb_atoms.size(), False).set_selected(residue_sel,
     True)
   xrs_adjacent_trimmed.set_sites_cart(pdb_atoms.extract_xyz())
   box = building.box_build_refine_base(
     xray_structure=xrs_adjacent_trimmed,
     pdb_hierarchy=pdb_hierarchy,
     selection=selection,
     processed_pdb_file=None,
     target_map=self.target_map,
     geometry_restraints_manager=grm_adjacent_trimmed.geometry,
     d_min=self.d_min,
     out=null_out(),
     debug=True)
   # place sidechain using mmtbx.refinement.real_space.fit_residue
   if ((atom_group.resname in rotatable_sidechain_atoms) and
       (use_chi1_sampling)) :
     fit_chi1_simple(
       residue=box.only_residue(),
       unit_cell=box.unit_cell_box,
       target_map=box.target_map_box,
       rotamer_eval=self.rotamer_eval)
     box.update_sites_from_pdb_atoms()
   else :
     box.fit_residue_in_box(backbone_sample_angle=backbone_sample_angle)
   if (anneal) :
     box.anneal(start_temperature=annealing_temperature)
   #box.real_space_refine()
   sites_new = box.update_original_coordinates()
   pdb_hierarchy.atoms().set_xyz(sites_new)
   return building.atom_group_as_hierarchy(new_atom_group)