示例#1
0
def table_ilms():
    np.random.seed(11)
    s = create_image()

    lilms = [
        ilms.LegendrePoly2P1D(shape=s.ilm.shape, order=(1, 1, 1)),
        ilms.LegendrePoly2P1D(shape=s.ilm.shape, order=(3, 3, 3)),
        ilms.BarnesStreakLegPoly2P1DX3(shape=s.ilm.shape,
                                       order=(1, 1, 1),
                                       npts=(10, 5)),
        ilms.BarnesStreakLegPoly2P1DX3(shape=s.ilm.shape,
                                       order=(1, 1, 2),
                                       npts=(30, 10)),
        ilms.BarnesStreakLegPoly2P1DX3(shape=s.ilm.shape,
                                       order=s.ilm.order,
                                       npts=(30, 10, 5)),
    ]
    names = [
        r'Legendre 2+1D (0,0,0)',
        r'Legendre 2+1D (2,2,2)',
        r'Barnes (10, 5) $N_z=1$',
        r'Barnes (30, 10) $N_z=2$',
        r'Barnes (30, 10, 5) $N_z=3$',
    ]

    def vary_func(s, data):
        s.set_ilm(data)

    return table(s, lilms, names, vary_func)
示例#2
0
def makestate(im, pos, rad, slab=None, mem_level='hi'):
    """
    Workhorse for creating & optimizing states with an initial centroid
    guess.

    This is an example function that works for a particular microscope. For
    your own microscope, you'll need to change particulars such as the psf
    type and the orders of the background and illumination.

    Parameters
    ----------
        im : :class:`~peri.util.RawImage`
            A RawImage of the data.
        pos : [N,3] element numpy.ndarray.
            The initial guess for the N particle positions.
        rad : N element numpy.ndarray.
            The initial guess for the N particle radii.

        slab : :class:`peri.comp.objs.Slab` or None, optional
            If not None, a slab corresponding to that in the image. Default
            is None.
        mem_level : {'lo', 'med-lo', 'med', 'med-hi', 'hi'}, optional
            A valid memory level for the state to control the memory overhead
            at the expense of accuracy. Default is `'hi'`

    Returns
    -------
        :class:`~peri.states.ImageState`
            An ImageState with a linked z-scale, a ConfocalImageModel, and
            all the necessary components with orders at which are useful for
            my particular test case.
    """
    if slab is not None:
        o = comp.ComponentCollection(
                [
                    objs.PlatonicSpheresCollection(pos, rad, zscale=zscale),
                    slab
                ],
                category='obj'
            )
    else:
        o = objs.PlatonicSpheresCollection(pos, rad, zscale=zscale)

    p = exactpsf.FixedSSChebLinePSF()
    npts, iorder = _calc_ilm_order(im.get_image().shape)
    i = ilms.BarnesStreakLegPoly2P1D(npts=npts, zorder=iorder)
    b = ilms.LegendrePoly2P1D(order=(9 ,3, 5), category='bkg')
    c = comp.GlobalScalar('offset', 0.0)
    s = states.ImageState(im, [o, i, b, c, p])
    runner.link_zscale(s)
    if mem_level != 'hi':
        s.set_mem_level(mem_level)

    opt.do_levmarq(s, ['ilm-scale'], max_iter=1, run_length=6, max_mem=1e4)
    return s
示例#3
0
def create_img():
    """Creates an image, as a `peri.util.Image`, which is similar
    to the image in the tutorial"""
    # 1. particles + coverslip
    rad = 0.5 * np.random.randn(POS.shape[0]) + 4.5  # 4.5 +- 0.5 px particles
    part = objs.PlatonicSpheresCollection(POS, rad, zscale=0.89)
    slab = objs.Slab(zpos=4.92, angles=(-4.7e-3, -7.3e-4))
    objects = comp.ComponentCollection([part, slab], category='obj')

    # 2. psf, ilm
    p = exactpsf.FixedSSChebLinePSF(kfki=1.07, zslab=-29.3, alpha=1.17,
            n2n1=0.98, sigkf=-0.33, zscale=0.89, laser_wavelength=0.45)
    i = ilms.BarnesStreakLegPoly2P1D(npts=(16,10,8,4), zorder=8)
    b = ilms.LegendrePoly2P1D(order=(7,2,2), category='bkg')
    off = comp.GlobalScalar(name='offset', value=-2.11)
    mdl = models.ConfocalImageModel()
    st = states.ImageState(util.NullImage(shape=[48,64,64]),
            [objects, p, i, b, off], mdl=mdl, model_as_data=True)
    b.update(b.params, BKGVALS)
    i.update(i.params, ILMVALS)
    im = st.model + np.random.randn(*st.model.shape) * 0.03
    return util.Image(im)
