Пример #1
0
def exercise_flood_fill():
  uc = uctbx.unit_cell('10 10 10 90 90 90')
  for uc in (uctbx.unit_cell('10 10 10 90 90 90'),
             uctbx.unit_cell('9 10 11 87 91 95')):
    gridding = maptbx.crystal_gridding(
      unit_cell=uc,
      pre_determined_n_real=(5,5,5))
    corner_cube = (0,4,20,24,100,104,120,124) # cube across all 8 corners
    channel = (12,37,38,39,42,43,62,63,67,68,87,112)
    data = flex.int(flex.grid(gridding.n_real()))
    for i in (corner_cube + channel): data[i] = 1
    flood_fill = masks.flood_fill(data, uc)
    assert data.count(0) == 105
    for i in corner_cube: assert data[i] == 2
    for i in channel: assert data[i] == 3
    assert approx_equal(flood_fill.centres_of_mass(),
                        ((-0.5, -0.5, -0.5), (-2.5, 7/3, 2.5)))
    assert approx_equal(flood_fill.centres_of_mass_frac(),
                        ((-0.1, -0.1, -0.1), (-0.5, 7/15, 0.5)))
    assert approx_equal(flood_fill.centres_of_mass_cart(),
                        uc.orthogonalize(flood_fill.centres_of_mass_frac()))
    assert flood_fill.n_voids() == 2
    assert approx_equal(flood_fill.grid_points_per_void(), (8, 12))
    if 0:
      from crys3d import wx_map_viewer
      wx_map_viewer.display(raw_map=data.as_double(), unit_cell=uc, wires=False)
    #
    gridding = maptbx.crystal_gridding(
      unit_cell=uc,
      pre_determined_n_real=(10,10,10))
    data = flex.int(flex.grid(gridding.n_real()))
    # parallelogram
    points = [(2,4,5),(3,4,5),(4,4,5),(5,4,5),(6,4,5),
              (3,5,5),(4,5,5),(5,5,5),(6,5,5),(7,5,5),
              (4,6,5),(5,6,5),(6,6,5),(7,6,5),(8,6,5)]
    points_frac = flex.vec3_double()
    for p in points:
      data[p] = 1
      points_frac.append([p[i]/gridding.n_real()[i] for i in range(3)])
    points_cart = uc.orthogonalize(points_frac)
    flood_fill = masks.flood_fill(data, uc)
    assert data.count(2) == 15
    assert approx_equal(flood_fill.centres_of_mass_frac(), ((0.5,0.5,0.5),))
    pai_cart = math.principal_axes_of_inertia(
      points=points_cart, weights=flex.double(points_cart.size(),1.0))
    F = matrix.sqr(uc.fractionalization_matrix())
    O = matrix.sqr(uc.orthogonalization_matrix())
    assert approx_equal(
      pai_cart.center_of_mass(), flood_fill.centres_of_mass_cart()[0])
    assert approx_equal(
      flood_fill.covariance_matrices_cart()[0],
      (F.transpose() * matrix.sym(
        sym_mat3=flood_fill.covariance_matrices_frac()[0]) * F).as_sym_mat3())
    assert approx_equal(
      pai_cart.inertia_tensor(), flood_fill.inertia_tensors_cart()[0])
    assert approx_equal(pai_cart.eigensystem().vectors(),
                        flood_fill.eigensystems_cart()[0].vectors())
    assert approx_equal(pai_cart.eigensystem().values(),
                        flood_fill.eigensystems_cart()[0].values())
  return
