Example #1
0
    def bond_angle_outliers(self):
        get_class = common_residue_names_get_class
        rc = restraints.combined(
               pdb_hierarchy  = self.pdb_hierarchy,
               xray_structure = self.model.get_xray_structure(),
               geometry_restraints_manager = self.model.get_restraints_manager().\
                                             geometry,
               ignore_hd      = False, # important
               outliers_only  = False,
               use_segids_in_place_of_chainids = False)

        bond_mean_delta, n_bonds, bond_mean = 0, 0, 0

        # bond outliers involving hydrogens
        outliers_bonds = []
        for result in rc.bonds.results:
            atom_info_hd = get_atom_info_if_hd(atoms_info=result.atoms_info)
            # Consider only H/D atoms
            if atom_info_hd is not None:
                # Calculate mean bond length and delta for non-water
                # --> used to get rough idea if H are at X-ray or neutron bond lengths.
                if (get_class(name=atom_info_hd.resname) != 'common_water'):
                    bond_mean_delta = bond_mean_delta + result.delta
                    bond_mean = bond_mean + result.model
                    n_bonds += 1
                if result.is_outlier():
                    atoms_str = mp_geo.get_atoms_str(
                        atoms_info=result.atoms_info)
                    outliers_bonds.append(
                        (atom_info_hd.id_str(), atoms_str, result.model,
                         result.delta, result.target, atom_info_hd.xyz))
        self.outliers_bonds = outliers_bonds

        bond_mean_delta = bond_mean_delta / n_bonds
        bond_mean = bond_mean / n_bonds

        xray_distances_used = False
        # value 0.08 was obtained by checking all 123 neutron models deposited
        # until Sep 2017 and by analysing delta
        if (bond_mean_delta >= 0.08 and self.use_neutron_distances):
            xray_distances_used = True

        self.bond_results = group_args(bond_mean_delta=bond_mean_delta,
                                       bond_mean=bond_mean,
                                       xray_distances_used=xray_distances_used)

        # angle outliers involving hydrogens
        outliers_angles = []
        for result in rc.angles.results:
            atom_info_hd = get_atom_info_if_hd(atoms_info=result.atoms_info)
            # Consider only H/D atoms
            if atom_info_hd is not None:
                if result.is_outlier():
                    atoms_str = mp_geo.get_atoms_str(
                        atoms_info=result.atoms_info)
                    outliers_angles.append([
                        atom_info_hd.id_str(), atoms_str, result.model,
                        result.delta, result.target, atom_info_hd.xyz
                    ])
        self.outliers_angles = outliers_angles
Example #2
0
def get_bond_and_angle_outliers(pdb_hierarchy,
                                xray_structure,
                                geometry_restraints_manager,
                                use_segids,
                                outliers_only=False,
                                type=None):
    rc = restraints.combined(
        pdb_hierarchy=pdb_hierarchy,
        xray_structure=xray_structure,
        geometry_restraints_manager=geometry_restraints_manager,
        ignore_hd=True,
        outliers_only=outliers_only,
        use_segids_in_place_of_chainids=use_segids)
    return rc
Example #3
0
def run_validation(pdb_file, ignore_hd=True):
    from mmtbx.validation import restraints
    import mmtbx.command_line
    cmdline = mmtbx.command_line.load_model_and_data(
        args=[pdb_file],
        master_phil=mmtbx.command_line.generic_simple_input_phil(),
        process_pdb_file=True,
        require_data=False,
        out=null_out())
    validation = restraints.combined(
        pdb_hierarchy=cmdline.pdb_hierarchy,
        xray_structure=cmdline.xray_structure,
        geometry_restraints_manager=cmdline.geometry,
        ignore_hd=ignore_hd)
    return validation
Example #4
0
def run_validation (pdb_file, ignore_hd=True) :
  from mmtbx.validation import restraints
  import mmtbx.command_line
  cmdline = mmtbx.command_line.load_model_and_data(
    args=[pdb_file],
    master_phil=mmtbx.command_line.generic_simple_input_phil(),
    process_pdb_file=True,
    require_data=False,
    out=null_out())
  validation = restraints.combined(
    pdb_hierarchy=cmdline.pdb_hierarchy,
    xray_structure=cmdline.xray_structure,
    geometry_restraints_manager=cmdline.geometry,
    ignore_hd=ignore_hd)
  return validation