示例#4
0
def locate_spheres(image,
                   feature_rad,
                   dofilter=False,
                   order=(3, 3, 3),
                   trim_edge=True,
                   **kwargs):
    """
    Get an initial featuring of sphere positions in an image.

    Parameters
    -----------
    image : :class:`peri.util.Image` object
        Image object which defines the image file as well as the region.

    feature_rad : float
        Radius of objects to find, in pixels. This is a featuring radius
        and not a real radius, so a better value is frequently smaller
        than the real radius (half the actual radius is good). If ``use_tp``
        is True, then the twice ``feature_rad`` is passed as trackpy's
        ``diameter`` keyword.

    dofilter : boolean, optional
        Whether to remove the background before featuring. Doing so can
        often greatly increase the success of initial featuring and
        decrease later optimization time. Filtering functions by fitting
        the image to a low-order polynomial and featuring the residuals.
        In doing so, this will change the mean intensity of the featured
        image and hence the good value of ``minmass`` will change when
        ``dofilter`` is True. Default is False.

    order : 3-element tuple, optional
        If `dofilter`, the 2+1D Leg Poly approximation to the background
        illumination field. Default is (3,3,3).

    Other Parameters
    ----------------
    invert : boolean, optional
        Whether to invert the image for featuring. Set to True if the
        image is dark particles on a bright background. Default is True
    minmass : Float or None, optional
        The minimum mass/masscut of a particle. Default is None, which
        calculates internally.
    use_tp : Bool, optional
        Whether or not to use trackpy. Default is False, since trackpy
        cuts out particles at the edge.

    Returns
    --------
    positions : np.ndarray [N,3]
        Positions of the particles in order (z,y,x) in image pixel units.

    Notes
    -----
    Optionally filters the image by fitting the image I(x,y,z) to a
    polynomial, then subtracts this fitted intensity variation and uses
    centroid methods to find the particles.
    """
    # We just want a smoothed field model of the image so that the residuals
    # are simply the particles without other complications
    m = models.SmoothFieldModel()
    I = ilms.LegendrePoly2P1D(order=order, constval=image.get_image().mean())
    s = states.ImageState(image, [I], pad=0, mdl=m)
    if dofilter:
        opt.do_levmarq(s, s.params)
    pos = addsub.feature_guess(s, feature_rad, trim_edge=trim_edge,
                               **kwargs)[0]
    return pos
示例#5
0
def do_fit(im, order=(15, 5, 5), maxcalls=50):
    ilm = ilms.LegendrePoly2P1D(im.shape, order=order)
    ilm.params[-order[-1]] = 1
    ilm.from_data(im, maxcalls=maxcalls)
    ilm.initialize()
    return ilm
示例#6
0
# We need to add a background. In principle, we could be use the same bkg
# that worked for our blank image. However, in practice this doesn't work so
# well, leaving noticeable residuals in z (try it!). The reason for this is
# that the point-spread function has very long, power-law tails. While the psf
# describes the image of a point fairly well, when the psf is integrated over
# the entire area of the coverslip these tails become very long, too long to
# capture with a reasonably-sized numerical psf. To account for this, we do
# some minor analytical calculations and realize that the effect of the long-
# tails of the psf when convolved with a slab looks like a background that
# varies slowly in z. Thus, to account for some of the long-tails in the psf,
# we use a background which varies in z. Since this z-dependence won't couple
# with the dark-current xy dependence in our detector, we can split this out
# as bkg = f(x,y) + g(z), like so:

bkg = ilms.LegendrePoly2P1D(order=(7, 3, 5), category='bkg', operation='+')

# This detail is important not so much for its effect on the reconstruction
# of this blank image, but for what it illustrates -- while it is practically
# impossible to implement an exact generative model, careful thinking can allow
# for a model that is almost equivalent to the exact answer. To answer how
# much this approximation matters for measuring particle properties in an,
# we could generate an image with a more exact representation of these psf
# long tails and then fit it with our more approximate model.
# Incidentally, while the support of our psf is finite, it's quite large --
# 35 pixels in z, or 44% of the image in z! If we wanted, we could increase
# this by changing the ``support_size`` keyword when calling
# exactpsf.FixedSSChebLinePSF.

# Finally, we create an offset:
off = comp.GlobalScalar('offset', 0.0)
示例#7
0
from peri.comp import objs

coverslip = objs.Slab(zpos=6)
particle_positions = numpy.load('../../Downloads/particle-positions.npy')
particle_radii = 5.0
particles = objs.PlatonicSpheresCollection(particle_positions, particle_radii)

from peri.comp import comp

objects = comp.ComponentCollection([particles, coverslip], category='obj')

from peri.comp import ilms

illumination = ilms.BarnesStreakLegPoly2P1D(npts=(16, 10, 8, 4), zorder=8)

