コード例 #1
0
def assign_signal_subclass(dtype,
                           signal_dimension,
                           signal_type="",
                           lazy=False):
    """Given record_by and signal_type return the matching Signal subclass.

    Parameters
    ----------
    dtype : :class:`~.numpy.dtype`
    signal_dimension: int
    signal_type : {None, "electron_diffraction", "diffraction_profile",
                   "diffraction_vectors", "crystallographic_map", str}
    lazy: bool

    Returns
    -------
    Signal or subclass

    """
    # TODO: This method needs to be re-written for pyXem signals!
    import hyperspy._lazy_signals
    from hyperspy.signal import BaseSignal
    # Check if parameter values are allowed:
    if np.issubdtype(dtype, np.complexfloating):
        dtype = 'complex'
    elif ('float' in dtype.name or 'int' in dtype.name or
          'void' in dtype.name or 'bool' in dtype.name or
          'object' in dtype.name):
        dtype = 'real'
    else:
        raise ValueError('Data type "{}" not understood!'.format(dtype.name))
    if not isinstance(signal_dimension, int) or signal_dimension < 0:
        raise ValueError("signal_dimension must be a positive interger")
    base_signals = find_subclasses(hyperspy.signals, BaseSignal)
    lazy_signals = find_subclasses(hyperspy._lazy_signals,
                                   hyperspy._lazy_signals.LazySignal)
    if lazy:
        signals = lazy_signals
    else:
        signals = {
            k: v for k,
            v in base_signals.items() if k not in lazy_signals}
    dtype_matches = [s for s in signals.values() if dtype == s._dtype]
    dtype_dim_matches = [s for s in dtype_matches
                         if signal_dimension == s._signal_dimension]
    dtype_dim_type_matches = [s for s in dtype_dim_matches if signal_type == s._signal_type
                              or signal_type in s._alias_signal_types]
    if dtype_dim_type_matches:
        # Perfect match found, return it.
        return dtype_dim_type_matches[0]
    elif [s for s in dtype_dim_matches if s._signal_type == ""]:
        # just signal_dimension and dtype matches
        # Return a general class for the given signal dimension.
        return [s for s in dtype_dim_matches if s._signal_type == ""][0]
    else:
        # no signal_dimension match either, hence return the general subclass for
        # correct dtype
        return [s for s in dtype_matches if s._signal_dimension == -
                1 and s._signal_type == ""][0]
コード例 #2
0
ファイル: test_inheritance.py プロジェクト: mstatkus/hyperspy
# This file is part of  HyperSpy.
#
#  HyperSpy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
#  HyperSpy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with  HyperSpy.  If not, see <http://www.gnu.org/licenses/>.

import numpy as np
import pytest

import hyperspy.signals
from hyperspy.misc.utils import find_subclasses
from hyperspy.signal import BaseSignal


@pytest.mark.parametrize("signal", find_subclasses(hyperspy.signals,
                                                   BaseSignal))
def test_lazy_signal_inheritance(signal):
    bs = getattr(hyperspy.signals, signal)
    s = bs(np.empty((2, ) * bs._signal_dimension))
    ls = s.as_lazy()
    assert isinstance(ls, bs)
