@register.filter()<EOL>def attachments(value, obj, width = WIDTH):

match = ATTACHMENT_REGEX.search(value)<EOL>safe = isinstance(value, (SafeString, SafeUnicode))<EOL>while not match is None and match.end() <= len(value):<EOL><INDENT>start = match.start()<EOL>end = match.end()<EOL>groups = match.groups()<EOL>if len(groups) > <NUM_LIT:0>:<EOL><INDENT>index = groups[<NUM_LIT:0>]<EOL>options = None<EOL>if len(groups) > <NUM_LIT:1>:<EOL><INDENT>options = groups[<NUM_LIT:1>]<EOL>if options:<EOL><INDENT>options = options.strip()<EOL>if options:<EOL><INDENT>try:<EOL><INDENT>options = split(smart_str(options))<EOL><DEDENT>except:<EOL><INDENT>options = None<EOL><DEDENT><DEDENT><DEDENT><DEDENT>args = []<EOL>kwargs = {<EOL>'<STR_LIT:width>': width<EOL>}<EOL>if options:<EOL><INDENT>for option in options:<EOL><INDENT>key, equals, val = option.partition('<STR_LIT:=>')<EOL>if equals != '<STR_LIT:=>':<EOL><INDENT>if key and not val:<EOL><INDENT>args.append(key)<EOL><DEDENT>continue<EOL><DEDENT>kwargs[key] = val<EOL><DEDENT><DEDENT>try:<EOL><INDENT>if isinstance(obj, dict):<EOL><INDENT>inner = Attachment(<EOL>**obj['<STR_LIT>'][int(index) - <NUM_LIT:1>]<EOL>).render(*args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>inner = obj.attachments.all()[int(index) - <NUM_LIT:1>].render(*args, **kwargs)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>inner = '<STR_LIT>'<EOL><DEDENT><DEDENT>else:<EOL><INDENT>inner = '<STR_LIT>'<EOL><DEDENT>value = value[:start] + inner + value[end:]<EOL>match = ATTACHMENT_REGEX.search(value, start + len(inner))<EOL><DEDENT>if safe:<EOL><INDENT>return mark_safe(value)<EOL><DEDENT>else:<EOL><INDENT>return value<EOL><DEDENT>

Parse the copy inside ``value`` and look for shortcodes in this format::

Here's an attachment

[attachment 1]

Replace the shortcode with a full image, video or audio element, or download link

:param obj: The object against which attachments are saved
:param width: The width of images or audio/video tags (defaults to the ``ATTACHMENT_WIDTH`` SETTING)


def aN(a, dim=<NUM_LIT:3>, dtype='<STR_LIT:int>'):

if not hasattr(a, '<STR_LIT>'):<EOL><INDENT>return np.array([a]*dim, dtype=dtype)<EOL><DEDENT>return np.array(a).astype(dtype)<EOL>

Convert an integer or iterable list to numpy array of length dim. This func
is used to allow other methods to take both scalars non-numpy arrays with
flexibility.

Parameters
----------
a : number, iterable, array-like
    The object to convert to numpy array

dim : integer
    The length of the resulting array

dtype : string or np.dtype
    Type which the resulting array should be, e.g. 'float', np.int8

Returns
-------
arr : numpy array
    Resulting numpy array of length ``dim`` and type ``dtype``

Examples
--------
>>> aN(1, dim=2, dtype='float')
array([ 1.,  1.])

>>> aN(1, dtype='int')
array([1, 1, 1])

>>> aN(np.array([1,2,3]), dtype='float')
array([ 1.,  2.,  3.])


def contains(self, items, pad=<NUM_LIT:0>):

o = ((items >= self.l-pad) & (items < self.r+pad))<EOL>if len(o.shape) == <NUM_LIT:2>:<EOL><INDENT>o = o.all(axis=-<NUM_LIT:1>)<EOL><DEDENT>elif len(o.shape) == <NUM_LIT:1>:<EOL><INDENT>o = o.all()<EOL><DEDENT>return o<EOL>

Test whether coordinates are contained within this tile.

Parameters
----------
items : ndarray [3] or [N, 3]
    N coordinates to check are within the bounds of the tile

pad : integer or ndarray [3]
    anisotropic padding to apply in the contain test

Examples
--------
>>> Tile(5, dim=2).contains([[-1, 0], [2, 3], [2, 6]])
array([False,  True, False], dtype=bool)


tiles = listify(tiles) + listify(args)<EOL>if len(tiles) < <NUM_LIT:2>:<EOL><INDENT>return tiles[<NUM_LIT:0>]<EOL><DEDENT>tile = tiles[<NUM_LIT:0>]<EOL>l, r = tile.l.copy(), tile.r.copy()<EOL>for tile in tiles[<NUM_LIT:1>:]:<EOL><INDENT>l = amin(l, tile.l)<EOL>r = amax(r, tile.r)<EOL><DEDENT>return Tile(l, r, dtype=l.dtype)<EOL>

Convex bounding box of a group of tiles

>>> Tile.boundingtile(Tile([0, 1], [5, 4]), Tile([1, 0], [4, 5]))
Tile [0, 0] -> [5, 5] ([5, 5])


if isinstance(b, (tuple, list, np.ndarray)):<EOL><INDENT>if isinstance(a, (tuple, list, np.ndarray)):<EOL><INDENT>return type(b)(a)<EOL><DEDENT>return type(b)([a])<EOL><DEDENT>else:<EOL><INDENT>if isinstance(a, (tuple, list, np.ndarray)) and len(a) == <NUM_LIT:1>:<EOL><INDENT>return a[<NUM_LIT:0>]<EOL><DEDENT>return a<EOL><DEDENT>return a<EOL>

If a single element list, extract the element as an object, otherwise
leave as it is.

Examples
--------
>>> delistify('string')
'string'

>>> delistify(['string'])
'string'

>>> delistify(['string', 'other'])
['string', 'other']

>>> delistify(np.array([1.0]))
1.0

>>> delistify([1, 2, 3])
[1, 2, 3]


def __init__(self, left, right=None, mins=None, maxs=None,<EOL>size=None, centered=False, dim=None, dtype='<STR_LIT:int>'):

self.dtype = dtype<EOL>dims = set([getdim(i) for i in [left, right, size]] + [dim])<EOL>dims = dims.difference(set([None]))<EOL>if len(dims) == <NUM_LIT:0>:<EOL><INDENT>dim = <NUM_LIT:3><EOL><DEDENT>elif len(dims) == <NUM_LIT:1>:<EOL><INDENT>dim = dims.pop()<EOL><DEDENT>elif len(dims) > <NUM_LIT:1>:<EOL><INDENT>raise AttributeError("<STR_LIT>")<EOL><DEDENT>nkw = {'<STR_LIT>': dim, '<STR_LIT>': self.dtype}<EOL>if right is None:<EOL><INDENT>if size is None:<EOL><INDENT>right = left<EOL>left = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>if not centered:<EOL><INDENT>right = aN(left, **nkw) + aN(size, **nkw)<EOL><DEDENT>else:<EOL><INDENT>l = aN(left, **nkw)<EOL>s = aN(size, **nkw)<EOL>if isint(self.dtype):<EOL><INDENT>left = l - s//<NUM_LIT:2><EOL>right = left + s<EOL><DEDENT>else:<EOL><INDENT>left, right = l - s/<NUM_LIT>, l + s/<NUM_LIT><EOL><DEDENT><DEDENT>assert np.all((right - left) == size)<EOL><DEDENT><DEDENT>left = aN(left, **nkw)<EOL>right = aN(right, **nkw)<EOL>if dim is not None:<EOL><INDENT>self.dim = dim<EOL>assert(left.shape[<NUM_LIT:0>] == dim)<EOL>assert(right.shape[<NUM_LIT:0>] == dim)<EOL><DEDENT>else:<EOL><INDENT>self.dim = left.shape[<NUM_LIT:0>]<EOL><DEDENT>if mins is not None:<EOL><INDENT>left = amax(left, aN(mins, **nkw))<EOL><DEDENT>if maxs is not None:<EOL><INDENT>right = amin(right, aN(maxs, **nkw))<EOL><DEDENT>self.l = np.array(left)<EOL>self.r = np.array(right)<EOL>self._build_caches()<EOL>

Creates a tile element which represents a hyperrectangle in D
dimensions. These hyperrectangles may be operated upon to find
intersections, bounding tiles, calculate interior coordinates
and other common operations.

Parameters
----------
left : number or array-like
    Left side of the tile

right : (optional) number or array-like
    If provided along with left, gives the right side of the tile

mins : (optional) number or array-like
    Can be provided to clip the sides of the Tile to certain minimum

maxs : (optional) number or array-like
    Can be provided to clip the sides of the Tile to certain maximum

size : (optional) number or array-like
    If provided along with left gives the size of the tile

centered : boolean
    * If true:   ``[left] - [size]/2 -> [left] + [size]/2``
    * If false:  ``[left] -> [left] + [size]``

dim : integer
    Number of dimensions for the Tile

dtype : string, np.dtype
    Resulting type of number for the Tile coordinates

Notes
-----

These parameters can be combined into many different combinations
(where [] indicates an array created from either a single number or any
iterable):

    * left : ``[0,0,0] -> [left]``
    * left, right : ``[left] -> [right]``
    * left, size (not centered) : ``[left] -> [left] + [size]``
    * left, size (yes centered) : ``[left] - [size]/2 -> [left] + [size]/2``

Each of these can be limited by using (mins, maxs) which are applied
after calculating left, right for each element:

    * ``left = max(left, [mins])``
    * ``right = min(right, [maxs])``

Since tiles are used for array slicing, they only allow integer values,
which can truncated without warning from float.

Notes on dimension. The dimensionality is determined first by the shape
of left, right, size if provided not as an integer. If it not provided there
then it is assumed to be 3D. This can be overridden by setting dim in the
arguments. For example:

    * Tile(3)         : ``[0,0,0] -> [3,3,3]``
    * Tile(3, dim=2)  : ``[0,0] -> [3,3]``
    * Tile([3])       : ``[0] -> [3]``

Examples
--------
>>> Tile(10)
Tile [0, 0, 0] -> [10, 10, 10] ([10, 10, 10])

>>> Tile([1,2])
Tile [0, 0] -> [1, 2] ([1, 2])

>>> Tile(0, size=4, centered=True)
Tile [-2, -2, -2] -> [2, 2, 2] ([4, 4, 4])

>>> Tile([-1, 0, 1], right=10, mins=0)
Tile [0, 0, 1] -> [10, 10, 10] ([10, 10, 9])

>>> Tile(10, dtype='float')
Tile [0.0, 0.0, 0.0] -> [10.0, 10.0, 10.0] ([10.0, 10.0, 10.0])


ll = np.abs(amin(self.l - tile.l, aN(<NUM_LIT:0>, dim=self.dim)))<EOL>rr = np.abs(amax(self.r - tile.r, aN(<NUM_LIT:0>, dim=self.dim)))<EOL>return ll, rr<EOL>

Get the left and right absolute overflow -- the amount of box
overhanging `tile`, can be viewed as self \\ tile (set theory relative
complement, but in a bounding sense)


def kvectors(self, norm=False, form='<STR_LIT>', real=False, shift=False):

if norm is False:<EOL><INDENT>norm = <NUM_LIT:1><EOL><DEDENT>if norm is True:<EOL><INDENT>norm = np.array(self.shape)<EOL><DEDENT>norm = aN(norm, self.dim, dtype='<STR_LIT:float>')<EOL>v = list(np.fft.fftfreq(self.shape[i])/norm[i] for i in range(self.dim))<EOL>if shift:<EOL><INDENT>v = list(np.fft.fftshift(t) for t in v)<EOL><DEDENT>if real:<EOL><INDENT>v[-<NUM_LIT:1>] = v[-<NUM_LIT:1>][:(self.shape[-<NUM_LIT:1>]+<NUM_LIT:1>)//<NUM_LIT:2>]<EOL><DEDENT>return self._format_vector(v, form=form)<EOL>

Return the kvectors associated with this tile, given the standard form
of -0.5 to 0.5. `norm` and `form` arguments arethe same as that passed to
`Tile.coords`.

Parameters
-----------
real : boolean
    whether to return kvectors associated with the real fft instead


if not isinstance(k, list):<EOL><INDENT>k = [k]<EOL><DEDENT>for i in k:<EOL><INDENT>if i in d:<EOL><INDENT>d.pop(i)<EOL><DEDENT><DEDENT>

Conditionally delete key (or list of keys) 'k' from dict 'd


mask = None<EOL>vecs = tile.coords(form='<STR_LIT>')<EOL>for v in vecs:<EOL><INDENT>v[self.slicer] = -<NUM_LIT:1><EOL>mask = mask & (v > <NUM_LIT:0>) if mask is not None else (v><NUM_LIT:0>)<EOL><DEDENT>return tuple(np.array(i).astype('<STR_LIT:int>') for i in zip(*[v[mask] for v in vecs]))<EOL>

Opposite slicer, the outer part wrt to a field


def _format_vector(self, vecs, form='<STR_LIT>'):

if form == '<STR_LIT>':<EOL><INDENT>return np.meshgrid(*vecs, indexing='<STR_LIT>')<EOL><DEDENT>elif form == '<STR_LIT>':<EOL><INDENT>vecs = np.meshgrid(*vecs, indexing='<STR_LIT>')<EOL>return np.rollaxis(np.array(np.broadcast_arrays(*vecs)),<NUM_LIT:0>,self.dim+<NUM_LIT:1>)<EOL><DEDENT>elif form == '<STR_LIT>':<EOL><INDENT>return vecs<EOL><DEDENT>else:<EOL><INDENT>return [v[self._coord_slicers[i]] for i,v in enumerate(vecs)]<EOL><DEDENT>

Format a 3d vector field in certain ways, see `coords` for a description
of each formatting method.


q = np.fft.fftn(im)<EOL>for k,v in self.filters:<EOL><INDENT>q[k] -= v<EOL><DEDENT>return np.real(np.fft.ifftn(q))<EOL>

Returns a filtered image after applying the Fourier-space filters


funcs0 = inspect.getmembers(subclass, predicate=inspect.ismethod)<EOL>funcs1 = inspect.getmembers(superclass, predicate=inspect.ismethod)<EOL>funcs1 = [f[<NUM_LIT:0>] for f in funcs1]<EOL>for name, func in funcs0:<EOL><INDENT>if name.startswith('<STR_LIT:_>'):<EOL><INDENT>continue<EOL><DEDENT>if name not in funcs1:<EOL><INDENT>continue<EOL><DEDENT>if func.__doc__ is None:<EOL><INDENT>func = getattr(subclass, name)<EOL>func.__func__.__doc__ = getattr(superclass, name).__func__.__doc__<EOL><DEDENT><DEDENT>

Apply the documentation from ``superclass`` to ``subclass`` by filling
in all overridden member function docstrings with those from the
parent class


return tuple(np.s_[l:r] for l,r in zip(*self.bounds))<EOL>

Array slicer object for this tile

>>> Tile((2,3)).slicer
(slice(0, 2, None), slice(0, 3, None))

>>> np.arange(10)[Tile((4,)).slicer]
array([0, 1, 2, 3])


tile = self.copy()<EOL>tile.l += dr<EOL>tile.r += dr<EOL>return tile<EOL>

Translate a tile by an amount dr

>>> Tile(5).translate(1)
Tile [1, 1, 1] -> [6, 6, 6] ([5, 5, 5])


self._deltas.append(time.time())<EOL>self.value = value<EOL>self._percent = <NUM_LIT> * self.value / self.num<EOL>if self.bar:<EOL><INDENT>self._bars = self._bar_symbol*int(np.round(self._percent / <NUM_LIT> * self._barsize))<EOL><DEDENT>if (len(self._deltas) < <NUM_LIT:2>) or (self._deltas[-<NUM_LIT:1>] - self._deltas[-<NUM_LIT:2>]) > <NUM_LIT>:<EOL><INDENT>self._estimate_time()<EOL>self._draw()<EOL><DEDENT>if self.value == self.num:<EOL><INDENT>self.end()<EOL><DEDENT>

Update the value of the progress and update progress bar.

Parameters
-----------
value : integer
    The current iteration of the progress


return np.prod(self.shape)<EOL>

Volume of the tile

>>> Tile(10).volume
1000

>>> Tile(np.sqrt(2), dim=2, dtype='float').volume #doctest: +ELLIPSIS
2.0000000000...


def __init__(self, filename, tile=None, invert=False, exposure=None,<EOL>float_precision=np.float64):

self.filename = filename<EOL>self.invert = invert<EOL>self.filters = None<EOL>self.exposure = exposure<EOL>if float_precision not in (np.float64, np.float32, np.float16):<EOL><INDENT>raise ValueError('<STR_LIT>' +<EOL>'<STR_LIT>')<EOL><DEDENT>self.float_precision = float_precision<EOL>image = self.load_image()<EOL>super(RawImage, self).__init__(image, tile=tile)<EOL>

An image object which stores information about desired region, exposure
compensation, color inversion, and filters to remove certain fourier
peaks.

Parameters
----------
filename : str
    Path of the image file. Recommended that you supply a relative path
    so that transfer between computers is possible, i.e. if the file is located
    at ``/home/user/data/1.tif`` then work in the directory ``/home/user/data``
    and supply the filename ``1.tif``.

tile : :class:`peri.util.Tile`
    the region of the image to crop out to use for the actual featuring, etc

invert : boolean
    Whether to invert the image.

exposure : tuple of numbers (min, max) | None
    If set, it is the values used to normalize the image. It is the
    values which map to 0 and 1 in the loaded version of the image, the
    default being for 8-bit images, mapping raw values (0, 255) to
    loaded values (0, 1). This functionality is provided since the
    noise and exposure may change between images where a common scaling
    is desired for proper comparison.  Setting this values allows a
    series of images to be initialized with the same ILM, PSF etc.
    Should be the bit value of the camera.

float_precision : numpy float datatype
    One of numpy.float16, numpy.float32, numpy.float64; precision
    for precomputed arrays. Default is np.float64; make it 16 or 32
    to save memory.


def __init__(self, num, label='<STR_LIT>', value=<NUM_LIT:0>, screen=<NUM_LIT>,<EOL>time_remaining=True, bar=True, bar_symbol='<STR_LIT:=>', bar_caps='<STR_LIT>',<EOL>bar_decimals=<NUM_LIT:2>, display=True):

<EOL>self.num = num<EOL>self.value = value<EOL>self._percent = <NUM_LIT:0><EOL>self.time_remaining = time_remaining<EOL>self._deltas = []<EOL>self.display = display<EOL>self.label = label<EOL>self.bar = bar<EOL>self._bar_symbol = bar_symbol<EOL>self._bar_caps = bar_caps<EOL>self._decimals = bar_decimals<EOL>self.screen = screen<EOL>if len(self._bar_caps) % <NUM_LIT:2> != <NUM_LIT:0>:<EOL><INDENT>raise AttributeError("<STR_LIT>")<EOL><DEDENT>if self.bar:<EOL><INDENT>self._numsize = <NUM_LIT:3> + self._decimals + <NUM_LIT:1><EOL>self._cap_len = len(self._bar_caps)//<NUM_LIT:2><EOL>self._capl = self._bar_caps[:self._cap_len]<EOL>self._capr = self._bar_caps[self._cap_len:]<EOL>self._time_space = <NUM_LIT:11> if self.time_remaining else <NUM_LIT:0><EOL>self._barsize = (<EOL>self.screen - len(self.label) - self._numsize -<EOL>len(self._bar_caps) - <NUM_LIT:2> - <NUM_LIT:1> - self._time_space<EOL>)<EOL>self._formatstr = '<STR_LIT>'<EOL>self._percent = <NUM_LIT:0><EOL>self._dt = '<STR_LIT>'<EOL>self._bars = '<STR_LIT>'<EOL>if self.time_remaining:<EOL><INDENT>self._formatstr += "<STR_LIT>"<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._digits = str(int(np.ceil(np.log10(self.num))))<EOL>self._formatstr = '<STR_LIT>'<EOL>self._dt = '<STR_LIT>'<EOL>if self.time_remaining:<EOL><INDENT>self._formatstr += "<STR_LIT>"<EOL><DEDENT><DEDENT>self.update()<EOL>

ProgressBar class which creates a dynamic ASCII progress bar of two
different varieties:

    1) A bar chart that looks like the following:
        ``Progress [================      ]  63.00%``

    2) A simple number completed look:
        ``Progress :   17 / 289``

