def render(self, im, cy_i): if self.std_x is None: self.std_x = [self.std] if self.std_y is None: self.std_y = [self.std] n_locs = len(self.locs) if len(self.std_x) != n_locs: self.std_x = np.repeat(self.std_x, (n_locs, )) if len(self.std_y) != n_locs: self.std_y = np.repeat(self.std_y, (n_locs, )) super().render(im, cy_i) mea = 17 for loc, amp, std_x, std_y in zip(self.locs, self.amps, self.std_x, self.std_y): frac_x = np.modf(loc[0])[0] frac_y = np.modf(loc[1])[0] peak_im = imops.gauss2_rho_form( amp=amp, std_x=std_x, std_y=std_y, pos_x=mea // 2 + frac_x, pos_y=mea // 2 + frac_y, rho=0.0, const=0.0, mea=mea, ) imops.accum_inplace(im, peak_im, loc=YX(*np.floor(loc)), center=True)
def _im(off, bg_std=14.0): bg_mean = 145 mea = 23 psf = imops.gauss2_rho_form( amp=1.0, std_x=1.5, std_y=1.5, pos_x=mea // 2, pos_y=mea // 2, rho=0.0, const=0.0, mea=mea, ) with synth.Synth(overwrite=True, dim=(mea, mea)) as s: peaks = ( synth.PeaksModelGaussianCircular(n_peaks=1) .amps_constant(val=1_000) .widths_uniform(1.5) ) peaks.locs = [(mea // 2 + off[0], mea // 2 + off[1])] synth.CameraModel(bias=bg_mean, std=bg_std) im = s.render_chcy()[0, 0] - bg_mean return im, psf
def render_at_loc(self, loc, amp=1.0, const=0.0, focus=1.0): interp_sigma_x_fn, interp_sigma_y_fn, interp_rho_fn = self._init_interpolation() loc_x = loc[1] loc_y = loc[0] sigma_x = interp_sigma_x_fn(loc_x, loc_y)[0] sigma_y = interp_sigma_y_fn(loc_x, loc_y)[0] rho = interp_rho_fn(loc_x, loc_y)[0] half_mea = self.hyper_peak_mea / 2.0 corner_x = np.floor(loc_x - half_mea + 0.5) corner_y = np.floor(loc_y - half_mea + 0.5) center_x = loc_x - corner_x center_y = loc_y - corner_y im = imops.gauss2_rho_form( amp=amp, std_x=sigma_x, std_y=sigma_y, pos_x=center_x, pos_y=center_y, rho=rho, const=const, mea=self.hyper_peak_mea, ) return im, (corner_y, corner_x)
def it_shifts(): im = imops.gauss2_rho_form(1.0, 2.0, 2.0, 5.5, 5.5, 0.0, 0.0, 11) shifted_im = imops.sub_pixel_shift(im, (0.2, 0.7)) com_after = imops.com(shifted_im ** 2) assert ( -0.05 < com_after[0] - (5.5 + 0.2) < 0.05 and -0.05 < com_after[1] - (5.5 + 0.7) < 0.05 )
def it_centers(): for x in np.linspace(-1, 1, 10): im = imops.gauss2_rho_form( 10, 1.5, 1.5, 8.5 + x, 8.5, rho=0.0, const=0, mea=17 ) uncentered = imops.com(im) assert (uncentered[1] - 8.5 - x) ** 2 < 0.08 ** 2 centered_im = imops.sub_pixel_center(im) centered = imops.com(centered_im) assert (centered[1] - 8.5) ** 2 < 0.08 ** 2
def it_returns_2_for_x_ellipse(): im = imops.gauss2_rho_form(10, 1.0, 1.5, 8, 8, rho=0.0, const=0, mea=17) ratio = imops.distribution_aspect_ratio(im) assert (ratio - 2.25)**2 < 0.01**2
def _test(true_params, start_params=None, noise=None): im = imops.gauss2_rho_form(*true_params, mea=11) locs = np.array([[5.0, 5.0]]) if start_params is None: start_params = true_params if noise is not None: im = im + np.random.normal(0, noise, size=im.shape) start_params = _full_params(start_params) pred_params, std_params = gauss2_fitter.fit_image( im, locs, np.array([start_params]), 11) return true_params, pred_params, std_params
def _peak(into_im, x, y, rho=0.0, mea=15, amp=1000.0, peak_sigma=1.8): corner_y = int(y - mea / 2.0 + 0.5) # int corner_x = int(x - mea / 2.0 + 0.5) off_y = y - corner_y # float off_x = x - corner_x peak_im = imops.gauss2_rho_form(amp, peak_sigma, peak_sigma, off_x, off_y, rho, 0.0, mea) imops.accum_inplace(into_im, peak_im, loc=XY(corner_x, corner_y), center=False)
def it_skips_nan_locs(): true_params = (1000, 1.8, 1.8, 5.0, 5.0, 0.0, 0.0) im = imops.gauss2_rho_form(*true_params, mea=11) locs = np.array([[5.0, 5.0], [np.nan, np.nan], [5.0, 5.0]]) start_params = np.repeat(_full_params(true_params)[None, :], (3, ), axis=0) pred_params, std_params = gauss2_fitter.fit_image( im, locs, start_params, 11) assert np.all(~np.isnan(pred_params[0, :])) assert np.all(np.isnan(pred_params[1, :])) assert np.all(~np.isnan(pred_params[2, :]))
def it_returns_3_for_rho_one_half(): im = imops.gauss2_rho_form(10, 1.0, 1.0, 8, 8, rho=0.5, const=0, mea=17) ratio = imops.distribution_aspect_ratio(im) assert (ratio - 3.0)**2 < 0.001**2
def it_returns_1_for_circluar(): im = imops.gauss2_rho_form(10, 1.0, 1.0, 8, 8, rho=0.0, const=0, mea=17) ratio = imops.distribution_aspect_ratio(im) assert (ratio - 1.0)**2 < 0.001**2
def approximate_psf(): """ Return a zero-centered AUC=1.0 2D Gaussian for peak finding """ std = 1.5 # This needs to be tuned and may be instrument dependent mea = 11 kern = imops.gauss2_rho_form( amp=1.0, std_x=std, std_y=std, pos_x=mea // 2, pos_y=mea // 2, rho=0.0, const=0.0, mea=mea, ) return kern - np.mean(kern)
def it_finds_one_peak_sub_pixel_exactly_under_ideal_conditions(): true_locs = np.array([[17.5, 17.5]]) peak_im = imops.gauss2_rho_form( amp=1000.0, std_x=1.8, std_y=1.8, pos_x=true_locs[0, 1], pos_y=true_locs[0, 0], rho=0.0, const=0.0, mea=35, ) pred_locs = peak_find._pixel_to_subpixel_one_im( peak_im, HW(11, 11), true_locs.astype(int) ) dists = np.linalg.norm(true_locs - pred_locs, axis=1) assert np.all(dists < 0.001)
def it_finds_one_peak_sub_pixel_exactly_under_ideal_conditions_many_offsets(): for trials in range(50): true_locs = np.random.uniform(-5, 5, size=(1, 2)) true_locs += 35 / 2 peak_im = imops.gauss2_rho_form( amp=1000.0, std_x=1.8, std_y=1.8, pos_x=true_locs[0, 1], pos_y=true_locs[0, 0], rho=0.0, const=0.0, mea=35, ) pred_locs = peak_find._pixel_to_subpixel_one_im( peak_im, HW(11, 11), true_locs.astype(int) ) dists = np.linalg.norm(true_locs - pred_locs, axis=1) assert np.all(dists < 0.001)
def render_one_reg(self, div_y, div_x, frac_y=0.0, frac_x=0.0, const=0.0): assert 0 <= div_y < self.hyper_n_divs assert 0 <= div_x < self.hyper_n_divs assert 0 <= frac_x <= 1.0 assert 0 <= frac_y <= 1.0 im = imops.gauss2_rho_form( amp=1.0, std_x=self.sigma_x[div_y, div_x], std_y=self.sigma_y[div_y, div_x], # Note that the following must be integer divide because the # fractional component is relative to the lower-left corner (origin) pos_x=self.hyper_peak_mea // 2 + frac_x, pos_y=self.hyper_peak_mea // 2 + frac_y, rho=self.rho[div_y, div_x], const=const, mea=self.hyper_peak_mea, ) # NORMALIZE to get an AUC exactly equal to 1.0 return im / np.sum(im)
def it_centers_odd(): # When mea is odd and the center is at +0.5 the center # pixel should be the brightes true_params = (100.0, 1.5, 1.5, 5.5, 5.5, 0.0, 0.0, 11) im = imops.gauss2_rho_form(*true_params) assert np.argwhere(im == im.max()).tolist() == [[5, 5]]
def it_centers_even(): # When mea is even and the center is split between the inner four pixels # pixel should be the brightes true_params = (100.0, 1.5, 1.5, 5.0, 5.0, 0.0, 0.0, 10) im = imops.gauss2_rho_form(*true_params) assert np.argwhere(im == im.max()).tolist() == [[4, 4], [4, 5], [5, 4], [5, 5]]
def it_fits_what_it_generates(): true_params = (10.0, 1.5, 1.8, 8.5, 8.0, 0.2, 5.0, 17) im = imops.gauss2_rho_form(*true_params) fit_params, _ = imops.fit_gauss2(im) assert np.all( (np.array(fit_params) - np.array(true_params))**2 < 0.0001**2)