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 it_handles_all_noise():
        with synth.Synth(overwrite=True) as s:
            synth.CameraModel(bias=bg_mean, std=bg_std)
            im = s.render_chcy()[0, 0]

        stats, fg_im, bg_im = worker._regional_bg_fg_stats(im, return_ims=True)
        _check_bg_stats(stats)
    def it_skips_too_oval():
        """It doesn't have to work perfectly every time, but pass once in a 10 try loop"""
        n_fails = 0
        for i in range(10):
            failed = 0
            locs = [[64, 54], [64, 70]]
            with synth.Synth(overwrite=True, dim=(128, 128)) as s:
                peaks = synth.PeaksModelGaussianCircular(
                    n_peaks=len(locs)
                ).amps_constant(val=4_000)
                peaks.std_x = [1.0, 1.0]
                peaks.std_y = [1.0, 2.0]
                synth.CameraModel(bias=bg_mean, std=bg_std)
                peaks.locs = locs
                im = s.render_chcy()[0, 0]
                im = im - bg_mean

            psf, reasons = worker._psf_estimate(
                im, peaks.locs, mea=17, return_reasons=True
            )
            for loc, reason in zip(peaks.locs, reasons):
                if loc[1] < 64:
                    if reason[worker.PSFEstimateMaskFields.skipped_too_oval] != 0:
                        failed += 1
                else:
                    if reason[worker.PSFEstimateMaskFields.skipped_too_oval] != 1:
                        failed += 1

            if failed != 0:
                n_fails += 1

        assert n_fails < 3
Beispiel #4
0
    def it_find_pixel_accurate():
        bg_std = 10
        with synth.Synth(dim=(512, 512), n_cycles=3) as s:
            true_n_peaks = 100
            peaks = (
                synth.PeaksModelGaussianCircular(n_peaks=true_n_peaks)
                .amps_constant(1000)
                .widths_uniform(1.5)
                .locs_randomize()
            )
            s.zero_aln_offsets()
            synth.CameraModel(0, bg_std)
            chcy_ims = s.render_chcy()

        im = filter_ims.filter_im(
            chcy_ims[0, 0],
            low_inflection=0.03,
            low_sharpness=50.0,
            high_inflection=0.5,
            high_sharpness=50.0,
        )
        kernel = approximate_psf()
        locs = peak_find.pixel_peak_find_one_im(chcy_ims[0, 0], kernel)
        n_peaks, n_dims = locs.shape
        assert n_dims == 2
        assert n_peaks > 0.80 * true_n_peaks
Beispiel #5
0
 def _synth(n_peaks=500):
     with synth.Synth(n_channels=1, n_cycles=3, dim=(512, 512)) as s:
         reg_psf = PriorsMLEFixtures.reg_psf_uniform()
         (
             synth.PeaksModelPSF(reg_psf, n_peaks=n_peaks)
             .amps_constant(5000)
             .locs_randomize()
         )
         synth.CameraModel(100, 30)
         synth.HaloModel()
         return s.aln_offsets, s.render_chcy()
    def _synth_field(n_cycles):
        with synth.Synth(n_channels=2, n_cycles=n_cycles, dim=dim) as s:
            peaks = (synth.PeaksModelGaussianCircular(
                n_peaks=n_peaks).locs_randomize().widths_uniform(
                    psf_width).channel_scale_factor(
                        channel_scale_factor).channel_peak_width_scale_factor(
                            channel_peak_width_scale_factor))
            synth.CameraModel(bg_mean=bg_mean, bg_std=bg_std)
            synth.HaloModel()
            synth.IlluminationQuadraticFalloffModel()

        return s, peaks
 def _ims():
     bg_mean = 145
     with synth.Synth(n_channels=2, n_cycles=3, overwrite=True, dim=(256, 256)) as s:
         (
             synth.PeaksModelGaussianCircular(n_peaks=1000)
             .amps_constant(val=4_000)
             .locs_randomize()
             .widths_uniform(1.5)
         )
         synth.CameraModel(bias=bg_mean, std=14)
         chcy_ims = s.render_chcy()
         return chcy_ims, s.aln_offsets
 def _im():
     bg_mean = 145
     with synth.Synth(overwrite=True, dim=(512, 512)) as s:
         (
             synth.PeaksModelGaussianCircular(n_peaks=1000)
             .amps_constant(val=4_000)
             .locs_randomize()
         )
         synth.CameraModel(bias=bg_mean, std=14)
         im = s.render_chcy()[0, 0]
         im = im - bg_mean
         return im
 def _make_image_n_locs(locs):
     with synth.Synth(overwrite=True, dim=(128, 128)) as s:
         peaks = (
             synth.PeaksModelGaussianCircular(n_peaks=len(locs))
             .amps_constant(val=4_000)
             .widths_uniform(1.5)
         )
         synth.CameraModel(bias=bg_mean, std=bg_std)
         peaks.locs = locs
         im = s.render_chcy()[0, 0]
         im = im - bg_mean
     return peaks, im
