Exemplo n.º 1
0
  def __init__ (self, pdb_hierarchy, xray_structure, fmodel,
                distance_cutoff=4.0, collect_all=True,
                molprobity_map_params=None) :
    validation.__init__(self)
    from mmtbx.real_space_correlation import extract_map_stats_for_single_atoms
    from cctbx import adptbx
    from scitbx.matrix import col
    self.n_bad = 0
    self.n_heavy = 0
    pdb_atoms = pdb_hierarchy.atoms()
    if(len(pdb_atoms)>1):
      assert (not pdb_atoms.extract_i_seq().all_eq(0))
    unit_cell = xray_structure.unit_cell()
    pair_asu_table = xray_structure.pair_asu_table(
      distance_cutoff = distance_cutoff)
    asu_mappings = pair_asu_table.asu_mappings()
    asu_table = pair_asu_table.table()
    u_isos = xray_structure.extract_u_iso_or_u_equiv()
    occupancies = xray_structure.scatterers().extract_occupancies()
    sites_cart = xray_structure.sites_cart()
    sites_frac = xray_structure.sites_frac()
    sel_cache = pdb_hierarchy.atom_selection_cache()
    water_sel = sel_cache.selection("resname HOH and name O")

    if (molprobity_map_params is not None):
      # assume parameters have been validated (symmetry of pdb and map matches)
      two_fofc_map = None
      fc_map = None
      d_min = None
      crystal_gridding = None

      # read two_fofc_map
      if (molprobity_map_params.map_file_name is not None):
        f = any_file(molprobity_map_params.map_file_name)
        two_fofc_map = f.file_object.map_data()
        d_min = molprobity_map_params.d_min
        crystal_gridding = maptbx.crystal_gridding(
          f.file_object.unit_cell(),
          space_group_info=space_group_info(f.file_object.space_group_number),
          pre_determined_n_real=f.file_object.unit_cell_grid)
      elif (molprobity_map_params.map_coefficients_file_name is not None):
        f = any_file(molprobity_map_params.map_coefficients_file_name)
        fourier_coefficients = f.file_server.get_miller_array(
          molprobity_map_params.map_coefficients_label)
        crystal_symmetry = fourier_coefficients.crystal_symmetry()
        d_min = fourier_coefficients.d_min()
        crystal_gridding = maptbx.crystal_gridding(
          crystal_symmetry.unit_cell(), d_min, resolution_factor=0.25,
          space_group_info=crystal_symmetry.space_group_info())
        two_fofc_map = miller.fft_map(
          crystal_gridding=crystal_gridding,
          fourier_coefficients=fourier_coefficients).apply_sigma_scaling().\
          real_map_unpadded()

      # calculate fc_map
      assert( (d_min is not None) and (crystal_gridding is not None) )
      f_calc = xray_structure.structure_factors(d_min=d_min).f_calc()
      fc_map = miller.fft_map(crystal_gridding=crystal_gridding,
                              fourier_coefficients=f_calc)
      fc_map = fc_map.apply_sigma_scaling().real_map_unpadded()

      map_stats = extract_map_stats_for_single_atoms(
        pdb_atoms=pdb_atoms,
        xray_structure=xray_structure,
        fmodel=None,
        selection=water_sel,
        fc_map=fc_map,
        two_fofc_map=two_fofc_map)
    else:
      map_stats = extract_map_stats_for_single_atoms(
        pdb_atoms=pdb_atoms,
        xray_structure=xray_structure,
        fmodel=fmodel,
        selection=water_sel)
    waters = []
    for i_seq, atom in enumerate(pdb_atoms) :
      if (water_sel[i_seq]) :
        rt_mx_i_inv = asu_mappings.get_rt_mx(i_seq, 0).inverse()
        self.n_total += 1
        asu_dict = asu_table[i_seq]
        nearest_atom = nearest_contact = None
        for j_seq, j_sym_groups in asu_dict.items() :
          atom_j = pdb_atoms[j_seq]
          site_j = sites_frac[j_seq]
          # Filter out hydrogens
          if atom_j.element.upper().strip() in ["H", "D"]:
            continue
          for j_sym_group in j_sym_groups:
            rt_mx = rt_mx_i_inv.multiply(asu_mappings.get_rt_mx(j_seq,
              j_sym_group[0]))
            site_ji = rt_mx * site_j
            site_ji_cart = xray_structure.unit_cell().orthogonalize(site_ji)
            vec_i = col(atom.xyz)
            vec_ji = col(site_ji_cart)
            dxyz = abs(vec_i - vec_ji)
            if (nearest_contact is None) or (dxyz < nearest_contact) :
              nearest_contact = dxyz
              nearest_atom = atom_info(pdb_atom=atom_j, symop=rt_mx)
        w = water(
          pdb_atom=atom,
          b_iso=adptbx.u_as_b(u_isos[i_seq]),
          occupancy=occupancies[i_seq],
          nearest_contact=nearest_contact,
          nearest_atom=nearest_atom,
          score=map_stats.two_fofc_ccs[i_seq],
          fmodel=map_stats.fmodel_values[i_seq],
          two_fofc=map_stats.two_fofc_values[i_seq],
          fofc=map_stats.fofc_values[i_seq],
          anom=map_stats.anom_values[i_seq],
          n_hbonds=None) # TODO
        if (w.is_bad_water()) :
          w.outlier = True
          self.n_bad += 1
        elif (w.is_heavy_atom()) :
          w.outlier = True
          self.n_heavy += 1
        if (w.outlier) or (collect_all) :
          self.results.append(w)
    self.n_outliers = len(self.results)