Example #5
0
def get_bond_and_angle_outliers(
      pdb_hierarchy,
      xray_structure,
      geometry_restraints_manager,
      use_segids,
      outliers_only=False,
      type=None):
  rc = restraints.combined(
         pdb_hierarchy=pdb_hierarchy,
         xray_structure=xray_structure,
         geometry_restraints_manager=geometry_restraints_manager,
         ignore_hd=True,
         outliers_only=outliers_only,
         use_segids_in_place_of_chainids=use_segids)
  return rc
Example #6
0
def run (args, log=sys.stdout) :
  processed_pdb_file = pdb_interpretation.run(
    args=args,
    substitute_non_crystallographic_unit_cell_if_necessary=True,
    log=log)
  xray_structure = processed_pdb_file.xray_structure()
  if xray_structure is None :
    raise Sorry("Could not calculate X-ray structure from this PDB file. "+
      "This is probably due to missing symmetry information (CRYST1 record.")
  geometry = processed_pdb_file.geometry_restraints_manager(
    show_energies=False)
  chain_proxies = processed_pdb_file.all_chain_proxies
  pdb_hierarchy = chain_proxies.pdb_hierarchy
  result = restraints.combined(
    pdb_hierarchy=chain_proxies.pdb_hierarchy,
    xray_structure=xray_structure,
    geometry_restraints_manager=geometry,
    ignore_hd=True)
  result.show(out=log, prefix="  ")
def run(args, log=sys.stdout):
    processed_pdb_file = pdb_interpretation.run(
        args=args,
        substitute_non_crystallographic_unit_cell_if_necessary=True,
        log=log)
    xray_structure = processed_pdb_file.xray_structure()
    if xray_structure is None:
        raise Sorry(
            "Could not calculate X-ray structure from this PDB file. " +
            "This is probably due to missing symmetry information (CRYST1 record."
        )
    geometry = processed_pdb_file.geometry_restraints_manager(
        show_energies=False)
    chain_proxies = processed_pdb_file.all_chain_proxies
    pdb_hierarchy = chain_proxies.pdb_hierarchy
    result = restraints.combined(pdb_hierarchy=chain_proxies.pdb_hierarchy,
                                 xray_structure=xray_structure,
                                 geometry_restraints_manager=geometry,
                                 ignore_hd=True)
    result.show(out=log, prefix="  ")
Example #8
0
 def run_geometry_validation(self) :
   from mmtbx.validation import restraints
   restraints = restraints.combined(
     pdb_hierarchy=self.cmdline.pdb_hierarchy,
     xray_structure=self.cmdline.xray_structure,
     geometry_restraints_manager=self.cmdline.geometry,
     ignore_hd=True,
     cdl=False)
   restraints.angles.show()
   # get bond legth outlier data
   for result in restraints.bonds.results :
     #print >> sys.stderr, dir(result)
     # Since this is a bond length there are two atoms involved 
     reskey0,name0 = self.get_res_key_and_atom(result.atoms_info[0])
     reskey1,name1 = self.get_res_key_and_atom(result.atoms_info[1])
     self.residues[reskey0].add_bondlength_result(result,reskey0,name0,
                                                         reskey1,name1)
     if reskey0 != reskey1 :
       self.residues[reskey1].add_bondlength_result(result,reskey1,name1,
                                                           reskey0,name0)
   for result in restraints.angles.results :
     #print >> sys.stderr, dir(result)
     # Since this is a angle there are three atoms involved 
     reskey0,name0 = self.get_res_key_and_atom(result.atoms_info[0])
     reskey1,name1 = self.get_res_key_and_atom(result.atoms_info[1])
     reskey2,name2 = self.get_res_key_and_atom(result.atoms_info[2])
     # The logic that follows inserts the angle outlier info into the
     # two or one residue[s] involved. At least two of the three residues
     # will be the same residue.
     self.residues[reskey0].add_angle_result(result,reskey0,name0,
                                                    reskey1,name1,
                                                    reskey2,name2)
     if reskey0 != reskey1 :
       self.residues[reskey1].add_angle_result(result,reskey1,name1,
                                                      reskey0,name0,
                                                      reskey2,name2)
     elif reskey0 != reskey2 :
       self.residues[reskey2].add_angle_result(result,reskey2,name2,
                                                      reskey1,name1,
                                                      reskey0,name0)