Пример #2
0
def exercise_flood_fill():
    uc = uctbx.unit_cell('10 10 10 90 90 90')
    for uc in (uctbx.unit_cell('10 10 10 90 90 90'),
               uctbx.unit_cell('9 10 11 87 91 95')):
        gridding = maptbx.crystal_gridding(unit_cell=uc,
                                           pre_determined_n_real=(5, 5, 5))
        corner_cube = (0, 4, 20, 24, 100, 104, 120, 124
                       )  # cube across all 8 corners
        channel = (12, 37, 38, 39, 42, 43, 62, 63, 67, 68, 87, 112)
        data = flex.int(flex.grid(gridding.n_real()))
        for i in (corner_cube + channel):
            data[i] = 1
        flood_fill = masks.flood_fill(data, uc)
        assert data.count(0) == 105
        for i in corner_cube:
            assert data[i] == 2
        for i in channel:
            assert data[i] == 3
        assert approx_equal(flood_fill.centres_of_mass(),
                            ((-0.5, -0.5, -0.5), (-2.5, 7 / 3, 2.5)))
        assert approx_equal(flood_fill.centres_of_mass_frac(),
                            ((-0.1, -0.1, -0.1), (-0.5, 7 / 15, 0.5)))
        assert approx_equal(
            flood_fill.centres_of_mass_cart(),
            uc.orthogonalize(flood_fill.centres_of_mass_frac()))
        assert flood_fill.n_voids() == 2
        assert approx_equal(flood_fill.grid_points_per_void(), (8, 12))
        if 0:
            from crys3d import wx_map_viewer
            wx_map_viewer.display(raw_map=data.as_double(),
                                  unit_cell=uc,
                                  wires=False)
        #
        gridding = maptbx.crystal_gridding(unit_cell=uc,
                                           pre_determined_n_real=(10, 10, 10))
        data = flex.int(flex.grid(gridding.n_real()))
        # parallelogram
        points = [(2, 4, 5), (3, 4, 5), (4, 4, 5), (5, 4, 5), (6, 4, 5),
                  (3, 5, 5), (4, 5, 5), (5, 5, 5), (6, 5, 5), (7, 5, 5),
                  (4, 6, 5), (5, 6, 5), (6, 6, 5), (7, 6, 5), (8, 6, 5)]
        points_frac = flex.vec3_double()
        for p in points:
            data[p] = 1
            points_frac.append([p[i] / gridding.n_real()[i] for i in range(3)])
        points_cart = uc.orthogonalize(points_frac)
        flood_fill = masks.flood_fill(data, uc)
        assert data.count(2) == 15
        assert approx_equal(flood_fill.centres_of_mass_frac(),
                            ((0.5, 0.5, 0.5), ))
        pai_cart = math.principal_axes_of_inertia(points=points_cart,
                                                  weights=flex.double(
                                                      points_cart.size(), 1.0))
        F = matrix.sqr(uc.fractionalization_matrix())
        O = matrix.sqr(uc.orthogonalization_matrix())
        assert approx_equal(pai_cart.center_of_mass(),
                            flood_fill.centres_of_mass_cart()[0])
        assert approx_equal(
            flood_fill.covariance_matrices_cart()[0],
            (F.transpose() *
             matrix.sym(sym_mat3=flood_fill.covariance_matrices_frac()[0]) *
             F).as_sym_mat3())
        assert approx_equal(pai_cart.inertia_tensor(),
                            flood_fill.inertia_tensors_cart()[0])
        assert approx_equal(pai_cart.eigensystem().vectors(),
                            flood_fill.eigensystems_cart()[0].vectors())
        assert approx_equal(pai_cart.eigensystem().values(),
                            flood_fill.eigensystems_cart()[0].values())
    return