Exemplo n.º 2
0
    def __init__(self,
                 pdb_hierarchy,
                 xray_structure,
                 fmodel,
                 distance_cutoff=4.0,
                 collect_all=True,
                 molprobity_map_params=None):
        validation.__init__(self)
        from mmtbx.real_space_correlation import extract_map_stats_for_single_atoms
        from cctbx import adptbx
        from scitbx.matrix import col
        self.n_bad = 0
        self.n_heavy = 0
        pdb_atoms = pdb_hierarchy.atoms()
        if (len(pdb_atoms) > 1):
            assert (not pdb_atoms.extract_i_seq().all_eq(0))
        unit_cell = xray_structure.unit_cell()
        pair_asu_table = xray_structure.pair_asu_table(
            distance_cutoff=distance_cutoff)
        asu_mappings = pair_asu_table.asu_mappings()
        asu_table = pair_asu_table.table()
        u_isos = xray_structure.extract_u_iso_or_u_equiv()
        occupancies = xray_structure.scatterers().extract_occupancies()
        sites_frac = xray_structure.sites_frac()
        sel_cache = pdb_hierarchy.atom_selection_cache()
        water_sel = sel_cache.selection("water")

        if (molprobity_map_params is not None):
            # assume parameters have been validated (symmetry of pdb and map matches)
            two_fofc_map = None
            fc_map = None
            d_min = None
            crystal_gridding = None

            # read two_fofc_map
            if (molprobity_map_params.map_file_name is not None):
                f = any_file(molprobity_map_params.map_file_name)
                two_fofc_map = f.file_object.map_data()
                d_min = molprobity_map_params.d_min
                crystal_gridding = maptbx.crystal_gridding(
                    f.file_object.unit_cell(),
                    space_group_info=space_group_info(
                        f.file_object.space_group_number),
                    pre_determined_n_real=f.file_object.unit_cell_grid)

                pdb_atoms = pdb_hierarchy.atoms()
                xray_structure = pdb_hierarchy.extract_xray_structure(
                    crystal_symmetry=f.crystal_symmetry())
                unit_cell = xray_structure.unit_cell()
                # check for origin shift
                # ---------------------------------------------------------------------
                soin = maptbx.shift_origin_if_needed(
                    map_data=two_fofc_map,
                    sites_cart=xray_structure.sites_cart(),
                    crystal_symmetry=xray_structure.crystal_symmetry())
                two_fofc_map = soin.map_data
                xray_structure.set_sites_cart(soin.sites_cart)
                # ---------------------------------------------------------------------
                pair_asu_table = xray_structure.pair_asu_table(
                    distance_cutoff=distance_cutoff)
                asu_mappings = pair_asu_table.asu_mappings()
                asu_table = pair_asu_table.table()
                u_isos = xray_structure.extract_u_iso_or_u_equiv()
                occupancies = xray_structure.scatterers().extract_occupancies()
                sites_frac = xray_structure.sites_frac()
                sel_cache = pdb_hierarchy.atom_selection_cache()
                water_sel = sel_cache.selection("water")

            elif (molprobity_map_params.map_coefficients_file_name
                  is not None):
                f = any_file(molprobity_map_params.map_coefficients_file_name)
                fourier_coefficients = f.file_server.get_miller_array(
                    molprobity_map_params.map_coefficients_label)
                crystal_symmetry = fourier_coefficients.crystal_symmetry()
                d_min = fourier_coefficients.d_min()
                crystal_gridding = maptbx.crystal_gridding(
                    crystal_symmetry.unit_cell(),
                    d_min,
                    resolution_factor=0.25,
                    space_group_info=crystal_symmetry.space_group_info())
                two_fofc_map = miller.fft_map(
                  crystal_gridding=crystal_gridding,
                  fourier_coefficients=fourier_coefficients).apply_sigma_scaling().\
                  real_map_unpadded()

            # calculate fc_map
            assert ((d_min is not None) and (crystal_gridding is not None))
            f_calc = xray_structure.structure_factors(d_min=d_min).f_calc()
            fc_map = miller.fft_map(crystal_gridding=crystal_gridding,
                                    fourier_coefficients=f_calc)
            fc_map = fc_map.apply_sigma_scaling().real_map_unpadded()

            map_stats = extract_map_stats_for_single_atoms(
                pdb_atoms=pdb_atoms,
                xray_structure=xray_structure,
                fmodel=None,
                selection=water_sel,
                fc_map=fc_map,
                two_fofc_map=two_fofc_map)
        else:
            map_stats = extract_map_stats_for_single_atoms(
                pdb_atoms=pdb_atoms,
                xray_structure=xray_structure,
                fmodel=fmodel,
                selection=water_sel)
        waters = []
        for i_seq, atom in enumerate(pdb_atoms):
            if (water_sel[i_seq]):
                rt_mx_i_inv = asu_mappings.get_rt_mx(i_seq, 0).inverse()
                self.n_total += 1
                asu_dict = asu_table[i_seq]
                nearest_atom = nearest_contact = None
                for j_seq, j_sym_groups in asu_dict.items():
                    atom_j = pdb_atoms[j_seq]
                    site_j = sites_frac[j_seq]
                    # Filter out hydrogens
                    if atom_j.element.upper().strip() in ["H", "D"]:
                        continue
                    for j_sym_group in j_sym_groups:
                        rt_mx = rt_mx_i_inv.multiply(
                            asu_mappings.get_rt_mx(j_seq, j_sym_group[0]))
                        site_ji = rt_mx * site_j
                        site_ji_cart = xray_structure.unit_cell(
                        ).orthogonalize(site_ji)
                        vec_i = col(atom.xyz)
                        vec_ji = col(site_ji_cart)
                        dxyz = abs(vec_i - vec_ji)
                        if (nearest_contact is None) or (dxyz <
                                                         nearest_contact):
                            nearest_contact = dxyz
                            nearest_atom = atom_info(pdb_atom=atom_j,
                                                     symop=rt_mx)
                w = water(pdb_atom=atom,
                          b_iso=adptbx.u_as_b(u_isos[i_seq]),
                          occupancy=occupancies[i_seq],
                          nearest_contact=nearest_contact,
                          nearest_atom=nearest_atom,
                          score=map_stats.two_fofc_ccs[i_seq],
                          fmodel=map_stats.fmodel_values[i_seq],
                          two_fofc=map_stats.two_fofc_values[i_seq],
                          fofc=map_stats.fofc_values[i_seq],
                          anom=map_stats.anom_values[i_seq],
                          n_hbonds=None)  # TODO
                if (w.is_bad_water()):
                    w.outlier = True
                    self.n_bad += 1
                elif (w.is_heavy_atom()):
                    w.outlier = True
                    self.n_heavy += 1
                if (w.outlier) or (collect_all):
                    self.results.append(w)
        self.n_outliers = len(self.results)
