Пример #1
0
def cbed_frame(fy=128, fx=128, zero=None, a=None, b=None, indices=None, radius=4, all_equal=False):
    if zero is None:
        zero = (fy//2, fx//2)
    zero = np.array(zero)
    if a is None:
        a = (fy//8, 0)
    a = np.array(a)
    if b is None:
        b = make_cartesian(make_polar(a) - (0, np.pi/2))
    b = np.array(b)
    if indices is None:
        indices = np.mgrid[-10:11, -10:11]
    indices, peaks = frame_peaks(fy=fy, fx=fx, zero=zero, a=a, b=b, r=radius, indices=indices)

    data = np.zeros((1, fy, fx), dtype=np.float32)

    dists = np.linalg.norm(peaks - zero, axis=-1)
    max_dist = dists.max()

    for i, p in enumerate(peaks):
        data += m.circular(
            centerX=p[1],
            centerY=p[0],
            imageSizeX=fx,
            imageSizeY=fy,
            radius=radius,
            antialiased=True,
        ) * (1 if all_equal else max_dist - dists[i] + i)

    return (data, indices, peaks)
Пример #2
0
def run_refine(ctx,
               dataset,
               zero,
               a,
               b,
               match_pattern: MatchPattern,
               matcher: grm.Matcher,
               correlation='fast',
               match='fast',
               indices=None,
               steps=5,
               zero_shift=None,
               roi=None,
               progress=False):
    '''
    Wrapper function to refine the given lattice for each frame by calculating
    approximate peak positions and refining them for each frame using a
    combination of :class:`libertem_blobfinder.CorrelationUDF` and
    :class:`libertem_blobfinder.RefinementMixin`.

    .. versionchanged:: 0.3.0
        Support for :class:`FullFrameCorrelationUDF`
        through parameter :code:`correlation = 'fullframe'`

    Parameters
    ----------

    ctx : libertem.api.Context
        Instance of a LiberTEM :class:`~libertem.api.Context`
    dataset : libertem.io.dataset.base.DataSet
        Instance of a :class:`~libertem.io.dataset.base.DataSet`
    zero : numpy.ndarray
        Approximate value for "zero" point (y, x) in px (origin, zero order
        peak)
    a : numpy.ndarray
        Approximate value for "a" vector (y, x) in px.
    b : numpy.ndarray
        Approximate value for "b" vector (y, x) in px.
    match_pattern : MatchPattern
        Instance of :class:`~MatchPattern`
    matcher : libertem.analysis.gridmatching.Matcher
        Instance of :class:`~libertem.analysis.gridmatching.Matcher` to perform the matching
    correlation : {'fast', 'sparse', 'fullframe'}, optional
        'fast', 'sparse' or 'fullframe' to select :class:`~FastCorrelationUDF`,
        :class:`~SparseCorrelationUDF` or :class:`~FullFrameCorrelationUDF`
    match : {'fast', 'affine'}, optional
        'fast' or 'affine' to select
        :class:`~FastmatchMixin` or :class:`~AffineMixin`
    indices : numpy.ndarray, optional
        Indices to refine. This is trimmed down to
        positions within the frame. As a convenience, for the indices parameter
        this function accepts both shape (n, 2) and (2, n, m) so that
        numpy.mgrid[h:k, i:j] works directly to specify indices. This saves
        boilerplate code when using this function.
        Default: numpy.mgrid[-10:10, -10:10].
    steps : int, optional
        Only for correlation == 'sparse': Correlation steps. See
        :meth:`~SparseCorelationUDF.__init__` for
        details.
    zero_shift : Union[AUXBufferWrapper, numpy.ndarray, None], optional
        Zero shift, for example descan error. Can be :code:`None`, :code:`numpy.array((y, x))`
        or AUX data with :code:`(y, x)` for each frame. Only supported for correlation methods
        :code:`fast` and `fullframe`.
    roi : numpy.ndarray, optional
        ROI for :meth:`~libertem.api.Context.run_udf`
    progress : bool, optional
        Show progress bar. Default :code:`False`

    Returns
    -------
    result : Dict[str, BufferWrapper]
        Result buffers of the UDF. See
        :meth:`libertem_blobfinder.correlation.CorrelationUDF.get_result_buffers` and
        :meth:`RefinementMixin.get_result_buffers` for details on the available
        buffers.
    used_indices : numpy.ndarray
        The peak indices that were within the frame.

    Examples
    --------

    >>> dataset = ctx.load(
    ...     filetype="memory",
    ...     data=np.zeros(shape=(2, 2, 128, 128), dtype=np.float32)
    ... )
    >>> (result, used_indices) = run_refine(
    ...     ctx, dataset,
    ...     zero=(64, 64), a=(1, 0), b=(0, 1),
    ...     match_pattern=libertem_blobfinder.common.patterns.RadialGradient(radius=4),
    ...     matcher=grm.Matcher()
    ... )
    >>> result['centers'].data  #doctest: +ELLIPSIS
    array(...)
    '''
    if indices is None:
        indices = np.mgrid[-10:11, -10:11]

    (fy, fx) = tuple(dataset.shape.sig)

    indices, peaks = frame_peaks(fy=fy,
                                 fx=fx,
                                 zero=zero,
                                 a=a,
                                 b=b,
                                 r=match_pattern.search,
                                 indices=indices)
    peaks = peaks.astype('int')

    if correlation == 'fast':
        method = FastCorrelationUDF
    elif correlation == 'sparse':
        method = SparseCorrelationUDF
    elif correlation == 'fullframe':
        method = FullFrameCorrelationUDF
    else:
        raise ValueError(
            "Unknown correlation method %s. Supported are 'fast' and 'sparse'"
            % correlation)

    if match == 'affine':
        mixin = AffineMixin
    elif match == 'fast':
        mixin = FastmatchMixin
    else:
        raise ValueError(
            "Unknown match method %s. Supported are 'fast' and 'affine'" %
            match)

    # The inheritance order matters: FIRST the mixin, which calls
    # the super class methods.
    class MyUDF(mixin, method):
        pass

    udf = MyUDF(
        peaks=peaks,
        indices=indices,
        start_zero=zero,
        start_a=a,
        start_b=b,
        match_pattern=match_pattern,
        matcher=matcher,
        steps=steps,
        zero_shift=zero_shift,
    )

    result = ctx.run_udf(dataset=dataset, udf=udf, roi=roi, progress=progress)
    return (result, indices)
Пример #3
0
def run_refine(ctx,
               dataset,
               zero,
               a,
               b,
               match_pattern: MatchPattern,
               matcher: grm.Matcher,
               correlation='fast',
               match='fast',
               indices=None,
               steps=5,
               roi=None):
    '''
    Refine the given lattice for each frame by calculating approximate peak positions and refining
    them for each frame by using the blobcorrelation and methods of
    :class:`~libertem.analysis.gridmatching.Matcher`.

    Parameters
    ----------

    ctx : libertem.api.Context
        Instance of a LiberTEM :class:`~libertem.api.Context`
    dataset : libertem.io.dataset.base.DataSet
        Instance of a :class:`~libertem.io.dataset.base.DataSet`
    zero : numpy.ndarray
        Approximate value for "zero" point (y, x) in px (origin, zero order peak)
    a : numpy.ndarray
        Approximate value for "a" vector (y, x) in px.
    b : numpy.ndarray
        Approximate value for "b" vector (y, x) in px.
    match_pattern : MatchPattern
        Instance of :class:`~MatchPattern`
    matcher : libertem.analysis.gridmatching.Matcher
        Instance of :class:`~libertem.analysis.gridmatching.Matcher` to perform the matching
    correlation : {'fast', 'sparse'}, optional
        'fast' or 'sparse' to select :class:`~FastCorrelationUDF` or :class:`~SparseCorrelationUDF`
    match : {'fast', 'affine'}, optional
        'fast' or 'affine' to select :class:`~FastmatchMixin` or :class:`~AffineMixin`
    indices : numpy.ndarray, optional
        Indices to refine. This is trimmed down to positions within the frame.
        As a convenience, for the indices parameter this function accepts both shape
        (n, 2) and (2, n, m) so that numpy.mgrid[h:k, i:j] works directly to specify indices.
        This saves boilerplate code when using this function. Default: numpy.mgrid[-10:10, -10:10].
    steps : int, optional
        Only for correlation == 'sparse': Correlation steps.
        See :meth:`~SparseCorelationUDF.__init__` for details.
    roi : numpy.ndarray, optional
        ROI for :meth:`~libertem.api.Context.run_udf`

    Returns
    -------

    Tuple[Dict[str, BufferWrapper], numpy.ndarray]
        :code:`(result, used_indices)` where :code:`result` is a :code:`dict`
        mapping buffer names to result buffers based on

        .. code-block:: python

            {
                'centers': BufferWrapper(
                    kind="nav", extra_shape=(num_disks, 2), dtype="u2"
                ),
                'refineds': BufferWrapper(
                    kind="nav", extra_shape=(num_disks, 2), dtype="float32"
                ),
                'peak_values': BufferWrapper(
                    kind="nav", extra_shape=(num_disks,), dtype="float32"
                ),
                'peak_elevations': BufferWrapper(
                    kind="nav", extra_shape=(num_disks,), dtype="float32"
                ),
                'zero': BufferWrapper(
                    kind="nav", extra_shape=(2,), dtype="float32"
                ),
                'a': BufferWrapper(
                    kind="nav", extra_shape=(2,), dtype="float32"
                ),
                'b': BufferWrapper(
                    kind="nav", extra_shape=(2,), dtype="float32"
                ),
                'selector': BufferWrapper(
                    kind="nav", extra_shape=(num_disks,), dtype="bool"
                ),
                'error': self.buffer(
                    kind="nav", dtype="float32",
                ),
            }

        and :code:`used_indices` are the indices that were within the frame.

    Examples
    --------

    >>> dataset = ctx.load(
    ...     filetype="memory",
    ...     data=np.zeros(shape=(2, 2, 128, 128), dtype=np.float32)
    ... )
    >>> (result, used_indices) = run_refine(
    ...     ctx, dataset,
    ...     zero=(64, 64), a=(1, 0), b=(0, 1),
    ...     match_pattern=RadialGradient(radius=4),
    ...     matcher=grm.Matcher()
    ... )
    >>> result['centers'].data  #doctest: +ELLIPSIS
    array(...)

    '''
    if indices is None:
        indices = np.mgrid[-10:11, -10:11]

    (fy, fx) = tuple(dataset.shape.sig)

    indices, peaks = frame_peaks(fy=fy,
                                 fx=fx,
                                 zero=zero,
                                 a=a,
                                 b=b,
                                 r=match_pattern.search,
                                 indices=indices)
    peaks = peaks.astype('int')

    if correlation == 'fast':
        method = FastCorrelationUDF
    elif correlation == 'sparse':
        method = SparseCorrelationUDF
    else:
        raise ValueError(
            "Unknown correlation method %s. Supported are 'fast' and 'sparse'"
            % correlation)

    if match == 'affine':
        mixin = AffineMixin
    elif match == 'fast':
        mixin = FastmatchMixin
    else:
        raise ValueError(
            "Unknown match method %s. Supported are 'fast' and 'affine'" %
            match)

    # The inheritance order matters: FIRST the mixin, which calls
    # the super class methods.
    class MyUDF(mixin, method):
        pass

    udf = MyUDF(peaks=peaks,
                indices=indices,
                start_zero=zero,
                start_a=a,
                start_b=b,
                match_pattern=match_pattern,
                matcher=matcher,
                steps=steps)

    result = ctx.run_udf(
        dataset=dataset,
        udf=udf,
        roi=roi,
    )
    return (result, indices)