def get_resnums_of_chain_rama_outliers(self, pdb_hierarchy):
   phi_psi_atoms = utils.get_phi_psi_atoms(pdb_hierarchy, omega=True)
   # pdb_hierarchy.write_pdb_file(file_name="phi_psi_atoms.pdb")
   # print "len phi psi atoms", len(phi_psi_atoms)
   result = []
   rama_results = []
   ranges_for_idealization = []
   # print >> self.log, "rama outliers for input hierarchy:"
   list_of_reference_exclusion = []
   outp = utils.list_rama_outliers_h(pdb_hierarchy, self.r)
   print >> self.log, outp
   for phi_psi_pair, rama_key, omega in phi_psi_atoms:
     if phi_psi_pair[0] is not None and phi_psi_pair[1] is not None:
       # print "resseq:", phi_psi_pair[0][2].parent().parent().resseq
       ev = utils.rama_evaluate(phi_psi_pair, self.r, rama_key)
       # print "  ev", ev
       rama_results.append(ev)
       # print phi_psi_pair[0][0].id_str()
       resnum = phi_psi_pair[0][2].parent().parent().resseq
       if ev == ramalyze.RAMALYZE_OUTLIER:
         result.append(resnum)
       if omega is not None and abs(abs(omega)-180) > 30:
         print >> self.log, "Spotted twisted/cis peptide:", resnum, omega
         result.append(resnum)
   # STOP()
   return result
Exemple #2
0
 def idealize_chain(self, hierarchy):
     # check no ac:
     for c in hierarchy.chains():
         if len(c.conformers()) > 1:
             raise Sorry("Alternative conformations are not supported.")
         if "UNK" in c.get_residue_names_padded():
             pass
             # raise Sorry("UNK residues are not supported.")
     working_h = hierarchy.deep_copy()
     working_h.reset_atom_i_seqs()
     rama_results = []
     ranges_for_idealization = []
     print >> self.log, "rama outliers for input hierarchy:"
     rama_out_resnums = self.get_resnums_of_chain_rama_outliers(working_h)
     if len(rama_out_resnums) == 0:
         return None, None
     # get list of residue numbers that should be excluded from reference
     list_of_reference_exclusion = []
     for resnum in rama_out_resnums:
         excl_res = get_res_nums_around(hierarchy,
                                        resnum,
                                        2,
                                        2,
                                        include_intermediate=True)
         list_of_reference_exclusion += excl_res
     out_i = 0
     chain_ss_annot = self.secondary_structure_annotation
     if chain_ss_annot is not None:
         chain_ss_annot = self.secondary_structure_annotation.deep_copy()
         chain_ss_annot.remove_empty_annotations(hierarchy=working_h)
     for rama_out_resnum in rama_out_resnums:
         print >> self.log
         print >> self.log, "Fixing outlier:", rama_out_resnum
         self.log.flush()
         new_h = self.fix_rama_outlier(pdb_hierarchy=working_h,
                                       out_res_num=rama_out_resnum,
                                       prefix=self.params.output_prefix,
                                       minimize=False,
                                       ss_annotation=chain_ss_annot)
         print >> self.log, "listing outliers after loop minimization"
         outp = utils.list_rama_outliers_h(new_h, self.r)
         print >> self.log, outp
         self.log.flush()
         # fn = "%s_after_loop_%d.pdb" % (self.params.output_prefix, out_i)
         # print >> self.log, "  writing file %s" % fn
         # new_h.write_pdb_file(file_name=fn)
         working_h = new_h
         out_i += 1
     return list_of_reference_exclusion, new_h
 def get_resnums_of_chain_rama_outliers(self, pdb_hierarchy):
     phi_psi_atoms = utils.get_phi_psi_atoms(pdb_hierarchy)
     # print "len phi psi atoms", len(phi_psi_atoms)
     result = []
     rama_results = []
     ranges_for_idealization = []
     # print >> self.log, "rama outliers for input hierarchy:"
     list_of_reference_exclusion = []
     outp = utils.list_rama_outliers_h(pdb_hierarchy, self.r)
     print >>self.log, outp
     for phi_psi_pair, rama_key in phi_psi_atoms:
         # print "resseq:", phi_psi_pair[0][2].parent().parent().resseq
         ev = utils.rama_evaluate(phi_psi_pair, self.r, rama_key)
         # print "  ev", ev
         rama_results.append(ev)
         if ev == ramalyze.RAMALYZE_OUTLIER:
             resnum = phi_psi_pair[0][2].parent().parent().resseq
             result.append(resnum)
     return result