Exemplo n.º 3
0
 def __init__ (self, pdb_hierarchy, xray_structure, fmodel,
     distance_cutoff=4.0, collect_all=True) :
   validation.__init__(self)
   from mmtbx.real_space_correlation import extract_map_stats_for_single_atoms
   from cctbx import adptbx
   from scitbx.matrix import col
   self.n_bad = 0
   self.n_heavy = 0
   pdb_atoms = pdb_hierarchy.atoms()
   if(len(pdb_atoms)>1):
     assert (not pdb_atoms.extract_i_seq().all_eq(0))
   unit_cell = xray_structure.unit_cell()
   pair_asu_table = xray_structure.pair_asu_table(
     distance_cutoff = distance_cutoff)
   asu_mappings = pair_asu_table.asu_mappings()
   asu_table = pair_asu_table.table()
   u_isos = xray_structure.extract_u_iso_or_u_equiv()
   occupancies = xray_structure.scatterers().extract_occupancies()
   sites_cart = xray_structure.sites_cart()
   sites_frac = xray_structure.sites_frac()
   sel_cache = pdb_hierarchy.atom_selection_cache()
   water_sel = sel_cache.selection("resname HOH and name O")
   map_stats = extract_map_stats_for_single_atoms(
     pdb_atoms=pdb_atoms,
     xray_structure=xray_structure,
     fmodel=fmodel,
     selection=water_sel)
   waters = []
   for i_seq, atom in enumerate(pdb_atoms) :
     if (water_sel[i_seq]) :
       rt_mx_i_inv = asu_mappings.get_rt_mx(i_seq, 0).inverse()
       self.n_total += 1
       asu_dict = asu_table[i_seq]
       nearest_atom = nearest_contact = None
       for j_seq, j_sym_groups in asu_dict.items() :
         atom_j = pdb_atoms[j_seq]
         site_j = sites_frac[j_seq]
         # Filter out hydrogens
         if atom_j.element.upper().strip() in ["H", "D"]:
           continue
         for j_sym_group in j_sym_groups:
           rt_mx = rt_mx_i_inv.multiply(asu_mappings.get_rt_mx(j_seq,
             j_sym_group[0]))
           site_ji = rt_mx * site_j
           site_ji_cart = xray_structure.unit_cell().orthogonalize(site_ji)
           vec_i = col(atom.xyz)
           vec_ji = col(site_ji_cart)
           dxyz = abs(vec_i - vec_ji)
           if (nearest_contact is None) or (dxyz < nearest_contact) :
             nearest_contact = dxyz
             nearest_atom = atom_info(pdb_atom=atom_j, symop=rt_mx)
       w = water(
         pdb_atom=atom,
         b_iso=adptbx.u_as_b(u_isos[i_seq]),
         occupancy=occupancies[i_seq],
         nearest_contact=nearest_contact,
         nearest_atom=nearest_atom,
         score=map_stats.two_fofc_ccs[i_seq],
         fmodel=map_stats.fmodel_values[i_seq],
         two_fofc=map_stats.two_fofc_values[i_seq],
         fofc=map_stats.fofc_values[i_seq],
         anom=map_stats.anom_values[i_seq],
         n_hbonds=None) # TODO
       if (w.is_bad_water()) :
         w.outlier = True
         self.n_bad += 1
       elif (w.is_heavy_atom()) :
         w.outlier = True
         self.n_heavy += 1
       if (w.outlier) or (collect_all) :
         self.results.append(w)
   self.n_outliers = len(self.results)