Parameters
-----------
num : integer
    The number of tasks that need to be completed

label : string [default: 'Progress']
    The label for this particular progress indicator,

value : integer [default: 0]
    Starting value

screen : integer [default: 79]
    Size the screen to use for the progress bar

time_remaining : boolean [default: True]
    Display estimated time remaining

bar : boolean [default: True]
    Whether or not to display the bar chart

bar_symbol : char [default: '=']
    The character to use to fill in the bar chart

bar_caps : string [default: '[]']
    Characters to use as the end caps of the.  The string will be split in
    half and each half put on a side of the chart

bar_decimals : integer [default: 2]
    Number of decimal places to include in the percentage

display : boolean [default: True]
    a crutch so that we don't have a lot of ``if``s later.  display
    or don't display the progress bar


self.tile = tile<EOL>

Sets the current tile of the image to a `peri.util.Tile`


self.exposure = exposure<EOL>

Set the exposure parameter for this image, which determines the
values which get mapped to (0,1) in the output image.

See also
--------
:class:`peri.util.RawImage`


tiles = listify(tiles) + listify(args)<EOL>if len(tiles) < <NUM_LIT:2>:<EOL><INDENT>return tiles[<NUM_LIT:0>]<EOL><DEDENT>tile = tiles[<NUM_LIT:0>]<EOL>l, r = tile.l.copy(), tile.r.copy()<EOL>for tile in tiles[<NUM_LIT:1>:]:<EOL><INDENT>l = amax(l, tile.l)<EOL>r = amin(r, tile.r)<EOL><DEDENT>return Tile(l, r, dtype=l.dtype)<EOL>

Intersection of tiles, returned as a tile

>>> Tile.intersection(Tile([0, 1], [5, 4]), Tile([1, 0], [4, 5]))
Tile [1, 1] -> [4, 4] ([3, 3])


t0, t1 = scaled.min(), scaled.max()<EOL>r0, r1 = float(raw.min()), float(raw.max())<EOL>rmin = (t1*r0 - t0*r1) / (t1 - t0)<EOL>rmax = (r1 - r0) / (t1 - t0) + rmin<EOL>return (rmin, rmax)<EOL>

When given a raw image and the scaled version of the same image, it
extracts the ``exposure`` parameters associated with those images.
This is useful when

Parameters
----------
raw : array_like
    The image loaded fresh from a file

scaled : array_like
    Image scaled using :func:`peri.initializers.normalize`

Returns
-------
exposure : tuple of numbers
    Returns the exposure parameters (emin, emax) which get mapped to
    (0, 1) in the scaled image. Can be passed to
    :func:`~peri.util.RawImage.__init__`


try:<EOL><INDENT>image = initializers.load_tiff(self.filename)<EOL>image = initializers.normalize(<EOL>image, invert=self.invert, scale=self.exposure,<EOL>dtype=self.float_precision<EOL>)<EOL><DEDENT>except IOError as e:<EOL><INDENT>log.error("<STR_LIT>" % self.filename)<EOL>raise e<EOL><DEDENT>return image<EOL>

Read the file and perform any transforms to get a loaded image


if a is None:<EOL><INDENT>return []<EOL><DEDENT>elif not isinstance(a, (tuple, list, np.ndarray)):<EOL><INDENT>return [a]<EOL><DEDENT>return list(a)<EOL>

Convert a scalar ``a`` to a list and all iterables to list as well.

Examples
--------
>>> listify(0)
[0]

>>> listify([1,2,3])
[1, 2, 3]

>>> listify('a')
['a']

>>> listify(np.array([1,2,3]))
[1, 2, 3]

>>> listify('string')
['string']


def _jtj(self, funct, params=None, dl=<NUM_LIT>, rts=False, **kwargs):

grad = self._grad(funct=funct, params=params, dl=dl, rts=rts, **kwargs)<EOL>return np.dot(grad, grad.T)<EOL>

jTj of a `func` wrt to parmaeters `params`. (see _graddoc)


return self._model<EOL>


<EOL>comps = self.affected_components(params)<EOL>if len(comps) == <NUM_LIT:0>:<EOL><INDENT>return False<EOL><DEDENT>otile, itile, iotile = self.get_update_io_tiles(params, values)<EOL>if otile is None:<EOL><INDENT>return False<EOL><DEDENT>self.set_tile(otile)<EOL>oldmodel = self._model[itile.slicer].copy()<EOL>if len(comps) == <NUM_LIT:1> and self.mdl.get_difference_model(comps[<NUM_LIT:0>].category):<EOL><INDENT>comp = comps[<NUM_LIT:0>]<EOL>model0 = copy.deepcopy(comp.get())<EOL>super(ImageState, self).update(params, values)<EOL>model1 = copy.deepcopy(comp.get())<EOL>diff = model1 - model0<EOL>diff = self.mdl.evaluate(<EOL>self.comps, '<STR_LIT>', diffmap={comp.category: diff}<EOL>)<EOL>if isinstance(model0, (float, int)):<EOL><INDENT>self._model[itile.slicer] += diff<EOL><DEDENT>else:<EOL><INDENT>self._model[itile.slicer] += diff[iotile.slicer]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>super(ImageState, self).update(params, values)<EOL>diff = self.mdl.evaluate(self.comps, '<STR_LIT>')<EOL>self._model[itile.slicer] = diff[iotile.slicer]<EOL><DEDENT>newmodel = self._model[itile.slicer].copy()<EOL>self.update_from_model_change(oldmodel, newmodel, itile)<EOL>return True<EOL>

Actually perform an image (etc) update based on a set of params and
values. These parameter can be any present in the components in any
number. If there is only one component affected then difference image
updates will be employed.


def _calc_loglikelihood(self, model=None, tile=None):

if model is None:<EOL><INDENT>res = self.residuals<EOL><DEDENT>else:<EOL><INDENT>res = model - self._data[tile.slicer]<EOL><DEDENT>sig, isig = self.sigma, <NUM_LIT:1.0>/self.sigma<EOL>nlogs = -np.log(np.sqrt(<NUM_LIT:2>*np.pi)*sig)*res.size<EOL>return -<NUM_LIT:0.5>*isig*isig*np.dot(res.flat, res.flat) + nlogs<EOL>

Allows for fast local updates of log-likelihood


def __init__(self, image, comps, mdl=models.ConfocalImageModel(), sigma=<NUM_LIT>,<EOL>priors=None, pad=<NUM_LIT>, model_as_data=False):

self.dim = image.get_image().ndim<EOL>self.sigma = sigma<EOL>self.priors = priors<EOL>self.pad = util.aN(pad, dim=self.dim)<EOL>self.model_as_data = model_as_data<EOL>comp.ComponentCollection.__init__(self, comps=comps)<EOL>self.set_model(mdl=mdl)<EOL>self.set_image(image)<EOL>self.build_funcs()<EOL>if self.model_as_data:<EOL><INDENT>self.model_to_data(self.sigma)<EOL><DEDENT>

The state object to create a confocal image.  The model is that of
a spatially varying illumination field, from which platonic particle
shapes are subtracted.  This is then spread with a point spread function
(PSF).

Parameters
-----------
image : :class:`peri.util.Image` object
    The raw image with which to compare the model image from this
    class.  This image should have been prepared through
    prepare_for_state, which does things such as padding necessary for
    this class. In the case of the RawImage, paths are used to keep
    track of the image object to save on pickle size.

comp : list of :class:`peri.comp.comp.Component` or :class:`peri.comp.comp.ComponentCollection`
    Components used to make up the model image. Each separate component
    must be of a different category, otherwise combining them would be
    ambiguous. If you desire multiple Components of one category,
    combine them using a ComponentCollection (which has functions for
    combining) and supply that to the comps list.

    The component types must match the list of categories in the
    ``ImageState.catmap`` which tells how components are matched to
    parts of the model equation.

mdl : :class:`peri.models.Model` object
    Model defining how to combine different Components into a single
    model.

priors: list of ``peri.priors`` [default: ()]
    Whether or not to turn on overlap priors using neighborlists

pad : integer or tuple of integers (optional)
    No recommended to set by hand.  The padding level of the raw image
    needed by the PSF support.

model_as_data : boolean
    Whether to use the model image as the true image after initializing


params, values = self.stack.pop()<EOL>self.update(params, values)<EOL>

Pop the last update from the stack push by
:func:`peri.states.States.push_update` by undoing the chnage last
performed.


if isinstance(image, np.ndarray):<EOL><INDENT>image = util.Image(image)<EOL><DEDENT>if isinstance(image, util.NullImage):<EOL><INDENT>self.model_as_data = True<EOL><DEDENT>else:<EOL><INDENT>self.model_as_data = False<EOL><DEDENT>self.image = image<EOL>self._data = self.image.get_padded_image(self.pad)<EOL>self.oshape = util.Tile(self._data.shape)<EOL>self.ishape = self.oshape.pad(-self.pad)<EOL>self.inner = self.ishape.slicer<EOL>for c in self.comps:<EOL><INDENT>c.set_shape(self.oshape, self.ishape)<EOL><DEDENT>self._model = np.zeros(self._data.shape, dtype=np.float64)<EOL>self._residuals = np.zeros(self._data.shape, dtype=np.float64)<EOL>self.calculate_model()<EOL>

Update the current comparison (real) image


def save(state, filename=None, desc='<STR_LIT>', extra=None):

if isinstance(state.image, util.RawImage):<EOL><INDENT>desc = desc or '<STR_LIT>'<EOL>filename = filename or state.image.filename + '<STR_LIT>' + desc + '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>if not filename:<EOL><INDENT>raise AttributeError("<STR_LIT>")<EOL><DEDENT><DEDENT>if extra is None:<EOL><INDENT>save = state<EOL><DEDENT>else:<EOL><INDENT>save = [state] + extra<EOL><DEDENT>if os.path.exists(filename):<EOL><INDENT>ff = "<STR_LIT>".format(filename)<EOL>if os.path.exists(ff):<EOL><INDENT>os.remove(ff)<EOL><DEDENT>os.rename(filename, ff)<EOL><DEDENT>pickle.dump(save, open(filename, '<STR_LIT:wb>'), protocol=<NUM_LIT:2>)<EOL>

Save the current state with extra information (for example samples and LL
from the optimization procedure).

Parameters
----------
state : peri.states.ImageState
    the state object which to save

filename : string
    if provided, will override the default that is constructed based on
    the state's raw image file.  If there is no filename and the state has
    a RawImage, the it is saved to RawImage.filename + "-peri-save.pkl"

desc : string
    if provided, will augment the default filename to be
    RawImage.filename + '-peri-' + desc + '.pkl'

extra : list of pickleable objects
    if provided, will be saved with the state


self.hyper_parameters.update(params, values)<EOL>

Update any single hyper parameter or group of parameters ``params``
with ``values``.

Parameters
----------
params : string or list of strings
    Parameter names which to update