Example #9
0
    def __init__(self,
                 pdb_hierarchy,
                 xray_structure=None,
                 fmodel=None,
                 fmodel_neutron=None,
                 geometry_restraints_manager=None,
                 crystal_symmetry=None,
                 sequences=None,
                 flags=None,
                 header_info=None,
                 raw_data=None,
                 unmerged_data=None,
                 all_chain_proxies=None,
                 keep_hydrogens=True,
                 nuclear=False,
                 save_probe_unformatted_file=None,
                 show_hydrogen_outliers=False,
                 min_cc_two_fofc=0.8,
                 n_bins_data=10,
                 count_anomalous_pairs_separately=False,
                 use_internal_variance=True,
                 outliers_only=True,
                 use_pdb_header_resolution_cutoffs=False,
                 file_name=None,
                 ligand_selection=None,
                 rotamer_library="8000",
                 map_params=None):
        assert rotamer_library == "8000", "data_version given to RotamerEval not recognized."
        for name in self.__slots__:
            setattr(self, name, None)
        # very important - the i_seq attributes may be extracted later
        pdb_hierarchy.atoms().reset_i_seq()
        self.pdb_hierarchy = pdb_hierarchy
        if (xray_structure is None):
            if (fmodel is not None):
                xray_structure = fmodel.xray_structure
            elif (crystal_symmetry is not None):
                xray_structure = pdb_hierarchy.extract_xray_structure(
                    crystal_symmetry=crystal_symmetry)
        self.crystal_symmetry = crystal_symmetry
        if (crystal_symmetry is None) and (fmodel is not None):
            self.crystal_symmetry = fmodel.f_obs().crystal_symmetry()

        # use maps (fmodel is not used)
        # run earlier since pdb_hierarchy gets modified
        use_maps = False
        if (map_params is not None):
            use_maps = ((map_params.input.maps.map_file_name) or
                        ((map_params.input.maps.map_coefficients_file_name) and
                         (map_params.input.maps.map_coefficients_label)))
        if (use_maps):
            if (flags.real_space):
                self.real_space = experimental.real_space(
                    fmodel=None,
                    pdb_hierarchy=pdb_hierarchy,
                    crystal_symmetry=self.crystal_symmetry,
                    cc_min=min_cc_two_fofc,
                    molprobity_map_params=map_params.input.maps)
            if (flags.waters):
                self.waters = waters.waters(
                    pdb_hierarchy=pdb_hierarchy,
                    xray_structure=xray_structure,
                    fmodel=None,
                    collect_all=True,
                    molprobity_map_params=map_params.input.maps)

        self.header_info = header_info
        if (flags is None):
            flags = molprobity_flags()
        import mmtbx.model.statistics
        self.model_statistics_geometry = mmtbx.model.statistics.geometry(
            pdb_hierarchy=pdb_hierarchy,
            geometry_restraints_manager=geometry_restraints_manager,
            use_hydrogens=keep_hydrogens,
            use_nuclear=nuclear)
        self.model_statistics_geometry_result = \
          self.model_statistics_geometry.result()
        self.ramalyze = self.model_statistics_geometry_result.ramachandran.ramalyze
        self.omegalyze = self.model_statistics_geometry_result.omega.omegalyze
        self.rotalyze = self.model_statistics_geometry_result.rotamer.rotalyze
        self.cbetadev = self.model_statistics_geometry_result.c_beta.cbetadev
        self.clashes = self.model_statistics_geometry_result.clash.clashes
        if pdb_hierarchy.contains_protein():
            self.find_missing_atoms(out=null_out())
            if (flags.nqh):
                self.nqh_flips = clashscore.nqh_flips(
                    pdb_hierarchy=pdb_hierarchy)
        if (pdb_hierarchy.contains_rna() and flags.rna
                and libtbx.env.has_module(name="suitename")):
            if (geometry_restraints_manager is not None):
                self.rna = rna_validate.rna_validation(
                    pdb_hierarchy=pdb_hierarchy,
                    geometry_restraints_manager=geometry_restraints_manager,
                    outliers_only=outliers_only,
                    params=None)
        if (flags.model_stats) and (xray_structure is not None):
            self.model_stats = model_properties.model_statistics(
                pdb_hierarchy=pdb_hierarchy,
                xray_structure=xray_structure,
                all_chain_proxies=all_chain_proxies,
                ignore_hd=(not nuclear),
                ligand_selection=ligand_selection)
        if (geometry_restraints_manager is not None) and (flags.restraints):
            assert (xray_structure is not None)
            self.restraints = restraints.combined(
                pdb_hierarchy=pdb_hierarchy,
                xray_structure=xray_structure,
                geometry_restraints_manager=geometry_restraints_manager,
                ignore_hd=(not nuclear),
                cdl=getattr(all_chain_proxies, "use_cdl", None))
        if (sequences is not None) and (flags.seq):
            self.sequence = sequence.validation(
                pdb_hierarchy=pdb_hierarchy,
                sequences=sequences,
                log=null_out(),
                include_secondary_structure=True,
                extract_coordinates=True)

        if (fmodel is not None):
            if (use_pdb_header_resolution_cutoffs) and (header_info
                                                        is not None):
                fmodel = fmodel.resolution_filter(d_min=header_info.d_min,
                                                  d_max=header_info.d_max)
            if (flags.rfactors):
                self.data_stats = experimental.data_statistics(
                    fmodel,
                    raw_data=raw_data,
                    n_bins=n_bins_data,
                    count_anomalous_pairs_separately=
                    count_anomalous_pairs_separately)

            if (not use_maps):  # if maps are used, keep previous results
                if (flags.real_space):
                    self.real_space = experimental.real_space(
                        fmodel=fmodel,
                        pdb_hierarchy=pdb_hierarchy,
                        cc_min=min_cc_two_fofc)
                if (flags.waters):
                    self.waters = waters.waters(pdb_hierarchy=pdb_hierarchy,
                                                xray_structure=xray_structure,
                                                fmodel=fmodel,
                                                collect_all=True)

            if (unmerged_data is not None):
                self.merging = experimental.merging_and_model_statistics(
                    f_obs=fmodel.f_obs(),
                    f_model=fmodel.f_model(),
                    r_free_flags=fmodel.r_free_flags(),
                    unmerged_i_obs=unmerged_data,
                    anomalous=count_anomalous_pairs_separately,
                    use_internal_variance=use_internal_variance,
                    n_bins=n_bins_data)
            if (flags.xtriage):
                import mmtbx.scaling.xtriage
                f_model = abs(
                    fmodel.f_model()).set_observation_type_xray_amplitude()
                if (raw_data is not None):
                    f_model, obs = f_model.common_sets(other=raw_data)
                else:
                    obs = fmodel.f_obs()
                self.xtriage = mmtbx.scaling.xtriage.xtriage_analyses(
                    miller_obs=obs,
                    miller_calc=f_model,
                    unmerged_obs=unmerged_data,  # XXX some redundancy here...
                    text_out=null_out())
        if (fmodel_neutron is not None) and (flags.rfactors):
            self.neutron_stats = experimental.data_statistics(
                fmodel_neutron,
                n_bins=n_bins_data,
                count_anomalous_pairs_separately=False)
        if (pdb_hierarchy.models_size() == 1):
            self._multi_criterion = multi_criterion_view(pdb_hierarchy)

        # wilson B
        self.wilson_b = None
        if (fmodel is not None):
            self.wilson_b = fmodel.wilson_b()
        elif (fmodel_neutron is not None):
            self.wilson_b = fmodel_neutron.wilson_b()
