def map_to_image_space(refl, d, dhs, dks, dls): from scitbx.array_family import flex d_elems = d.elems bb = refl.bounding_box dxs = d_elems[0] * dhs + d_elems[1] * dks + d_elems[2] * dls dys = d_elems[3] * dhs + d_elems[4] * dks + d_elems[5] * dls dzs = d_elems[6] * dhs + d_elems[7] * dks + d_elems[8] * dls xs = flex.floor(dxs + refl.image_coord_px[0]).iround() - bb[0] ys = flex.floor(dys + refl.image_coord_px[1]).iround() - bb[2] zs = flex.floor(dzs + refl.frame_number).iround() - bb[4] xyz = flex.vec3_int(zs, ys, xs) xyz = xyz.select((xs >= 0 and xs < (bb[1] - bb[0])) & (ys >= 0 and ys < (bb[3] - bb[2])) & (zs >= 0 and zs < (bb[5] - bb[4]))) for _xyz in xyz: refl.shoebox[_xyz] += 1 return
def compute_threshold( self, image, mask, *, imageset, i_panel, region_of_interest=None, **kwargs ): r""" Compute the threshold. :param image: The image to process :param mask: The pixel mask on the image :\*\*kwargs: Arbitrary keyword arguments :returns: A boolean mask showing foreground/background pixels """ if self.kernel: image = convolve(image, self.kernel) panel = imageset.get_detector()[i_panel] beam = imageset.get_beam() # Get 2θ array for the panel or ROI two_theta_array = panel.get_two_theta_array(beam.get_s0()) if region_of_interest: x0, x1, y0, y1 = region_of_interest two_theta_array = two_theta_array[y0:y1, x0:x1] # Convert to 2θ bin selections lookup = two_theta_array - flex.min(two_theta_array) n_bins = self.params.spotfinder.threshold.radial_profile.n_bins multiplier = n_bins / flex.max(lookup + 1e-10) lookup *= multiplier # values now in range [0,n_bins+1) lookup = ( flex.floor(lookup).iround().as_size_t() ) # values now in range [0,n_bins-1] # Calculate median intensity and IQR within each bin of masked values masked_lookup = lookup.select(mask.as_1d()) masked_image = image.select(mask.as_1d()) binned_statistics = BinnedStatistics(masked_image, masked_lookup, n_bins) med_I = binned_statistics.get_medians() iqr = binned_statistics.get_iqrs() # Determine the threshold value for each bin. This should be at least # 1 quantum greater value than the median to avoid selecting everything # in low background cases n_iqr = self.params.spotfinder.threshold.radial_profile.n_iqr add_level = n_iqr * iqr adu = 1 / panel.get_gain() add_level.set_selected(add_level <= adu, 2.0 * adu) threshold = med_I + add_level # Now construct a threshold image thresh_im = threshold.select(lookup.as_1d()) # Peaks are unmasked pixels greater than the threshold peaks = image > thresh_im return peaks & mask