Пример #3
0
def exercise_masks(xs,
                   fo_sq,
                   solvent_radius,
                   shrink_truncation_radius,
                   resolution_factor=None,
                   grid_step=None,
                   resolution_cutoff=None,
                   atom_radii_table=None,
                   use_space_group_symmetry=False,
                   debug=False,
                   verbose=False):
    assert resolution_factor is None or grid_step is None
    xs_ref = xs.deep_copy_scatterers()
    time_total = time_log("masks total").start()
    fo_sq = fo_sq.customized_copy(anomalous_flag=True)
    fo_sq = fo_sq.eliminate_sys_absent()
    merging = fo_sq.merge_equivalents()
    fo_sq_merged = merging.array()
    if resolution_cutoff is not None:
        fo_sq_merged = fo_sq_merged.resolution_filter(d_min=resolution_cutoff)
    if verbose:
        print "Merging summary:"
        print "R-int, R-sigma: %.4f, %.4f" % (merging.r_int(),
                                              merging.r_sigma())
        merging.show_summary()
        print
        fo_sq_merged.show_comprehensive_summary()
        print
    mask = masks.mask(xs, fo_sq_merged)
    time_compute_mask = time_log("compute mask").start()
    mask.compute(solvent_radius=solvent_radius,
                 shrink_truncation_radius=shrink_truncation_radius,
                 resolution_factor=resolution_factor,
                 grid_step=grid_step,
                 atom_radii_table=atom_radii_table,
                 use_space_group_symmetry=use_space_group_symmetry)
    time_compute_mask.stop()
    time_structure_factors = time_log("structure factors").start()
    f_mask = mask.structure_factors()
    time_structure_factors.stop()
    mask.show_summary()
    f_model = mask.f_model()
    # write modified intensities as shelxl hkl
    out = StringIO()
    modified_fo_sq = mask.modified_intensities()
    modified_fo_sq.export_as_shelx_hklf(out)
    out_file = open('modified.hkl', 'w')
    out_file.write(out.getvalue())
    out_file.close()

    if verbose:
        print
        print time_log.legend
        print time_compute_mask.report()
        print time_structure_factors.report()
        print time_total.log()

    if debug:
        f_obs = fo_sq_merged.as_amplitude_array()
        sf = xray.structure_factors.from_scatterers(miller_set=f_obs,
                                                    cos_sin_table=True)
        f_calc = sf(xs, f_obs).f_calc()
        f_model = mask.f_model()
        scale_factor = f_obs.scale_factor(f_model)
        # f_obs - f_calc
        k = f_obs.scale_factor(f_calc)
        f_obs_minus_f_calc = f_obs.f_obs_minus_f_calc(1 / k, f_calc)
        diff_map_calc = miller.fft_map(mask.crystal_gridding,
                                       f_obs_minus_f_calc)
        diff_map_calc.apply_volume_scaling()
        # f_mask
        mask_map = miller.fft_map(mask.crystal_gridding, f_mask)
        mask_map.apply_volume_scaling()
        # f_model
        model_map = miller.fft_map(mask.crystal_gridding, f_model)
        model_map.apply_volume_scaling()
        # f_obs - f_model
        f_obs_minus_f_model = f_obs.f_obs_minus_f_calc(1 / scale_factor,
                                                       f_model)
        diff_map_model = miller.fft_map(mask.crystal_gridding,
                                        f_obs_minus_f_model)
        diff_map_model.apply_volume_scaling()
        # modified f_obs
        modified_fo_sq_map = miller.fft_map(
            mask.crystal_gridding,
            modified_fo_sq.as_amplitude_array().phase_transfer(f_calc))
        modified_fo_sq_map.apply_volume_scaling()
        # view the maps
        from crys3d import wx_map_viewer
        wx_map_viewer.display(title="Mask",
                              raw_map=mask.mask.data.as_double(),
                              unit_cell=f_obs.unit_cell())
        wx_map_viewer.display(title="f_obs - f_calc",
                              raw_map=diff_map_calc.real_map(),
                              unit_cell=f_obs.unit_cell())
        wx_map_viewer.display(title="f_mask",
                              raw_map=mask_map.real_map(),
                              unit_cell=f_obs.unit_cell())
        wx_map_viewer.display(title="f_model",
                              raw_map=model_map.real_map(),
                              unit_cell=f_obs.unit_cell())
        wx_map_viewer.display(title="f_obs - f_model",
                              raw_map=diff_map_model.real_map(),
                              unit_cell=f_obs.unit_cell())
        wx_map_viewer.display(title="modified_fo_sq",
                              raw_map=modified_fo_sq_map.real_map(),
                              unit_cell=f_obs.unit_cell())
    return mask