コード例 #3
0
ファイル: io.py プロジェクト: swang29/kikuchipy
def assign_signal_subclass(dtype,
                           signal_dimension,
                           signal_type='',
                           lazy=False):
    """Given record_by and signal_type return the matching signal
    subclass.

    Parameters
    ----------
    dtype : :class:`~.numpy.dtype`
    signal_dimension : int
    signal_type : {'', 'EBSD', 'RadonTransform', str}, optional
    lazy : bool, optional

    Returns
    -------
    Signal or subclass
    """
    import kikuchipy.signals
    import kikuchipy.lazy_signals
    from hyperspy.signal import BaseSignal
    from hyperspy.signals import Signal1D, Signal2D
    from hyperspy._lazy_signals import LazySignal, LazySignal1D, LazySignal2D

    # Check if parameter values are allowed:
    if np.issubdtype(dtype, np.complexfloating):
        dtype = 'complex'
    elif ('float' in dtype.name or 'int' in dtype.name or 'void' in dtype.name
          or 'bool' in dtype.name or 'object' in dtype.name):
        dtype = 'real'
    else:
        raise ValueError("Data type '{}' not understood.".format(dtype.name))

    if not isinstance(signal_dimension, int) or signal_dimension < 0:
        raise ValueError("signal_dimension must be a positive integer.")

    base_signals = find_subclasses(kikuchipy.signals, BaseSignal)
    lazy_signals = find_subclasses(kikuchipy.lazy_signals, LazySignal)

    # Add HyperSpy's BaseSignal, Signal1D, Signal2D and their lazy partners for
    # when signal_type = ''
    base_signals.update({
        'BaseSignal': BaseSignal,
        'Signal1D': Signal1D,
        'Signal2D': Signal2D
    })
    lazy_signals.update({
        'LazySignal1D': LazySignal1D,
        'LazySignal2D': LazySignal2D
    })

    if lazy:
        signals = lazy_signals
    else:
        signals = {
            k: v
            for k, v in base_signals.items() if k not in lazy_signals
        }
    dtype_matches = [s for s in signals.values() if dtype == s._dtype]
    dtype_dim_matches = [
        s for s in dtype_matches if signal_dimension == s._signal_dimension
    ]
    dtype_dim_type_matches = [
        s for s in dtype_dim_matches if signal_type == s._signal_type
        or signal_type in s._alias_signal_types
    ]

    if dtype_dim_type_matches:  # Perfect match found, return it
        return dtype_dim_type_matches[0]
    elif [s for s in dtype_dim_matches if s._signal_type == '']:
        # Just signal_dimension and dtype matches
        # Return a general class for the given signal dimension
        return [s for s in dtype_dim_matches if s._signal_type == ''][0]
    else:
        # No signal_dimension match either, hence return the general subclass
        # for correct dtype
        return [
            s for s in dtype_matches
            if s._signal_dimension == -1 and s._signal_type == ''
        ][0]
コード例 #4
0
def _assign_signal_subclass(
    dtype: np.dtype,
    signal_dimension: int,
    signal_type: str = "",
    lazy: bool = False,
):
    """Given ``record_by`` and ``signal_type`` return the matching
    signal subclass.

    This function is a modified version of
    :func:`hyperspy.io.assign_signal_subclass`.

    Parameters
    ----------
    dtype
        Data type of signal data.
    signal_dimension
        Number of signal dimensions.
    signal_type
        Signal type. Options are ""/"EBSD"/"EBSDMasterPattern".
    lazy
        Open the data lazily without actually reading the data from disk
        until required. Allows opening arbitrary sized datasets. Default
        is False.

    Returns
    -------
    Signal or subclass
    """
    # Check if parameter values are allowed
    if (
        "float" in dtype.name
        or "int" in dtype.name
        or "void" in dtype.name
        or "bool" in dtype.name
        or "object" in dtype.name
    ):
        dtype = "real"
    else:
        raise ValueError(f"Data type '{dtype.name}' not understood.")
    if not isinstance(signal_dimension, int) or signal_dimension < 0:
        raise ValueError(
            "Signal dimension must be a positive integer and not "
            f"'{signal_dimension}'."
        )

    # Get possible signal classes
    signals = {
        key: value
        for key, value in find_subclasses(kikuchipy.signals, BaseSignal).items()
        if value._lazy == lazy
    }

    # Get signals matching both input signal's dtype and signal dimension
    dtype_matches = [s for s in signals.values() if s._dtype == dtype]
    dtype_dim_matches = [
        s for s in dtype_matches if s._signal_dimension == signal_dimension
    ]
    dtype_dim_type_matches = [
        s
        for s in dtype_dim_matches
        if signal_type == s._signal_type or signal_type in s._alias_signal_types
    ]

    if len(dtype_dim_type_matches) == 1:
        matches = dtype_dim_type_matches
    else:
        raise ValueError(
            f"No kikuchipy signals match dtype '{dtype}', signal dimension "
            f"'{signal_dimension}' and signal_type '{signal_type}'."
        )

    return matches[0]
コード例 #5
0
ファイル: test_inheritance.py プロジェクト: woozey/hyperspy
import numpy as np
import pytest

from hyperspy.misc.utils import find_subclasses
from hyperspy.signal import BaseSignal
import hyperspy.signals


@pytest.mark.parametrize("signal",
                         find_subclasses(hyperspy.signals, BaseSignal))
def test_lazy_signal_inheritance(signal):
    bs = getattr(hyperspy.signals, signal)
    s = bs(np.empty((2,) * bs._signal_dimension))
    ls = s.as_lazy()
    assert isinstance(ls, bs)