Source code for nxtomomill.converter.hdf5.acquisition.zseriesacquisition

# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2015-2020 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/

"""
module to define a tomography z-series acquisition (made by bliss)
"""

__authors__ = [
    "H. Payno",
]
__license__ = "MIT"
__date__ = "27/11/2020"


from typing import Iterable

import h5py
import numpy
from silx.io.url import DataUrl
from silx.io.utils import h5py_read_dataset
from silx.utils.proxy import docstring

from nxtomomill.io.config import TomoHDF5Config

from .baseacquisition import BaseAcquisition, EntryReader
from .standardacquisition import StandardAcquisition

try:
    import hdf5plugin  # noqa F401
except ImportError:
    pass


[docs]def is_z_series_frm_titles(entry: h5py.Group, configuration: TomoHDF5Config) -> bool: """ is the provided h5py Group is tomography z series acquisition. the entry should be an 'initialization' entry. We will look on z_title_entries to know if this is a z entry or not """ try: title = h5py_read_dataset(entry["title"]) except Exception: return False else: for init_title in configuration.zserie_init_titles: if title.startswith(init_title): return True return False
[docs]def is_pcotomo_frm_titles(entry: h5py.Group, configuration: TomoHDF5Config) -> bool: """ if the provided h5py.Group must be consider as an "initialization" entry/scan of a pcotomo acquistion """ try: title = h5py_read_dataset(entry["title"]) except Exception: return False else: for pcotomo_init_title in configuration.pcotomo_init_titles: if title.startswith(pcotomo_init_title): return True return False
[docs]def is_z_series_frm_z_translation( projection_urls: Iterable, configuration: TomoHDF5Config ): """ :param Iterable projection_urls: list of DataUrl pointing to projection nodes. :return: True if the set of projections should be considered as a zserie """ z_values = set() for url in projection_urls: with EntryReader(url) as entry: z_values_tmp, _ = BaseAcquisition.get_z_translation_frm( entry, n_frame=None, configuration=configuration ) if z_values_tmp is not None: if isinstance(z_values_tmp, Iterable): z_values.update(z_values_tmp) else: z_values.add(z_values_tmp) return len(z_values) > 1
[docs]class ZSeriesBaseAcquisition(BaseAcquisition): """ A 'z serie acquisition' is considered as a serie of _StandardAcquisition. Registered scan can be split according to z_translation value. """
[docs] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._acquisitions = {} """key is z value and value is _StandardAcquisition"""
[docs] def get_expected_nx_tomo(self): return 1
[docs] def get_standard_sub_acquisitions(self) -> tuple: """ Return the tuple of all :class:`.StandardAcquisition` composing _acquisitions """ return tuple(self._acquisitions.values())
def get_z(self, entry): if not isinstance(entry, h5py.Group): raise TypeError("entry: expected h5py.Group") z_array = self._get_z_translation(entry, n_frame=None)[0] if z_array is None: raise ValueError(f"No z found for scan {entry.name}") if isinstance(z_array, (numpy.ndarray, tuple, list)): z_array = set(z_array) else: z_array = set((z_array,)) # might need an epsilon here ? if len(z_array) > 1: raise ValueError(f"More than one value of z found for {entry.name}") else: return z_array.pop()
[docs] @docstring(BaseAcquisition.register_step) def register_step( self, url: DataUrl, entry_type, copy_frames: bool = False ) -> None: """ :param url: """ with EntryReader(url) as entry: z = self.get_z(entry) if z not in self._acquisitions: self._acquisitions[z] = StandardAcquisition( root_url=url, configuration=self.configuration, detector_sel_callback=self._detector_sel_callback, start_index=self.start_index + len(self._acquisitions), parent=self, ) self._acquisitions[z].register_step( url=url, entry_type=entry_type, copy_frames=copy_frames )
@property def require_x_translation(self): return True @property def require_z_translation(self): return True @property def is_xrd_ct(self): return False
[docs] @docstring(BaseAcquisition) def is_different_sequence(self, entry): return True