background = ilms.LegendrePoly2P1D(order=(7, 2, 2), category='bkg')

offset = comp.GlobalScalar(name='offset', value=0.)

from peri.comp import exactpsf

point_spread_function = exactpsf.FixedSSChebLinePSF()

from peri import models

model = models.ConfocalImageModel()

print(model)

from peri import states
示例#8
0
def table():
    s = create_image(identity=True)

    lpoly = [0.0, 0.0, 0.01, 0.05, 0.10]
    dnames = ['0.0', '0.0', '0.01', '0.05', '0.10']

    lilms = [
        ilms.LegendrePoly2P1D(shape=s.ilm.shape, order=(1, 1, 1)),
        ilms.LegendrePoly2P1D(shape=s.ilm.shape, order=(3, 3, 3)),
        ilms.BarnesStreakLegPoly2P1DX3(shape=s.ilm.shape,
                                       order=(1, 1, 1),
                                       npts=(10, 5)),
        ilms.BarnesStreakLegPoly2P1DX3(shape=s.ilm.shape,
                                       order=(1, 1, 2),
                                       npts=(30, 10)),
        ilms.BarnesStreakLegPoly2P1DX3(shape=s.ilm.shape,
                                       order=s.ilm.order,
                                       npts=(30, 10, 5)),
    ]
    lnames = [
        r'Legendre 2+1D (0,0,0)',
        r'Legendre 2+1D (2,2,2)',
        r'Barnes (10, 5), $N_z=1$',
        r'Barnes (30, 10), $N_z=2$',
        r'Barnes (30, 10, 5), $N_z=3$',
    ]

    lpsfs = [
        psfs.IdentityPSF(shape=s.psf.shape, params=np.array([0.0])),
        psfs.AnisotropicGaussian(shape=s.psf.shape, params=(2.0, 1.0, 3.0)),
        psfs.Gaussian4DLegPoly(shape=s.psf.shape, order=(3, 3, 3)),
        exactpsf.FixedSSChebLinePSF(
            shape=s.psf.shape,
            zrange=(0, s.psf.shape[0]),
            cheb_degree=3,
            cheb_evals=6,
            support_size=FIXEDSS,
            zslab=10.,
            cutoffval=1. / 255,
            measurement_iterations=3,
        ),
        exactpsf.FixedSSChebLinePSF(
            shape=s.psf.shape,
            zrange=(0, s.psf.shape[0]),
            cheb_degree=6,
            cheb_evals=8,
            support_size=FIXEDSS,
            zslab=10.,
            cutoffval=1. / 255,
            measurement_iterations=3,
        ),
    ]
    pnames = [
        r'Identity',
        r'Gaussian$(x,y)$',
        r'Gaussian$(x,y,z,z^{\prime})$',
        r'Cheby linescan (3,6)',
        r'Cheby linescan (6,8)',
    ]

    results = OrderedDict()

    for i in xrange(len(lpoly)):
        print dnames[i], lnames[i], pnames[i]
        poly = lpoly[i]
        ilm = lilms[i]
        psf = lpsfs[i]

        s = create_image(polydispersity=poly)
        s.set_ilm(ilm)
        s.set_psf(psf)
        if isinstance(s.ilm, ilms.BarnesStreakLegPoly2P1DX3):
            s.ilm.randomize_parameters(ptp=0.4, vmax=1.0, fourier=False)
        s.reset()
        s.model_to_true_image()

        pos1 = trackpy(s)
        pos0 = s.obj.pos.copy()

        s.obj.set_pos_rad(pos1, s.obj.rad.mean() * np.ones(pos1.shape[0]))
        s.reset()

        slicer = s.get_difference_image().shape[0] / 2
        results[i] = (
            dnames[i],
            lnames[i],
            pnames[i],
            s.get_difference_image()[slicer].copy(),
            pos0,
            pos1,
        )

    return results
示例#9
0
from peri import states, util, models
from peri.comp import psfs, objs, ilms, GlobalScalar, ComponentCollection
from peri.test import nbody

import peri.opt.optimize as opt
import peri.opt.addsubtract as addsub

im = util.NullImage(shape=(32, ) * 3)
pos, rad, tile = nbody.create_configuration(3, im.tile)

P = ComponentCollection(
    [objs.PlatonicSpheresCollection(pos, rad),
     objs.Slab(2)], category='obj')

H = psfs.AnisotropicGaussian()
I = ilms.BarnesStreakLegPoly2P1D(npts=(25, 13, 3),
                                 zorder=2,
                                 local_updates=False)
B = ilms.LegendrePoly2P1D(order=(3, 1, 1), category='bkg', constval=0.01)
C = GlobalScalar('offset', 0.0)
I.randomize_parameters()

s = states.ImageState(im, [B, I, H, P, C], pad=16, model_as_data=True)