Exemple #4
0
 def get_resnums_of_chain_rama_outliers(self, pdb_hierarchy):
     phi_psi_atoms = utils.get_phi_psi_atoms(pdb_hierarchy)
     # print "len phi psi atoms", len(phi_psi_atoms)
     result = []
     rama_results = []
     ranges_for_idealization = []
     # print >> self.log, "rama outliers for input hierarchy:"
     list_of_reference_exclusion = []
     outp = utils.list_rama_outliers_h(pdb_hierarchy, self.r)
     print >> self.log, outp
     for phi_psi_pair, rama_key in phi_psi_atoms:
         # print "resseq:", phi_psi_pair[0][2].parent().parent().resseq
         ev = utils.rama_evaluate(phi_psi_pair, self.r, rama_key)
         # print "  ev", ev
         rama_results.append(ev)
         if ev == ramalyze.RAMALYZE_OUTLIER:
             resnum = phi_psi_pair[0][2].parent().parent().resseq
             result.append(resnum)
     return result
 def idealize_chain(self, hierarchy):
   # check no ac:
   for c in hierarchy.chains():
     if len(c.conformers()) > 1:
       raise Sorry("Alternative conformations are not supported.")
     if "UNK" in c.get_residue_names_padded():
       pass
       # raise Sorry("UNK residues are not supported.")
   working_h = hierarchy.deep_copy()
   working_h.reset_atom_i_seqs()
   rama_results = []
   ranges_for_idealization = []
   print >> self.log, "rama outliers for input hierarchy:"
   rama_out_resnums = self.get_resnums_of_chain_rama_outliers(
       working_h)
   if len(rama_out_resnums) == 0:
     return None, None
   # get list of residue numbers that should be excluded from reference
   list_of_reference_exclusion = []
   for resnum in rama_out_resnums:
     excl_res = get_res_nums_around(
         hierarchy, resnum, 2, 2, include_intermediate=True)
     list_of_reference_exclusion += excl_res
   out_i = 0
   for rama_out_resnum in rama_out_resnums:
     print >> self.log
     print >> self.log, "Fixing outlier:", rama_out_resnum
     self.log.flush()
     new_h = self.fix_rama_outlier(
       pdb_hierarchy=working_h,
       out_res_num=rama_out_resnum,
       prefix=self.params.output_prefix,
       minimize=False)
     print >> self.log, "listing outliers after loop minimization"
     outp = utils.list_rama_outliers_h(new_h, self.r)
     print >> self.log, outp
     self.log.flush()
     fn = "%s_after_loop_%d.pdb" % (self.params.output_prefix, out_i)
     # print >> self.log, "  writing file %s" % fn
     # new_h.write_pdb_file(file_name=fn)
     working_h = new_h
     out_i += 1
   return list_of_reference_exclusion, new_h
  def __init__(self,
               pdb_hierarchy,
               params=None,
               secondary_structure_annotation=None,
               reference_map=None,
               crystal_symmetry=None,
               grm=None,
               rama_manager=None,
               rotamer_manager=None,
               log=null_out(),
               verbose=False,
               tried_rama_angles={},
               tried_final_rama_angles={},
               n_run=0):
    if len(pdb_hierarchy.models()) > 1:
      raise Sorry("Multi-model files are not supported")
    self.original_pdb_h = pdb_hierarchy
    self.secondary_structure_annotation=secondary_structure_annotation
    asc = pdb_hierarchy.atom_selection_cache()
    self.xrs = pdb_hierarchy.extract_xray_structure(crystal_symmetry=crystal_symmetry)
    self.reference_map = reference_map
    self.resulting_pdb_h = pdb_hierarchy.deep_copy()
    self.resulting_pdb_h.reset_atom_i_seqs()
    self.params = self.process_params(params)
    self.log = log
    self.verbose = verbose
    self.grm = grm
    self.r = rama_manager
    self.ideal_res_dict = idealized_aa.residue_dict()
    self.n_run = n_run
    if self.r is None:
      self.r = rama_eval()
    self.rotamer_manager = rotamer_manager
    if self.rotamer_manager is None:
      self.rotamer_manager = RotamerEval()
    ram = ramalyze.ramalyze(pdb_hierarchy=pdb_hierarchy)
    self.p_initial_rama_outliers = ram.out_percent
    self.p_before_minimization_rama_outliers = None
    self.p_after_minimiaztion_rama_outliers = None
    n_inputs = [reference_map, crystal_symmetry].count(None)
    if not (n_inputs == 0 or n_inputs == 2):
      print >> log, "Need to have both map and symmetry info. Not using map."
      self.reference_map = None

    # here we are recording what CCD solutions were used to fix particular
    # outliers to not use the same in the next CCD try.
    # Nested dict. First level:
    # key: chain id, value: dict
    #   key: resid (string), value: list of tried variants.
    self.tried_rama_angles = tried_rama_angles
    self.tried_final_rama_angles = tried_final_rama_angles

    berkeley_count = utils.list_rama_outliers_h(self.resulting_pdb_h).count("\n")
    self.berkeley_p_before_minimization_rama_outliers = \
        berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
    n_bad_omegas = utils.n_bad_omegas(self.resulting_pdb_h)

    self.berkeley_p_after_minimiaztion_rama_outliers = self.berkeley_p_before_minimization_rama_outliers
    self.ref_exclusion_selection = ""
    self.number_of_ccd_trials = 0
    # print "logic expr outcome:", (self.number_of_ccd_trials < 10 and self.berkeley_p_before_minimization_rama_outliers > 0.001)
    # print self.number_of_ccd_trials < 10
    # print "berkeley before rama out:", self.berkeley_p_before_minimization_rama_outliers
    if (self.berkeley_p_before_minimization_rama_outliers <= 0.001 and
        (n_bad_omegas<1 and self.params.make_all_trans)):
      print >> self.log, "No ramachandran outliers, skipping CCD step."
    print "n_bad_omegas", n_bad_omegas
    print "self.params.make_all_trans",self.params.make_all_trans
    if not self.params.enabled:
      print >> self.log, "Loop idealization is not enabled, use 'enabled=True'."
    while (self.number_of_ccd_trials < self.params.number_of_ccd_trials
        and (self.berkeley_p_after_minimiaztion_rama_outliers > 0.001 or
            (n_bad_omegas>=1 and self.params.make_all_trans))
        and self.params.enabled):
      print >> self.log, "CCD try number, outliers:", self.number_of_ccd_trials, self.berkeley_p_before_minimization_rama_outliers
      processed_chain_ids = []
      for chain in self.resulting_pdb_h.only_model().chains():
        if chain.id not in self.tried_rama_angles.keys():
          self.tried_rama_angles[chain.id] = {}
        if chain.id not in self.tried_final_rama_angles.keys():
          self.tried_final_rama_angles[chain.id] = {}
        print >> self.log, "Idealizing chain %s" % chain.id
        if chain.id not in processed_chain_ids:
          processed_chain_ids.append(chain.id)
        else:
          continue
        selection = "protein and chain %s and (name N or name CA or name C or name O)" % chain.id
        sel = asc.selection("chain %s" % chain.id)
        chain_h = self.resulting_pdb_h.select(sel)
        m = chain_h.only_model()
        i = 0
        cutted_chain_h = None
        for c in m.chains():
          if i == 0:
            cutted_chain_h = iotbx.pdb.hierarchy.new_hierarchy_from_chain(c)
          else:
            print >> self.log, "WARNING!!! Duplicating chain ids! Only the first chain will be processed."
            print >> self.log, "  Removing chain %s with %d residues" % (c.id, len(c.residues()))
            m.remove_chain(c)
          i += 1
        exclusions, ch_h = self.idealize_chain(
            hierarchy=(cutted_chain_h if cutted_chain_h else chain_h),
            tried_rama_angles_for_chain=self.tried_rama_angles[chain.id],
            tried_final_rama_angles_for_chain=self.tried_final_rama_angles[chain.id])
        if ch_h is not None:
          set_xyz_smart(
              # dest_h=self.resulting_pdb_h,
              dest_h=chain,
              source_h=ch_h)
          for resnum in exclusions:
            selection += " and not resseq %s" % resnum
        self.ref_exclusion_selection += "(%s) or " % selection
        print "self.tried_rama_angles", self.tried_rama_angles
        print "self.tried_final_rama_angles", self.tried_final_rama_angles
      #
      # dumping and reloading hierarchy to do proper rounding of coordinates
      self.resulting_pdb_h = iotbx.pdb.input(
          source_info=None,
          lines=self.resulting_pdb_h.as_pdb_string()).construct_hierarchy()
      berkeley_count = utils.list_rama_outliers_h(self.resulting_pdb_h).count("\n")
      self.berkeley_p_before_minimization_rama_outliers = \
          berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
      if len(self.ref_exclusion_selection) > 0:
        self.ref_exclusion_selection = self.ref_exclusion_selection[:-3]
      ram = ramalyze.ramalyze(pdb_hierarchy=self.resulting_pdb_h)
      self.p_before_minimization_rama_outliers = ram.out_percent

      duke_count = ram.get_outliers_count_and_fraction()[0]
      if berkeley_count != duke_count:
        print >> self.log, "Discrepancy between berkeley and duke after ccd:", berkeley_count, duke_count
        self.resulting_pdb_h.write_pdb_file(file_name="%d%s_discrepancy.pdb" % (self.number_of_ccd_trials, self.params.output_prefix))
      if self.params.debug:
        self.resulting_pdb_h.write_pdb_file(
            file_name="%d%s_all_not_minized.pdb" % (self.number_of_ccd_trials,
                self.params.output_prefix))
      if self.params.minimize_whole:
        print >> self.log, "minimizing whole chain..."
        print >> self.log, "self.ref_exclusion_selection", self.ref_exclusion_selection
        # print >> sel
        # XXX but first let's check and fix rotamers...
        print >> self.log, "Fixing/checking rotamers in loop idealization..."
        excl_sel = self.ref_exclusion_selection
        if len(excl_sel) == 0:
          excl_sel = None
        non_outliers_for_check = asc.selection("(%s)" % self.ref_exclusion_selection)
        pre_result_h = mmtbx.utils.fix_rotamer_outliers(
          pdb_hierarchy=self.resulting_pdb_h,
          grm=self.grm.geometry,
          xrs=self.xrs,
          map_data=self.reference_map,
          radius=5,
          mon_lib_srv=None,
          rotamer_manager=self.rotamer_manager,
          backrub_range=None, # don't sample backrub at this point
          non_outliers_to_check=non_outliers_for_check, # bool selection
          asc=asc,
          verbose=True,
          log=self.log)

        if self.reference_map is None:
          minimize_wrapper_for_ramachandran(
              hierarchy=self.resulting_pdb_h,
              xrs=self.xrs,
              original_pdb_h=self.original_pdb_h,
              excl_string_selection=self.ref_exclusion_selection,
              grm=self.grm,
              log=None,
              ss_annotation=self.secondary_structure_annotation)
        else:
          mwwm = minimize_wrapper_with_map(
              pdb_h=self.resulting_pdb_h,
              xrs=self.xrs,
              target_map=self.reference_map,
              grm=self.grm,
              ss_annotation=self.secondary_structure_annotation,
              number_of_cycles=Auto,
              log=self.log)
      if self.params.debug:
        self.resulting_pdb_h.write_pdb_file(
            file_name="%d%s_all_minized.pdb" % (self.number_of_ccd_trials,
                self.params.output_prefix))
      ram = ramalyze.ramalyze(pdb_hierarchy=self.resulting_pdb_h)
      self.p_after_minimiaztion_rama_outliers = ram.out_percent
      berkeley_count = utils.list_rama_outliers_h(self.resulting_pdb_h).count("\n")
      duke_count = ram.get_outliers_count_and_fraction()[0]
      n_bad_omegas = utils.n_bad_omegas(self.resulting_pdb_h)
      self.berkeley_p_after_minimiaztion_rama_outliers = \
          berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
      if berkeley_count != duke_count:
        print >> self.log, "Discrepancy between berkeley and duke after min:", berkeley_count, duke_count
      else:
        print >> self.log, "Number of Rama outliers after min:", berkeley_count
      print >> self.log, "Number of bad omegas:", n_bad_omegas
      self.number_of_ccd_trials += 1
  def idealize_chain(self, hierarchy, tried_rama_angles_for_chain={},
      tried_final_rama_angles_for_chain={}):
    # check no ac:
    for c in hierarchy.chains():
      if len(c.conformers()) > 1:
        raise Sorry("Alternative conformations are not supported.")
      if "UNK" in c.get_residue_names_padded():
        pass
        # raise Sorry("UNK residues are not supported.")
    working_h = hierarchy.deep_copy()
    working_h.reset_atom_i_seqs()
    rama_results = []
    ranges_for_idealization = []
    print >> self.log, "rama outliers for input hierarchy:"
    rama_out_resnums = self.get_resnums_of_chain_rama_outliers(
        working_h)
    if len(rama_out_resnums) == 0:
      return None, None
    # get list of residue numbers that should be excluded from reference
    list_of_reference_exclusion = []
    for resnum in rama_out_resnums:
      excl_res = get_res_nums_around(
          hierarchy, [resnum], 2, 2, include_intermediate=True)
      list_of_reference_exclusion += excl_res
    out_i = 0
    chain_ss_annot = self.secondary_structure_annotation
    if chain_ss_annot is not None:
      chain_ss_annot = self.secondary_structure_annotation.deep_copy()
      chain_ss_annot.remove_empty_annotations(hierarchy=working_h)
    # combine outliers next to each other
    comb_rama_out_resnums = [[rama_out_resnums[0]]]
    for r_out_resnum in rama_out_resnums[1:]:
      if abs(hy36decode(4, r_out_resnum)-hy36decode(4, comb_rama_out_resnums[-1][-1])) < 2:
        # combine
        comb_rama_out_resnums[-1].append(r_out_resnum)
      else:
        # separate
        comb_rama_out_resnums.append([r_out_resnum])

    print >> self.log, "Combined outliers for fixing:", comb_rama_out_resnums
    for rama_out_resnum in comb_rama_out_resnums:
      print >> self.log
      print >> self.log, "Fixing outlier:", rama_out_resnum
      self.log.flush()

      new_h = self.fix_rama_outlier(
        pdb_hierarchy=working_h,
        out_res_num_list=rama_out_resnum,
        prefix=self.params.output_prefix,
        minimize=False,
        ss_annotation=chain_ss_annot,
        tried_rama_angles_for_chain=tried_rama_angles_for_chain,
        tried_final_rama_angles_for_chain=tried_final_rama_angles_for_chain)
      print >> self.log, "listing outliers after loop minimization"
      outp = utils.list_rama_outliers_h(new_h, self.r)
      print >> self.log, outp
      utils.list_omega_outliers(new_h, self.log)
      self.log.flush()
      working_h = new_h
      out_i += 1
    return list_of_reference_exclusion, new_h