Example #10
0
  def __init__ (self,
      pdb_hierarchy,
      xray_structure=None,
      fmodel=None,
      fmodel_neutron=None,
      geometry_restraints_manager=None,
      crystal_symmetry=None,
      sequences=None,
      flags=None,
      header_info=None,
      raw_data=None,
      unmerged_data=None,
      all_chain_proxies=None,
      keep_hydrogens=True,
      nuclear=False,
      save_probe_unformatted_file=None,
      show_hydrogen_outliers=False,
      min_cc_two_fofc=0.8,
      n_bins_data=10,
      count_anomalous_pairs_separately=False,
      use_internal_variance=True,
      outliers_only=True,
      use_pdb_header_resolution_cutoffs=False,
      file_name=None,
      ligand_selection=None,
      rotamer_library="8000",
      map_params=None) :
    assert rotamer_library == "8000", "data_version given to RotamerEval not recognized."
    for name in self.__slots__ :
      setattr(self, name, None)
    # very important - the i_seq attributes may be extracted later
    pdb_hierarchy.atoms().reset_i_seq()
    self.pdb_hierarchy = pdb_hierarchy
    if (xray_structure is None) :
      if (fmodel is not None) :
        xray_structure = fmodel.xray_structure
      elif (crystal_symmetry is not None) :
        xray_structure = pdb_hierarchy.extract_xray_structure(
          crystal_symmetry=crystal_symmetry)
    self.crystal_symmetry = crystal_symmetry
    if (crystal_symmetry is None) and (fmodel is not None) :
      self.crystal_symmetry = fmodel.f_obs().crystal_symmetry()
    self.header_info = header_info
    if (flags is None) :
      flags = molprobity_flags()
    if pdb_hierarchy.contains_protein() :
      if (flags.ramalyze) :
        self.ramalyze = ramalyze.ramalyze(
          pdb_hierarchy=pdb_hierarchy,
          outliers_only=outliers_only,
          out=null_out(),
          quiet=True)
