Source code for libertem.analysis.masks

from .base import BaseAnalysis, AnalysisResultSet, AnalysisResult
from libertem.udf.masks import ApplyMasksUDF
from libertem.analysis.getroi import get_roi


class BaseMasksAnalysis(BaseAnalysis):
    """
    Base class for any masks-based analysis; you only need to implement
    ``get_results``, ``get_udf_results`` and ``get_mask_factories``.
    Overwrite  ``get_use_sparse`` to return True to calculate with sparse mask matrices.

    .. versionchanged:: 0.4.0
        Add support to use this Analysis with both ApplyMasksJob and ApplyMasksUDF :issue:`549`

    .. versionchanged:: 0.7.0
        ApplyMasksJob support removed
    """
    def get_udf(self):
        return ApplyMasksUDF(
            mask_factories=self.get_mask_factories(),
            use_sparse=self.get_use_sparse(),
            mask_count=self.get_preset_mask_count(),
            mask_dtype=self.get_preset_mask_dtype(),
            preferred_dtype=self.get_preset_dtype()
        )

    def get_mask_factories(self):
        raise NotImplementedError()

    def get_use_sparse(self):
        return self.parameters.get('use_sparse', None)

    def get_preset_mask_count(self):
        return self.parameters.get('mask_count', None)

    def get_preset_mask_dtype(self):
        return self.parameters.get('mask_dtype', None)

    def get_preset_dtype(self):
        return self.parameters.get('dtype', None)


class SingleMaskAnalysis(BaseMasksAnalysis):
    def get_udf_results(self, udf_results, roi, damage):
        data = udf_results['intensity'].data
        return self.get_generic_results(data[..., 0], damage=damage)

    def get_description(self):
        raise NotImplementedError

    def get_generic_results(self, data, damage):
        from libertem.viz import visualize_simple
        if data.dtype.kind == 'c':
            return SingleMaskResultSet(
                self.get_complex_results(
                    data,
                    key_prefix='intensity',
                    title='intensity',
                    desc=self.get_description(),
                    damage=damage,
                )
            )
        return SingleMaskResultSet([
            AnalysisResult(
                raw_data=data,
                visualized=visualize_simple(data, damage=damage),
                key="intensity", title="intensity [lin]",
                desc=f'{self.get_description()} lin-scaled'
            ),
            AnalysisResult(
                raw_data=data,
                visualized=visualize_simple(data, logarithmic=True, damage=damage),
                key="intensity_log", title="intensity [log]",
                desc=f'{self.get_description()} log-scaled'
            ),
        ])


[docs] class MasksResultSet(AnalysisResultSet): """ Running a :class:`MasksAnalysis` via :meth:`libertem.api.Context.run` on a dataset returns an instance of this class. If any of the masks or the dataset contain complex numbers, the regular mask results attributes carry the absolute value of the results, and additional attributes with real part, imaginary part, phase and full complex result are available. .. versionadded:: 0.3.0 Attributes ---------- mask_0, mask_1, ..., mask_<n> : libertem.analysis.base.AnalysisResult For dataset and masks containing only real numbers: Results of the element-wise multiplication and sum of each individual mask with each detector frame. Each mask result has the shape of the navigation dimension. These keys contain the absolute value of the result if dataset or masks contain complex numbers. mask_0, mask_0_real, mask_0_imag, mask_0_angle, mask_0_complex,\ mask_1, mask_1_real, ...,\ mask_<n>, ..., mask_<n>_complex : libertem.analysis.base.AnalysisResult If masks or dataset contain complex numbers: Absolute, real part, imaginary part, phase angle, complex result of the element-wise multiplication and sum of each individual mask with each detector frame. Each mask result has the shape of the navigation dimension. """ pass
[docs] class SingleMaskResultSet(AnalysisResultSet): """ A number of Analyses that are based on applying a single mask create an instance of this class as a result when executed via :meth:`libertem.api.Context.run`. If the dataset contains complex numbers, the regular result attribute carries the absolute value of the result, and additional attributes with real part, imaginary part, phase and full complex result are available. .. versionadded:: 0.3.0 Attributes ---------- intensity : libertem.analysis.base.AnalysisResult Sum of the selected region for each detector frame, with shape of the navigation dimension. Absolute of the result if the dataset or mask contains complex numbers. intensity_log : libertem.analysis.base.AnalysisResult Log-scaled sum of the selected region for each detector frame, with shape of the navigation dimension. Absolute of the result if the dataset or mask contains complex numbers. .. versionadded:: 0.6.0 intensity_real : libertem.analysis.base.AnalysisResult Real part of the sum of the selected region. This is only available if the dataset or mask contains complex numbers. intensity_imag : libertem.analysis.base.AnalysisResult Imaginary part of the sum of the selected region. This is only available if the dataset contains complex numbers. intensity_angle : libertem.analysis.base.AnalysisResult Phase angle of the sum of the selected region. This is only available if the dataset or mask contains complex numbers. intensity_complex : libertem.analysis.base.AnalysisResult Complex result of the sum of the selected region. This is only available if the dataset or mask contains complex numbers. """ pass
class MasksAnalysis(BaseMasksAnalysis): TYPE = 'UDF' def get_mask_factories(self): return self.parameters['factories'] def get_generic_results(self, data, damage): from libertem.viz import visualize_simple if data.dtype.kind == 'c': results = [] for idx in range(data.shape[-1]): results.extend( self.get_complex_results( data[..., idx], key_prefix="mask_%d" % idx, title="mask %d" % idx, desc="integrated intensity for mask %d" % idx, damage=damage ) ) return MasksResultSet(results) return MasksResultSet([ AnalysisResult( raw_data=data[..., idx], visualized=visualize_simple(data[..., idx], damage=damage), key="mask_%d" % idx, title="mask %d" % idx, desc="integrated intensity for mask %d" % idx) for idx in range(data.shape[-1]) ]) def get_roi(self): return get_roi(params=self.parameters, shape=self.dataset.shape.nav) def get_udf_results(self, udf_results, roi, damage): data = udf_results['intensity'].data return self.get_generic_results(data, damage=damage)