Пример #4
0
 def structure_factors(self, max_cycles=10):
   """P. van der Sluis and A. L. Spek, Acta Cryst. (1990). A46, 194-201."""
   assert self.mask is not None
   if self.n_voids() == 0: return
   if self.use_set_completion:
     f_calc_set = self.complete_set
   else:
     f_calc_set = self.fo2.set()
   self.f_calc = f_calc_set.structure_factors_from_scatterers(
     self.xray_structure, algorithm="direct").f_calc()
   f_obs = self.f_obs()
   self.scale_factor = flex.sum(f_obs.data())/flex.sum(
     flex.abs(self.f_calc.data()))
   f_obs_minus_f_calc = f_obs.f_obs_minus_f_calc(
     1/self.scale_factor, self.f_calc)
   self.fft_scale = self.xray_structure.unit_cell().volume()\
       / self.crystal_gridding.n_grid_points()
   epsilon_for_min_residual = 2
   for i in range(max_cycles):
     self.diff_map = miller.fft_map(self.crystal_gridding, f_obs_minus_f_calc)
     self.diff_map.apply_volume_scaling()
     stats = self.diff_map.statistics()
     masked_diff_map = self.diff_map.real_map_unpadded().set_selected(
       self.mask.data.as_double() == 0, 0)
     n_solvent_grid_points = self.n_solvent_grid_points()
     for j in range(self.n_voids()):
       # exclude voids with negative electron counts from the masked map
       # set the electron density in those areas to be zero
       selection = self.mask.data == j+2
       if self.exclude_void_flags[j]:
         masked_diff_map.set_selected(selection, 0)
         continue
       diff_map_ = masked_diff_map.deep_copy().set_selected(~selection, 0)
       f_000 = flex.sum(diff_map_) * self.fft_scale
       f_000_s = f_000 * (
         self.crystal_gridding.n_grid_points() /
         (self.crystal_gridding.n_grid_points() - n_solvent_grid_points))
       if f_000_s < 0:
         masked_diff_map.set_selected(selection, 0)
         f_000_s = 0
         self.exclude_void_flags[j] = True
     self.f_000 = flex.sum(masked_diff_map) * self.fft_scale
     f_000_s = self.f_000 * (masked_diff_map.size() /
       (masked_diff_map.size() - self.n_solvent_grid_points()))
     if (self.f_000_s is not None and
         approx_equal_relatively(self.f_000_s, f_000_s, 0.0001)):
       break # we have reached convergence
     else:
       self.f_000_s = f_000_s
     masked_diff_map.add_selected(
       self.mask.data.as_double() > 0,
       self.f_000_s/self.xray_structure.unit_cell().volume())
     if 0:
       from crys3d import wx_map_viewer
       wx_map_viewer.display(
         title="masked diff_map",
         raw_map=masked_diff_map.as_double(),
         unit_cell=f_obs.unit_cell())
     self._f_mask = f_obs.structure_factors_from_map(map=masked_diff_map)
     self._f_mask *= self.fft_scale
     scales = []
     residuals = []
     min_residual = 1000
     for epsilon in xfrange(epsilon_for_min_residual, 0.9, -0.2):
       f_model_ = self.f_model(epsilon=epsilon)
       scale = flex.sum(f_obs.data())/flex.sum(flex.abs(f_model_.data()))
       residual = flex.sum(flex.abs(
         1/scale * flex.abs(f_obs.data())- flex.abs(f_model_.data()))) \
                / flex.sum(1/scale * flex.abs(f_obs.data()))
       scales.append(scale)
       residuals.append(residual)
       min_residual = min(min_residual, residual)
       if min_residual == residual:
         scale_for_min_residual = scale
         epsilon_for_min_residual = epsilon
     self.scale_factor = scale_for_min_residual
     f_model = self.f_model(epsilon=epsilon_for_min_residual)
     f_obs = self.f_obs()
     f_obs_minus_f_calc = f_obs.phase_transfer(f_model).f_obs_minus_f_calc(
       1/self.scale_factor, self.f_calc)
   return self._f_mask
Пример #5
0
    def structure_factors(self, max_cycles=10):
        """P. van der Sluis and A. L. Spek, Acta Cryst. (1990). A46, 194-201."""
        assert self.mask is not None
        if self.n_voids() == 0:
            return
        if self.use_set_completion:
            f_calc_set = self.complete_set
        else:
            f_calc_set = self.fo2.set()
        self.f_calc = f_calc_set.structure_factors_from_scatterers(self.xray_structure, algorithm="direct").f_calc()
        f_obs = self.f_obs()
        self.scale_factor = flex.sum(f_obs.data()) / flex.sum(flex.abs(self.f_calc.data()))
        f_obs_minus_f_calc = f_obs.f_obs_minus_f_calc(1 / self.scale_factor, self.f_calc)
        self.fft_scale = self.xray_structure.unit_cell().volume() / self.crystal_gridding.n_grid_points()
        epsilon_for_min_residual = 2
        for i in range(max_cycles):
            self.diff_map = miller.fft_map(self.crystal_gridding, f_obs_minus_f_calc)
            self.diff_map.apply_volume_scaling()
            stats = self.diff_map.statistics()
            masked_diff_map = self.diff_map.real_map_unpadded().set_selected(self.mask.data.as_double() == 0, 0)
            n_solvent_grid_points = self.n_solvent_grid_points()
            for j in range(self.n_voids()):
                # exclude voids with negative electron counts from the masked map
                # set the electron density in those areas to be zero
                selection = self.mask.data == j + 2
                if self.exclude_void_flags[j]:
                    masked_diff_map.set_selected(selection, 0)
                    continue
                diff_map_ = masked_diff_map.deep_copy().set_selected(~selection, 0)
                f_000 = flex.sum(diff_map_) * self.fft_scale
                f_000_s = f_000 * (
                    self.crystal_gridding.n_grid_points()
                    / (self.crystal_gridding.n_grid_points() - n_solvent_grid_points)
                )
                if f_000_s < 0:
                    masked_diff_map.set_selected(selection, 0)
                    f_000_s = 0
                    self.exclude_void_flags[j] = True
            self.f_000 = flex.sum(masked_diff_map) * self.fft_scale
            f_000_s = self.f_000 * (masked_diff_map.size() / (masked_diff_map.size() - self.n_solvent_grid_points()))
            if self.f_000_s is not None and approx_equal_relatively(self.f_000_s, f_000_s, 0.0001):
                break  # we have reached convergence
            else:
                self.f_000_s = f_000_s
            masked_diff_map.add_selected(
                self.mask.data.as_double() > 0, self.f_000_s / self.xray_structure.unit_cell().volume()
            )
            if 0:
                from crys3d import wx_map_viewer

                wx_map_viewer.display(
                    title="masked diff_map", raw_map=masked_diff_map.as_double(), unit_cell=f_obs.unit_cell()
                )
            self._f_mask = f_obs.structure_factors_from_map(map=masked_diff_map)
            self._f_mask *= self.fft_scale
            scales = []
            residuals = []
            min_residual = 1000
            for epsilon in xfrange(epsilon_for_min_residual, 0.9, -0.2):
                f_model_ = self.f_model(epsilon=epsilon)
                scale = flex.sum(f_obs.data()) / flex.sum(flex.abs(f_model_.data()))
                residual = flex.sum(
                    flex.abs(1 / scale * flex.abs(f_obs.data()) - flex.abs(f_model_.data()))
                ) / flex.sum(1 / scale * flex.abs(f_obs.data()))
                scales.append(scale)
                residuals.append(residual)
                min_residual = min(min_residual, residual)
                if min_residual == residual:
                    scale_for_min_residual = scale
                    epsilon_for_min_residual = epsilon
            self.scale_factor = scale_for_min_residual
            f_model = self.f_model(epsilon=epsilon_for_min_residual)
            f_obs = self.f_obs()
            f_obs_minus_f_calc = f_obs.phase_transfer(f_model).f_obs_minus_f_calc(1 / self.scale_factor, self.f_calc)
        return self._f_mask