value : number or list of numbers
    Values of those parameters which to update


def crb(self, params=None, *args, **kwargs):

fish = self.fisherinformation(params=params, *args, **kwargs)<EOL>return np.sqrt(np.diag(np.linalg.inv(fish))) * self.sigma<EOL>

Calculate the diagonal elements of the minimum covariance of the model
with respect to parameters params. ``*args`` and ``**kwargs`` go to
``fisherinformation``.


for c in self.comps:<EOL><INDENT>if c.category == name:<EOL><INDENT>return c<EOL><DEDENT><DEDENT>return None<EOL>


pass<EOL>

Class property: the current model fit to the data. Should return a
number or ndarray. Ideally this object should be an object updated by
the :func:`peri.states.State.update` function and simply returned in
this property


return self._model[self.inner]<EOL>


def _grad_one_param(self, funct, p, dl=<NUM_LIT>, rts=False, nout=<NUM_LIT:1>, **kwargs):

vals = self.get_values(p)<EOL>f0 = funct(**kwargs)<EOL>self.update(p, vals+dl)<EOL>f1 = funct(**kwargs)<EOL>if rts:<EOL><INDENT>self.update(p, vals)<EOL><DEDENT>if nout == <NUM_LIT:1>:<EOL><INDENT>return (f1 - f0) / dl<EOL><DEDENT>else:<EOL><INDENT>return [(f1[i] - f0[i]) / dl for i in range(nout)]<EOL><DEDENT>

Gradient of `func` wrt a single parameter `p`. (see _graddoc)


r = self.residuals.ravel()<EOL>return np.dot(r,r)<EOL>

Class property: Sum of the squared errors,
:math:`E = \sum_i (D_i - M_i(\\theta))^2`


def _hess_two_param(self, funct, p0, p1, dl=<NUM_LIT>, rts=False, **kwargs):

vals0 = self.get_values(p0)<EOL>vals1 = self.get_values(p1)<EOL>f00 = funct(**kwargs)<EOL>self.update(p0, vals0+dl)<EOL>f10 = funct(**kwargs)<EOL>self.update(p1, vals1+dl)<EOL>f11 = funct(**kwargs)<EOL>self.update(p0, vals0)<EOL>f01 = funct(**kwargs)<EOL>if rts:<EOL><INDENT>self.update(p0, vals0)<EOL>self.update(p1, vals1)<EOL><DEDENT>return (f11 - f10 - f01 + f00) / (dl**<NUM_LIT:2>)<EOL>

Hessian of `func` wrt two parameters `p0` and `p1`. (see _graddoc)


def _grad(self, funct, params=None, dl=<NUM_LIT>, rts=False, nout=<NUM_LIT:1>, out=None,<EOL>**kwargs):

