def filter_ice(reflections, steps): from cctbx import miller, sgtbx, uctbx from matplotlib import pyplot as plt d_spacings = 1 / reflections["rlp"].norms() d_star_sq = uctbx.d_as_d_star_sq(d_spacings) from dials.algorithms.spot_finding.per_image_analysis import ice_rings_selection from dials.algorithms.integration import filtering ice_uc = uctbx.unit_cell((4.498, 4.498, 7.338, 90, 90, 120)) ice_sg = sgtbx.space_group_info(number=194).group() ice_generator = miller.index_generator(ice_uc, ice_sg.type(), False, flex.min(d_spacings)) ice_indices = ice_generator.to_array() ice_d_spacings = flex.sorted(ice_uc.d(ice_indices)) ice_d_star_sq = uctbx.d_as_d_star_sq(ice_d_spacings) cubic_ice_uc = uctbx.unit_cell((6.358, 6.358, 6.358, 90, 90, 90)) cubic_ice_sg = sgtbx.space_group_info(number=227).group() cubic_ice_generator = miller.index_generator(cubic_ice_uc, cubic_ice_sg.type(), False, flex.min(d_spacings)) cubic_ice_indices = cubic_ice_generator.to_array() cubic_ice_d_spacings = flex.sorted(cubic_ice_uc.d(cubic_ice_indices)) cubic_ice_d_star_sq = uctbx.d_as_d_star_sq(cubic_ice_d_spacings) import numpy widths = flex.double(numpy.geomspace(start=0.0001, stop=0.01, num=steps)) n_spots = flex.double() total_intensity = flex.double() for width in widths: d_min = flex.min(d_spacings) ice_filter = filtering.PowderRingFilter(ice_uc, ice_sg, d_min, width) ice_sel = ice_filter(d_spacings) n_spots.append(ice_sel.count(False)) if "intensity.sum.value" in reflections: total_intensity.append( flex.sum(reflections["intensity.sum.value"].select(~ice_sel))) fig, axes = plt.subplots(nrows=2, figsize=(12, 8), sharex=True) axes[0].plot(widths, n_spots, label="#spots", marker="+") if total_intensity.size(): axes[1].plot(widths, total_intensity, label="total intensity", marker="+") axes[0].set_ylabel("# spots remaining") axes[1].set_xlabel("Ice ring width (1/d^2)") axes[1].set_ylabel("Total intensity") for ax in axes: ax.set_xlim(0, flex.max(widths)) plt.savefig("ice_ring_filtering.png") plt.clf() return
def test_powder_ring_filter(): unit_cell = uctbx.unit_cell((4.498, 4.498, 7.338, 90, 90, 120)) space_group = sgtbx.space_group_info(number=194).group() d_spacings = flex.double([1.9220704466392748]) d_min = flex.min(d_spacings) ice_filter = filtering.PowderRingFilter(unit_cell, space_group, d_min, width=0.004) assert min(uctbx.d_star_sq_as_d(ice_filter.d_star_sq)) < d_min assert all(ice_filter(d_spacings))
def ice_rings_selection(reflections, width=0.004): d_star_sq = flex.pow2(reflections["rlp"].norms()) d_spacings = uctbx.d_star_sq_as_d(d_star_sq) unit_cell = uctbx.unit_cell((4.498, 4.498, 7.338, 90, 90, 120)) space_group = sgtbx.space_group_info(number=194).group() if d_spacings: ice_filter = filtering.PowderRingFilter(unit_cell, space_group, flex.min(d_spacings), width) ice_sel = ice_filter(d_spacings) return ice_sel else: return None
def ice_rings_selection(reflections): d_star_sq = flex.pow2(reflections['rlp'].norms()) d_spacings = uctbx.d_star_sq_as_d(d_star_sq) from dials.algorithms.integration import filtering unit_cell = uctbx.unit_cell((4.498,4.498,7.338,90,90,120)) space_group = sgtbx.space_group_info(number=194).group() width = 0.06 if d_spacings: ice_filter = filtering.PowderRingFilter( unit_cell, space_group, flex.min(d_spacings)-width, width) ice_sel = ice_filter(d_spacings) return ice_sel else: return None
def run_filtering(params, experiments, reflections): """Execute the script.""" # Check params if params.d_min is not None and params.d_max is not None: if params.d_min > params.d_max: raise Sorry("d_min must be less than d_max") if params.d_min is not None or params.d_max is not None or params.ice_rings.filter: if "d" not in reflections: if experiments and any(experiments.crystals()): # Calculate d-spacings from the miller indices print("Reflection table does not have resolution information. " "Attempting to calculate this from the experiment list") sel = reflections["id"] >= 0 if sel.count(False) > 0: print( "Removing {} reflections with negative experiment id". format(sel.count(False))) reflections = reflections.select(sel) reflections.compute_d(experiments) elif experiments: # Calculate d-spacings from the observed reflection centroids if "rlp" not in reflections: if "xyzobs.mm.value" not in reflections: reflections.centroid_px_to_mm(experiments) reflections.map_centroids_to_reciprocal_space(experiments) d_star_sq = flex.pow2(reflections["rlp"].norms()) reflections["d"] = uctbx.d_star_sq_as_d(d_star_sq) else: raise Sorry("reflection table has no resolution information " "and no experiment list provided to calculate it") # Check params if params.partiality.min is not None and params.partiality.max is not None: if params.min > params.max: raise Sorry("partiality.min must be less than partiality.d_max") if params.partiality.min is not None or params.partiality.max is not None: if "partiality" not in reflections: raise Sorry("Reflection table has no partiality information") print("{} reflections loaded".format(len(reflections))) # Filter by logical expression using flags if params.flag_expression is not None: inc = eval_flag_expression(params.flag_expression, reflections) reflections = reflections.select(inc) print("Selected {} reflections by flags".format(len(reflections))) # Filter based on experiment ID if params.id: selection = reflections["id"] == params.id[0] for exp_id in params.id[1:]: selection = selection | (reflections["id"] == exp_id) reflections = reflections.select(selection) print("Selected %d reflections by experiment id" % (len(reflections))) # Filter based on panel number if params.panel: selection = reflections["panel"] == params.panel[0] for pnl_id in params.panel[1:]: selection = selection | (reflections["panel"] == pnl_id) reflections = reflections.select(selection) print("Selected %d reflections by panel number" % (len(reflections))) # Filter based on resolution if params.d_min is not None: selection = reflections["d"] >= params.d_min reflections = reflections.select(selection) print("Selected %d reflections with d >= %f" % (len(reflections), params.d_min)) # Filter based on resolution if params.d_max is not None: selection = reflections["d"] <= params.d_max reflections = reflections.select(selection) print("Selected %d reflections with d <= %f" % (len(reflections), params.d_max)) # Filter based on partiality if params.partiality.min is not None: selection = reflections["partiality"] >= params.partiality.min reflections = reflections.select(selection) print("Selected %d reflections with partiality >= %f" % (len(reflections), params.partiality.min)) # Filter based on partiality if params.partiality.max is not None: selection = reflections["partiality"] <= params.partiality.max reflections = reflections.select(selection) print("Selected %d reflections with partiality <= %f" % (len(reflections), params.partiality.max)) # 'Good' intensity selection if params.select_good_intensities: if "intensity.sum.variance" not in reflections: raise Sorry("No intensity.sum.variance in reflection table.") if "intensity.prf.variance" in reflections: reducer = SumAndPrfIntensityReducer else: reducer = SumIntensityReducer try: reflections = reducer.filter_bad_variances(reflections) reflections = reducer.combine_and_filter_partials( reflections, partiality_threshold=0.99, combine_partials=False) except ValueError as e: raise Sorry(e) # Dead time filter if params.dead_time.value > 0: reflections = filter_by_dead_time( reflections, experiments, params.dead_time.value, params.dead_time.reject_fraction, ) # Filter powder rings if params.ice_rings.filter: d_min = params.ice_rings.d_min width = params.ice_rings.width if d_min is None: d_min = flex.min(reflections["d"]) ice_filter = filtering.PowderRingFilter( params.ice_rings.unit_cell, params.ice_rings.space_group.group(), d_min, width, ) ice_sel = ice_filter(reflections["d"]) print("Rejecting %i reflections at ice ring resolution" % ice_sel.count(True)) reflections = reflections.select(~ice_sel) # Save filtered reflections to file if params.output.reflections: print("Saving {0} reflections to {1}".format( len(reflections), params.output.reflections)) reflections.as_file(params.output.reflections)
def run(self): '''Execute the script.''' from dials.array_family import flex from dials.util.options import flatten_reflections from dials.util.options import flatten_datablocks from dials.util.options import flatten_experiments from libtbx.utils import Sorry # Parse the command line params, options = self.parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) if params.input.datablock is not None and len(params.input.datablock): datablocks = flatten_datablocks(params.input.datablock) assert len(datablocks) == 1 imagesets = datablocks[0].extract_imagesets() assert len(imagesets) == 1 imageset = imagesets[0] elif params.input.experiments is not None and len( params.input.experiments): experiments = flatten_experiments(params.input.experiments) assert len(datablocks) == 1 imageset = experiments[0].imageset else: imageset = None if len(reflections) == 0: self.parser.print_help() raise Sorry('No valid reflection file given') if len(reflections) != 1: self.parser.print_help() raise Sorry('Exactly 1 reflection file must be specified') reflections = reflections[0] # Check params if params.d_min is not None and params.d_max is not None: if params.d_min > params.d_max: raise Sorry("d_min must be less than d_max") if params.d_min is not None or params.d_max is not None: if 'd' not in reflections: raise Sorry("Reflection table has no resolution information") # Check params if params.partiality.min is not None and params.partiality.max is not None: if params.min > params.max: raise Sorry( "partiality.min must be less than partiality.d_max") if params.partiality.min is not None or params.partiality.max is not None: if 'partiality' not in reflections: raise Sorry("Reflection table has no partiality information") print "{0} reflections loaded".format(len(reflections)) if (len(params.inclusions.flag) == 0 and len(params.exclusions.flag) == 0 and params.d_min is None and params.d_max is None and params.partiality.min is None and params.partiality.max is None and not params.ice_rings.filter): print "No filter specified. Performing analysis instead." return self.analysis(reflections) # Build up the initial inclusion selection inc = flex.bool(len(reflections), True) # 2016/07/06 GW logic here not right should be && for each flag not or? for flag in params.inclusions.flag: sel = reflections.get_flags(getattr(reflections.flags, flag)) inc = inc & sel reflections = reflections.select(inc) print "{0} reflections selected to form the working set".format( len(reflections)) # Make requested exclusions from the current selection exc = flex.bool(len(reflections)) for flag in params.exclusions.flag: print flag sel = reflections.get_flags(getattr(reflections.flags, flag)) exc = exc | sel reflections = reflections.select(~exc) print "{0} reflections excluded from the working set".format( exc.count(True)) # Filter based on resolution if params.d_min is not None: selection = reflections['d'] >= params.d_min reflections = reflections.select(selection) print "Selected %d reflections with d >= %f" % (len(reflections), params.d_min) # Filter based on resolution if params.d_max is not None: selection = reflections['d'] <= params.d_max reflections = reflections.select(selection) print "Selected %d reflections with d <= %f" % (len(reflections), params.d_max) # Filter based on partiality if params.partiality.min is not None: selection = reflections['partiality'] >= params.partiality.min reflections = reflections.select(selection) print "Selected %d reflections with partiality >= %f" % ( len(reflections), params.partiality.min) # Filter based on partiality if params.partiality.max is not None: selection = reflections['partiality'] <= params.partiality.max reflections = reflections.select(selection) print "Selected %d reflections with partiality <= %f" % ( len(reflections), params.partiality.max) # Filter powder rings if params.ice_rings.filter: from dials.algorithms.integration import filtering if 'd' in reflections: d_spacings = reflections['d'] else: from cctbx import uctbx if 'rlp' not in reflections: assert imageset is not None from dials.algorithms.spot_finding.per_image_analysis import map_to_reciprocal_space reflections = map_to_reciprocal_space( reflections, imageset) d_star_sq = flex.pow2(reflections['rlp'].norms()) d_spacings = uctbx.d_star_sq_as_d(d_star_sq) d_min = params.ice_rings.d_min width = params.ice_rings.width if d_min is None: d_min = flex.min(d_spacings) ice_filter = filtering.PowderRingFilter( params.ice_rings.unit_cell, params.ice_rings.space_group.group(), d_min, width) ice_sel = ice_filter(d_spacings) print "Rejecting %i reflections at ice ring resolution" % ice_sel.count( True) reflections = reflections.select(~ice_sel) #reflections = reflections.select(ice_sel) # Save filtered reflections to file if params.output.reflections: print "Saving {0} reflections to {1}".format( len(reflections), params.output.reflections) reflections.as_pickle(params.output.reflections) return