##### omegalyze ################################################################
      if (flags.omegalyze) :
        self.omegalyze = omegalyze.omegalyze(
          pdb_hierarchy=pdb_hierarchy,
          nontrans_only=outliers_only,
          out=null_out(),
          quiet=True)
##### omegalyze ################################################################
      if (flags.rotalyze) :
        self.rotalyze = rotalyze.rotalyze(
          pdb_hierarchy=pdb_hierarchy,
          data_version=rotamer_library,
          outliers_only=outliers_only,
          out=null_out(),
          quiet=True)
      if (flags.cbetadev) :
        self.cbetadev = cbetadev.cbetadev(
          pdb_hierarchy=pdb_hierarchy,
          outliers_only=outliers_only,
          out=null_out(),
          quiet=True)
      if (flags.nqh) :
        self.nqh_flips = clashscore.nqh_flips(
          pdb_hierarchy=pdb_hierarchy)
    if (pdb_hierarchy.contains_rna() and flags.rna and
        libtbx.env.has_module(name="suitename")) :
      if (geometry_restraints_manager is not None) :
        self.rna = rna_validate.rna_validation(
          pdb_hierarchy=pdb_hierarchy,
          geometry_restraints_manager=geometry_restraints_manager,
          outliers_only=outliers_only,
          params=None)
    if (flags.clashscore) :
      self.clashes = clashscore.clashscore(
        pdb_hierarchy=pdb_hierarchy,
        save_probe_unformatted_file=save_probe_unformatted_file,
        nuclear=nuclear,
        keep_hydrogens=keep_hydrogens,
        out=null_out(),
        verbose=False)
    if (flags.model_stats) and (xray_structure is not None) :
      self.model_stats = model_properties.model_statistics(
        pdb_hierarchy=pdb_hierarchy,
        xray_structure=xray_structure,
        all_chain_proxies=all_chain_proxies,
        ignore_hd=(not nuclear),
        ligand_selection=ligand_selection)
    if (geometry_restraints_manager is not None) and (flags.restraints) :
      assert (xray_structure is not None)
      self.restraints = restraints.combined(
        pdb_hierarchy=pdb_hierarchy,
        xray_structure=xray_structure,
        geometry_restraints_manager=geometry_restraints_manager,
        ignore_hd=(not nuclear),
        cdl=getattr(all_chain_proxies, "use_cdl", None))
    if (sequences is not None) and (flags.seq) :
      self.sequence = sequence.validation(
        pdb_hierarchy=pdb_hierarchy,
        sequences=sequences,
        log=null_out(),
        include_secondary_structure=True,
        extract_coordinates=True)

    # use maps (fmodel is not used)
    use_maps = False
    if (map_params is not None):
      use_maps = ( (map_params.input.maps.map_file_name) or
                   ( (map_params.input.maps.map_coefficients_file_name) and
                     (map_params.input.maps.map_coefficients_label) ) )
    if (use_maps):
      if (flags.real_space):
        self.real_space = experimental.real_space(
          fmodel=None,
          pdb_hierarchy=pdb_hierarchy,
          cc_min=min_cc_two_fofc,
          molprobity_map_params=map_params.input.maps)
      if (flags.waters):
        self.waters = waters.waters(
          pdb_hierarchy=pdb_hierarchy,
          xray_structure=xray_structure,
          fmodel=None,
          collect_all=True,
          molprobity_map_params=map_params.input.maps)

    if (fmodel is not None) :
      if (use_pdb_header_resolution_cutoffs) and (header_info is not None) :
        fmodel = fmodel.resolution_filter(
          d_min=header_info.d_min,
          d_max=header_info.d_max)
      if (flags.rfactors) :
        self.data_stats = experimental.data_statistics(fmodel,
          raw_data=raw_data,
          n_bins=n_bins_data,
          count_anomalous_pairs_separately=count_anomalous_pairs_separately)

      if (not use_maps): # if maps are used, keep previous results
        if (flags.real_space):
          self.real_space = experimental.real_space(
            fmodel=fmodel,
            pdb_hierarchy=pdb_hierarchy,
            cc_min=min_cc_two_fofc)
        if (flags.waters) :
          self.waters = waters.waters(
            pdb_hierarchy=pdb_hierarchy,
            xray_structure=xray_structure,
            fmodel=fmodel,
            collect_all=True)

      if (unmerged_data is not None) :
        self.merging = experimental.merging_and_model_statistics(
          f_obs=fmodel.f_obs(),
          f_model=fmodel.f_model(),
          r_free_flags=fmodel.r_free_flags(),
          unmerged_i_obs=unmerged_data,
          anomalous=count_anomalous_pairs_separately,
          use_internal_variance=use_internal_variance,
          n_bins=n_bins_data)
      if (flags.xtriage) :
        import mmtbx.scaling.xtriage
        f_model = abs(fmodel.f_model()).set_observation_type_xray_amplitude()
        if (raw_data is not None) :
          f_model, obs = f_model.common_sets(other=raw_data)
        else :
          obs = fmodel.f_obs()
        self.xtriage = mmtbx.scaling.xtriage.xtriage_analyses(
          miller_obs=obs,
          miller_calc=f_model,
          unmerged_obs=unmerged_data, # XXX some redundancy here...
          text_out=null_out())
    if (fmodel_neutron is not None) and (flags.rfactors) :
      self.neutron_stats = experimental.data_statistics(fmodel_neutron,
        n_bins=n_bins_data,
        count_anomalous_pairs_separately=False)
    if (pdb_hierarchy.models_size() == 1) :
      self._multi_criterion = multi_criterion_view(pdb_hierarchy)
