def fourier_coefficients_as_map(self, map_coeffs, n_real=None): ''' Convert Fourier coefficients into to a real-space map with gridding matching this existing map_manager. If this map_manager does not have map already, it is required that the parameter n_real (equivalent to self.map_data.all() if the map is present) is supplied. Requires that this map_manager has origin at (0,0,0) (i.e., shift_origin() has been applied if necessary) ''' assert map_coeffs assert isinstance(map_coeffs.data(), flex.complex_double) assert (self.map_data() and self.map_data().origin()==(0,0,0) ) or ( n_real is not None) if self.map_data(): assert n_real is None if self.map_data(): n_real=self.map_data().all() return maptbx.map_coefficients_to_map( map_coeffs = map_coeffs, crystal_symmetry = self.crystal_symmetry(), n_real = n_real)
def scale_map_coeffs(n_real=None, randomized_map_coeffs=None, map_coeffs=None, high_resolution_noise_fraction=None, low_resolution_noise_fraction=None, random_selection_within_bins=False, low_resolution_noise_cutoff=None, log=sys.stdout): ''' Scale map coefficients to target value vs resolution, optionally randomize Scales map coefficients in resolution bins, scale factor adjusted to yield high_resolution_noise_fraction at high-resolution limit and low_resolution_noise_fraction at low_resolution_noise_cutoff and linearly between in 1/resolution. Optionally randomizes amplitudes and phases by shuffling within bins ''' assert random_selection_within_bins or randomized_map_coeffs if not hasattr(map_coeffs, 'binner') or not map_coeffs.binner(): map_coeffs.setup_binner(auto_binning=True) d_max, d_min = map_coeffs.d_max_min() if d_max < 0: d_max = 1.e+10 if random_selection_within_bins: new_map_coeffs = map_coeffs.customized_copy( data=flex.complex_double(map_coeffs.size(), (0 + 0.j))) print("\nGenerating map randomized in Fourier space", file=log) else: new_map_coeffs = randomized_map_coeffs print("Relative error added at high-resolution: %.3f" % (high_resolution_noise_fraction), file=log) print("Relative error added at low-resolution: %.3f" % (low_resolution_noise_fraction), file=log) print("Resolution Noise ratio RMS original RMS error ", file=log) for i_bin in map_coeffs.binner().range_used(): sel = map_coeffs.binner().selection(i_bin) dd = map_coeffs.d_spacings().data().select(sel) local_d_mean = dd.min_max_mean().mean local_s_mean = 1 / local_d_mean s_max = 1 / max(1.e-10, d_min) if low_resolution_noise_cutoff: s_min = 1 / max(1.e-10, min(d_max, low_resolution_noise_cutoff)) else: s_min = 1 / max(1.e-10, d_max) fraction_high = max( 0., min(1., (local_s_mean - s_min) / max(1.e-10, s_max - s_min))) noise_ratio=low_resolution_noise_fraction+\ fraction_high * ( high_resolution_noise_fraction- low_resolution_noise_fraction) mc = map_coeffs.select(sel) rms_original = norm(mc.data()) if random_selection_within_bins: # randomize, normalize, scale fp, phi = map_coeffs_as_fp_phi(mc) sel_fp = flex.random_permutation(fp.size()) new_fp = fp.select(sel_fp) data = new_fp.data() data *= noise_ratio sel_phi = flex.random_permutation(phi.size()) new_phi = phi.select(sel_phi) new_mc = fp_phi_as_map_coeffs(new_fp, new_phi) else: # just normalize and scale randomized_mc = randomized_map_coeffs.select(sel) rms_new = norm(randomized_mc.data()) scale = rms_original / max(1.e-10, rms_new) new_fp, new_phi = map_coeffs_as_fp_phi(randomized_mc) data = new_fp.data() data *= noise_ratio * scale new_mc = fp_phi_as_map_coeffs(new_fp, new_phi) rms_new = norm(new_mc.data()) new_map_coeffs.data().set_selected(sel, new_mc.data()) print(" %.3f %.3f %.3f %.3f " % (local_d_mean, noise_ratio, rms_original, rms_new), file=log) # Convert to map from cctbx import maptbx return maptbx.map_coefficients_to_map( map_coeffs=new_map_coeffs, crystal_symmetry=new_map_coeffs.crystal_symmetry(), n_real=n_real)