def exercise_2():
    pdb_str = """\
CRYST1   12.000    8.000   12.000  90.02  89.96  90.05 P 1           1
ATOM     39  N   ASN A   6       5.514   2.664   4.856  1.00 11.99           N
ATOM     40  CA  ASN A   6       6.831   2.310   4.318  1.00 12.30           C
ATOM     41  C   ASN A   6       7.854   2.761   5.324  1.00 13.40           C
ATOM     42  O   ASN A   6       8.219   3.943   5.374  1.00 13.92           O
ATOM     43  CB  ASN A   6       7.065   3.016   2.993  1.00 12.13           C
ATOM     44  CG  ASN A   6       5.961   2.735   2.003  1.00 12.77           C
ATOM     45  OD1 ASN A   6       5.798   1.604   1.551  1.00 14.27           O
ATOM     46  ND2 ASN A   6       5.195   3.747   1.679  1.00 10.07           N
ATOM     47  N   TYR A   7       8.292   1.817   6.147  1.00 14.70           N
ATOM     48  CA  TYR A   7       9.159   2.144   7.299  1.00 15.18           C
ATOM     49  C   TYR A   7      10.603   2.331   6.885  1.00 15.91           C
ATOM     50  O   TYR A   7      11.041   1.811   5.855  1.00 15.76           O
ATOM     51  CB  TYR A   7       9.061   1.065   8.369  1.00 15.35           C
ATOM     52  CG  TYR A   7       7.665   0.929   8.902  1.00 14.45           C
ATOM     53  CD1 TYR A   7       6.771   0.021   8.327  1.00 15.68           C
ATOM     54  CD2 TYR A   7       7.210   1.756   9.920  1.00 14.80           C
ATOM     55  CE1 TYR A   7       5.480  -0.094   8.796  1.00 13.46           C
ATOM     56  CE2 TYR A   7       5.904   1.649  10.416  1.00 14.33           C
ATOM     57  CZ  TYR A   7       5.047   0.729   9.831  1.00 15.09           C
ATOM     58  OH  TYR A   7       3.766   0.589  10.291  1.00 14.39           O
ATOM     59  OXT TYR A   7      11.358   2.999   7.612  1.00 17.49           O
TER
ATOM      1  N   ASN B   6       1.414   5.113   6.019  1.00 12.99           N
ATOM      2  CA  ASN B   6       2.720   4.776   5.445  1.00 13.30           C
ATOM      3  C   ASN B   6       3.763   5.209   6.438  1.00 14.40           C
ATOM      4  O   ASN B   6       4.125   6.391   6.507  1.00 14.92           O
ATOM      5  CB  ASN B   6       2.922   5.513   4.131  1.00 13.13           C
ATOM      6  CG  ASN B   6       1.798   5.250   3.160  1.00 13.77           C
ATOM      7  OD1 ASN B   6       1.629   4.129   2.686  1.00 15.27           O
ATOM      8  ND2 ASN B   6       1.022   6.266   2.875  1.00 11.07           N
ATOM      9  N   TYR B   7       4.222   4.248   7.230  1.00 15.70           N
ATOM     10  CA  TYR B   7       5.113   4.552   8.370  1.00 16.18           C
ATOM     11  C   TYR B   7       6.547   4.754   7.929  1.00 16.91           C
ATOM     12  O   TYR B   7       6.964   4.259   6.878  1.00 16.76           O
ATOM     13  CB  TYR B   7       5.042   3.449   9.417  1.00 16.35           C
ATOM     14  CG  TYR B   7       3.659   3.296   9.977  1.00 15.45           C
ATOM     15  CD1 TYR B   7       2.756   2.398   9.402  1.00 16.68           C
ATOM     16  CD2 TYR B   7       3.224   4.098  11.023  1.00 15.80           C
ATOM     17  CE1 TYR B   7       1.476   2.267   9.896  1.00 14.46           C
ATOM     18  CE2 TYR B   7       1.929   3.975  11.545  1.00 15.33           C
ATOM     19  CZ  TYR B   7       1.063   3.065  10.959  1.00 16.09           C
ATOM     20  OH  TYR B   7      -0.207   2.910  11.443  1.00 15.39           O
ATOM     21  OXT TYR B   7       7.316   5.408   8.654  1.00 18.49           O
END
"""
    pdb_in = iotbx.pdb.hierarchy.input(pdb_string=pdb_str)
    xrs = pdb_in.input.xray_structure_simple()
    fc = abs(xrs.structure_factors(d_min=1.5).f_calc())
    fc = fc.set_observation_type_xray_amplitude()
    sigf = flex.double(fc.size(), 0.1) + (fc.data() * 0.03)
    fc = fc.customized_copy(sigmas=sigf)
    # and now add twinning
    fc_twin = fc.twin_data(twin_law='-l,-k,-h', alpha=0.4)
    flags = fc_twin.generate_r_free_flags(use_lattice_symmetry=True)
    fmodel = mmtbx.utils.fmodel_simple(f_obs=fc_twin,
                                       r_free_flags=flags,
                                       xray_structures=[xrs],
                                       scattering_table="n_gaussian")
    assert (fmodel.twin_law is not None)
    map_stats = real_space_correlation.extract_map_stats_for_single_atoms(
        xray_structure=xrs, pdb_atoms=pdb_in.hierarchy.atoms(), fmodel=fmodel)
    sel_cache = pdb_in.hierarchy.atom_selection_cache()
    sel = sel_cache.selection("chain B")
    map_stats_2 = real_space_correlation.extract_map_stats_for_single_atoms(
        xray_structure=xrs,
        pdb_atoms=pdb_in.hierarchy.atoms(),
        fmodel=fmodel,
        selection=sel)
    map_stats_3 = real_space_correlation.map_statistics_for_atom_selection(
        atom_selection=sel, fmodel=fmodel)
