<commit_before>import copy

import h5py
import numpy as np
from skimage.restoration import unwrap_phase

from . import holo
from .image_data import Amplitude, Phase
from .meta import MetaDict, META_KEYS
from ._version import version as __version__

VALID_INPUT_DATA = ["field",
                    "hologram",
                    "phase",
                    ("phase", "amplitude"),
                    ("phase", "intensity"),
                    ]


class QPImage(object):
    _instances = 0

    def __init__(self, data=None, bg_data=None, which_data="phase",
                 meta_data={}, h5file=None, h5mode="a"
                 ):
        """Quantitative phase image manipulation

        This class implements various tasks for quantitative phase
        imaging, including phase unwrapping, background correction,
        numerical focusing, and data export.

        Parameters
        ----------
        data: 2d ndarray (float or complex) or list
            The experimental data (see `which_data`)
        bg_data: 2d ndarray (float or complex), list, or `None`
            The background data (must be same type as `data`)
        which_data: str
            String or comma-separated list of strings indicating
            the order and type of input data. Valid values are
            "field", "phase", "phase,amplitude", or "phase,intensity",
            where the latter two require an indexable object with
            the phase data as first element.
        meta_data: dict
            Meta data associated with the input data.
            see :py:class:`qpimage.META_KEYS`
        h5file: str, h5py.Group, h5py.File, or None
            A path to an hdf5 data file where all data is cached. If
            set to `None` (default), all data will be handled in
            memory using the "core" driver of the :mod:`h5py`'s
            :class:`h5py:File` class. If the file does not exist,
            it is created. If the file already exists, it is opened
            with the file mode defined by `hdf5_mode`. If this is
            an instance of h5py.Group or h5py.File, then this will
            be used to internally store all data.
        h5mode: str
            Valid file modes are (only applies if `h5file` is a path)
              - "r": Readonly, file must exist
              - "r+": Read/write, file must exist
              - "w": Create file, truncate if exists
              - "w-" or "x": Create file, fail if exists
              - "a": Read/write if exists, create otherwise (default)

        Notes
        -----
        QPImage is slicable; the following returns a new QPImage with
        the same meta data, but with all background corrections merged
        into the raw data:

        .. code-block:: python

            qpi = QPImage(data=...)
            qpi_scliced = qpi[10:20, 40:30]
        """
        if data and not isinstance(data, np.ndarray):
            msg = "`data` must be numpy.ndarray!"
            if isinstance(data, str):
                msg += " Did you mean `h5file={}`?".format(data)
            raise ValueError(msg)
        if isinstance(h5file, h5py.Group):
            self.h5 = h5file
            self._do_h5_cleanup = False
        else:
            if h5file is None:
                h5kwargs = {"name": "qpimage{}.h5".format(QPImage._instances),
                            "driver": "core",
                            "backing_store": False,
                            "mode": "a"}
            else:
                h5kwargs = {"name": str(h5file),
                            "mode": h5mode}
            self.h5 = h5py.File(**h5kwargs)<commit_msg>Regression: test against None and allow tuple and list<commit_after>import copy

import h5py
import numpy as np
from skimage.restoration import unwrap_phase

from . import holo
from .image_data import Amplitude, Phase
from .meta import MetaDict, META_KEYS
from ._version import version as __version__

VALID_INPUT_DATA = ["field",
                    "hologram",
                    "phase",
                    ("phase", "amplitude"),
                    ("phase", "intensity"),
                    ]


class QPImage(object):
    _instances = 0

    def __init__(self, data=None, bg_data=None, which_data="phase",
                 meta_data={}, h5file=None, h5mode="a"
                 ):
        """Quantitative phase image manipulation

        This class implements various tasks for quantitative phase
        imaging, including phase unwrapping, background correction,
        numerical focusing, and data export.

        Parameters
        ----------
        data: 2d ndarray (float or complex) or list
            The experimental data (see `which_data`)
        bg_data: 2d ndarray (float or complex), list, or `None`
            The background data (must be same type as `data`)
        which_data: str
            String or comma-separated list of strings indicating
            the order and type of input data. Valid values are
            "field", "phase", "phase,amplitude", or "phase,intensity",
            where the latter two require an indexable object with
            the phase data as first element.
        meta_data: dict
            Meta data associated with the input data.
            see :py:class:`qpimage.META_KEYS`
        h5file: str, h5py.Group, h5py.File, or None
            A path to an hdf5 data file where all data is cached. If
            set to `None` (default), all data will be handled in
            memory using the "core" driver of the :mod:`h5py`'s
            :class:`h5py:File` class. If the file does not exist,
            it is created. If the file already exists, it is opened
            with the file mode defined by `hdf5_mode`. If this is
            an instance of h5py.Group or h5py.File, then this will
            be used to internally store all data.
        h5mode: str
            Valid file modes are (only applies if `h5file` is a path)
              - "r": Readonly, file must exist
              - "r+": Read/write, file must exist
              - "w": Create file, truncate if exists
              - "w-" or "x": Create file, fail if exists
              - "a": Read/write if exists, create otherwise (default)

        Notes
        -----
        QPImage is slicable; the following returns a new QPImage with
        the same meta data, but with all background corrections merged
        into the raw data:

        .. code-block:: python

            qpi = QPImage(data=...)
            qpi_scliced = qpi[10:20, 40:30]
        """
        if (data is not None and
                not isinstance(data, (np.ndarray, list, tuple))):
            msg = "`data` must be numpy.ndarray!"
            if isinstance(data, str):
                msg += " Did you mean `h5file={}`?".format(data)
            raise ValueError(msg)
        if isinstance(h5file, h5py.Group):
            self.h5 = h5file
            self._do_h5_cleanup = False
        else:
            if h5file is None:
                h5kwargs = {"name": "qpimage{}.h5".format(QPImage._instances),
                            "driver": "core",
                            "backing_store": False,
                            "mode": "a"}
            else:
                h5kwargs = {"name": str(h5file),
                            "mode": h5mode}
            self.h5 = h5py.File(**h5kwargs)
{'fraction_non_alphanumeric': 0.08800326441784548, 'fraction_numerical': 0.01088139281828074, 'mean_word_length': 1.7092851879145172, 'pattern_counts': {'":': 22, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1626070', 'n_tokens_mistral': 2008, 'n_tokens_neox': 1931, 'n_words': 740}