def zest_regional_bg_fg_stats():
    divs = 5
    bg_mean = 100
    bg_std = 10
    with synth.Synth(overwrite=True) as s:
        (
            synth.PeaksModelGaussianCircular(n_peaks=100)
            .locs_randomize()
            .amps_constant(val=10000)
        )
        synth.CameraModel(bias=bg_mean, std=bg_std)
        im = s.render_chcy()[0, 0]

    def _check_bg_stats(stats):
        # Check that bg mean and std are close
        assert np.all((stats[:, :, 0] - bg_mean) ** 2 < 3 ** 2)
        assert np.all((stats[:, :, 1] - bg_std) ** 2 < 2 ** 2)

    def it_returns_stats_regionally():
        stats = worker._regional_bg_fg_stats(im, divs=divs)
        assert stats.shape == (5, 5, 4)
        _check_bg_stats(stats)

    def it_varies_divs():
        stats = worker._regional_bg_fg_stats(im, divs=10)
        assert stats.shape == (10, 10, 4)

    def it_returns_fg_and_bg_ims():
        stats, fg_im, bg_im = worker._regional_bg_fg_stats(im, return_ims=True)
        assert stats.shape == (5, 5, 4)
        _check_bg_stats(stats)
        assert fg_im.shape == im.shape
        assert bg_im.shape == im.shape

    def it_handles_all_zeros():
        im = np.zeros((512, 512))
        stats, fg_im, bg_im = worker._regional_bg_fg_stats(im, return_ims=True)
        assert np.all(stats[:, :, 0] == 0)
        assert np.all(stats[:, :, 1] == 0)
        assert np.all(np.isnan(stats[:, :, 2]))
        assert np.all(np.isnan(stats[:, :, 3]))

    def it_handles_all_noise():
        with synth.Synth(overwrite=True) as s:
            synth.CameraModel(bias=bg_mean, std=bg_std)
            im = s.render_chcy()[0, 0]

        stats, fg_im, bg_im = worker._regional_bg_fg_stats(im, return_ims=True)
        _check_bg_stats(stats)

    zest()
 def it_finds_peaks_as_they_approach():
     for dist in np.linspace(10, 0, 10):
         with synth.Synth(overwrite=True, dim=(128, 128)) as s:
             peaks = (
                 synth.PeaksModelGaussianCircular(n_peaks=2)
                 .amps_constant(val=4_000)
                 .widths_uniform(1.5)
             )
             synth.CameraModel(bias=bg_mean, std=11)
             peaks.locs[0] = (64, 64 - dist)
             peaks.locs[1] = (64, 64 + dist)
             im = s.render_chcy()[0, 0]
             im = im - bg_mean
         locs = worker._peak_find(im)
         if dist > 1.5:
             # After 1.5 pixels (total of 3 pixels) then they peaks should merge
             assert locs.shape == (2, 2)
         assert np.all((locs[:, 0] - 64) ** 2 < 1.5 ** 2)
Beispiel #12
0
        def _synth_field(fl_i):
            with synth.Synth(n_channels=n_channels, n_cycles=n_cycles,
                             dim=dim) as s:
                peaks = (synth.PeaksModelGaussianCircular(
                    n_peaks=n_peaks).locs_randomize().widths_uniform(
                        psf_width).amps_constant(gain))
                synth.CameraModel(bg_mean=bg_mean, bg_std=bg_std)
                synth.HaloModel()
                synth.IlluminationQuadraticFalloffModel()

            chcy_ims = s.render_chcy(0)

            for ch_i in range(chcy_ims.shape[0]):
                for cy_i in range(chcy_ims.shape[1]):
                    np.save(
                        str(source_folder /
                            f"area_{fl_i:03d}_cell_000_{ch_i:03d}nm_{cy_i:03d}.npy"
                            ),
                        chcy_ims[ch_i, cy_i],
                    )
