def generate_mock_rms_fc_list(self, n_bins=None, d_min=None, map_model_manager=None, model=None, out=null_out()): mmm = map_model_manager if not model: from cctbx.development.create_models_or_maps import generate_model model = generate_model(n_residues=100, b_iso=0, log=null_out()) # shift the model and return it with new crystal_symmetry from cctbx.maptbx.box import shift_and_box_model model = shift_and_box_model(model=model, crystal_symmetry=mmm.crystal_symmetry()) model.set_shift_cart((0, 0, 0)) model = mmm.remove_model_outside_map(model=model, boundary=0, return_as_new_model=True) map_id_model_map = 'map_for_mock_data' out_sav = mmm.log mmm.set_log(null_out()) mmm.generate_map(model=model, gridding=mmm.get_any_map_manager().map_data().all(), d_min=d_min, map_id=map_id_model_map) map_coeffs = mmm.get_map_manager_by_id( map_id_model_map).map_as_fourier_coefficients(d_min=d_min) mmm.remove_map_manager_by_id(map_id=map_id_model_map) mmm.set_log(out_sav) f_array = get_map_coeffs_as_fp_phi(map_coeffs, n_bins=n_bins, d_min=d_min).f_array rms_fc_list = flex.double() for i_bin in f_array.binner().range_used(): sel = f_array.binner().selection(i_bin) fc = map_coeffs.select(sel) f_array_fc = map_coeffs_to_fp(fc) rms_fc = f_array_fc.data().norm() rms_fc_list.append(rms_fc) self.rms_fc_list = rms_fc_list
def generate_mock_rms_fc_list(self, n_bins=None, d_min=None, map_model_manager=None, model=None, k_sol=None, b_sol=None, n_bins_use=None, out=null_out()): mmm = map_model_manager if not model: from cctbx.development.create_models_or_maps import generate_model model = generate_model(n_residues=100, b_iso=0, log=null_out()) # shift the model and return it with new crystal_symmetry from cctbx.maptbx.box import shift_and_box_model model = shift_and_box_model(model=model, crystal_symmetry=mmm.crystal_symmetry()) model.set_shift_cart((0, 0, 0)) model = mmm.remove_model_outside_map(model=model, boundary=0, return_as_new_model=True) map_id_model_map = 'map_for_mock_data' out_sav = mmm.log mmm.set_log(null_out()) mmm.generate_map(model=model, gridding=mmm.get_any_map_manager().map_data().all(), d_min=d_min, k_sol=k_sol, b_sol=b_sol, map_id=map_id_model_map) self.rms_fc_list = mmm.get_rms_f_list(map_id=map_id_model_map, d_min=d_min, n_bins=n_bins).rms_f_list self.n_bins_use = n_bins_use # just save it mmm.remove_map_manager_by_id(map_id=map_id_model_map) mmm.set_log(out_sav)
def exercise(): """Test prepare_map_for_docking using data with known errors.""" # Generate two half-maps with same anisotropic signal, independent anisotropic # noise. Test to see how well optimal map coefficients are estimated. # Start by working out how large the padding will have to be so that # starting automatically-generated map will be large enough to contain # sphere with room to spare around model. n_residues = 25 d_min = 2.5 from cctbx.development.create_models_or_maps import generate_model test_model = generate_model(n_residues=n_residues) sites_cart = test_model.get_sites_cart() cart_min = flex.double(sites_cart.min()) cart_max = flex.double(sites_cart.max()) box_centre = (cart_min + cart_max) / 2 dsqrmax = flex.max((sites_cart - tuple(box_centre)).norms())**2 model_radius = math.sqrt(dsqrmax) min_model_extent = flex.min(cart_max - cart_min) pad_to_allow_cube = model_radius - min_model_extent / 2 # Extra space needed for eventual masking boundary_to_smoothing_ratio = 2 soft_mask_radius = d_min padding = soft_mask_radius * boundary_to_smoothing_ratio box_cushion = padding + pad_to_allow_cube + d_min # A bit extra # Make map in box big enough to cut out cube containing sphere mmm = map_model_manager() mmm.generate_map(n_residues=n_residues, d_min=d_min, k_sol=0.1, b_sol=50., box_cushion=box_cushion) # Keep copy of perfect map for tests of success mm_start = mmm.map_manager().deep_copy() mmm.add_map_manager_by_id(mm_start, 'perfect_map') model = mmm.model() sites_cart = model.get_sites_cart() cart_min = flex.double(sites_cart.min()) cart_max = flex.double(sites_cart.max()) # Turn starting map into map coeffs for the signal ucpars = mmm.map_manager().unit_cell().parameters() d_max = max(ucpars[0], ucpars[1], ucpars[2]) start_map_coeffs = mmm.map_as_fourier_coefficients(d_min=d_min, d_max=d_max) # Apply anisotropic scaling to map coeffs b_target = (100., 200., 300., -50., 50., 100.) u_star_s = adptbx.u_cart_as_u_star(start_map_coeffs.unit_cell(), adptbx.b_as_u(b_target)) # b_model = (30.,30.,30.,0.,0.,0.) # All atoms in model have B=30 # b_expected = list((flex.double(b_target) + flex.double(b_model))) scaled_map_coeffs = start_map_coeffs.apply_debye_waller_factors( u_star=u_star_s) # Generate map coefficient errors for first half-map from complex normal # distribution b_target_e = (0., 0., 0., -50., -50., 100.) # Anisotropy for error terms u_star_e = adptbx.u_cart_as_u_star(start_map_coeffs.unit_cell(), adptbx.b_as_u(b_target_e)) se_target = 10. # Target for SigmaE variance term rsigma = math.sqrt(se_target / 2.) jj = 0. + 1.j # Define I for generating complex numbers random_complexes1 = flex.complex_double() ncoeffs = start_map_coeffs.size() random.seed(123457) # Make runs reproducible for i in range(ncoeffs): random_complexes1.append( random.gauss(0., rsigma) + random.gauss(0., rsigma) * jj) rc1_miller = start_map_coeffs.customized_copy(data=random_complexes1) mc1_delta = rc1_miller.apply_debye_waller_factors(u_star=u_star_e) map1_coeffs = scaled_map_coeffs.customized_copy( data=scaled_map_coeffs.data() + mc1_delta.data()) # Repeat for second half map with independent errors from same distribution random_complexes2 = flex.complex_double() for i in range(ncoeffs): random_complexes2.append( random.gauss(0., rsigma) + random.gauss(0., rsigma) * jj) rc2_miller = start_map_coeffs.customized_copy(data=random_complexes2) mc2_delta = rc2_miller.apply_debye_waller_factors(u_star=u_star_e) map2_coeffs = scaled_map_coeffs.customized_copy( data=scaled_map_coeffs.data() + mc2_delta.data()) # mmm.write_model("fake_map.pdb") mmm.add_map_from_fourier_coefficients(map1_coeffs, map_id='map_manager_1') mmm.add_map_from_fourier_coefficients(map2_coeffs, map_id='map_manager_2') # Replace original map_manager with mean of half-maps mm_mean_data = (mmm.map_manager_1().map_data() + mmm.map_manager_2().map_data()) / 2 mmm.map_manager().set_map_data(map_data=mm_mean_data) # Add mask map for ordered component of map protein_mw = n_residues * 110. # MW from model would be better... nucleic_mw = None mask_id = 'ordered_volume_mask' add_ordered_volume_mask(mmm, d_min, protein_mw=protein_mw, nucleic_mw=nucleic_mw, map_id_out=mask_id) box_centre = tuple(flex.double((ucpars[0], ucpars[1], ucpars[2])) / 2) # Now refine to assess parameters describing map errors results = assess_cryoem_errors(mmm, d_min, sphere_cent=tuple(box_centre), radius=model_radius + d_min, verbosity=0) # resultsdict = results.resultsdict # b_refined_a = resultsdict["a_baniso"] # print("\nIdeal A tensor as Baniso: ", b_expected) # print("Refined A tensor as Baniso", b_refined_a) # Note that all maps have been cut out with a spherical mask, so compare using these new_mmm = results.new_mmm perfect_mapCC = new_mmm.map_model_cc(map_id='perfect_map') mapCC = new_mmm.map_model_cc(map_id='map_manager_wtd') # Achieved map start_mapCC = new_mmm.map_model_cc( ) # Starting map with noise and anisotropy mc_perfect = new_mmm.map_as_fourier_coefficients(d_min=d_min, d_max=d_max, map_id='perfect_map') mc_achieved = new_mmm.map_as_fourier_coefficients(d_min=d_min, d_max=d_max, map_id='map_manager_wtd') # Compare with results using theoretically perfect error parameters to compute # ideal map coefficients. sigmaS_terms = flex.pow2(get_power_spectrum( mc_perfect)) # Actual signal power before anisotropy mc_start = new_mmm.map_as_fourier_coefficients(d_min=d_min, d_max=d_max) eE_ideal = mc_start.deep_copy() ones_array = flex.double(eE_ideal.size(), 1) all_ones = eE_ideal.customized_copy(data=ones_array) u_star_s2 = tuple(flex.double(u_star_s) * 2.) # Square anisotropy for signal power calc sigmaS_terms = sigmaS_terms * all_ones.apply_debye_waller_factors( u_star=u_star_s2).data() # Corrected for anisotropy u_star_e2 = tuple(flex.double(u_star_e) * 2.) sigmaE_terms = all_ones.apply_debye_waller_factors( u_star=u_star_e2).data() * se_target scale_terms = 1. / flex.sqrt(sigmaS_terms + sigmaE_terms / 2.) dobs_terms = 1. / flex.sqrt(1. + sigmaE_terms / (2 * sigmaS_terms)) mc_ideal = eE_ideal.customized_copy(data=eE_ideal.data() * scale_terms * dobs_terms) # write_mtz(mc_achieved,"achieved_map.mtz","achieved") # write_mtz(mc_ideal,"ideal_map.mtz","ideal") mapCC_ideal_achieved = mc_ideal.map_correlation(other=mc_achieved) # print("CC between ideal and achieved maps:",mapCC_ideal_achieved) assert (mapCC_ideal_achieved > 0.92) new_mmm.add_map_from_fourier_coefficients(mc_ideal, map_id='ideal_map') ideal_mapCC = new_mmm.map_model_cc(map_id='ideal_map') # print("Perfect, starting, ideal and achieved mapCC: ", perfect_mapCC, start_mapCC, ideal_mapCC, mapCC) assert (mapCC > 0.98 * ideal_mapCC)
def exercise(): """Test prepare_map_for_docking using data with known errors.""" # Generate two half-maps with same anisotropic signal, # independent anisotropic noise. Test to see if # simulation parameters are recovered. # Start by working out how large the padding will have to be so that # starting automatically-generated map will be large enough to contain # sphere with room to spare around model. n_residues = 25 d_min = 2.5 from cctbx.development.create_models_or_maps import generate_model test_model = generate_model(n_residues=n_residues) sites_cart = test_model.get_sites_cart() cart_min = flex.double(sites_cart.min()) cart_max = flex.double(sites_cart.max()) box_centre = (cart_min+cart_max)/2 dsqrmax = flex.max( (sites_cart - tuple(box_centre)).norms() )**2 model_radius = math.sqrt(dsqrmax) min_model_extent = flex.min(cart_max - cart_min) pad_to_allow_cube = model_radius - min_model_extent/2 # Extra space needed for eventual masking boundary_to_smoothing_ratio = 2 soft_mask_radius = d_min padding = soft_mask_radius * boundary_to_smoothing_ratio box_cushion = padding + pad_to_allow_cube # Make map in box big enough to cut out cube containing sphere mmm = map_model_manager() mmm.generate_map( n_residues=n_residues, d_min=d_min, k_sol=0.1, b_sol=50., box_cushion=box_cushion) model = mmm.model() sites_cart = model.get_sites_cart() cart_min = flex.double(sites_cart.min()) cart_max = flex.double(sites_cart.max()) # Turn starting map into map coeffs for the signal ucpars = mmm.map_manager().unit_cell().parameters() d_max=max(ucpars[0], ucpars[1], ucpars[2]) start_map_coeffs = mmm.map_as_fourier_coefficients( d_min=d_min, d_max=d_max) # Apply anisotropic scaling to map coeffs b_target = (100.,200.,300.,-50.,50.,100.) b_model = (30.,30.,30.,0.,0.,0.) # All atoms in model have B=30 u_star = adptbx.u_cart_as_u_star( start_map_coeffs.unit_cell(), adptbx.b_as_u(b_target)) b_expected = list((flex.double(b_target) + flex.double(b_model))) scaled_map_coeffs = start_map_coeffs.apply_debye_waller_factors(u_star=u_star) # Generate map coefficient errors for first half-map from complex normal # distribution b_target_e = (0.,0.,0.,-50.,-50.,100.) # Anisotropy for error terms u_star_e = adptbx.u_cart_as_u_star( start_map_coeffs.unit_cell(), adptbx.b_as_u(b_target_e)) se_target = 1. # Target for SigmaE variance term rsigma = math.sqrt(se_target / 2.) jj = 0.+1.j # Define I for generating complex numbers random_complexes1 = flex.complex_double() ncoeffs=start_map_coeffs.size() random.seed(123457) # Make runs reproducible for i in range(ncoeffs): random_complexes1.append(random.gauss(0.,rsigma) + random.gauss(0.,rsigma)*jj) rc1_miller = start_map_coeffs.customized_copy(data=random_complexes1) mc1_delta = rc1_miller.apply_debye_waller_factors(u_star=u_star_e) map1_coeffs = scaled_map_coeffs.customized_copy( data=scaled_map_coeffs.data() + mc1_delta.data()) # Repeat for second half map with independent errors from same distribution random_complexes2 = flex.complex_double() for i in range(ncoeffs): random_complexes2.append(random.gauss(0.,rsigma) + random.gauss(0.,rsigma)*jj) rc2_miller = start_map_coeffs.customized_copy(data=random_complexes2) mc2_delta = rc2_miller.apply_debye_waller_factors(u_star=u_star_e) map2_coeffs = scaled_map_coeffs.customized_copy( data=scaled_map_coeffs.data() + mc2_delta.data()) mmm.add_map_from_fourier_coefficients( map1_coeffs, map_id = 'map_manager_1') mmm.add_map_from_fourier_coefficients( map2_coeffs, map_id = 'map_manager_2') radius = model_radius + 5. # Sphere as large as possible to allow masking results = run_refine_cryoem_errors( mmm, d_min, sphere_cent=tuple(box_centre), radius=radius, verbosity=0) resultsdict = results.resultsdict b_refined_a = resultsdict["a_baniso"] # print("\nIdeal A tensor as Baniso: ", b_expected) # print("Refined A tensor as Baniso", b_refined_a) b_refined_e = resultsdict["sigmaE_baniso"] # Note: refers to intensity scale # print("\nIdeal SigmaE tensor as Baniso: ",list(flex.double(b_target_e*2))) # print("Refined SigmaE tensor as Baniso", b_refined_e) for i in range(6): assert(approx_equal(b_refined_a[i],b_expected[i], eps=25)) assert(approx_equal(b_refined_e[i],2*b_target_e[i], eps=25))