예제 #1
0
    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
예제 #2
0
    def it_finds_sub_pixel_exactly_under_ideal_conditions():
        """
        Test the helper _sub_pixel_peak_find instead of sub_pixel_peak_find
        because we don't want to have to reconcile the peak ordering
        from the synth with the arbitrary order they are found by the
        peak finder
        """

        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_grid()
                .locs_add_random_subpixel()
            )
            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 np.all(dists < 0.01)
예제 #3
0
    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
예제 #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
    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
예제 #6
0
 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
예제 #7
0
 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
예제 #8
0
 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
예제 #9
0
 def _synth(im_mea, n_cycles):
     """
     No noise or background to simulate post-filtering images
     """
     dim = (im_mea, im_mea)
     with synth.Synth(n_channels=1, n_cycles=n_cycles, dim=dim) as s:
         (
             synth.PeaksModelGaussianCircular(n_peaks=int(0.005 * im_mea ** 2))
             .uniform_width_and_heights()
             .amps_constant(5000)
             .locs_randomize()
         )
         return s.aln_offsets, s.render_chcy()
예제 #10
0
 def _synth():
     ch_scale = (1.0, 1.0)
     ch_aln = np.array([0.0, 0.0, -5.0, -5.0]).reshape((-1, 2))
     with synth.Synth(n_channels=2, n_cycles=3, dim=(512, 512)) as s:
         s.channel_aln_offsets(ch_aln)
         (
             synth.PeaksModelGaussianCircular(n_peaks=500)
             .uniform_width_and_heights()
             .amps_constant(5000)
             .locs_randomize()
             .channel_scale_factor(ch_scale)
         )
         return s.aln_offsets, s.render_chcy()
예제 #11
0
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()
예제 #12
0
 def _synth():
     ch_scale = (1.0, 1.0)
     ch_aln = np.array([
         [0.0, 0.0],
         [-5.0, -5.0],
     ])
     with synth.Synth(n_channels=n_channels,
                      n_cycles=3,
                      dim=(im_mea, im_mea)) as s:
         s.channel_aln_offsets(ch_aln)
         peaks = (synth.PeaksModelGaussianCircular(
             n_peaks=500).uniform_width_and_heights().amps_constant(
                 5000).locs_randomize().channel_scale_factor(ch_scale))
         return s.render_chcy(), peaks
예제 #13
0
 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)
예제 #14
0
파일: main.py 프로젝트: erisyon/plaster
        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],
                    )
예제 #15
0
 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])
예제 #16
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
예제 #17
0
    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
예제 #18
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
예제 #19
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