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 exercise_masks(): mt = flex.mersenne_twister(seed=0) xs_ref = structure.from_shelx( file=cStringIO.StringIO(YAKRUY_ins)) mi = xs_ref.crystal_symmetry().build_miller_set( d_min=0.5, anomalous_flag=False) fo = mi.structure_factors_from_scatterers( xs_ref, algorithm="direct").f_calc().as_amplitude_array() k = 0.05 + 10 * mt.random_double() fo = fo.customized_copy(data=fo.data()*k) fo2 = fo.f_as_f_sq() acetonitrile_sel = xs_ref.label_selection( 'N4', 'C20', 'C21', 'H211', 'H212', 'H213') xs_no_sol = xs_ref.deep_copy_scatterers().select( acetonitrile_sel, negate=True) # check what happens when no voids are found mask = masks.mask(xs_ref, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1/2, atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}) assert mask.structure_factors() is None assert mask.n_voids() == 0 assert mask.n_solvent_grid_points() == 0 assert mask.f_mask() is None assert mask.f_model() is None assert mask.modified_intensities() is None assert mask.f_000 is None s = cStringIO.StringIO() mask.show_summary(log=s) assert not show_diff(s.getvalue(), """\ use_set_completion: False solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: B C H N O 1.63 1.70 1.20 1.55 1.52 Total solvent accessible volume / cell = 0.0 Ang^3 [0.0%] gridding: (30,45,54) """) # and now with some voids fo2_complete = fo2.sort() fo2_missing_1 = fo2.select_indices(flex.miller_index([(0,0,1), ]), negate=True) mt = flex.mersenne_twister(seed=0) fo2_incomplete = fo2.select(mt.random_bool(fo2.size(), 0.95)) for fo2, use_space_group_symmetry in zip( (fo2_complete, fo2_complete, fo2_missing_1, fo2_incomplete), (True, False, True, True)): if fo2 is fo2_complete: use_set_completion=False else: use_set_completion=True mask = masks.mask(xs_no_sol, fo2, use_set_completion=use_set_completion) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1/3, #atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}, use_space_group_symmetry=use_space_group_symmetry) n_voids = flex.max(mask.mask.data) - 1 f_mask = mask.structure_factors() f_model = mask.f_model() modified_fo = mask.modified_intensities().as_amplitude_array() f_obs_minus_f_model = fo.common_set(f_model).f_obs_minus_f_calc(f_obs_factor=1/k, f_calc=f_model) diff_map = miller.fft_map(mask.crystal_gridding, f_obs_minus_f_model) diff_map.apply_volume_scaling() stats = diff_map.statistics() assert n_voids == 2 assert approx_equal(n_voids, mask.n_voids()) assert mask.n_solvent_grid_points() == 42148 if fo2 is fo2_complete: # check the difference map has no large peaks/holes assert max(stats.max(), abs(stats.min())) < 0.11 # expected electron count: 44 assert approx_equal(mask.f_000_s, 44, eps=1) assert modified_fo.r1_factor(mask.f_calc.common_set(modified_fo), k) < 0.006 assert fo.common_set(fo2).r1_factor(f_model.common_set(fo2), k) < 0.006 s = cStringIO.StringIO() mask.show_summary(log=s) assert not show_diff(s.getvalue(), """\ use_set_completion: True solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: C H N O 1.77 1.20 1.50 1.45 Total solvent accessible volume / cell = 146.5 Ang^3 [16.3%] Total electron count / cell = 43.2 gridding: (45,72,80) Void #Grid points Vol/A^3 Vol/% Centre of mass (frac) Eigenvectors (frac) 1 21074 73.3 8.1 ( 0.267, 0.461, 0.672) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) 2 21074 73.3 8.1 (-0.267, 0.539, 0.328) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) Void Vol/Ang^3 #Electrons 1 73.3 21.6 2 73.3 21.6 """) cif_block = mask.as_cif_block() fo2 = fo.f_as_f_sq() # this bit is necessary until we have constraints, as # otherwise the hydrogens just disappear into the ether. xs = xs_no_sol.deep_copy_scatterers() h_selection = xs.element_selection('H') orig_flags = xs.scatterer_flags() flags = orig_flags.deep_copy() for flag, is_h in zip(flags, h_selection): if is_h: flag.set_grads(False) xs.set_scatterer_flags(flags) # first refine with no mask xs = exercise_least_squares(xs, fo2, mask=None) xs.set_scatterer_flags(orig_flags) for i in range(1): # compute improved mask/f_mask mask = masks.mask(xs, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}, resolution_factor=1/3) mask.structure_factors() xs = exercise_least_squares(xs, fo2, mask) # again exclude hydrogens from tests because of lack of constraints emma_ref = xs_no_sol.select(h_selection, negate=True).as_emma_model() match = emma.model_matches(emma_ref, xs.select( h_selection, negate=True).as_emma_model()).refined_matches[0] assert approx_equal(match.rms, 0, eps=1e-3)
def exercise_masks(): mt = flex.mersenne_twister(seed=0) xs_ref = structure.from_shelx(file=StringIO(YAKRUY_ins)) mi = xs_ref.crystal_symmetry().build_miller_set(d_min=0.5, anomalous_flag=False) fo = mi.structure_factors_from_scatterers( xs_ref, algorithm="direct").f_calc().as_amplitude_array() k = 0.05 + 10 * mt.random_double() fo = fo.customized_copy(data=fo.data() * k) fo2 = fo.f_as_f_sq() acetonitrile_sel = xs_ref.label_selection('N4', 'C20', 'C21', 'H211', 'H212', 'H213') xs_no_sol = xs_ref.deep_copy_scatterers().select(acetonitrile_sel, negate=True) # check what happens when no voids are found mask = masks.mask(xs_ref, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1 / 2, atom_radii_table={ 'C': 1.70, 'B': 1.63, 'N': 1.55, 'O': 1.52 }) assert mask.structure_factors() is None assert mask.n_voids() == 0 assert mask.n_solvent_grid_points() == 0 assert mask.f_mask() is None assert mask.f_model() is None assert mask.modified_intensities() is None assert mask.f_000 is None s = StringIO() mask.show_summary(log=s) assert not show_diff( s.getvalue(), """\ use_set_completion: False solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: B C H N O 1.63 1.70 1.20 1.55 1.52 Total solvent accessible volume / cell = 0.0 Ang^3 [0.0%] gridding: (30,45,54) """) # and now with some voids fo2_complete = fo2.sort() fo2_missing_1 = fo2.select_indices(flex.miller_index([ (0, 0, 1), ]), negate=True) mt = flex.mersenne_twister(seed=0) fo2_incomplete = fo2.select(mt.random_bool(fo2.size(), 0.95)) for fo2, use_space_group_symmetry in zip( (fo2_complete, fo2_complete, fo2_missing_1, fo2_incomplete), (True, False, True, True)): if fo2 is fo2_complete: use_set_completion = False else: use_set_completion = True mask = masks.mask(xs_no_sol, fo2, use_set_completion=use_set_completion) mask.compute( solvent_radius=1.2, shrink_truncation_radius=1.2, resolution_factor=1 / 3, #atom_radii_table={'C':1.70, 'B':1.63, 'N':1.55, 'O':1.52}, use_space_group_symmetry=use_space_group_symmetry) n_voids = flex.max(mask.mask.data) - 1 f_mask = mask.structure_factors() f_model = mask.f_model() modified_fo = mask.modified_intensities().as_amplitude_array() f_obs_minus_f_model = fo.common_set(f_model).f_obs_minus_f_calc( f_obs_factor=1 / k, f_calc=f_model) diff_map = miller.fft_map(mask.crystal_gridding, f_obs_minus_f_model) diff_map.apply_volume_scaling() stats = diff_map.statistics() assert n_voids == 2 assert approx_equal(n_voids, mask.n_voids()) assert mask.n_solvent_grid_points() == 42148 if fo2 is fo2_complete: # check the difference map has no large peaks/holes assert max(stats.max(), abs(stats.min())) < 0.11 # expected electron count: 44 assert approx_equal(mask.f_000_s, 44, eps=1) assert modified_fo.r1_factor(mask.f_calc.common_set(modified_fo), k) < 0.006 assert fo.common_set(fo2).r1_factor(f_model.common_set(fo2), k) < 0.006 s = StringIO() mask.show_summary(log=s) assert not show_diff( s.getvalue(), """\ use_set_completion: True solvent_radius: 1.20 shrink_truncation_radius: 1.20 van der Waals radii: C H N O 1.77 1.20 1.50 1.45 Total solvent accessible volume / cell = 146.5 Ang^3 [16.3%] Total electron count / cell = 43.2 gridding: (45,72,80) Void #Grid points Vol/A^3 Vol/% Centre of mass (frac) Eigenvectors (frac) 1 21074 73.3 8.1 ( 0.267, 0.461, 0.672) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) 2 21074 73.3 8.1 (-0.267, 0.539, 0.328) 1 ( 0.982, 0.126, 0.142) 2 (-0.166, 0.206, 0.964) 3 (-0.092, 0.970,-0.223) Void Vol/Ang^3 #Electrons 1 73.3 21.6 2 73.3 21.6 """) cif_block = mask.as_cif_block() fo2 = fo.f_as_f_sq() # this bit is necessary until we have constraints, as # otherwise the hydrogens just disappear into the ether. xs = xs_no_sol.deep_copy_scatterers() h_selection = xs.element_selection('H') orig_flags = xs.scatterer_flags() flags = orig_flags.deep_copy() for flag, is_h in zip(flags, h_selection): if is_h: flag.set_grads(False) xs.set_scatterer_flags(flags) # first refine with no mask xs = exercise_least_squares(xs, fo2, mask=None) xs.set_scatterer_flags(orig_flags) for i in range(1): # compute improved mask/f_mask mask = masks.mask(xs, fo2) mask.compute(solvent_radius=1.2, shrink_truncation_radius=1.2, atom_radii_table={ 'C': 1.70, 'B': 1.63, 'N': 1.55, 'O': 1.52 }, resolution_factor=1 / 3) mask.structure_factors() xs = exercise_least_squares(xs, fo2, mask) # again exclude hydrogens from tests because of lack of constraints emma_ref = xs_no_sol.select(h_selection, negate=True).as_emma_model() match = emma.model_matches( emma_ref, xs.select(h_selection, negate=True).as_emma_model()).refined_matches[0] assert approx_equal(match.rms, 0, eps=1e-3)
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