Exemple #8
0
    def __init__(self,
                 pdb_hierarchy,
                 params=None,
                 secondary_structure_annotation=None,
                 reference_map=None,
                 crystal_symmetry=None,
                 grm=None,
                 rama_manager=None,
                 rotamer_manager=None,
                 log=null_out(),
                 verbose=False):
        if len(pdb_hierarchy.models()) > 1:
            raise Sorry("Multi-model files are not supported")
        self.original_pdb_h = pdb_hierarchy
        self.secondary_structure_annotation = secondary_structure_annotation
        asc = pdb_hierarchy.atom_selection_cache()
        self.xrs = pdb_hierarchy.extract_xray_structure(
            crystal_symmetry=crystal_symmetry)
        self.reference_map = reference_map
        self.resulting_pdb_h = pdb_hierarchy.deep_copy()
        self.resulting_pdb_h.reset_atom_i_seqs()
        self.params = self.process_params(params)
        self.log = log
        self.verbose = verbose
        self.grm = grm
        self.r = rama_manager
        if self.r is None:
            self.r = rama_eval()
        self.rotamer_manager = rotamer_manager
        if self.rotamer_manager is None:
            self.rotamer_manager = RotamerEval()
        ram = ramalyze.ramalyze(pdb_hierarchy=pdb_hierarchy)
        self.p_initial_rama_outliers = ram.out_percent
        self.p_before_minimization_rama_outliers = None
        self.p_after_minimiaztion_rama_outliers = None
        n_inputs = [reference_map, crystal_symmetry].count(None)
        if not (n_inputs == 0 or n_inputs == 2):
            print >> log, "Need to have both map and symmetry info. Not using map."
            self.reference_map = None

        berkeley_count = utils.list_rama_outliers_h(
            self.resulting_pdb_h).count("\n")
        self.berkeley_p_before_minimization_rama_outliers = \
            berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100

        # self.berkeley_p_before_minimization_rama_outliers = None
        self.berkeley_p_after_minimiaztion_rama_outliers = self.berkeley_p_before_minimization_rama_outliers
        self.ref_exclusion_selection = ""
        number_of_ccd_trials = 0
        # print "logic expr outcome:", (number_of_ccd_trials < 10 and self.berkeley_p_before_minimization_rama_outliers > 0.001)
        # print number_of_ccd_trials < 10
        # print "berkeley before rama out:", self.berkeley_p_before_minimization_rama_outliers
        if self.berkeley_p_before_minimization_rama_outliers <= 0.001:
            print >> self.log, "No ramachandran outliers, skipping CCD step."
        if not self.params.enabled:
            print >> self.log, "Loop idealization is not enabled, use 'enabled=True'."
        while (number_of_ccd_trials < self.params.number_of_ccd_trials
               and self.berkeley_p_after_minimiaztion_rama_outliers > 0.001
               and self.params.enabled):
            print "CCD try number, outliers:", number_of_ccd_trials, self.berkeley_p_before_minimization_rama_outliers
            number_of_ccd_trials += 1
            processed_chain_ids = []
            for chain in self.resulting_pdb_h.only_model().chains():
                print >> self.log, "Idealizing chain %s" % chain.id
                if chain.id not in processed_chain_ids:
                    processed_chain_ids.append(chain.id)
                else:
                    continue
                selection = "protein and chain %s and (name N or name CA or name C or name O)" % chain.id
                sel = asc.selection("chain %s" % chain.id)
                chain_h = self.resulting_pdb_h.select(sel)
                m = chain_h.only_model()
                i = 0
                cutted_chain_h = None
                for c in m.chains():
                    if i == 0:
                        cutted_chain_h = iotbx.pdb.hierarchy.new_hierarchy_from_chain(
                            c)
                    else:
                        print >> self.log, "WARNING!!! Duplicating chain ids! Only the first chain will be processed."
                        print >> self.log, "  Removing chain %s with %d residues" % (
                            c.id, len(c.residues()))
                        m.remove_chain(c)
                    i += 1
                exclusions, ch_h = self.idealize_chain(
                    hierarchy=(cutted_chain_h if cutted_chain_h else chain_h))
                if ch_h is not None:
                    set_xyz_smart(
                        # dest_h=self.resulting_pdb_h,
                        dest_h=chain,
                        source_h=ch_h)
                    for resnum in exclusions:
                        selection += " and not resseq %s" % resnum
                self.ref_exclusion_selection += "(%s) or " % selection
            #
            # dumping and reloading hierarchy to do proper rounding of coordinates
            self.resulting_pdb_h = iotbx.pdb.input(
                source_info=None, lines=self.resulting_pdb_h.as_pdb_string(
                )).construct_hierarchy()
            berkeley_count = utils.list_rama_outliers_h(
                self.resulting_pdb_h).count("\n")
            self.berkeley_p_before_minimization_rama_outliers = \
                berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
            if len(self.ref_exclusion_selection) > 0:
                self.ref_exclusion_selection = self.ref_exclusion_selection[:
                                                                            -3]
            # self.resulting_pdb_h.write_pdb_file(file_name="%s_before_minimization.pdb" % self.params.output_prefix)
            ram = ramalyze.ramalyze(pdb_hierarchy=self.resulting_pdb_h)
            self.p_before_minimization_rama_outliers = ram.out_percent

            duke_count = ram.get_outliers_count_and_fraction()[0]
            if berkeley_count != duke_count:
                print >> self.log, "Discrepancy between berkeley and duke after ccd:", berkeley_count, duke_count

            if self.params.minimize_whole:
                print >> self.log, "minimizing whole thing..."
                print >> self.log, "self.ref_exclusion_selection", self.ref_exclusion_selection
                # print >> sel
                if self.reference_map is None:
                    minimize_wrapper_for_ramachandran(
                        hierarchy=self.resulting_pdb_h,
                        xrs=self.xrs,
                        original_pdb_h=self.original_pdb_h,
                        excl_string_selection=self.ref_exclusion_selection,
                        grm=self.grm,
                        log=None,
                        ss_annotation=self.secondary_structure_annotation)
                else:
                    mwwm = minimize_wrapper_with_map(
                        pdb_h=self.resulting_pdb_h,
                        xrs=self.xrs,
                        target_map=self.reference_map,
                        grm=self.grm,
                        ss_annotation=self.secondary_structure_annotation,
                        log=self.log)
                # self.resulting_pdb_h.write_pdb_file(file_name="%s_all_minized.pdb" % self.params.output_prefix)
                ram = ramalyze.ramalyze(pdb_hierarchy=self.resulting_pdb_h)
                self.p_after_minimiaztion_rama_outliers = ram.out_percent
                berkeley_count = utils.list_rama_outliers_h(
                    self.resulting_pdb_h).count("\n")
                duke_count = ram.get_outliers_count_and_fraction()[0]
                self.berkeley_p_after_minimiaztion_rama_outliers = \
                    berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
            if berkeley_count != duke_count:
                print >> self.log, "Discrepancy between berkeley and duke after min:", berkeley_count, duke_count
            else:
                print >> self.log, "Number of Rama outliers after min:", berkeley_count
  def __init__(self,
               pdb_hierarchy,
               params=None,
               secondary_structure_annotation=None,
               log=null_out(),
               verbose=True):
    if len(pdb_hierarchy.models()) > 1:
      raise Sorry("Multi-model files are not supported")
    self.original_pdb_h = pdb_hierarchy
    self.secondary_structure_annotation=secondary_structure_annotation
    xrs = pdb_hierarchy.extract_xray_structure()
    asc = pdb_hierarchy.atom_selection_cache()
    self.resulting_pdb_h = pdb_hierarchy.deep_copy()
    self.resulting_pdb_h.reset_atom_i_seqs()
    self.params = self.process_params(params)
    self.log = log
    self.verbose = verbose
    self.r = rama_eval()
    self.rotamer_manager = RotamerEval()
    ram = ramalyze.ramalyze(pdb_hierarchy=pdb_hierarchy)
    self.p_initial_rama_outliers = ram.out_percent
    self.p_before_minimization_rama_outliers = None
    self.p_after_minimiaztion_rama_outliers = None

    berkeley_count = utils.list_rama_outliers_h(self.resulting_pdb_h).count("\n")
    self.berkeley_p_before_minimization_rama_outliers = \
        berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100

    # self.berkeley_p_before_minimization_rama_outliers = None
    self.berkeley_p_after_minimiaztion_rama_outliers = None
    self.ref_exclusion_selection = ""
    number_of_ccd_trials = 0
    # print "logic expr outcome:", (number_of_ccd_trials < 10 and self.berkeley_p_before_minimization_rama_outliers > 0.001)
    # print number_of_ccd_trials < 10
    # print "berkeley before rama out:", self.berkeley_p_before_minimization_rama_outliers
    if self.berkeley_p_before_minimization_rama_outliers <= 0.001:
      print >> self.log, "No ramachandran outliers, skipping CCD step."
    if not self.params.enabled:
      print >> self.log, "Loop idealization is not enabled, use 'enabled=True'."
    while (number_of_ccd_trials < self.params.number_of_ccd_trials
        and self.berkeley_p_before_minimization_rama_outliers > 0.001
        and self.params.enabled):
      print "CCD try number, outliers:", number_of_ccd_trials, self.berkeley_p_before_minimization_rama_outliers
      number_of_ccd_trials += 1
      processed_chain_ids = []
      for chain in self.resulting_pdb_h.only_model().chains():
        print >> self.log, "Idealizing chain %s" % chain.id
        if chain.id not in processed_chain_ids:
          processed_chain_ids.append(chain.id)
        else:
          continue
        selection = "protein and chain %s and (name N or name CA or name C or name O)" % chain.id
        sel = asc.selection("chain %s" % chain.id)
        chain_h = self.resulting_pdb_h.select(sel)
        m = chain_h.only_model()
        i = 0
        cutted_chain_h = None
        for c in m.chains():
          if i == 0:
            cutted_chain_h = iotbx.pdb.hierarchy.new_hierarchy_from_chain(c)
          else:
            print >> self.log, "WARNING!!! Duplicating chain ids! Only the first chain will be processed."
            print >> self.log, "  Removing chain %s with %d residues" % (c.id, len(c.residues()))
            m.remove_chain(c)
          i += 1
        exclusions, ch_h = self.idealize_chain(
            hierarchy=(cutted_chain_h if cutted_chain_h else chain_h))
        if ch_h is not None:
          set_xyz_smart(
              # dest_h=self.resulting_pdb_h,
              dest_h=chain,
              source_h=ch_h)
          for resnum in exclusions:
            selection += " and not resseq %s" % resnum
        self.ref_exclusion_selection += "(%s) or " % selection
      #
      # dumping and reloading hierarchy to do proper rounding of coordinates
      self.resulting_pdb_h = iotbx.pdb.input(
          source_info=None,
          lines=self.resulting_pdb_h.as_pdb_string()).construct_hierarchy()
      berkeley_count = utils.list_rama_outliers_h(self.resulting_pdb_h).count("\n")
      self.berkeley_p_before_minimization_rama_outliers = \
          berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
    if len(self.ref_exclusion_selection) > 0:
      self.ref_exclusion_selection = self.ref_exclusion_selection[:-3]
    self.resulting_pdb_h.write_pdb_file(file_name="%s_before_minimization.pdb" % self.params.output_prefix)
    ram = ramalyze.ramalyze(pdb_hierarchy=self.resulting_pdb_h)
    self.p_before_minimization_rama_outliers = ram.out_percent

    duke_count = ram.get_outliers_count_and_fraction()[0]
    if berkeley_count != duke_count:
      print >> self.log, "Discrepancy between berkeley and duke after ccd:", berkeley_count, duke_count

    if self.params.minimize_whole:
      print >> self.log, "minimizing whole thing..."
      print >> self.log, "self.ref_exclusion_selection", self.ref_exclusion_selection
      # print >> sel
      minimize_wrapper_for_ramachandran(
          hierarchy=self.resulting_pdb_h,
          xrs=xrs,
          original_pdb_h=self.original_pdb_h,
          excl_string_selection=self.ref_exclusion_selection,
          log=None,
          ss_annotation=self.secondary_structure_annotation)
      # self.resulting_pdb_h.write_pdb_file(file_name="%s_all_minized.pdb" % self.params.output_prefix)
      ram = ramalyze.ramalyze(pdb_hierarchy=self.resulting_pdb_h)
      self.p_after_minimiaztion_rama_outliers = ram.out_percent
      berkeley_count = utils.list_rama_outliers_h(self.resulting_pdb_h).count("\n")
      duke_count = ram.get_outliers_count_and_fraction()[0]
      self.berkeley_p_after_minimiaztion_rama_outliers = \
          berkeley_count/float(self.resulting_pdb_h.overall_counts().n_residues)*100
      if berkeley_count != duke_count:
        print >> self.log, "Discrepancy between berkeley and duke after min:", berkeley_count, duke_count
      else:
        print >> self.log, "Number of Rama outliers after min:", berkeley_count