def exercise_2 () :
  pdb_str = """\
CRYST1   12.000    8.000   12.000  90.02  89.96  90.05 P 1           1
ATOM     39  N   ASN A   6       5.514   2.664   4.856  1.00 11.99           N
ATOM     40  CA  ASN A   6       6.831   2.310   4.318  1.00 12.30           C
ATOM     41  C   ASN A   6       7.854   2.761   5.324  1.00 13.40           C
ATOM     42  O   ASN A   6       8.219   3.943   5.374  1.00 13.92           O
ATOM     43  CB  ASN A   6       7.065   3.016   2.993  1.00 12.13           C
ATOM     44  CG  ASN A   6       5.961   2.735   2.003  1.00 12.77           C
ATOM     45  OD1 ASN A   6       5.798   1.604   1.551  1.00 14.27           O
ATOM     46  ND2 ASN A   6       5.195   3.747   1.679  1.00 10.07           N
ATOM     47  N   TYR A   7       8.292   1.817   6.147  1.00 14.70           N
ATOM     48  CA  TYR A   7       9.159   2.144   7.299  1.00 15.18           C
ATOM     49  C   TYR A   7      10.603   2.331   6.885  1.00 15.91           C
ATOM     50  O   TYR A   7      11.041   1.811   5.855  1.00 15.76           O
ATOM     51  CB  TYR A   7       9.061   1.065   8.369  1.00 15.35           C
ATOM     52  CG  TYR A   7       7.665   0.929   8.902  1.00 14.45           C
ATOM     53  CD1 TYR A   7       6.771   0.021   8.327  1.00 15.68           C
ATOM     54  CD2 TYR A   7       7.210   1.756   9.920  1.00 14.80           C
ATOM     55  CE1 TYR A   7       5.480  -0.094   8.796  1.00 13.46           C
ATOM     56  CE2 TYR A   7       5.904   1.649  10.416  1.00 14.33           C
ATOM     57  CZ  TYR A   7       5.047   0.729   9.831  1.00 15.09           C
ATOM     58  OH  TYR A   7       3.766   0.589  10.291  1.00 14.39           O
ATOM     59  OXT TYR A   7      11.358   2.999   7.612  1.00 17.49           O
TER
ATOM      1  N   ASN B   6       1.414   5.113   6.019  1.00 12.99           N
ATOM      2  CA  ASN B   6       2.720   4.776   5.445  1.00 13.30           C
ATOM      3  C   ASN B   6       3.763   5.209   6.438  1.00 14.40           C
ATOM      4  O   ASN B   6       4.125   6.391   6.507  1.00 14.92           O
ATOM      5  CB  ASN B   6       2.922   5.513   4.131  1.00 13.13           C
ATOM      6  CG  ASN B   6       1.798   5.250   3.160  1.00 13.77           C
ATOM      7  OD1 ASN B   6       1.629   4.129   2.686  1.00 15.27           O
ATOM      8  ND2 ASN B   6       1.022   6.266   2.875  1.00 11.07           N
ATOM      9  N   TYR B   7       4.222   4.248   7.230  1.00 15.70           N
ATOM     10  CA  TYR B   7       5.113   4.552   8.370  1.00 16.18           C
ATOM     11  C   TYR B   7       6.547   4.754   7.929  1.00 16.91           C
ATOM     12  O   TYR B   7       6.964   4.259   6.878  1.00 16.76           O
ATOM     13  CB  TYR B   7       5.042   3.449   9.417  1.00 16.35           C
ATOM     14  CG  TYR B   7       3.659   3.296   9.977  1.00 15.45           C
ATOM     15  CD1 TYR B   7       2.756   2.398   9.402  1.00 16.68           C
ATOM     16  CD2 TYR B   7       3.224   4.098  11.023  1.00 15.80           C
ATOM     17  CE1 TYR B   7       1.476   2.267   9.896  1.00 14.46           C
ATOM     18  CE2 TYR B   7       1.929   3.975  11.545  1.00 15.33           C
ATOM     19  CZ  TYR B   7       1.063   3.065  10.959  1.00 16.09           C
ATOM     20  OH  TYR B   7      -0.207   2.910  11.443  1.00 15.39           O
ATOM     21  OXT TYR B   7       7.316   5.408   8.654  1.00 18.49           O
END
"""
  pdb_in = iotbx.pdb.hierarchy.input(pdb_string=pdb_str)
  xrs = pdb_in.input.xray_structure_simple()
  fc = abs(xrs.structure_factors(d_min=1.5).f_calc())
  fc = fc.set_observation_type_xray_amplitude()
  sigf = flex.double(fc.size(), 0.1) + (fc.data() * 0.03)
  fc = fc.customized_copy(sigmas=sigf)
  # and now add twinning
  fc_twin = fc.twin_data(twin_law='-l,-k,-h', alpha=0.4)
  flags = fc_twin.generate_r_free_flags(use_lattice_symmetry=True)
  fmodel = mmtbx.utils.fmodel_simple(
    f_obs=fc_twin,
    r_free_flags=flags,
    xray_structures=[xrs],
    scattering_table="n_gaussian")
  assert (fmodel.twin_law is not None)
  map_stats = real_space_correlation.extract_map_stats_for_single_atoms(
    xray_structure=xrs,
    pdb_atoms=pdb_in.hierarchy.atoms(),
    fmodel=fmodel)
  sel_cache = pdb_in.hierarchy.atom_selection_cache()
  sel = sel_cache.selection("chain B")
  map_stats_2 = real_space_correlation.extract_map_stats_for_single_atoms(
    xray_structure=xrs,
    pdb_atoms=pdb_in.hierarchy.atoms(),
    fmodel=fmodel,
    selection=sel)
  map_stats_3 = real_space_correlation.map_statistics_for_atom_selection(
    atom_selection=sel,
    fmodel=fmodel)