if params is None:<EOL><INDENT>params = self.param_all()<EOL><DEDENT>ps = util.listify(params)<EOL>f0 = funct(**kwargs)<EOL>calc_shape = (<EOL>lambda ar: (len(ps),) + (ar.shape if isinstance(<EOL>ar, np.ndarray) else (<NUM_LIT:1>,)))<EOL>if out is not None:<EOL><INDENT>grad = out  <EOL><DEDENT>elif nout == <NUM_LIT:1>:<EOL><INDENT>shape = calc_shape(f0)<EOL>grad = np.zeros(shape)  <EOL><DEDENT>else:<EOL><INDENT>shape = [calc_shape(f0[i]) for i in range(nout)]<EOL>grad = [np.zeros(shp) for shp in shape]<EOL><DEDENT>for i, p in enumerate(ps):<EOL><INDENT>if nout == <NUM_LIT:1>:<EOL><INDENT>grad[i] = self._grad_one_param(funct, p, dl=dl, rts=rts,<EOL>nout=nout, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>stuff = self._grad_one_param(funct, p, dl=dl, rts=rts,<EOL>nout=nout, **kwargs)<EOL>for a in range(nout): grad[a][i] = stuff[a]<EOL><DEDENT><DEDENT>return grad<EOL>

Gradient of `func` wrt a set of parameters params. (see _graddoc)


im = self.model.copy()<EOL>im += sigma*np.random.randn(*im.shape)<EOL>self.set_image(util.NullImage(image=im))<EOL>

Switch out the data for the model's recreation of the data.


def volume_render(field, outfile, maxopacity=<NUM_LIT:1.0>, cmap='<STR_LIT>',<EOL>size=<NUM_LIT>, elevation=<NUM_LIT>, azimuth=<NUM_LIT>, bkg=(<NUM_LIT:0.0>, <NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>opacitycut=<NUM_LIT>, offscreen=False, rayfunction='<STR_LIT>'):

sh = field.shape<EOL>dataImporter = vtk.vtkImageImport()<EOL>dataImporter.SetDataScalarTypeToUnsignedChar()<EOL>data_string = field.tostring()<EOL>dataImporter.SetNumberOfScalarComponents(<NUM_LIT:1>)<EOL>dataImporter.CopyImportVoidPointer(data_string, len(data_string))<EOL>dataImporter.SetDataExtent(<NUM_LIT:0>, sh[<NUM_LIT:2>]-<NUM_LIT:1>, <NUM_LIT:0>, sh[<NUM_LIT:1>]-<NUM_LIT:1>, <NUM_LIT:0>, sh[<NUM_LIT:0>]-<NUM_LIT:1>)<EOL>dataImporter.SetWholeExtent(<NUM_LIT:0>, sh[<NUM_LIT:2>]-<NUM_LIT:1>, <NUM_LIT:0>, sh[<NUM_LIT:1>]-<NUM_LIT:1>, <NUM_LIT:0>, sh[<NUM_LIT:0>]-<NUM_LIT:1>)<EOL>alphaChannelFunc = vtk.vtkPiecewiseFunction()<EOL>alphaChannelFunc.AddPoint(<NUM_LIT:0>, <NUM_LIT:0.0>)<EOL>alphaChannelFunc.AddPoint(int(<NUM_LIT:255>*opacitycut), maxopacity)<EOL>volumeProperty = vtk.vtkVolumeProperty()<EOL>colorFunc = cmap2colorfunc(cmap)<EOL>volumeProperty.SetColor(colorFunc)<EOL>volumeProperty.SetScalarOpacity(alphaChannelFunc)<EOL>volumeMapper = vtk.vtkVolumeRayCastMapper()<EOL>if rayfunction == '<STR_LIT>':<EOL><INDENT>comp = vtk.vtkVolumeRayCastMIPFunction()<EOL>comp.SetMaximizeMethodToOpacity()<EOL><DEDENT>elif rayfunction == '<STR_LIT>':<EOL><INDENT>comp = vtk.vtkVolumeRayCastCompositeFunction()<EOL><DEDENT>elif rayfunction == '<STR_LIT>':<EOL><INDENT>comp = vtk.vtkVolumeRayCastIsosurfaceFunction()<EOL>comp.SetIsoValue(maxopacity/<NUM_LIT:2>)<EOL><DEDENT>else:<EOL><INDENT>comp = vtk.vtkVolumeRayCastIsosurfaceFunction()<EOL><DEDENT>volumeMapper.SetSampleDistance(<NUM_LIT:0.1>)<EOL>volumeMapper.SetVolumeRayCastFunction(comp)<EOL>if rayfunction == '<STR_LIT>':<EOL><INDENT>volumeMapper = vtk.vtkSmartVolumeMapper()<EOL><DEDENT>volumeMapper.SetInputConnection(dataImporter.GetOutputPort())<EOL>volume = vtk.vtkVolume()<EOL>volume.SetMapper(volumeMapper)<EOL>volume.SetProperty(volumeProperty)<EOL>light = vtk.vtkLight()<EOL>light.SetLightType(vtk.VTK_LIGHT_TYPE_HEADLIGHT)<EOL>light.SetIntensity(<NUM_LIT>)<EOL>light.SwitchOn()<EOL>renderer = vtk.vtkRenderer()<EOL>renderWin = vtk.vtkRenderWindow()<EOL>renderWin.AddRenderer(renderer)<EOL>renderWin.SetOffScreenRendering(<NUM_LIT:1>);<EOL>if not hasattr(size, '<STR_LIT>'):<EOL><INDENT>size = (size, size)<EOL><DEDENT>renderer.AddVolume(volume)<EOL>renderer.AddLight(light)<EOL>renderer.SetBackground(*bkg)<EOL>renderWin.SetSize(*size)<EOL>if offscreen:<EOL><INDENT>renderWin.SetOffScreenRendering(<NUM_LIT:1>)<EOL><DEDENT>def exitCheck(obj, event):<EOL><INDENT>if obj.GetEventPending() != <NUM_LIT:0>:<EOL><INDENT>obj.SetAbortRender(<NUM_LIT:1>)<EOL><DEDENT><DEDENT>renderWin.AddObserver("<STR_LIT>", exitCheck)<EOL>renderInteractor = vtk.vtkRenderWindowInteractor()<EOL>renderInteractor.Initialize()<EOL>renderWin.Render()<EOL>renderInteractor.Start()<EOL>writer = vtk.vtkPNGWriter()<EOL>w2i = vtk.vtkWindowToImageFilter()<EOL>w2i.SetInput(renderWin)<EOL>writer.SetInputConnection(w2i.GetOutputPort())<EOL>renderWin.Render()<EOL>ac = renderer.GetActiveCamera()<EOL>ac.Elevation(elevation)<EOL>ac.Azimuth(azimuth)<EOL>renderer.ResetCameraClippingRange()<EOL>renderWin.Render()<EOL>w2i.Modified()<EOL>writer.SetFileName(outfile)<EOL>writer.Write()<EOL>

Uses vtk to make render an image of a field, with control over the
camera angle and colormap.

Input Parameters
----------------
    field : np.ndarray
        3D array of the field to render.
    outfile : string
        The save name of the image.
    maxopacity : Float
        Default is 1.0
    cmap : matplotlib colormap string
        Passed to cmap2colorfunc. Default is bone.
    size : 2-element list-like of ints or Int
        The size of the final rendered image.
    elevation : Numeric
        The elevation of the camera angle, in degrees. Default is 45
    azimuth : Numeric
        The azimuth of the camera angle, in degrees. Default is 45
    bkg : Tuple of floats
        3-element tuple of floats on [0,1] of the background image color.
        Default is (0., 0., 0.).


def norm(field, vmin=<NUM_LIT:0>, vmax=<NUM_LIT:255>):

field = <NUM_LIT:255>*np.clip(field, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>field = field.astype('<STR_LIT>')<EOL>return field<EOL>

Truncates field to 0,1; then normalizes to a uin8 on [0,255]


es, pp = field.split('<STR_LIT:->')  <EOL>if pp == '<STR_LIT>':<EOL><INDENT>o = state.get('<STR_LIT>')<EOL>if isinstance(o, peri.comp.comp.ComponentCollection):<EOL><INDENT>wts = <NUM_LIT:0>*o.get()[state.inner]<EOL>for c in o.comps:<EOL><INDENT>if isinstance(c, peri.comp.objs.PlatonicSpheresCollection):<EOL><INDENT>wts += c.get()[state.inner]<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>wts = o.get()[state.inner]<EOL><DEDENT><DEDENT>elif pp == '<STR_LIT>':<EOL><INDENT>wts = state.get('<STR_LIT>').get()[state.inner]<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if es == '<STR_LIT>':<EOL><INDENT>out = (<NUM_LIT:1>-state.data) * (wts > <NUM_LIT>)<EOL><DEDENT>elif es == '<STR_LIT>':<EOL><INDENT>out = wts<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return norm(clip(roll(out)))<EOL>

Given a state, extracts a field. Extracted value depends on the value
of field:
    'exp-particles' : The inverted data in the regions of the particles,
            zeros otherwise -- i.e. particles + noise.
    'exp-platonic'  : Same as above, but nonzero in the region of the
            entire platonic image -- i.e. platonic + noise.
    'sim-particles' : Just the particles image; no noise from the data.
    'sim-platonic'  : Just the platonic image; no noise from the data.


def make_clean_figure(figsize, remove_tooltips=False, remove_keybindings=False):

tooltip = mpl.rcParams['<STR_LIT>']<EOL>if remove_tooltips:<EOL><INDENT>mpl.rcParams['<STR_LIT>'] = '<STR_LIT:None>'<EOL><DEDENT>fig = pl.figure(figsize=figsize)<EOL>mpl.rcParams['<STR_LIT>'] = tooltip<EOL>if remove_keybindings:<EOL><INDENT>fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id)<EOL><DEDENT>return fig<EOL>

Makes a `matplotlib.pyplot.Figure` without tooltips or keybindings

Parameters
----------
figsize : tuple
    Figsize as passed to `matplotlib.pyplot.figure`
remove_tooltips, remove_keybindings : bool
    Set to True to remove the tooltips bar or any key bindings,
    respectively. Default is False

Returns
-------
fig : `matplotlib.pyplot.Figure`


def __init__(self, field, onesided=True, vmin=None, vmax=None, cmap=None,<EOL>dohist=False, fourier=False, tooltips=False, size=<NUM_LIT:8>):

self.vmin = vmin<EOL>self.vmax = vmax<EOL>self.field = field<EOL>self.onesided = onesided<EOL>self.dohist = dohist<EOL>self.fourier = fourier<EOL>if cmap is not None:<EOL><INDENT>self.cmap = cmap<EOL><DEDENT>else:<EOL><INDENT>self.cmap = '<STR_LIT>' if self.onesided else '<STR_LIT>'<EOL><DEDENT>z,y,x = [float(i) for i in self.field.shape]<EOL>w = float(x + z)<EOL>h = float(y + z)<EOL>self.fig = make_clean_figure(<EOL>figsize=(size * w/h, size), remove_tooltips=not tooltips,<EOL>remove_keybindings=True)<EOL>self.g = {}<EOL>self.g['<STR_LIT>'] = self.fig.add_axes((<NUM_LIT:0.0>, <NUM_LIT:1>-y/h, x/w,   y/h))<EOL>self.g['<STR_LIT>'] = self.fig.add_axes((<NUM_LIT:0.0>, <NUM_LIT:0.0>,   x/w,   <NUM_LIT:1>-y/h))<EOL>self.g['<STR_LIT>'] = self.fig.add_axes((x/w, <NUM_LIT:1>-y/h, <NUM_LIT:1>-x/w, y/h))<EOL>self.g['<STR_LIT>'] = self.fig.add_axes((x/w, <NUM_LIT:0.0>,   <NUM_LIT:1>-x/w, <NUM_LIT:1>-y/h))<EOL>self.slices = (np.array(self.field.shape)/<NUM_LIT:2>).astype('<STR_LIT:int>')<EOL>if self.fourier:<EOL><INDENT>self.field = np.fft.fftshift(np.fft.fftn(self.field))<EOL><DEDENT>self.draw()<EOL>self.register_events()<EOL>

Easy interactive viewing of 3D ndarray with view selection.

Navigate in 3D by clicking on the three panels which are slices
through the array at a given position.

Parameters
----------
field : np.ndarray
    The field to view
onesided : bool, optional
    Whether to use the default one-sided or two-sided colormap.
    Over-ridden by cmap. Default is True
vmin, vmax : numeric, optional
    The min, max colorbar range, as passed to the matplotlib
    colormap. Default is the (min, max) of the data.
cmap : {None, valid matplotlib colormap}, optional
    Use to directly a specific colormap, e.g. `'bone'`. If None
    selects `'bone' if onesided else 'RdBu'`. Default is None
dohist : bool, optional
    Set to True to include a histogram of `field` in an
    additional panel. Default is False
fourier : bool, optional
    Set to True to view the Fourier transform of field. Default
    is False
tooltips : bool, optional
    Whether to include the tooltips bar on the figure. Default
    is False
size : numeric, optional
    The rough figure size of the viewer; the actual size is re-
    scaled based on the field's size. Default is 8


def _particle_func(self, coords, pos, wid):

dx, dy, dz = [c - p for c,p in zip(coords, pos)]<EOL>dr2 = dx*dx + dy*dy + dz*dz<EOL>return np.exp(-dr2/(<NUM_LIT:2>*wid*wid))<EOL>

Draws a gaussian, range is (0,1]. Coords = [3,n]


<EOL>dp = self.pos - p<EOL>dist2 = (dp*dp).sum(axis=<NUM_LIT:1>)<EOL>ind = dist2.argmin()<EOL>rp = self.pos[ind].copy()<EOL>self.pos = np.delete(self.pos, ind, axis=<NUM_LIT:0>)<EOL>return rp<EOL>

removes the closest particle in self.pos to ``p``


m = np.clip(self.particle_field, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>part_color = np.zeros(self._image.shape)<EOL>for a in range(<NUM_LIT:4>): part_color[:,:,:,a] = self.part_col[a]<EOL>self.field = np.zeros(self._image.shape)<EOL>for a in range(<NUM_LIT:4>):<EOL><INDENT>self.field[:,:,:,a] = m*part_color[:,:,:,a] + (<NUM_LIT:1>-m) * self._image[:,:,:,a]<EOL><DEDENT>


ans = data - vmin<EOL>ans /= (vmax - vmin)<EOL>return np.clip(ans, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>

Clips data on [vmin, vmax]; then rescales to [0,1]


def crb_compare(state0, samples0, state1, samples1, crb0=None, crb1=None,<EOL>zlayer=None, xlayer=None):

s0 = state0<EOL>s1 = state1<EOL>h0 = np.array(samples0)<EOL>h1 = np.array(samples1)<EOL>slicez = zlayer or s0.image.shape[<NUM_LIT:0>]//<NUM_LIT:2><EOL>slicex = xlayer or s0.image.shape[<NUM_LIT:2>]//<NUM_LIT:2><EOL>slicer1 = np.s_[slicez,s0.pad:-s0.pad,s0.pad:-s0.pad]<EOL>slicer2 = np.s_[s0.pad:-s0.pad,s0.pad:-s0.pad,slicex]<EOL>center = (slicez, s0.image.shape[<NUM_LIT:1>]//<NUM_LIT:2>, slicex)<EOL>mu0 = h0.mean(axis=<NUM_LIT:0>)<EOL>mu1 = h1.mean(axis=<NUM_LIT:0>)<EOL>std0 = h0.std(axis=<NUM_LIT:0>)<EOL>std1 = h1.std(axis=<NUM_LIT:0>)<EOL>mask0 = (s0.state[s0.b_typ]==<NUM_LIT:1.>) & (<EOL>analyze.trim_box(s0, mu0[s0.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)))<EOL>mask1 = (s1.state[s1.b_typ]==<NUM_LIT:1.>) & (<EOL>analyze.trim_box(s1, mu1[s1.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)))<EOL>active0 = np.arange(s0.N)[mask0]<EOL>active1 = np.arange(s1.N)[mask1]<EOL>pos0 = mu0[s0.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)[active0]<EOL>pos1 = mu1[s1.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)[active1]<EOL>rad0 = mu0[s0.b_rad][active0]<EOL>rad1 = mu1[s1.b_rad][active1]<EOL>link = analyze.nearest(pos0, pos1)<EOL>dpos = pos0 - pos1[link]<EOL>drad = rad0 - rad1[link]<EOL>drift = dpos.mean(axis=<NUM_LIT:0>)<EOL>log.info('<STR_LIT>'.format(drift))<EOL>dpos -= drift<EOL>fig = pl.figure(figsize=(<NUM_LIT>,<NUM_LIT:10>))<EOL>gs0 = ImageGrid(fig, rect=[<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>], nrows_ncols=(<NUM_LIT:2>,<NUM_LIT:3>), axes_pad=<NUM_LIT:0.1>)<EOL>lbl(gs0[<NUM_LIT:0>], '<STR_LIT:A>')<EOL>for i,slicer in enumerate([slicer1, slicer2]):<EOL><INDENT>ax_real = gs0[<NUM_LIT:3>*i+<NUM_LIT:0>]<EOL>ax_fake = gs0[<NUM_LIT:3>*i+<NUM_LIT:1>]<EOL>ax_diff = gs0[<NUM_LIT:3>*i+<NUM_LIT:2>]<EOL>diff0 = s0.get_model_image() - s0.image<EOL>diff1 = s1.get_model_image() - s1.image<EOL>a = (s0.image - s1.image)<EOL>b = (s0.get_model_image() - s1.get_model_image())<EOL>c = (diff0 - diff1)<EOL>ptp = <NUM_LIT>*max([np.abs(a).max(), np.abs(b).max(), np.abs(c).max()])<EOL>cmap = pl.cm.RdBu_r<EOL>ax_real.imshow(a[slicer], cmap=cmap, vmin=-ptp, vmax=ptp)<EOL>ax_real.set_xticks([])<EOL>ax_real.set_yticks([])<EOL>ax_fake.imshow(b[slicer], cmap=cmap, vmin=-ptp, vmax=ptp)<EOL>ax_fake.set_xticks([])<EOL>ax_fake.set_yticks([])<EOL>ax_diff.imshow(c[slicer], cmap=cmap, vmin=-ptp, vmax=ptp)<EOL>ax_diff.set_xticks([])<EOL>ax_diff.set_yticks([])<EOL>if i == <NUM_LIT:0>:<EOL><INDENT>ax_real.set_title(r"<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_fake.set_title(r"<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_diff.set_title(r"<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_real.set_ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>ax_real.set_ylabel('<STR_LIT>')<EOL><DEDENT><DEDENT>gs1 = GridSpec(<NUM_LIT:1>,<NUM_LIT:3>, left=<NUM_LIT>, bottom=<NUM_LIT>, right=<NUM_LIT>, top=<NUM_LIT>,<EOL>wspace=<NUM_LIT>, hspace=<NUM_LIT>)<EOL>spos0 = std0[s0.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)[active0]<EOL>spos1 = std1[s1.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)[active1]<EOL>srad0 = std0[s0.b_rad][active0]<EOL>srad1 = std1[s1.b_rad][active1]<EOL>def hist(ax, vals, bins, *args, **kwargs):<EOL><INDENT>y,x = np.histogram(vals, bins=bins)<EOL>x = (x[<NUM_LIT:1>:] + x[:-<NUM_LIT:1>])/<NUM_LIT:2><EOL>y /= len(vals)<EOL>ax.plot(x,y, *args, **kwargs)<EOL><DEDENT>def pp(ind, tarr, tsim, tcrb, var='<STR_LIT:x>'):<EOL><INDENT>bins = <NUM_LIT:10>**np.linspace(-<NUM_LIT:3>, <NUM_LIT:0.0>, <NUM_LIT:30>)<EOL>bin2 = <NUM_LIT:10>**np.linspace(-<NUM_LIT:3>, <NUM_LIT:0.0>, <NUM_LIT:100>)<EOL>bins = np.linspace(<NUM_LIT:0.0>, <NUM_LIT>, <NUM_LIT:30>)<EOL>bin2 = np.linspace(<NUM_LIT:0.0>, <NUM_LIT>, <NUM_LIT:100>)<EOL>xlim = (<NUM_LIT:0.0>, <NUM_LIT>)<EOL>ylim = (<NUM_LIT>, <NUM_LIT:30>)<EOL>ticks = ticker.FuncFormatter(lambda x, pos: '<STR_LIT>'.format(np.log10(x)))<EOL>scaler = lambda x: x <EOL>ax_crb = pl.subplot(gs1[<NUM_LIT:0>,ind])<EOL>ax_crb.hist(scaler(np.abs(tarr)), bins=bins,<EOL>normed=True, alpha=<NUM_LIT>, histtype='<STR_LIT>', lw=<NUM_LIT:1>)<EOL>ax_crb.hist(scaler(np.abs(tcrb)).ravel(), bins=bin2,<EOL>normed=True, alpha=<NUM_LIT:1.0>, histtype='<STR_LIT>', ls='<STR_LIT>', lw=<NUM_LIT>, color='<STR_LIT:k>')<EOL>ax_crb.hist(scaler(np.abs(tsim).ravel()), bins=bin2,<EOL>normed=True, alpha=<NUM_LIT:1.0>, histtype='<STR_LIT>', lw=<NUM_LIT:3>)<EOL>ax_crb.set_xlabel(r"<STR_LIT>" % (var,var), fontsize=<NUM_LIT>)<EOL>ax_crb.set_xlim(xlim)<EOL>ax_crb.grid(b=False, which='<STR_LIT>', axis='<STR_LIT>')<EOL>if ind == <NUM_LIT:0>:<EOL><INDENT>lbl(ax_crb, '<STR_LIT:B>')<EOL>ax_crb.set_ylabel(r"<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>ax_crb.set_yticks([])<EOL><DEDENT>ax_crb.locator_params(axis='<STR_LIT:x>', nbins=<NUM_LIT:3>)<EOL><DEDENT>f,g = <NUM_LIT>, <NUM_LIT><EOL>sim = f*sim_crb_diff(spos0[:,<NUM_LIT:1>], spos1[:,<NUM_LIT:1>][link])<EOL>crb = g*sim_crb_diff(crb0[<NUM_LIT:0>][:,<NUM_LIT:1>][active0], crb1[<NUM_LIT:0>][:,<NUM_LIT:1>][active1][link])<EOL>pp(<NUM_LIT:0>, dpos[:,<NUM_LIT:1>], sim, crb, '<STR_LIT:x>')<EOL>sim = f*sim_crb_diff(spos0[:,<NUM_LIT:0>], spos1[:,<NUM_LIT:0>][link])<EOL>crb = g*sim_crb_diff(crb0[<NUM_LIT:0>][:,<NUM_LIT:0>][active0], crb1[<NUM_LIT:0>][:,<NUM_LIT:0>][active1][link])<EOL>pp(<NUM_LIT:1>, dpos[:,<NUM_LIT:0>], sim, crb, '<STR_LIT:z>')<EOL>sim = f*sim_crb_diff(srad0, srad1[link])<EOL>crb = g*sim_crb_diff(crb0[<NUM_LIT:1>][active0], crb1[<NUM_LIT:1>][active1][link])<EOL>pp(<NUM_LIT:2>, drad, sim, crb, '<STR_LIT:a>')<EOL>gs2 = GridSpec(<NUM_LIT:2>,<NUM_LIT:2>, left=<NUM_LIT>, bottom=<NUM_LIT>, right=<NUM_LIT>, top=<NUM_LIT>,<EOL>wspace=<NUM_LIT>, hspace=<NUM_LIT>)<EOL>ax_hist = pl.subplot(gs2[<NUM_LIT:0>,<NUM_LIT:0>])<EOL>ax_hist.hist(std0[s0.b_pos], bins=np.logspace(-<NUM_LIT>, <NUM_LIT:0>, <NUM_LIT:50>), alpha=<NUM_LIT>, label='<STR_LIT>', histtype='<STR_LIT>')<EOL>ax_hist.hist(std0[s0.b_rad], bins=np.logspace(-<NUM_LIT>, <NUM_LIT:0>, <NUM_LIT:50>), alpha=<NUM_LIT>, label='<STR_LIT>', histtype='<STR_LIT>')<EOL>ax_hist.set_xlim((<NUM_LIT:10>**-<NUM_LIT>, <NUM_LIT:1>))<EOL>ax_hist.semilogx()<EOL>ax_hist.set_xlabel(r"<STR_LIT>")<EOL>ax_hist.set_ylabel(r"<STR_LIT>")<EOL>ax_hist.legend(loc='<STR_LIT>')<EOL>lbl(ax_hist, '<STR_LIT:C>')<EOL>imdiff = ((s0.get_model_image() - s0.image)/s0._sigma_field)[s0.image_mask==<NUM_LIT:1.>].ravel()<EOL>mu = imdiff.mean()<EOL>x = np.linspace(-<NUM_LIT:5>,<NUM_LIT:5>,<NUM_LIT>)<EOL>ax_diff = pl.subplot(gs2[<NUM_LIT:0>,<NUM_LIT:1>])<EOL>ax_diff.plot(x, <NUM_LIT:1.0>/np.sqrt(<NUM_LIT:2>*np.pi) * np.exp(-(x-mu)**<NUM_LIT:2> / <NUM_LIT:2>), '<STR_LIT:->', alpha=<NUM_LIT>, color='<STR_LIT:k>', lw=<NUM_LIT:2>)<EOL>ax_diff.hist(imdiff, bins=<NUM_LIT:1000>, histtype='<STR_LIT>', alpha=<NUM_LIT>, normed=True)<EOL>ax_diff.semilogy()<EOL>ax_diff.set_ylabel(r"<STR_LIT>")<EOL>ax_diff.set_xlabel(r"<STR_LIT>")<EOL>ax_diff.locator_params(axis='<STR_LIT:x>', nbins=<NUM_LIT:5>)<EOL>ax_diff.grid(b=False, which='<STR_LIT>', axis='<STR_LIT:y>')<EOL>ax_diff.set_xlim(-<NUM_LIT:5>, <NUM_LIT:5>)<EOL>ax_diff.set_ylim(<NUM_LIT>, <NUM_LIT>)<EOL>lbl(ax_diff, '<STR_LIT:D>')<EOL>pos = mu0[s0.b_pos].reshape(-<NUM_LIT:1>,<NUM_LIT:3>)<EOL>rad = mu0[s0.b_rad]<EOL>mask = analyze.trim_box(s0, pos)<EOL>pos = pos[mask]<EOL>rad = rad[mask]<EOL>gx, gy = analyze.gofr(pos, rad, mu0[s0.b_zscale][<NUM_LIT:0>], resolution=<NUM_LIT>,mask_start=<NUM_LIT:0.5>)<EOL>mask = gx < <NUM_LIT:5><EOL>gx = gx[mask]<EOL>gy = gy[mask]<EOL>ax_gofr = pl.subplot(gs2[<NUM_LIT:1>,<NUM_LIT:0>])<EOL>ax_gofr.plot(gx, gy, '<STR_LIT:->', lw=<NUM_LIT:1>)<EOL>ax_gofr.set_xlabel(r"<STR_LIT>")<EOL>ax_gofr.set_ylabel(r"<STR_LIT>")<EOL>ax_gofr.locator_params(axis='<STR_LIT>', nbins=<NUM_LIT:5>)<EOL>lbl(ax_gofr, '<STR_LIT:E>')<EOL>gx, gy = analyze.gofr(pos, rad, mu0[s0.b_zscale][<NUM_LIT:0>], method='<STR_LIT>')<EOL>mask = gx < <NUM_LIT:5><EOL>gx = gx[mask]<EOL>gy = gy[mask]<EOL>gy[gy <= <NUM_LIT:0.>] = gy[gy><NUM_LIT:0>].min()<EOL>ax_gofrs = pl.subplot(gs2[<NUM_LIT:1>,<NUM_LIT:1>])<EOL>ax_gofrs.plot(gx, gy, '<STR_LIT:->', lw=<NUM_LIT:1>)<EOL>ax_gofrs.set_xlabel(r"<STR_LIT>")<EOL>ax_gofrs.set_ylabel(r"<STR_LIT>")<EOL>ax_gofrs.locator_params(axis='<STR_LIT>', nbins=<NUM_LIT:5>)<EOL>ax_gofrs.grid(b=False, which='<STR_LIT>', axis='<STR_LIT:y>')<EOL>lbl(ax_gofrs, '<STR_LIT:F>')<EOL>ylim = ax_gofrs.get_ylim()<EOL>ax_gofrs.set_ylim(gy.min(), ylim[<NUM_LIT:1>])<EOL>

To run, do:

s,h = pickle...
s1,h1 = pickle...
    i.e. /media/scratch/bamf/vacancy/vacancy_zoom-1.tif_t002.tif-featured-v2.pkl
    i.e. /media/scratch/bamf/frozen-particles/0.tif-featured-full.pkl
crb0 = diag_crb_particles(s); crb1 = diag_crb_particles(s1)
crb_compare(s,h[-25:],s1,h1[-25:], crb0, crb1)


pl.close('<STR_LIT:all>')<EOL>slicez = int(round(z.mean()))<EOL>slicex = s.image.shape[<NUM_LIT:2>]//<NUM_LIT:2><EOL>slicer1 = np.s_[slicez,s.pad:-s.pad,s.pad:-s.pad]<EOL>slicer2 = np.s_[s.pad:-s.pad,s.pad:-s.pad,slicex]<EOL>center = (slicez, s.image.shape[<NUM_LIT:1>]//<NUM_LIT:2>, slicex)<EOL>fig = pl.figure(figsize=(factor*<NUM_LIT>,factor*<NUM_LIT:10>))<EOL>gs1 = ImageGrid(fig, rect=[<NUM_LIT:0.0>, <NUM_LIT>, <NUM_LIT:1.0>, <NUM_LIT>], nrows_ncols=(<NUM_LIT:1>,<NUM_LIT:3>),<EOL>axes_pad=<NUM_LIT:0.1>)<EOL>ax_real = gs1[<NUM_LIT:0>]<EOL>ax_fake = gs1[<NUM_LIT:1>]<EOL>ax_diff = gs1[<NUM_LIT:2>]<EOL>diff = s.get_model_image() - s.image<EOL>ax_real.imshow(s.image[slicer1], cmap=pl.cm.bone_r)<EOL>ax_real.set_xticks([])<EOL>ax_real.set_yticks([])<EOL>ax_real.set_title("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_fake.imshow(s.get_model_image()[slicer1], cmap=pl.cm.bone_r)<EOL>ax_fake.set_xticks([])<EOL>ax_fake.set_yticks([])<EOL>ax_fake.set_title("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_diff.imshow(diff[slicer1], cmap=pl.cm.RdBu, vmin=-<NUM_LIT:0.1>, vmax=<NUM_LIT:0.1>)<EOL>ax_diff.set_xticks([])<EOL>ax_diff.set_yticks([])<EOL>ax_diff.set_title("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>gs2 = ImageGrid(fig, rect=[<NUM_LIT:0.1>, <NUM_LIT:0.0>, <NUM_LIT>, <NUM_LIT>], nrows_ncols=(<NUM_LIT:3>,<NUM_LIT:2>),<EOL>axes_pad=<NUM_LIT:0.1>)<EOL>ax_plt1 = fig.add_subplot(gs2[<NUM_LIT:0>])<EOL>ax_plt2 = fig.add_subplot(gs2[<NUM_LIT:1>])<EOL>ax_ilm1 = fig.add_subplot(gs2[<NUM_LIT:2>])<EOL>ax_ilm2 = fig.add_subplot(gs2[<NUM_LIT:3>])<EOL>ax_psf1 = fig.add_subplot(gs2[<NUM_LIT:4>])<EOL>ax_psf2 = fig.add_subplot(gs2[<NUM_LIT:5>])<EOL>c = int(z.mean()), int(y.mean())+s.pad, int(x.mean())+s.pad<EOL>if s.image.shape[<NUM_LIT:0>] > <NUM_LIT:2>*s.image.shape[<NUM_LIT:1>]//<NUM_LIT:3>:<EOL><INDENT>w = s.image.shape[<NUM_LIT:2>] - <NUM_LIT:2>*s.pad<EOL>h = <NUM_LIT:2>*w//<NUM_LIT:3><EOL><DEDENT>else:<EOL><INDENT>h = s.image.shape[<NUM_LIT:0>] - <NUM_LIT:2>*s.pad<EOL>w = <NUM_LIT:3>*h//<NUM_LIT:2><EOL><DEDENT>w,h = w//<NUM_LIT:2>, h//<NUM_LIT:2><EOL>xyslice = np.s_[slicez, c[<NUM_LIT:1>]-h:c[<NUM_LIT:1>]+h, c[<NUM_LIT:2>]-w:c[<NUM_LIT:2>]+w]<EOL>yzslice = np.s_[c[<NUM_LIT:0>]-h:c[<NUM_LIT:0>]+h, c[<NUM_LIT:1>]-w:c[<NUM_LIT:1>]+w, slicex]<EOL>ax_plt1.imshow(<NUM_LIT:1>-s.obj.get_field()[xyslice], cmap=pl.cm.bone_r, vmin=<NUM_LIT:0>, vmax=<NUM_LIT:1>)<EOL>ax_plt1.set_xticks([])<EOL>ax_plt1.set_yticks([])<EOL>ax_plt1.set_ylabel("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_plt1.set_title("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_plt2.imshow(<NUM_LIT:1>-s._platonic_image()[yzslice], cmap=pl.cm.bone_r, vmin=<NUM_LIT:0>, vmax=<NUM_LIT:1>)<EOL>ax_plt2.set_xticks([])<EOL>ax_plt2.set_yticks([])<EOL>ax_plt2.set_title("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_ilm1.imshow(s.ilm.get_field()[xyslice], cmap=pl.cm.bone_r)<EOL>ax_ilm1.set_xticks([])<EOL>ax_ilm1.set_yticks([])<EOL>ax_ilm1.set_ylabel("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_ilm2.imshow(s.ilm.get_field()[yzslice], cmap=pl.cm.bone_r)<EOL>ax_ilm2.set_xticks([])<EOL>ax_ilm2.set_yticks([])<EOL>t = s.ilm.get_field().copy()<EOL>t *= <NUM_LIT:0><EOL>t[c] = <NUM_LIT:1><EOL>s.psf.set_tile(util.Tile(t.shape))<EOL>psf = (s.psf.execute(t)+<NUM_LIT>)**<NUM_LIT:0.1><EOL>ax_psf1.imshow(psf[xyslice], cmap=pl.cm.bone)<EOL>ax_psf1.set_xticks([])<EOL>ax_psf1.set_yticks([])<EOL>ax_psf1.set_ylabel("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_psf2.imshow(psf[yzslice], cmap=pl.cm.bone)<EOL>ax_psf2.set_xticks([])<EOL>ax_psf2.set_yticks([])<EOL>ax_zoom = fig.add_axes([<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>])<EOL>im = s.image[slicer1]<EOL>sh = np.array(im.shape)<EOL>cx = x.mean()<EOL>cy = y.mean()<EOL>extent = [<NUM_LIT:0>,sh[<NUM_LIT:0>],<NUM_LIT:0>,sh[<NUM_LIT:1>]]<EOL>ax_zoom.set_xticks([])<EOL>ax_zoom.set_yticks([])<EOL>ax_zoom.imshow(im, extent=extent, cmap=pl.cm.bone_r)<EOL>ax_zoom.set_xlim(cx-<NUM_LIT:12>, cx+<NUM_LIT:12>)<EOL>ax_zoom.set_ylim(cy-<NUM_LIT:12>, cy+<NUM_LIT:12>)<EOL>ax_zoom.set_title("<STR_LIT>", fontsize=<NUM_LIT>)<EOL>ax_zoom.hexbin(x,y, gridsize=<NUM_LIT:32>, mincnt=<NUM_LIT:0>, cmap=pl.cm.hot)<EOL>zoom1 = zoomed_inset_axes(ax_zoom, <NUM_LIT:30>, loc=<NUM_LIT:3>)<EOL>zoom1.imshow(im, extent=extent, cmap=pl.cm.bone_r)<EOL>zoom1.set_xlim(cx-<NUM_LIT:1.0>/<NUM_LIT:6>, cx+<NUM_LIT:1.0>/<NUM_LIT:6>)<EOL>zoom1.set_ylim(cy-<NUM_LIT:1.0>/<NUM_LIT:6>, cy+<NUM_LIT:1.0>/<NUM_LIT:6>)<EOL>zoom1.hexbin(x,y,gridsize=<NUM_LIT:32>, mincnt=<NUM_LIT:5>, cmap=pl.cm.hot)<EOL>zoom1.set_xticks([])<EOL>zoom1.set_yticks([])<EOL>zoom1.hlines(cy-<NUM_LIT:1.0>/<NUM_LIT:6> + <NUM_LIT:1.0>/<NUM_LIT:32>, cx-<NUM_LIT:1.0>/<NUM_LIT:6>+<NUM_LIT>, cx-<NUM_LIT:1.0>/<NUM_LIT:6>+<NUM_LIT>+<NUM_LIT>, lw=<NUM_LIT:3>)<EOL>zoom1.text(cx-<NUM_LIT:1.0>/<NUM_LIT:6> + <NUM_LIT:1.0>/<NUM_LIT>, cy-<NUM_LIT:1.0>/<NUM_LIT:6>+<NUM_LIT>, '<STR_LIT>')<EOL>mark_inset(ax_zoom, zoom1, loc1=<NUM_LIT:2>, loc2=<NUM_LIT:4>, fc="<STR_LIT:none>", ec="<STR_LIT>")<EOL>

Samples x,y,z,r are created by:
b = s.blocks_particle(#)
h = runner.sample_state(s, b, stepout=0.05, N=2000, doprint=True)
z,y,x,r = h.get_histogram().T


def compare_data_model_residuals(s, tile, data_vmin='<STR_LIT>', data_vmax='<STR_LIT>',<EOL>res_vmin=-<NUM_LIT:0.1>, res_vmax=<NUM_LIT:0.1>, edgepts='<STR_LIT>', do_imshow=True,<EOL>data_cmap=plt.cm.bone, res_cmap=plt.cm.RdBu):

<EOL>residuals = s.residuals[tile.slicer].squeeze()<EOL>data = s.data[tile.slicer].squeeze()<EOL>model = s.model[tile.slicer].squeeze()<EOL>if data.ndim != <NUM_LIT:2>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>im = np.zeros([data.shape[<NUM_LIT:0>], data.shape[<NUM_LIT:1>], <NUM_LIT:4>])<EOL>if data_vmin == '<STR_LIT>':<EOL><INDENT>data_vmin = <NUM_LIT:0.5>*(data.min() + model.min())<EOL><DEDENT>if data_vmax == '<STR_LIT>':<EOL><INDENT>data_vmax = <NUM_LIT:0.5>*(data.max() + model.max())<EOL><DEDENT>upper_mask, center_mask, lower_mask = trisect_image(im.shape, edgepts)<EOL>gm = data_cmap(center_data(model, data_vmin, data_vmax))<EOL>dt = data_cmap(center_data(data, data_vmin, data_vmax))<EOL>rs = res_cmap(center_data(residuals, res_vmin, res_vmax))<EOL>for a in range(<NUM_LIT:4>):<EOL><INDENT>im[:,:,a][upper_mask] = rs[:,:,a][upper_mask]<EOL>im[:,:,a][center_mask] = gm[:,:,a][center_mask]<EOL>im[:,:,a][lower_mask] = dt[:,:,a][lower_mask]<EOL><DEDENT>if do_imshow:<EOL><INDENT>return plt.imshow(im)<EOL><DEDENT>else:<EOL><INDENT>return im<EOL><DEDENT>

Compare the data, model, and residuals of a state.

Makes an image of any 2D slice of a state that compares the data,
model, and residuals. The upper left portion of the image is the raw
data, the central portion the model, and the lower right portion the
image. Either plots the image using plt.imshow() or returns a
np.ndarray of the image pixels for later use.

Parameters
----------
    st : peri.ImageState object
        The state to plot.
    tile : peri.util.Tile object
        The slice of the image to plot. Can be any xy, xz, or yz
        projection, but it must return a valid 2D slice (the slice is
        squeezed internally).

    data_vmin : {Float, `calc`}, optional
        vmin for the imshow for the data and generative model (shared).
        Default is 'calc' = 0.5(data.min() + model.min())
    data_vmax : {Float, `calc`}, optional
        vmax for the imshow for the data and generative model (shared).
        Default is 'calc' = 0.5(data.max() + model.max())
    res_vmin : Float, optional
        vmin for the imshow for the residuals. Default is -0.1
        Default is 'calc' = 0.5(data.min() + model.min())
    res_vmax : Float, optional
        vmax for the imshow for the residuals. Default is +0.1
    edgepts : {Nested list-like, Float, 'calc'}, optional.
        The vertices of the triangles which determine the splitting of
        the image. The vertices are at (image corner, (edge, y), and
        (x,edge), where edge is the appropriate edge of the image.
            edgepts[0] : (x,y) points for the upper edge
            edgepts[1] : (x,y) points for the lower edge
        where `x` is the coordinate along the image's 0th axis and `y`
        along the images 1st axis. Default is 'calc,' which calculates
        edge points by splitting the image into 3 regions of equal
        area. If edgepts is a float scalar, calculates the edge points
        based on a constant fraction of distance from the edge.
    do_imshow : Bool
        If True, imshow's and returns the returned handle.
        If False, returns the array as a [M,N,4] array.
    data_cmap : matplotlib colormap instance
        The colormap to use for the data and model.
    res_cmap : matplotlib colormap instance
        The colormap to use for the residuals.

Returns
-------
    image : {matplotlib.pyplot.AxesImage, numpy.ndarray}
        If `do_imshow` == True, the returned handle from imshow.
        If `do_imshow` == False, an [M,N,4] np.ndarray of the image
        pixels.


def sim_crb_diff(std0, std1, N=<NUM_LIT>):

a = std0*np.random.randn(N, len(std0))<EOL>b = std1*np.random.randn(N, len(std1))<EOL>return a - b<EOL>

each element of std0 should correspond with the element of std1


im_x, im_y = np.meshgrid(np.arange(imshape[<NUM_LIT:0>]), np.arange(imshape[<NUM_LIT:1>]),<EOL>indexing='<STR_LIT>')<EOL>if np.size(edgepts) == <NUM_LIT:1>:<EOL><INDENT>f = np.sqrt(<NUM_LIT>/<NUM_LIT>) if edgepts == '<STR_LIT>' else edgepts<EOL>lower_edge = (imshape[<NUM_LIT:0>] * (<NUM_LIT:1>-f),  imshape[<NUM_LIT:1>] * f)<EOL>upper_edge = (imshape[<NUM_LIT:0>] * f,      imshape[<NUM_LIT:1>] * (<NUM_LIT:1>-f))<EOL><DEDENT>else:<EOL><INDENT>upper_edge, lower_edge = edgepts<EOL><DEDENT>lower_slope = lower_edge[<NUM_LIT:1>] / max(float(imshape[<NUM_LIT:0>] - lower_edge[<NUM_LIT:0>]), <NUM_LIT>)<EOL>upper_slope = (imshape[<NUM_LIT:1>] - upper_edge[<NUM_LIT:1>]) / float(upper_edge[<NUM_LIT:0>])<EOL>lower_intercept = -lower_slope * lower_edge[<NUM_LIT:0>]<EOL>upper_intercept = upper_edge[<NUM_LIT:1>]<EOL>lower_mask = im_y < (im_x * lower_slope + lower_intercept)<EOL>upper_mask = im_y > (im_x * upper_slope + upper_intercept)<EOL>center_mask= -(lower_mask | upper_mask)<EOL>return upper_mask, center_mask, lower_mask<EOL>

Returns 3 masks that trisect an image into 3 triangular portions.

Parameters
----------
    imshape : 2-element list-like of ints
        The shape of the image. Elements after the first 2 are ignored.

    edgepts : Nested list-like, float, or `calc`, optional.
        The vertices of the triangles which determine the splitting of
        the image. The vertices are at (image corner, (edge, y), and
        (x,edge), where edge is the appropriate edge of the image.
            edgepts[0] : (x,y) points for the upper edge
            edgepts[1] : (x,y) points for the lower edge
        where `x` is the coordinate along the image's 0th axis and `y`
        along the images 1st axis. Default is 'calc,' which calculates
        edge points by splitting the image into 3 regions of equal
        area. If edgepts is a float scalar, calculates the edge points
        based on a constant fraction of distance from the edge.

Returns
-------
    upper_mask : numpy.ndarray
        Boolean array; True in the image's upper  region.
    center_mask : numpy.ndarray
        Boolean array; True in the image's center region.
    lower_mask : numpy.ndarray
        Boolean array; True in the image's lower  region.


def local_max_featuring(im, radius=<NUM_LIT>, noise_size=<NUM_LIT:1.>, bkg_size=None,<EOL>minmass=<NUM_LIT:1.>, trim_edge=False):

if radius <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>filtered = nd.gaussian_filter(im, noise_size, mode='<STR_LIT>')<EOL>if bkg_size is None:<EOL><INDENT>bkg_size = <NUM_LIT:2>*radius<EOL><DEDENT>filtered -= nd.gaussian_filter(filtered, bkg_size, mode='<STR_LIT>')<EOL>footprint = generate_sphere(radius)<EOL>e = nd.maximum_filter(filtered, footprint=footprint)<EOL>mass_im = nd.convolve(filtered, footprint, mode='<STR_LIT>')<EOL>good_im = (e==filtered) * (mass_im > minmass)<EOL>pos = np.transpose(np.nonzero(good_im))<EOL>if trim_edge:<EOL><INDENT>good = np.all(pos > <NUM_LIT:0>, axis=<NUM_LIT:1>) & np.all(pos+<NUM_LIT:1> < im.shape, axis=<NUM_LIT:1>)<EOL>pos = pos[good, :].copy()<EOL><DEDENT>masses = mass_im[pos[:,<NUM_LIT:0>], pos[:,<NUM_LIT:1>], pos[:,<NUM_LIT:2>]].copy()<EOL>return pos, masses<EOL>

Local max featuring to identify bright spherical particles on a
    dark background.

    Parameters
    ----------
        im : numpy.ndarray
            The image to identify particles in.
        radius : Float > 0, optional
            Featuring radius of the particles. Default is 2.5
        noise_size : Float, optional
            Size of Gaussian kernel for smoothing out noise. Default is 1.
        bkg_size : Float or None, optional
            Size of the Gaussian kernel for removing long-wavelength
            background. Default is None, which gives `2 * radius`
        minmass : Float, optional
            Return only particles with a ``mass > minmass``. Default is 1.
        trim_edge : Bool, optional
            Set to True to omit particles identified exactly at the edge
            of the image. False-positive features frequently occur here
            because of the reflected bandpass featuring. Default is
            False, i.e. find particles at the edge of the image.

    Returns
    -------
        pos, mass : numpy.ndarray
            Particle positions and masses


def identify_slab(im, sigma=<NUM_LIT>, region_size=<NUM_LIT:10>, masscut=<NUM_LIT>, asdict=False):

<EOL>fim = nd.filters.gaussian_filter(im, sigma)<EOL>trc, det = harris_feature(fim, region_size, to_return='<STR_LIT>')<EOL>dnrm = det / (trc*trc)<EOL>trc_cut = otsu_threshold(trc)<EOL>det_cut = otsu_threshold(dnrm)<EOL>slabs = (trc > trc_cut) & (dnrm < det_cut)<EOL>labeled, nslabs = nd.label(slabs)<EOL>masses = [(labeled == i).sum() for i in range(<NUM_LIT:1>, nslabs+<NUM_LIT:1>)]<EOL>good = np.array([m > masscut for m in masses])<EOL>inds = np.nonzero(good)[<NUM_LIT:0>] + <NUM_LIT:1>  <EOL>poses = np.array(nd.measurements.center_of_mass(trc, labeled, inds))<EOL>normals = []<EOL>z = np.arange(im.shape[<NUM_LIT:0>]).reshape(-<NUM_LIT:1>,<NUM_LIT:1>,<NUM_LIT:1>).astype('<STR_LIT:float>')<EOL>y = np.arange(im.shape[<NUM_LIT:1>]).reshape(<NUM_LIT:1>,-<NUM_LIT:1>,<NUM_LIT:1>).astype('<STR_LIT:float>')<EOL>x = np.arange(im.shape[<NUM_LIT:2>]).reshape(<NUM_LIT:1>,<NUM_LIT:1>,-<NUM_LIT:1>).astype('<STR_LIT:float>')<EOL>gim = [nd.sobel(fim, axis=i) for i in range(fim.ndim)]<EOL>for i, p in zip(range(<NUM_LIT:1>, nslabs+<NUM_LIT:1>), poses):<EOL><INDENT>wts = trc * (labeled == i)<EOL>wts /= wts.sum()<EOL>zc, yc, xc = [xi-pi for xi, pi in zip([z,y,x],p.squeeze())]<EOL>cov = [[np.sum(xi*xj*wts) for xi in [zc,yc,xc]] for xj in [zc,yc,xc]]<EOL>vl, vc = np.linalg.eigh(cov)<EOL>normal = vc[:,<NUM_LIT:0>]<EOL>gn = np.sum([n*g[tuple(p.astype('<STR_LIT:int>'))] for g,n in zip(gim, normal)])<EOL>normal *= np.sign(gn)<EOL>normals.append(normal)<EOL><DEDENT>if asdict:<EOL><INDENT>get_theta = lambda n: -np.arctan2(n[<NUM_LIT:1>], -n[<NUM_LIT:0>])<EOL>get_phi = lambda n: np.arcsin(n[<NUM_LIT:2>])<EOL>return [{'<STR_LIT>':p[<NUM_LIT:0>], '<STR_LIT>':(get_theta(n), get_phi(n))}<EOL>for p, n in zip(poses, normals)]<EOL><DEDENT>else:<EOL><INDENT>return poses, np.array(normals)<EOL><DEDENT>

Identifies slabs in an image.

Functions by running a Harris-inspired edge detection on the image,
thresholding the edge, then clustering.

Parameters
----------
    im : numpy.ndarray
        3D array of the image to analyze.
    sigma : Float, optional
        Gaussian blurring kernel to remove non-slab features such as
        noise and particles. Default is 5.
    region_size : Int, optional
        The size of region for Harris corner featuring. Default is 10
    masscut : Float, optional
        The minimum number of pixels for a feature to be identified as
        a slab. Default is 1e4; should be smaller for smaller images.
    asdict : Bool, optional
        Set to True to return a list of dicts, with keys of ``'theta'``
        and ``'phi'`` as rotation angles about the x- and z- axes, and
        of ``'zpos'`` for the z-position, i.e. a list of dicts which
        can be unpacked into a :class:``peri.comp.objs.Slab``

Returns
-------
    [poses, normals] : numpy.ndarray
        The positions and normals of each slab in the image; ``poses[i]``
        and ``normals[i]`` are the ``i``th slab. Returned if ``asdict``
        is False
    [list]
        A list of dictionaries. Returned if ``asdict`` is True


def normalize(im, invert=False, scale=None, dtype=np.float64):

if dtype not in {np.float16, np.float32, np.float64}:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>out = im.astype('<STR_LIT:float>').copy()<EOL>scale = scale or (<NUM_LIT:0.0>, <NUM_LIT>)<EOL>l, u = (float(i) for i in scale)<EOL>out = (out - l) / (u - l)<EOL>if invert:<EOL><INDENT>out = -out + (out.max() + out.min())<EOL><DEDENT>return out.astype(dtype)<EOL>

Normalize a field to a (min, max) exposure range, default is (0, 255).
(min, max) exposure values. Invert the image if requested.


def harris_feature(im, region_size=<NUM_LIT:5>, to_return='<STR_LIT>', scale=<NUM_LIT>):

ndim = im.ndim<EOL>grads = [nd.sobel(im, axis=i) for i in range(ndim)]<EOL>matrix = np.zeros((ndim, ndim) + im.shape)<EOL>for a in range(ndim):<EOL><INDENT>for b in range(ndim):<EOL><INDENT>matrix[a,b] = nd.filters.gaussian_filter(grads[a]*grads[b],<EOL>region_size)<EOL><DEDENT><DEDENT>if to_return == '<STR_LIT>':<EOL><INDENT>return matrix<EOL><DEDENT>trc = np.trace(matrix, axis1=<NUM_LIT:0>, axis2=<NUM_LIT:1>)<EOL>det = np.linalg.det(matrix.T).T<EOL>if to_return == '<STR_LIT>':<EOL><INDENT>return trc, det<EOL><DEDENT>else:<EOL><INDENT>harris = det - scale*trc*trc<EOL>return harris<EOL><DEDENT>

Harris-motivated feature detection on a d-dimensional image.

Parameters
---------
    im
    region_size
    to_return : {'harris','matrix','trace-determinant'}


h0, x0 = np.histogram(data.ravel(), bins=bins)<EOL>h = h0.astype('<STR_LIT:float>') / h0.sum()  <EOL>x = <NUM_LIT:0.5>*(x0[<NUM_LIT:1>:] + x0[:-<NUM_LIT:1>])  <EOL>wk = np.array([h[:i+<NUM_LIT:1>].sum() for i in range(h.size)])  <EOL>mk = np.array([sum(x[:i+<NUM_LIT:1>]*h[:i+<NUM_LIT:1>]) for i in range(h.size)])  <EOL>mt = mk[-<NUM_LIT:1>]  <EOL>sb = (mt*wk - mk)**<NUM_LIT:2> / (wk*(<NUM_LIT:1>-wk) + <NUM_LIT>)  <EOL>ind = sb.argmax()<EOL>return <NUM_LIT:0.5>*(x0[ind] + x0[ind+<NUM_LIT:1>])<EOL>

Otsu threshold on data.

Otsu thresholding [1]_is a method for selecting an intensity value
for thresholding an image into foreground and background. The sel-
ected intensity threshold maximizes the inter-class variance.

Parameters
----------
    data : numpy.ndarray
        The data to threshold
    bins : Int or numpy.ndarray, optional
        Bin edges, as passed to numpy.histogram

Returns
-------
    numpy.float
        The value of the threshold which maximizes the inter-class
        variance.

Notes
-----
    This could be generalized to more than 2 classes.
References
----------
    ..[1] N. Otsu, "A Threshold Selection Method from Gray-level
        Histograms," IEEE Trans. Syst., Man, Cybern., Syst., 9, 1,
        62-66 (1979)


def calculate_polychrome_pinhole_psf(x, y, z, normalize=False, kfki=<NUM_LIT>,<EOL>sigkf=<NUM_LIT:0.1>, zint=<NUM_LIT>, nkpts=<NUM_LIT:3>, dist_type='<STR_LIT>', **kwargs):

<EOL>kfkipts, wts = get_polydisp_pts_wts(kfki, sigkf, dist_type=dist_type,<EOL>nkpts=nkpts)<EOL>rho = np.sqrt(x**<NUM_LIT:2> + y**<NUM_LIT:2>)<EOL>phi = np.arctan2(y, x)<EOL>hsym, hasym = get_hsym_asym(rho, z, zint=zint, get_hdet=False, **kwargs)<EOL>hilm = (hsym + np.cos(<NUM_LIT:2>*phi)*hasym)<EOL>hdet_func = lambda kfki: get_hsym_asym(rho*kfki, z*kfki,<EOL>zint=kfki*zint, get_hdet=True, **kwargs)[<NUM_LIT:0>]<EOL>inner = [wts[a] * hdet_func(kfkipts[a]) for a in range(nkpts)]<EOL>hdet = np.sum(inner, axis=<NUM_LIT:0>)<EOL>if normalize:<EOL><INDENT>hilm /= hilm.sum()<EOL>hdet /= hdet.sum()<EOL><DEDENT>psf = hdet * hilm<EOL>return psf if normalize else psf / psf.sum()<EOL>

Calculates the perfect-pinhole PSF, for a set of points (x,y,z).

Parameters
-----------
    x : numpy.ndarray
        The x-coordinate of the PSF in units of 1/ the wavevector of
        the incoming light.
    y : numpy.ndarray
        The y-coordinate.
    z : numpy.ndarray
        The z-coordinate.
    kfki : Float
        The mean ratio of the outgoing light's wavevector to the incoming
        light's. Default is 0.89.
    sigkf : Float
        Standard deviation of kfki; the distribution of the light values
        will be approximately kfki +- sigkf.
    zint : Float
        The (scalar) distance from the interface, in units of
        1/k_incoming. Default is 100.0
    dist_type: The distribution type of the polychromatic light.
        Can be one of 'laguerre'/'gamma' or 'gaussian.' If 'gaussian'
        the resulting k-values are taken in absolute value. Default
        is 'gaussian.'
    normalize : Bool
        Set to True to normalize the psf correctly, accounting for
        intensity variations with depth. This will give a psf that does
        not sum to 1. Default is False.

Other Parameters
----------------
    alpha : Float
        The opening angle of the lens. Default is 1.
    n2n1 : Float
        The ratio of the index in the 2nd medium to that in the first.
        Default is 0.95

Returns
-------
    psf : numpy.ndarray, of shape x.shape

Comments
--------
    (1) The PSF is not necessarily centered on the z=0 pixel, since the
        calculation includes the shift.

    (2) If you want z-varying illumination of the psf then set
        normalize=True. This does the normalization by doing:
            hsym, hasym /= hsym.sum()
            hdet /= hdet.sum()
        and then calculating the psf that way. So if you want the
        intensity to be correct you need to use a large-ish array of
        roughly equally spaced points. Or do it manually by calling
        get_hsym_asym()


pts_hg, wts_hg = np.polynomial.hermite.hermgauss(npts*<NUM_LIT:2>)<EOL>pts_hg = pts_hg[npts:]<EOL>wts_hg = wts_hg[npts:] * np.exp(pts_hg*pts_hg)<EOL>return pts_hg, wts_hg<EOL>

Returns Hermite-Gauss quadrature points for even functions


def calculate_linescan_ilm_psf(y,z, polar_angle=<NUM_LIT:0.>, nlpts=<NUM_LIT:1>,<EOL>pinhole_width=<NUM_LIT:1>, use_laggauss=False, **kwargs):

if use_laggauss:<EOL><INDENT>x_vals, wts = calc_pts_lag()<EOL><DEDENT>else:<EOL><INDENT>x_vals, wts = calc_pts_hg()<EOL><DEDENT>xg, yg, zg = [np.zeros( list(y.shape) + [x_vals.size] ) for a in range(<NUM_LIT:3>)]<EOL>hilm = np.zeros(xg.shape)<EOL>for a in range(x_vals.size):<EOL><INDENT>xg[...,a] = x_vals[a]<EOL>yg[...,a] = y.copy()<EOL>zg[...,a] = z.copy()<EOL><DEDENT>y_pinhole, wts_pinhole = np.polynomial.hermite.hermgauss(nlpts)<EOL>y_pinhole *= np.sqrt(<NUM_LIT:2>)*pinhole_width<EOL>wts_pinhole /= np.sqrt(np.pi)<EOL>for yp, wp in zip(y_pinhole, wts_pinhole):<EOL><INDENT>rho = np.sqrt(xg*xg + (yg-yp)*(yg-yp))<EOL>phi = np.arctan2(yg,xg)<EOL>hsym, hasym = get_hsym_asym(rho,zg,get_hdet = False, **kwargs)<EOL>hilm += wp*(hsym + np.cos(<NUM_LIT:2>*(phi-polar_angle))*hasym)<EOL><DEDENT>for a in range(x_vals.size):<EOL><INDENT>hilm[...,a] *= wts[a]<EOL><DEDENT>return hilm.sum(axis=-<NUM_LIT:1>)*<NUM_LIT><EOL>

Calculates the illumination PSF for a line-scanning confocal with the
confocal line oriented along the x direction.

Parameters
----------
    y : numpy.ndarray
        The y points (in-plane, perpendicular to the line direction)
        at which to evaluate the illumination PSF, in units of 1/k.
        Arbitrary shape.
    z : numpy.ndarray
        The z points (optical axis) at which to evaluate the illum-
        ination PSF, in units of 1/k. Must be the same shape as `y`
    polar_angle : Float, optional
        The angle of the illuminating light's polarization with
        respect to the line's orientation along x. Default is 0.
    pinhole_width : Float, optional
        The width of the geometric image of the line projected onto
        the sample, in units of 1/k. Default is 1. The perfect line
        image is assumed to be a Gaussian. If `nlpts` is set to 1,
        the line will always be of zero width.
    nlpts : Int, optional
        The number of points to use for Hermite-gauss quadrature over
        the line's width. Default is 1, corresponding to a zero-width
        line.
    use_laggauss : Bool, optional
        Set to True to use a more-accurate sinh'd Laguerre-Gauss
        quadrature for integration over the line's length (more accurate
        in the same amount of time). Default is False for backwards
        compatibility.  FIXME what did we do here?

Other Parameters
----------------
    alpha : Float, optional
        The acceptance angle of the lens, on (0,pi/2). Default is 1.
    zint : Float, optional
        The distance of the len's unaberrated focal point from the
        optical interface, in units of 1/k. Default is 100.
    n2n1 : Float, optional
        The ratio n2/n1 of the index mismatch between the sample
        (index n2) and the optical train (index n1). Must be on
        [0,inf) but should be near 1. Default is 0.95

Returns
-------
    hilm : numpy.ndarray
        The line illumination, of the same shape as y and z.


def get_K(rho, z, alpha=<NUM_LIT:1.0>, zint=<NUM_LIT>, n2n1=<NUM_LIT>, get_hdet=False, K=<NUM_LIT:1>,<EOL>Kprefactor=None, return_Kprefactor=False, npts=<NUM_LIT:20>, **kwargs):

<EOL>if type(rho) != np.ndarray or type(z) != np.ndarray or (rho.shape != z.shape):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>pts, wts = np.polynomial.legendre.leggauss(npts)<EOL>n1n2 = <NUM_LIT:1.0>/n2n1<EOL>rr = np.ravel(rho)<EOL>zr = np.ravel(z)<EOL>cos_theta = <NUM_LIT:0.5>*(<NUM_LIT:1>-np.cos(alpha))*pts+<NUM_LIT:0.5>*(<NUM_LIT:1>+np.cos(alpha))<EOL>if Kprefactor is None:<EOL><INDENT>Kprefactor = get_Kprefactor(z, cos_theta, zint=zint,n2n1=n2n1,get_hdet=get_hdet, **kwargs)<EOL><DEDENT>if K==<NUM_LIT:1>:<EOL><INDENT>part_1 = j0(np.outer(rr,np.sqrt(<NUM_LIT:1>-cos_theta**<NUM_LIT:2>)))*np.outer(np.ones_like(rr), <NUM_LIT:0.5>*(get_taus(cos_theta,n2n1=n2n1)+get_taup(cos_theta,n2n1=n2n1)*csqrt(<NUM_LIT:1>-n1n2**<NUM_LIT:2>*(<NUM_LIT:1>-cos_theta**<NUM_LIT:2>))))<EOL>integrand = Kprefactor * part_1<EOL><DEDENT>elif K==<NUM_LIT:2>:<EOL><INDENT>part_2=j2(np.outer(rr,np.sqrt(<NUM_LIT:1>-cos_theta**<NUM_LIT:2>)))*np.outer(np.ones_like(rr),<NUM_LIT:0.5>*(get_taus(cos_theta,n2n1=n2n1)-get_taup(cos_theta,n2n1=n2n1)*csqrt(<NUM_LIT:1>-n1n2**<NUM_LIT:2>*(<NUM_LIT:1>-cos_theta**<NUM_LIT:2>))))<EOL>integrand = Kprefactor * part_2<EOL><DEDENT>elif K==<NUM_LIT:3>:<EOL><INDENT>part_3=j1(np.outer(rho,np.sqrt(<NUM_LIT:1>-cos_theta**<NUM_LIT:2>)))*np.outer(np.ones_like(rr), n1n2*get_taup(cos_theta,n2n1=n2n1)*np.sqrt(<NUM_LIT:1>-cos_theta**<NUM_LIT:2>))<EOL>integrand = Kprefactor * part_3<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>big_wts=np.outer(np.ones_like(rr), wts)<EOL>kint = (big_wts*integrand).sum(axis=<NUM_LIT:1>) * <NUM_LIT:0.5>*(<NUM_LIT:1>-np.cos(alpha))<EOL>if return_Kprefactor:<EOL><INDENT>return kint.reshape(rho.shape), Kprefactor<EOL><DEDENT>else:<EOL><INDENT>return kint.reshape(rho.shape)<EOL><DEDENT>

Calculates one of three electric field integrals.

Internal function for calculating point spread functions. Returns
one of three electric field integrals that describe the electric
field near the focus of a lens; these integrals appear in Hell's psf
calculation.

Parameters
----------
    rho : numpy.ndarray
        Rho in cylindrical coordinates, in units of 1/k.
    z : numpy.ndarray
        Z in cylindrical coordinates, in units of 1/k. `rho` and
        `z` must be the same shape

    alpha : Float, optional
        The acceptance angle of the lens, on (0,pi/2). Default is 1.
    zint : Float, optional
        The distance of the len's unaberrated focal point from the
        optical interface, in units of 1/k. Default is 100.
    n2n1 : Float, optional
        The ratio n2/n1 of the index mismatch between the sample
        (index n2) and the optical train (index n1). Must be on
        [0,inf) but should be near 1. Default is 0.95
    get_hdet : Bool, optional
        Set to True to get the detection portion of the psf; False
        to get the illumination portion of the psf. Default is True
    K : {1, 2, 3}, optional
        Which of the 3 integrals to evaluate. Default is 1
    Kprefactor : numpy.ndarray or None
        This array is calculated internally and optionally returned;
        pass it back to avoid recalculation and increase speed. Default
        is None, i.e. calculate it internally.
    return_Kprefactor : Bool, optional
        Set to True to also return the Kprefactor (parameter above)
        to speed up the calculation for the next values of K. Default
        is False
    npts : Int, optional
        The number of points to use for Gauss-Legendre quadrature of
        the integral. Default is 20, which is a good number for x,y,z
        less than 100 or so.

Returns
-------
    kint : numpy.ndarray
        The integral K_i; rho.shape numpy.array
    [, Kprefactor] : numpy.ndarray
        The prefactor that is independent of which integral is being
        calculated but does depend on the parameters; can be passed
        back to the function for speed.

Notes
-----
    npts=20 gives double precision (no difference between 20, 30, and
    doing all the integrals with scipy.quad). The integrals are only
    over the acceptance angle of the lens, so for moderate x,y,z they
    don't vary too rapidly. For x,y,z, zint large compared to 100, a
    higher npts might be necessary.


to_return = <NUM_LIT>/(x+<NUM_LIT>)*j1(x) - j0(x)<EOL>to_return[x==<NUM_LIT:0>] = <NUM_LIT:0><EOL>return to_return<EOL>

A fast j2 defined in terms of other special functions


def get_Kprefactor(z, cos_theta, zint=<NUM_LIT>, n2n1=<NUM_LIT>, get_hdet=False,<EOL>**kwargs):

phase = f_theta(cos_theta, zint, z, n2n1=n2n1, **kwargs)<EOL>to_return = np.exp(-<NUM_LIT>*phase)<EOL>if not get_hdet:<EOL><INDENT>to_return *= np.outer(np.ones_like(z),np.sqrt(cos_theta))<EOL><DEDENT>return to_return<EOL>

Returns a prefactor in the electric field integral.

This is an internal function called by get_K. The returned prefactor
in the integrand is independent of which integral is being called;
it is a combination of the exp(1j*phase) and apodization.

Parameters
----------
    z : numpy.ndarray
        The values of z (distance along optical axis) at which to
        calculate the prefactor. Size is unrelated to the size of
        `cos_theta`
    cos_theta : numpy.ndarray
        The values of cos(theta) (i.e. position on the incoming
        focal spherical wavefront) at which to calculate the
        prefactor. Size is unrelated to the size of `z`
    zint : Float, optional
        The position of the optical interface, in units of 1/k.
        Default is 100.
    n2n1 : Float, optional
        The ratio of the index mismatch between the optics (n1) and
        the sample (n2). Default is 0.95
    get_hdet : Bool, optional
        Set to True to calculate the detection prefactor vs the
        illumination prefactor (i.e. False to include apodization).
        Default is False

Returns
-------
    numpy.ndarray
        The prefactor, of size [`z.size`, `cos_theta.size`], sampled
        at the values [`z`, `cos_theta`]


return <NUM_LIT>/(<NUM_LIT:1>+csqrt(<NUM_LIT:1>+(n2n1**<NUM_LIT:2>-<NUM_LIT:1>)*cos_theta**-<NUM_LIT:2>))<EOL>

Calculates the Fresnel reflectivity for s-polarized light incident on an
interface with index ration n2n1.

Parameters
----------
    cos_theta : Float or numpy.ndarray
        The _cosine_ of the angle of the incoming light. Float.
    n2n1 : Float, optional
        The ratio n2/n1 of the 2nd material's index n2 to the first's n1
        Default is 0.95

Returns
-------
    Float or numpy.ndarray
        The reflectivity, in the same type (ndarray or Float) and
        shape as cos_theta


def f_theta(cos_theta, zint, z, n2n1=<NUM_LIT>, sph6_ab=None, **kwargs):

wvfront = (np.outer(np.ones_like(z)*zint, cos_theta) -<EOL>np.outer(zint+z, csqrt(n2n1**<NUM_LIT:2>-<NUM_LIT:1>+cos_theta**<NUM_LIT:2>)))<EOL>if (sph6_ab is not None) and (not np.isnan(sph6_ab)):<EOL><INDENT>sec2_theta = <NUM_LIT:1.0>/(cos_theta*cos_theta)<EOL>wvfront += sph6_ab * (sec2_theta-<NUM_LIT:1>)*(sec2_theta-<NUM_LIT:2>)*cos_theta<EOL><DEDENT>if wvfront.dtype == np.dtype('<STR_LIT>'):<EOL><INDENT>wvfront.imag = -np.abs(wvfront.imag)<EOL><DEDENT>return wvfront<EOL>

Returns the wavefront aberration for an aberrated, defocused lens.

Calculates the portions of the wavefront distortion due to z, theta
only, for a lens with defocus and spherical aberration induced by
coverslip mismatch. (The rho portion can be analytically integrated
to Bessels.)

Parameters
----------
    cos_theta : numpy.ndarray.
        The N values of cos(theta) at which to compute f_theta.
    zint : Float
        The position of the lens relative to the interface.
    z : numpy.ndarray
        The M z-values to compute f_theta at. `z.size` is unrelated
        to `cos_theta.size`
    n2n1: Float, optional
        The ratio of the index of the immersed medium to the optics.
        Default is 0.95
    sph6_ab : Float or None, optional
        Set sph6_ab to a nonzero value to add residual 6th-order
        spherical aberration that is proportional to sph6_ab. Default
        is None (i.e. doesn't calculate).

Returns
-------
    wvfront : numpy.ndarray
        The aberrated wavefront, as a function of theta and z.
        Shape is [z.size, cos_theta.size]


def calculate_linescan_psf(x, y, z, normalize=False, kfki=<NUM_LIT>, zint=<NUM_LIT>,<EOL>polar_angle=<NUM_LIT:0.>, wrap=True, **kwargs):

<EOL>if wrap:<EOL><INDENT>xpts = vec_to_halfvec(x)<EOL>ypts = vec_to_halfvec(y)<EOL>x3, y3, z3 = np.meshgrid(xpts, ypts, z, indexing='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>x3,y3,z3 = np.meshgrid(x, y, z, indexing='<STR_LIT>')<EOL><DEDENT>rho3 = np.sqrt(x3*x3 + y3*y3)<EOL>if wrap:<EOL><INDENT>y2,z2 = np.meshgrid(ypts, z, indexing='<STR_LIT>')<EOL>hilm0 = calculate_linescan_ilm_psf(y2, z2, zint=zint,<EOL>polar_angle=polar_angle, **kwargs)<EOL>if ypts[<NUM_LIT:0>] == <NUM_LIT:0>:<EOL><INDENT>hilm = np.append(hilm0[-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>], hilm0, axis=<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>hilm = np.append(hilm0[::-<NUM_LIT:1>], hilm0, axis=<NUM_LIT:0>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>y2,z2 = np.meshgrid(y, z, indexing='<STR_LIT>')<EOL>hilm = calculate_linescan_ilm_psf(y2, z2, zint=zint,<EOL>polar_angle=polar_angle, **kwargs)<EOL><DEDENT>if wrap:<EOL><INDENT>func = lambda *args: get_hsym_asym(rho3*kfki, z3*kfki, zint=kfki*zint,<EOL>get_hdet=True, **kwargs)[<NUM_LIT:0>]<EOL>hdet = wrap_and_calc_psf(xpts, ypts, z, func)<EOL><DEDENT>else:<EOL><INDENT>hdet, toss = get_hsym_asym(rho3*kfki, z3*kfki, zint=kfki*zint,<EOL>get_hdet=True, **kwargs)<EOL><DEDENT>if normalize:<EOL><INDENT>hilm /= hilm.sum()<EOL>hdet /= hdet.sum()<EOL><DEDENT>for a in range(x.size):<EOL><INDENT>hdet[a] *= hilm<EOL><DEDENT>return hdet if normalize else hdet / hdet.sum()<EOL>

Calculates the point spread function of a line-scanning confocal.

Make x,y,z  __1D__ numpy.arrays, with x the direction along the
scan line. (to make the calculation faster since I dont' need the line
ilm for each x).

Parameters
----------
    x : numpy.ndarray
        _One_dimensional_ array of the x grid points (along the line
        illumination) at which to evaluate the psf. In units of
        1/k_incoming.
    y : numpy.ndarray
        _One_dimensional_ array of the y grid points (in plane,
        perpendicular to the line illumination) at which to evaluate
        the psf. In units of 1/k_incoming.
    z : numpy.ndarray
        _One_dimensional_ array of the z grid points (along the
        optical axis) at which to evaluate the psf. In units of
        1/k_incoming.
    normalize : Bool, optional
        Set to True to include the effects of PSF normalization on
        the image intensity. Default is False.
    kfki : Float, optional
        The ratio of the final light's wavevector to the incoming.
        Default is 0.889
    zint : Float, optional
        The position of the optical interface, in units of 1/k_incoming
        Default is 100.
    wrap : Bool, optional
        If True, wraps the psf calculation for speed, assuming that
        the input x, y are regularly-spaced points. If x,y are not
        regularly spaced then `wrap` must be set to False. Default is True.
    polar_angle : Float, optional
        The polarization angle of the light (radians) with respect to
        the line direction (x). Default is 0.

Other Parameters
----------------
    alpha : Float
        The opening angle of the lens. Default is 1.
    n2n1 : Float
        The ratio of the index in the 2nd medium to that in the first.
        Default is 0.95

Returns
-------
    numpy.ndarray
        A 3D- numpy.array of the point-spread function. Indexing is
        psf[x,y,z]; shape is [x.size, y,size, z.size]


scl = { <NUM_LIT:15>:<NUM_LIT>,<EOL><NUM_LIT:20>:<NUM_LIT>,<EOL><NUM_LIT>:<NUM_LIT>}[npts]<EOL>pts0, wts0 = np.polynomial.laguerre.laggauss(npts)<EOL>pts = np.sinh(pts0*scl)<EOL>wts = scl*wts0*np.cosh(pts0*scl)*np.exp(pts0)<EOL>return pts, wts<EOL>

Returns Gauss-Laguerre quadrature points rescaled for line scan integration

Parameters
----------
    npts : {15, 20, 25}, optional
        The number of points to

Notes
-----
    The scale is set internally as the best rescaling for a line scan
    integral; it was checked numerically for the allowed npts.
    Acceptable pts/scls/approximate line integral scan error:
    (pts,   scl  )      :         ERR
    ------------------------------------
    (15, 0.072144)      :       0.002193
    (20, 0.051532)      :       0.001498
    (25, 0.043266)      :       0.001209

    The previous HG(20) error was ~0.13ish


def wrap_and_calc_psf(xpts, ypts, zpts, func, **kwargs):

<EOL>for t in [xpts,ypts,zpts]:<EOL><INDENT>if len(t.shape) != <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>dx = <NUM_LIT:1> if xpts[<NUM_LIT:0>]==<NUM_LIT:0> else <NUM_LIT:0><EOL>dy = <NUM_LIT:1> if ypts[<NUM_LIT:0>]==<NUM_LIT:0> else <NUM_LIT:0><EOL>xg,yg,zg = np.meshgrid(xpts,ypts,zpts, indexing='<STR_LIT>')<EOL>xs, ys, zs = [ pts.size for pts in [xpts,ypts,zpts] ]<EOL>to_return = np.zeros([<NUM_LIT:2>*xs-dx, <NUM_LIT:2>*ys-dy, zs])<EOL>up_corner_psf = func(xg,yg,zg, **kwargs)<EOL>to_return[xs-dx:,ys-dy:,:] = up_corner_psf.copy()                     <EOL>if dx == <NUM_LIT:0>:<EOL><INDENT>to_return[:xs-dx,ys-dy:,:] = up_corner_psf[::-<NUM_LIT:1>,:,:].copy()       <EOL><DEDENT>else:<EOL><INDENT>to_return[:xs-dx,ys-dy:,:] = up_corner_psf[-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>,:,:].copy()    <EOL><DEDENT>if dy == <NUM_LIT:0>:<EOL><INDENT>to_return[xs-dx:,:ys-dy,:] = up_corner_psf[:,::-<NUM_LIT:1>,:].copy()       <EOL><DEDENT>else:<EOL><INDENT>to_return[xs-dx:,:ys-dy,:] = up_corner_psf[:,-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>,:].copy()    <EOL><DEDENT>if (dx == <NUM_LIT:0>) and (dy == <NUM_LIT:0>):<EOL><INDENT>to_return[:xs-dx,:ys-dy,:] = up_corner_psf[::-<NUM_LIT:1>,::-<NUM_LIT:1>,:].copy()    <EOL><DEDENT>elif (dx == <NUM_LIT:0>) and (dy != <NUM_LIT:0>):<EOL><INDENT>to_return[:xs-dx,:ys-dy,:] = up_corner_psf[::-<NUM_LIT:1>,-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>,:].copy() <EOL><DEDENT>elif (dy == <NUM_LIT:0>) and (dx != <NUM_LIT:0>):<EOL><INDENT>to_return[:xs-dx,:ys-dy,:] = up_corner_psf[-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>,::-<NUM_LIT:1>,:].copy() <EOL><DEDENT>else: <EOL><INDENT>to_return[:xs-dx,:ys-dy,:] = up_corner_psf[-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>,-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>,:].copy()<EOL><DEDENT>return to_return<EOL>

Wraps a point-spread function in x and y.

Speeds up psf calculations by a factor of 4 for free / some broadcasting
by exploiting the x->-x, y->-y symmetry of a psf function. Pass x and y
as the positive (say) values of the coordinates at which to evaluate func,
and it will return the function sampled at [x[::-1]] + x. Note it is not
wrapped in z.

Parameters
----------
    xpts : numpy.ndarray
        1D N-element numpy.array of the x-points to evaluate func at.
    ypts : numpy.ndarray
        y-points to evaluate func at.
    zpts : numpy.ndarray
        z-points to evaluate func at.
    func : function
        The function to evaluate and wrap around. Syntax must be
        func(x,y,z, **kwargs)
    **kwargs : Any parameters passed to the function.

Outputs
-------
    to_return : numpy.ndarray
        The wrapped and calculated psf, of shape
        [2*x.size - x0, 2*y.size - y0, z.size], where x0=1 if x[0]=0, etc.

Notes
-----
The coordinates should be something like numpy.arange(start, stop, diff),
with start near 0. If x[0]==0, all of x is calcualted but only x[1:]
is wrapped (i.e. it works whether or not x[0]=0).

This doesn't work directly for a linescan psf because the illumination
portion is not like a grid. However, the illumination and detection
are already combined with wrap_and_calc in calculate_linescan_psf etc.


@memoize()<EOL><INDENT>def _skew(self, x, z, d=<NUM_LIT:0>):<DEDENT>

<EOL>kval = (np.tanh(self._poly(z, self._kurtosis_coeffs(d)))+<NUM_LIT:1>)/<NUM_LIT><EOL>bdpoly = np.array([<EOL>-<NUM_LIT>,  <NUM_LIT>, -<NUM_LIT>,<EOL>-<NUM_LIT>, <NUM_LIT>, <NUM_LIT><EOL>])<EOL>top = np.polyval(bdpoly, kval)<EOL>skew = self._poly(z, self._skew_coeffs(d))<EOL>skewval = top*(np.tanh(skew) + <NUM_LIT:1>) - top<EOL>return skewval*(<NUM_LIT:3>*x - x**<NUM_LIT:3>)<EOL>

returns the kurtosis parameter for direction d, d=0 is rho, d=1 is z


@memoize()<EOL><INDENT>def _kurtosis(self, x, z, d=<NUM_LIT:0>):<DEDENT>

val = self._poly(z, self._kurtosis_coeffs(d))<EOL>return (np.tanh(val)+<NUM_LIT:1>)/<NUM_LIT>*(<NUM_LIT:3> - <NUM_LIT:6>*x**<NUM_LIT:2> + x**<NUM_LIT:4>)<EOL>


def randomize_parameters(self, ptp=<NUM_LIT>, fourier=False, vmin=None, vmax=None):

if vmin is not None and vmax is not None:<EOL><INDENT>ptp = vmax - vmin<EOL><DEDENT>elif vmax is not None and vmin is None:<EOL><INDENT>vmin = vmax - ptp<EOL><DEDENT>elif vmin is not None and vmax is None:<EOL><INDENT>vmax = vmin + ptp<EOL><DEDENT>else:<EOL><INDENT>vmax = <NUM_LIT:1.0><EOL>vmin = vmax - ptp<EOL><DEDENT>self.set_values(self.category+'<STR_LIT>', <NUM_LIT:1.0>)<EOL>self.set_values(self.category+'<STR_LIT>', <NUM_LIT:0.0>)<EOL>for k, v in iteritems(self.poly_params):<EOL><INDENT>norm = (self.zorder + <NUM_LIT:1.0>)*<NUM_LIT:2><EOL>self.set_values(k, ptp*(np.random.rand() - <NUM_LIT:0.5>) / norm)<EOL><DEDENT>for i, p in enumerate(self.barnes_params):<EOL><INDENT>N = len(p)<EOL>if fourier:<EOL><INDENT>t = ((np.random.rand(N)-<NUM_LIT:0.5>) + <NUM_LIT>*(np.random.rand(N)-<NUM_LIT:0.5>))/(np.arange(N)+<NUM_LIT:1>)<EOL>q = np.real(np.fft.ifftn(t)) / (i+<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>t = ptp*np.sqrt(N)*(np.random.rand(N)-<NUM_LIT:0.5>)<EOL>q = np.cumsum(t) / (i+<NUM_LIT:1>)<EOL><DEDENT>q = ptp * q / q.ptp() / len(self.barnes_params)<EOL>q -= q.mean()<EOL>self.set_values(p, q)<EOL><DEDENT>self._norm_stat = [ptp, vmin]<EOL>if self.shape:<EOL><INDENT>self.initialize()<EOL><DEDENT>if self._parent:<EOL><INDENT>param = self.category+'<STR_LIT>'<EOL>self.trigger_update(param, self.get_values(param))<EOL><DEDENT>

Create random parameters for this ILM that mimic experiments
as closely as possible without real assumptions.


def __init__(self, npts=(<NUM_LIT>,<NUM_LIT:20>), zorder=<NUM_LIT:7>, op='<STR_LIT:*>', barnes_dist=<NUM_LIT>,<EOL>barnes_clip_size=<NUM_LIT:3>, category='<STR_LIT>', shape=None,<EOL>float_precision=np.float64):

super(BarnesXYLegPolyZ, self).__init__(npts=npts, zorder=zorder,<EOL>op=op, barnes_dist=barnes_dist, barnes_clip_size=barnes_clip_size,<EOL>local_updates=True, category=category, shape=shape,<EOL>float_precision=float_precision)<EOL>

A Barnes interpolant. This one is of the form

.. math::
    I = \\left[1 + B(x,y) \\right]  (1 + z q(z)) + c

where B is a Barnes interpolants and q is a polynomial strictly in z.
Additionally.... operation multiply or x for poly?.
Always uses local updates, since evaluating a 2D barnes for an entire
image can be slow.

Parameters
----------
shape : iterable
    size of the field in pixels, needs to be padded shape

npts : 2-element tuple of ints, optional
    Number of control points used for the Barnes interpolant
    in x & y. Default is (40,20)

zorder : integer
    Number of orders for the z-polynomial.

op : string
    The operation to perform between Barnes and LegPoly, '*' or '+'.

barnes_dist : float
    Fractional distance to use for the barnes interpolator

local_updates : boolean
    Whether to perform local updates on the ILM

float_precision : numpy float datatype
    One of numpy.float16, numpy.float32, numpy.float64; precision
    for precomputed arrays. Default is np.float64; make it 16 or 32
    to save memory.


def __init__(self, npts=(<NUM_LIT>,<NUM_LIT:20>), zorder=<NUM_LIT:7>, op='<STR_LIT:*>', barnes_dist=<NUM_LIT>,<EOL>barnes_clip_size=<NUM_LIT:3>, local_updates=True, category='<STR_LIT>', shape=None,<EOL>float_precision=np.float64, donorm=True):

self.donorm = donorm<EOL>super(BarnesStreakLegPoly2P1D, self).__init__(npts=npts, zorder=zorder,<EOL>op=op, barnes_dist=barnes_dist, barnes_clip_size=barnes_clip_size,<EOL>local_updates=local_updates, category=category, shape=shape,<EOL>float_precision=float_precision)<EOL>

A Barnes interpolant. This one is of the form

.. math::
    I = \\left[1 + \\left(\\sum b_k(x) (o) L_k(y)\\right)\\right]  (1 + z q(z)) + c

where b_k are independent barnes interpolants and L_k are legendre
polynomials. q is a polynomial strictly in z. Additionally, the
operation (o) is settable.

Parameters
----------
shape : iterable
    size of the field in pixels, needs to be padded shape

npts : tuple of ints, optional
    Number of control points used for the Barnes interpolant b_k
    in the x-y sum. Default is (40,20)

zorder : integer
    Number of orders for the z-polynomial.

op : string
    The operation to perform between Barnes and LegPoly, '*' or '+'.

barnes_dist : float
    Fractional distance to use for the barnes interpolator

local_updates : boolean
    Whether to perform local updates on the ILM

float_precision : numpy float datatype
    One of numpy.float16, numpy.float32, numpy.float64; precision
    for precomputed arrays. Default is np.float64; make it 16 or 32
    to save memory.

donorm : Bool
    Whether or not to normalize the Barnes interpolation
    (compatibility patch). Use True, i.e. normalize the Barnes
    interpolant. Old version is False. Default is True.


return self._barnes(self.b_out)<EOL>

Returns the raveled values of the barnes on the field


def _kpad(self, field, finalshape, zpad=False, norm=True):

currshape = np.array(field.shape)<EOL>if any(finalshape < currshape):<EOL><INDENT>raise IndexError("<STR_LIT>")<EOL><DEDENT>d = finalshape - currshape<EOL>o = d % <NUM_LIT:2><EOL>d = np.floor_divide(d, <NUM_LIT:2>)<EOL>if not zpad:<EOL><INDENT>o[<NUM_LIT:0>] = <NUM_LIT:0><EOL><DEDENT>axes = None<EOL>pad = tuple((d[i]+o[i],d[i]) for i in [<NUM_LIT:0>,<NUM_LIT:1>,<NUM_LIT:2>])<EOL>rpsf = np.pad(field, pad, mode='<STR_LIT>', constant_values=<NUM_LIT:0>)<EOL>rpsf = np.fft.ifftshift(rpsf, axes=axes)<EOL>kpsf = fft.rfftn(rpsf, **fftkwargs)<EOL>if norm:<EOL><INDENT>kpsf /= kpsf[<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>]<EOL><DEDENT>return kpsf<EOL>

fftshift and pad the field with zeros until it has size finalshape.
if zpad is off, then no padding is put on the z direction. returns
the fourier transform of the field


mapper = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'<EOL>}<EOL>bads = [self.zscale, '<STR_LIT>']<EOL>d = {}<EOL>for k,v in iteritems(mapper):<EOL><INDENT>if k in self.param_dict:<EOL><INDENT>d[v] = self.param_dict[k]<EOL><DEDENT><DEDENT>d.update({<EOL>'<STR_LIT>': self.polar_angle,<EOL>'<STR_LIT>': self.normalize,<EOL>'<STR_LIT>':self.use_J1<EOL>})<EOL>if self.polychromatic:<EOL><INDENT>d.update({'<STR_LIT>': self.nkpts})<EOL>d.update({'<STR_LIT>': self.k_dist})<EOL><DEDENT>if self.do_pinhole:<EOL><INDENT>d.update({'<STR_LIT>': self.num_line_pts})<EOL><DEDENT>return d<EOL>

Pack the parameters into the form necessary for the integration
routines above.  For example, packs for calculate_linescan_psf


l,u = max(self.zrange[<NUM_LIT:0>], self.param_dict['<STR_LIT>']), self.zrange[<NUM_LIT:1>]<EOL>size_l, drift_l = self.measure_size_drift(l, size=self.support)<EOL>size_u, drift_u = self.measure_size_drift(u, size=self.support)<EOL>self.drift_poly = np.polyfit([l, u], [drift_l, drift_u], <NUM_LIT:1>)<EOL>

Get support size and drift polynomial for current set of params


def measure_size_drift(self, z, size=<NUM_LIT>, zoffset=<NUM_LIT:0.>):

drift = <NUM_LIT:0.0><EOL>for i in range(self.measurement_iterations):<EOL><INDENT>psf, vec = self.psf_slice(z, size=size, zoffset=zoffset+drift)<EOL>psf = psf / psf.sum()<EOL>drift += moment(psf, vec[<NUM_LIT:0>], order=<NUM_LIT:1>)<EOL>psize = [moment(psf, j, order=<NUM_LIT:2>) for j in vec]<EOL><DEDENT>return np.array(psize), drift<EOL>

Returns the 'size' of the psf in each direction a particular z (px)