GitLab will be upgraded on June 23rd evening. During the upgrade the service will be unavailable, sorry for the inconvenience.

Commit e2abf744 authored by payno's avatar payno

Merge branch 'handle_zserie_grp' into 'master'

Handle zserie grp

See merge request !39
parents 0559c556 69b6190d
Pipeline #44349 passed with stages
in 15 minutes and 4 seconds
Change Log
==========
0.5.0: XXXX/YY/ZZ
-----------------
* esrf
* TomoScanBase: add properties `sequence_name`, `sample_name` and `group_size`
* utils: add the concept of groups. A group for example is a set of sequences defining a zseries
0.4.0: 2020/11/09
-----------------
......
......@@ -28,3 +28,6 @@ __license__ = "MIT"
__date__ = "09/08/2018"
TYPES = ["EDF", "HDF5"]
from .hdf5scan import HDF5TomoScan
from .edfscan import EDFTomoScan
......@@ -89,6 +89,14 @@ class HDF5TomoScan(TomoScanBase):
_ROTATION_ANGLE_PATH = "sample/rotation_angle"
_SAMPLE_PATH = "sample"
_NAME_PATH = "sample/name"
_GRP_SIZE_ATTR = "group_size"
_SAMPLE_NAME_PATH = "sample/sample_name"
_X_TRANS_PATH = "sample/x_translation"
_Y_TRANS_PATH = "sample/y_translation"
......@@ -160,7 +168,9 @@ class HDF5TomoScan(TomoScanBase):
"unable to find a valid entry for %s" % self.master_file
)
# for now the default entry is 1_tomo but should change with time
self._name = None
self._sample_name = None
self._grp_size = None
# data caches
self._projections_compacted = None
self._flats = None
......@@ -355,6 +365,44 @@ class HDF5TomoScan(TomoScanBase):
def entry(self) -> str:
return self._entry
@property
def sequence_name(self):
"""Return the sequence name"""
if self._name is None and self.master_file and os.path.exists:
self._check_hdf5scan_validity()
with HDF5File(self.master_file, "r") as h5_file:
if self._NAME_PATH in h5_file[self._entry]:
self._name = h5py_read_dataset(
h5_file[self._entry][self._NAME_PATH]
)
return self._name
@property
@docstring(TomoScanBase.projections)
def sample_name(self):
if self._sample_name is None and self.master_file and os.path.exists:
self._check_hdf5scan_validity()
with HDF5File(self.master_file, "r") as h5_file:
if self._SAMPLE_NAME_PATH in h5_file[self._entry]:
self._sample_name = h5py_read_dataset(
h5_file[self._entry][self._SAMPLE_NAME_PATH]
)
return self._sample_name
@property
@docstring(TomoScanBase.projections)
def group_size(self):
if self._grp_size is None and self.master_file and os.path.exists:
self._check_hdf5scan_validity()
with HDF5File(self.master_file, "r") as h5_file:
if self._SAMPLE_PATH in h5_file[self._entry]:
grp = h5_file[self._entry][self._SAMPLE_PATH]
if self._GRP_SIZE_ATTR in grp.attrs:
self._grp_size = h5py_read_dataset(
grp.attrs[self._GRP_SIZE_ATTR]
)
return self._grp_size
@property
@docstring(TomoScanBase.projections)
def projections(self) -> typing.Union[dict, None]:
......
......@@ -31,8 +31,13 @@ __date__ = "10/10/2019"
import os
import fabio
from silx.io.url import DataUrl
from tomoscan.scanbase import TomoScanBase
from typing import Union
from typing import Iterable
import numpy
import logging
_logger = logging.getLogger(__name__)
def get_parameters_frm_par_or_info(file_: str) -> dict:
......@@ -172,3 +177,71 @@ def get_compacted_dataslices(urls):
)
)
return res
def from_sequences_to_grps(scans: Iterable) -> tuple:
"""
create group with the same sample name
:param Iterable scans:
:return: tuple of group of scans
"""
grps = {}
for scan in scans:
if not isinstance(scan, TomoScanBase):
raise TypeError("Elements are expected to be instance of " "TomoScanBase")
if scan.sample_name in grps:
grps[scan.sample_name].append(scan)
else:
grps[scan.sample_name] = [
scan,
]
return tuple(grps.values())
def check_grp_is_valid(scans: Iterable):
"""
Insure the provided group of scan is valid. Otherwise raise an error
:param Iterable scans: group of TomoScanBAse to check
"""
l_scans = set()
for scan in scans:
if not isinstance(scan, TomoScanBase):
raise TypeError("Elements are expected to be instance of " "TomoScanBase")
if scan in l_scans:
raise ValueError("{} is present at least twice")
elif len(l_scans) > 0:
if list(l_scans)[0].sample_name != scan.sample_name:
raise ValueError(
"{} and {} are from two different sample".format(scan, l_scans)
)
l_scans.add(scan)
def grp_is_complete(scans: Iterable) -> bool:
"""
Insure the provided group of scan is valid. Otherwise raise an error
:param Iterable scans: group of TomoScanBAse to check
:return: True if the group is complete
:rtype: bool
"""
if len(scans) == 0:
return True
try:
check_grp_is_valid(scans=scans)
except Exception as e:
_logger.error("provided group is invalid. {}".format(e))
else:
group_size = list(scans)[0].group_size
if group_size is None:
_logger.warning("No information found regarding group size")
return True
elif group_size == len(scans):
return True
elif group_size < len(scans):
_logger.warning("more scans found than group_size")
return True
else:
return False
......@@ -299,6 +299,22 @@ class TomoScanBase:
"""Parse the root folder and files to update informations"""
raise NotImplementedError("Base class")
@property
def sequence_name(self):
"""Return the sequence name"""
raise NotImplementedError("Base class")
@property
def sample_name(self):
"""Return the sample name"""
raise NotImplementedError("Base class")
@property
def group_size(self):
"""Used in the case of zseries for example. Return the number of
sequence expected on the acquisition"""
raise NotImplementedError("Base class")
def to_dict(self) -> dict:
"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment