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
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
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
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
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
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