Пример #6
0
def exercise_masks(xs, fo_sq,
                   solvent_radius,
                   shrink_truncation_radius,
                   resolution_factor=None,
                   grid_step=None,
                   resolution_cutoff=None,
                   atom_radii_table=None,
                   use_space_group_symmetry=False,
                   debug=False,
                   verbose=False):
  assert resolution_factor is None or grid_step is None
  xs_ref = xs.deep_copy_scatterers()
  time_total = time_log("masks total").start()
  fo_sq = fo_sq.customized_copy(anomalous_flag=True)
  fo_sq = fo_sq.eliminate_sys_absent()
  merging = fo_sq.merge_equivalents()
  fo_sq_merged = merging.array()
  if resolution_cutoff is not None:
    fo_sq_merged = fo_sq_merged.resolution_filter(d_min=resolution_cutoff)
  if verbose:
    print "Merging summary:"
    print "R-int, R-sigma: %.4f, %.4f" %(merging.r_int(), merging.r_sigma())
    merging.show_summary()
    print
    fo_sq_merged.show_comprehensive_summary()
    print
  mask = masks.mask(xs, fo_sq_merged)
  time_compute_mask = time_log("compute mask").start()
  mask.compute(solvent_radius=solvent_radius,
               shrink_truncation_radius=shrink_truncation_radius,
               resolution_factor=resolution_factor,
               grid_step=grid_step,
               atom_radii_table=atom_radii_table,
               use_space_group_symmetry=use_space_group_symmetry)
  time_compute_mask.stop()
  time_structure_factors = time_log("structure factors").start()
  f_mask = mask.structure_factors()
  time_structure_factors.stop()
  mask.show_summary()
  f_model = mask.f_model()
  # write modified intensities as shelxl hkl
  out = StringIO()
  modified_fo_sq = mask.modified_intensities()
  modified_fo_sq.export_as_shelx_hklf(out)
  out_file = open('modified.hkl', 'w')
  out_file.write(out.getvalue())
  out_file.close()

  if verbose:
    print
    print time_log.legend
    print time_compute_mask.report()
    print time_structure_factors.report()
    print time_total.log()

  if debug:
    f_obs = fo_sq_merged.as_amplitude_array()
    sf = xray.structure_factors.from_scatterers(
      miller_set=f_obs,
      cos_sin_table=True)
    f_calc = sf(xs, f_obs).f_calc()
    f_model = mask.f_model()
    scale_factor = f_obs.scale_factor(f_model)
    # f_obs - f_calc
    k = f_obs.scale_factor(f_calc)
    f_obs_minus_f_calc = f_obs.f_obs_minus_f_calc(1/k, f_calc)
    diff_map_calc = miller.fft_map(mask.crystal_gridding, f_obs_minus_f_calc)
    diff_map_calc.apply_volume_scaling()
    # f_mask
    mask_map = miller.fft_map(mask.crystal_gridding, f_mask)
    mask_map.apply_volume_scaling()
    # f_model
    model_map = miller.fft_map(mask.crystal_gridding, f_model)
    model_map.apply_volume_scaling()
    # f_obs - f_model
    f_obs_minus_f_model = f_obs.f_obs_minus_f_calc(1/scale_factor, f_model)
    diff_map_model = miller.fft_map(mask.crystal_gridding, f_obs_minus_f_model)
    diff_map_model.apply_volume_scaling()
    # modified f_obs
    modified_fo_sq_map = miller.fft_map(
      mask.crystal_gridding, modified_fo_sq.as_amplitude_array().phase_transfer(f_calc))
    modified_fo_sq_map.apply_volume_scaling()
    # view the maps
    from crys3d import wx_map_viewer
    wx_map_viewer.display(
      title="Mask",
      raw_map=mask.mask.data.as_double(),
      unit_cell=f_obs.unit_cell())
    wx_map_viewer.display(
      title="f_obs - f_calc",
      raw_map=diff_map_calc.real_map(),
      unit_cell=f_obs.unit_cell())
    wx_map_viewer.display(
      title="f_mask",
      raw_map=mask_map.real_map(),
      unit_cell=f_obs.unit_cell())
    wx_map_viewer.display(
      title="f_model",
      raw_map=model_map.real_map(),
      unit_cell=f_obs.unit_cell())
    wx_map_viewer.display(
      title="f_obs - f_model",
      raw_map=diff_map_model.real_map(),
      unit_cell=f_obs.unit_cell())
    wx_map_viewer.display(
      title="modified_fo_sq",
      raw_map=modified_fo_sq_map.real_map(),
      unit_cell=f_obs.unit_cell())
  return mask