Beispiel #13
0
    def it_finds_sub_pixel_well_under_typical_conditions():
        bg_std = 10
        with synth.Synth(dim=(512, 512), n_cycles=3) as s:
            true_n_peaks = 100
            peaks = (
                synth.PeaksModelGaussianCircular(n_peaks=true_n_peaks)
                .amps_constant(1000)
                .widths_uniform(1.5)
                .locs_randomize_away_from_edges()
            )
            synth.CameraModel(0, bg_std)
            s.zero_aln_offsets()
            chcy_ims = s.render_chcy()

        chcy_mean_im = np.mean(chcy_ims, axis=(0, 1))
        locs = peak_find._pixel_to_subpixel_one_im(
            chcy_mean_im, HW(peaks.mea, peaks.mea), peaks.locs.astype(int)
        )
        dists = np.linalg.norm(locs - peaks.locs, axis=1)

        assert (dists < 0.1).sum() > 30
        assert (dists < 0.2).sum() > 70
 def it_finds_peaks_as_density_increases():
     _expected = [
         [100, 88, 10],
         [125, 117, 10],
         [150, 134, 20],
         [175, 151, 25],
         [200, 172, 25],
     ]
     for expected, n_peaks in zip(_expected, np.linspace(100, 200, 5).astype(int)):
         with synth.Synth(overwrite=True, dim=(256, 256)) as s:
             peaks = (
                 synth.PeaksModelGaussianCircular(n_peaks=n_peaks)
                 .amps_constant(val=4_000)
                 .widths_uniform(1.5)
                 .locs_randomize_away_from_edges()
             )
             synth.CameraModel(bias=bg_mean, std=11)
             im = s.render_chcy()[0, 0]
             im = im - bg_mean
         locs = worker._peak_find(im)
         assert expected[0] == n_peaks
         assert utils.np_within(expected[1], locs.shape[0], expected[2])
    def _make_image(depth, n_peaks=1000):
        # This table is based on a fitting of the PSF using polymer spheres
        # s3://erisyon-acquire/Val/ESN/2020/2020_05/ESN_2020_05_21_amb/ESN_2020_21_amb_02_NSdeepredZ
        # Using the exploration notebook internal/explore/sigproc/psf_with_real_data.ipynb
        # The depth is set so that 0 microns is optimally in focus
        z_microns_to_peak_std = np.array(
            [
                [-0.25, 2.187504401090129],
                [-0.2, 2.063845408774231],
                [-0.15000000000000002, 2.001985762818282],
                [-0.1, 1.9433957713576882],
                [-0.05, 1.9091776019044606],
                [0.0, 1.8891420470361429],
                [0.05, 1.8951213618125622],
                [0.1, 1.9476507707766804],
                [0.15000000000000002, 2.0169404372571758],
                [0.2, 2.091394093944999],
                [0.25, 2.4354449946062364],
            ]
        )

        # Background parameters based on:
        # s3://erisyon-acquire/Val/ESN/2020/2020_05/ESN_2020_05_21_amb/ESN_2020_21_amb_01_JSP092Z
        with synth.Synth(overwrite=True, dim=(1024, 1024)) as s:
            idx = utils.np_arg_find_nearest(z_microns_to_peak_std[:, 0], depth)
            std = z_microns_to_peak_std[idx, 1]
            peaks = (
                synth.PeaksModelGaussianCircular(n_peaks=n_peaks)
                .locs_randomize()
                .amps_constant(val=4_000)
                # Amp of 4000 based on fitting of a peptide from: erisyon-acquire/Val/ESN/2020/2020_05/ESN_2020_05_21_amb/ESN_2020_21_amb_01_JSP092Z
                .widths_uniform(std)
            )
            synth.CameraModel(bias=bg_mean, std=bg_std)
            im = s.render_chcy()[0, 0]
            im = im - bg_mean
        return peaks, im, std