Example #11
0
  def __init__(self,
      model,
      fmodel=None,
      fmodel_neutron=None,
      sequences=None,
      flags=None,
      header_info=None,
      raw_data=None,
      unmerged_data=None,
      keep_hydrogens=True,
      nuclear=False,
      save_probe_unformatted_file=None,
      show_hydrogen_outliers=False,
      min_cc_two_fofc=0.8,
      n_bins_data=10,
      count_anomalous_pairs_separately=False,
      use_internal_variance=True,
      outliers_only=True,
      use_pdb_header_resolution_cutoffs=False,
      file_name=None,
      ligand_selection=None,
      rotamer_library="8000",
      map_params=None):
    assert rotamer_library == "8000", "data_version given to RotamerEval not recognized."
    for name in self.__slots__ :
      setattr(self, name, None)

    # use objects from model
    self.model = model
    if(not self.model.processed()):
      self.model.process(make_restraints=True)
    if(self.model is None and pdb_hierarchy is not None):
      import mmtbx.model
      self.model = mmtbx.model.manager(
        model_input = pdb_hierarchy.as_pdb_input())
      self.model.process(make_restraints=True)

    pdb_hierarchy = self.model.get_hierarchy()
    if(nuclear):
      self.model.setup_scattering_dictionaries(scattering_table="neutron")

    if (self.model is not None):
      if(self.model.get_restraints_manager() is None):
        self.model.process(make_restraints=True)
      pdb_hierarchy = self.model.get_hierarchy()
      xray_structure = self.model.get_xray_structure()
      geometry_restraints_manager = self.model.get_restraints_manager().geometry
      crystal_symmetry = self.model.crystal_symmetry()
      all_chain_proxies = None
    else:
      assert (pdb_hierarchy is not None)
      xray_structure = None
      geometry_restraints_manager = None
      crystal_symmetry = None
      all_chain_proxies = None

    # very important - the i_seq attributes may be extracted later
    pdb_hierarchy.atoms().reset_i_seq()
    self.pdb_hierarchy = pdb_hierarchy
    if (xray_structure is None):
      if (fmodel is not None):
        xray_structure = fmodel.xray_structure
      elif (crystal_symmetry is not None):
        xray_structure = pdb_hierarchy.extract_xray_structure(
          crystal_symmetry=crystal_symmetry)
    self.crystal_symmetry = crystal_symmetry
    if (crystal_symmetry is None) and (fmodel is not None):
      self.crystal_symmetry = fmodel.f_obs().crystal_symmetry()

    # use maps (fmodel is not used)
    # run earlier since pdb_hierarchy gets modified
    use_maps = False
    if (map_params is not None):
      use_maps = ( (map_params.input.maps.map_file_name) or
                   ( (map_params.input.maps.map_coefficients_file_name) and
                     (map_params.input.maps.map_coefficients_label) ) )
    if (use_maps):
      if (flags.real_space):
        self.real_space = experimental.real_space(
          fmodel=None,
          model=self.model,
          cc_min=min_cc_two_fofc,
          molprobity_map_params=map_params.input.maps)
      if (flags.waters):
        self.waters = waters.waters(
          pdb_hierarchy=pdb_hierarchy,
          xray_structure=xray_structure,
          fmodel=None,
          collect_all=True,
          molprobity_map_params=map_params.input.maps)

    self.header_info = header_info
    if (flags is None):
      flags = molprobity_flags()

    self.model_statistics_geometry = self.model.geometry_statistics(
      use_hydrogens=keep_hydrogens, condensed_probe=False, fast_clash=False)
    self.model_statistics_geometry_result = \
      self.model_statistics_geometry.result()
    self.ramalyze  = self.model_statistics_geometry_result.ramachandran.ramalyze
    self.omegalyze = self.model_statistics_geometry_result.omega.omegalyze
    self.rotalyze  = self.model_statistics_geometry_result.rotamer.rotalyze
    self.cbetadev  = self.model_statistics_geometry_result.c_beta.cbetadev
    self.clashes   = self.model_statistics_geometry_result.clash.clashes
    if pdb_hierarchy.contains_protein():
      self.find_missing_atoms(out=null_out())
      if (flags.nqh):
        self.nqh_flips = clashscore.nqh_flips(
          pdb_hierarchy=pdb_hierarchy)
    if (pdb_hierarchy.contains_rna() and flags.rna and
        libtbx.env.has_module(name="suitename")):
      if (geometry_restraints_manager is not None):
        self.rna = rna_validate.rna_validation(
          pdb_hierarchy=pdb_hierarchy,
          geometry_restraints_manager=geometry_restraints_manager,
          outliers_only=outliers_only,
          params=None)
    if (flags.model_stats) and (self.model is not None):
      # keep for backwards compatibility
      self.model_stats = model_properties.model_statistics(
        pdb_hierarchy=pdb_hierarchy,
        xray_structure=xray_structure,
        all_chain_proxies=all_chain_proxies,
        ignore_hd=(not nuclear),
        ligand_selection=ligand_selection)
      # ligand_selection is no longer available
      self.model_stats_new = self.model.composition()
      self.adp_stats = self.model.adp_statistics()
    if (geometry_restraints_manager is not None) and (flags.restraints):
      assert (xray_structure is not None)
      self.restraints = restraints.combined(
        pdb_hierarchy=pdb_hierarchy,
        xray_structure=xray_structure,
        geometry_restraints_manager=geometry_restraints_manager,
        ignore_hd=(not nuclear),
        cdl=getattr(all_chain_proxies, "use_cdl", None))
    if (sequences is not None) and (flags.seq):
      self.sequence = sequence.validation(
        pdb_hierarchy=pdb_hierarchy,
        sequences=sequences,
        log=null_out(),
        include_secondary_structure=True,
        extract_coordinates=True)

    if (fmodel is not None):
      if (use_pdb_header_resolution_cutoffs) and (header_info is not None):
        fmodel = fmodel.resolution_filter(
          d_min=header_info.d_min,
          d_max=header_info.d_max)
        fmodel.update_all_scales()
      if (flags.rfactors):
        self.data_stats = experimental.data_statistics(fmodel,
          raw_data=raw_data,
          n_bins=n_bins_data,
          count_anomalous_pairs_separately=count_anomalous_pairs_separately)

      if (not use_maps): # if maps are used, keep previous results
        if (flags.real_space):
          self.real_space = experimental.real_space(
            model=model,
            fmodel=fmodel,
            cc_min=min_cc_two_fofc)
        if (flags.waters):
          self.waters = waters.waters(
            pdb_hierarchy=pdb_hierarchy,
            xray_structure=xray_structure,
            fmodel=fmodel,
            collect_all=True)

      if (unmerged_data is not None):
        self.merging = experimental.merging_and_model_statistics(
          f_obs=fmodel.f_obs(),
          f_model=fmodel.f_model(),
          r_free_flags=fmodel.r_free_flags(),
          unmerged_i_obs=unmerged_data,
          anomalous=count_anomalous_pairs_separately,
          use_internal_variance=use_internal_variance,
          n_bins=n_bins_data)
      if (flags.xtriage):
        import mmtbx.scaling.xtriage
        f_model = abs(fmodel.f_model()).set_observation_type_xray_amplitude()
        if (raw_data is not None):
          f_model, obs = f_model.common_sets(other=raw_data)
        else :
          obs = fmodel.f_obs()
        self.xtriage = mmtbx.scaling.xtriage.xtriage_analyses(
          miller_obs=obs,
          miller_calc=f_model,
          unmerged_obs=unmerged_data, # XXX some redundancy here...
          text_out=null_out())
    if (fmodel_neutron is not None) and (flags.rfactors):
      self.neutron_stats = experimental.data_statistics(fmodel_neutron,
        n_bins=n_bins_data,
        count_anomalous_pairs_separately=False)
    if (pdb_hierarchy.models_size() == 1):
      self._multi_criterion = multi_criterion_view(pdb_hierarchy)

    # wilson B
    self.wilson_b = None
    if (fmodel is not None):
      self.wilson_b = fmodel.wilson_b()
    elif (fmodel_neutron is not None):
      self.wilson_b = fmodel_neutron.wilson_b()

    # validate hydrogens
    self.hydrogens = None
    if self.model is not None and self.model.has_hd():
      # import here to avoid circular import issues
      from mmtbx.hydrogens.validate_H import validate_H, validate_H_results
      hydrogens = validate_H(model, nuclear)
      hydrogens.validate_inputs()
      hydrogens.run()
      self.hydrogens = validate_H_results(hydrogens.get_results())

    # write probe file if needed (CLI and GUI)
    if (save_probe_unformatted_file is not None):
      pcm = self.clashes.probe_clashscore_manager
      try:
        with open(save_probe_unformatted_file, 'w') as f:
          f.write(pcm.probe_unformatted)
        self.clashes.probe_file = save_probe_unformatted_file
      except IOError as err:
        raise Sorry('%s could not be written correctly.\n%s' %
                    (save_probe_unformatted_file, err))