Beispiel #16
0
    def it_peak_find_very_different_channel_brightnesses_4_channels():
        """
        Test that as the number of channels increases that the de-duping
        continues to work
        """
        # fmt: off
        dyts = [
            [[1, 1, 1], [0, 0, 0], [0, 0, 0], [0, 0, 0]],  # On in ch 0
            [[0, 0, 0], [1, 1, 1], [0, 0, 0], [0, 0, 0]],  # On in ch 1
            [[0, 0, 0], [0, 0, 0], [1, 1, 1], [0, 0, 0]],  # On in ch 2
            [[0, 0, 0], [0, 0, 0], [0, 0, 0], [1, 1, 1]],  # On in ch 3
            [[1, 1, 1], [1, 1, 1], [0, 0, 0], [0, 0, 0]],  # Shared 0, 1
            [[0, 0, 0], [1, 1, 1], [1, 1, 1], [0, 0, 0]],  # Shared 1, 2
            [[0, 0, 0], [0, 0, 0], [1, 1, 1], [0, 0, 0]],  # Shared 2, 3
            [[1, 1, 1], [0, 0, 0], [1, 1, 1], [0, 0, 0]],  # Shared 0, 2
            # Good enough...
        ]
        # fmt: on

        probs = np.array([10, 10, 10, 10, 3, 3, 3, 3])
        probs = probs / np.sum(probs)

        n_peaks = 500
        ch_scale = (1.0, 0.1, 0.1, 0.1)
        ch_aln = np.array((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)).reshape((-1, 2))
        with synth.Synth(n_channels=4, n_cycles=3, dim=(512, 512)) as s:
            s.channel_aln_offsets(ch_aln)
            peaks = (
                synth.PeaksModelGaussianCircular(n_peaks=n_peaks)
                .uniform_width_and_heights()
                .locs_randomize()
                .channel_scale_factor(ch_scale)
                .multichannel_dyt_random_choice(dyts, probs)
                .gain_constant(5000)
            )
            synth.CameraModel(0, 5)
            ims = s.render_chcy()

            approx_psf = approximate_psf()
            found_locs = peak_find.peak_find_chcy_ims(ims, approx_psf, 0)

            def _compare(filt_true_locs):
                dists = cdist(filt_true_locs, found_locs, "euclidean")
                closest_i = np.argmin(dists, axis=1)
                closest_d = dists[np.arange(filt_true_locs.shape[0]), closest_i]
                new_locs_mask = closest_d > 1.5
                return filt_true_locs.shape[0], (~new_locs_mask).sum()

            n_true_ch0, n_found_ch0 = _compare(
                filt_true_locs=peaks.locs[
                    (peaks.dyt_iz == 0) | (peaks.dyt_iz == 4) | (peaks.dyt_iz == 7)
                ]
            )
            assert n_found_ch0 / n_true_ch0 > 0.70

            n_true_ch1, n_found_ch1 = _compare(
                filt_true_locs=peaks.locs[
                    (peaks.dyt_iz == 1) | (peaks.dyt_iz == 4) | (peaks.dyt_iz == 5)
                ]
            )
            assert n_found_ch1 / n_true_ch1 > 0.70

            n_true_ch2, n_found_ch2 = _compare(
                filt_true_locs=peaks.locs[
                    (peaks.dyt_iz == 2)
                    | (peaks.dyt_iz == 5)
                    | (peaks.dyt_iz == 6)
                    | (peaks.dyt_iz == 7)
                ]
            )
            assert n_found_ch2 / n_true_ch2 > 0.70

            n_true_ch3, n_found_ch3 = _compare(
                filt_true_locs=peaks.locs[(peaks.dyt_iz == 3)]
            )
            assert n_found_ch3 / n_true_ch3 > 0.70
Beispiel #17
0
    def it_peak_find_very_different_channel_brightnesses_2_channels():
        """
        Assume the images are already aligned.
        Synth two channels with 0.2 overlap
        Ensure that most of the true peaks in each channel are located
        There will be some collisions so it will not be perfect.
        """

        # fmt: off
        dyts = [
            [[1, 1, 1], [0, 0, 0]],  # On in ch 0
            [[0, 0, 0], [1, 1, 1]],  # On in ch 1
            [[1, 1, 1], [1, 1, 1]],  # Shared
        ]
        # fmt: on

        frac_shared = 0.20
        frac_unshared = (1.0 - frac_shared) / 2
        probs = [frac_unshared, frac_unshared, frac_shared]
        n_peaks = 500
        ch_scale = (1.0, 0.2)
        ch_aln = np.array((0.0, 0.0, 0.0, 0.0)).reshape((-1, 2))
        with synth.Synth(n_channels=2, n_cycles=3, dim=(512, 512)) as s:
            s.channel_aln_offsets(ch_aln)
            peaks = (
                synth.PeaksModelGaussianCircular(n_peaks=n_peaks)
                .uniform_width_and_heights()
                .locs_randomize()
                .channel_scale_factor(ch_scale)
                .multichannel_dyt_random_choice(dyts, probs)
                .gain_constant(5000)
            )
            synth.CameraModel(0, 5)
            ims = s.render_chcy()

            approx_psf = approximate_psf()
            found_locs = peak_find.peak_find_chcy_ims(ims, approx_psf, 0)

            """
            In each channel, how many of the TRUE exclusive peaks that were
            visible in that channel were found?
            How many of the true shared were found?

            for each of the three groups:
            cdist fro true set to the found and answer within 1.5 pixels.

            peaks.dyt_iz will have 0 (only channel 0), 1 (only ch 1) 2 = both
            """

            def _compare(filt_true_locs):
                dists = cdist(filt_true_locs, found_locs, "euclidean")
                closest_i = np.argmin(dists, axis=1)
                closest_d = dists[np.arange(filt_true_locs.shape[0]), closest_i]
                new_locs_mask = closest_d > 1.5
                return filt_true_locs.shape[0], (~new_locs_mask).sum()

            n_true_ch0, n_found_ch0 = _compare(
                filt_true_locs=peaks.locs[(peaks.dyt_iz == 0) | (peaks.dyt_iz == 2)]
            )
            n_true_ch1, n_found_ch1 = _compare(
                filt_true_locs=peaks.locs[(peaks.dyt_iz == 1) | (peaks.dyt_iz == 2)]
            )
            assert n_found_ch0 / n_true_ch0 > 0.75
            assert n_found_ch1 / n_true_ch1 > 0.75