diff options
Diffstat (limited to 'silx/io/nxdata')
-rw-r--r-- | silx/io/nxdata/__init__.py | 4 | ||||
-rw-r--r-- | silx/io/nxdata/_utils.py | 5 | ||||
-rw-r--r-- | silx/io/nxdata/parse.py | 93 | ||||
-rw-r--r-- | silx/io/nxdata/write.py | 5 |
4 files changed, 83 insertions, 24 deletions
diff --git a/silx/io/nxdata/__init__.py b/silx/io/nxdata/__init__.py index 796810f..5bfa442 100644 --- a/silx/io/nxdata/__init__.py +++ b/silx/io/nxdata/__init__.py @@ -51,6 +51,8 @@ Functions .. autofunction:: is_valid_nxdata +.. autofunction:: is_group_with_default_NXdata + .. autofunction:: is_NXentry_with_default_NXdata .. autofunction:: is_NXroot_with_default_NXdata @@ -59,6 +61,6 @@ Functions """ from .parse import NXdata, get_default, is_valid_nxdata, InvalidNXdataError, \ - is_NXentry_with_default_NXdata, is_NXroot_with_default_NXdata + is_NXentry_with_default_NXdata, is_NXroot_with_default_NXdata, is_group_with_default_NXdata from ._utils import get_attr_as_unicode, get_attr_as_string, nxdata_logger from .write import save_NXdata diff --git a/silx/io/nxdata/_utils.py b/silx/io/nxdata/_utils.py index 077f01d..8b3474a 100644 --- a/silx/io/nxdata/_utils.py +++ b/silx/io/nxdata/_utils.py @@ -25,12 +25,13 @@ """Utility functions used by NXdata validation and parsing.""" import copy -import numpy import logging +import numpy +import six + from silx.io import is_dataset from silx.utils.deprecation import deprecated -from silx.third_party import six __authors__ = ["P. Knobel"] diff --git a/silx/io/nxdata/parse.py b/silx/io/nxdata/parse.py index daf1b2e..cce47ab 100644 --- a/silx/io/nxdata/parse.py +++ b/silx/io/nxdata/parse.py @@ -1,7 +1,7 @@ # coding: utf-8 # /*########################################################################## # -# Copyright (c) 2017-2018 European Synchrotron Radiation Facility +# Copyright (c) 2017-2019 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 @@ -37,21 +37,23 @@ Other public functions: - :func:`is_valid_nxdata` - :func:`is_NXroot_with_default_NXdata` - :func:`is_NXentry_with_default_NXdata` + - :func:`is_group_with_default_NXdata` """ import numpy +import six + from silx.io.utils import is_group, is_file, is_dataset from ._utils import get_attr_as_unicode, INTERPDIM, nxdata_logger, \ get_uncertainties_names, get_signal_name, \ get_auxiliary_signals_names, validate_auxiliary_signals, validate_number_of_axes -from silx.third_party import six __authors__ = ["P. Knobel"] __license__ = "MIT" -__date__ = "17/04/2018" +__date__ = "15/02/2019" class InvalidNXdataError(Exception): @@ -136,7 +138,7 @@ class NXdata(object): self.axes_names = [] # check if axis dataset defines @long_name - for i, dsname in enumerate(self.axes_dataset_names): + for _, dsname in enumerate(self.axes_dataset_names): if dsname is not None and "long_name" in self.group[dsname].attrs: self.axes_names.append(get_attr_as_unicode(self.group[dsname], "long_name")) else: @@ -151,6 +153,7 @@ class NXdata(object): raise TypeError("group must be a h5py-like group") if get_attr_as_unicode(self.group, "NX_class") != "NXdata": self.issues.append("Group has no attribute @NX_class='NXdata'") + return signal_name = get_signal_name(self.group) if signal_name is None: @@ -180,8 +183,14 @@ class NXdata(object): uncertainties_names = get_uncertainties_names(self.group, signal_name) if uncertainties_names is not None: if len(uncertainties_names) != len(axes_names): - self.issues.append("@uncertainties does not define the same " + - "number of fields than @axes") + if len(uncertainties_names) < len(axes_names): + # ignore the field to avoid index error in the axes loop + uncertainties_names = None + self.issues.append("@uncertainties does not define the same " + + "number of fields than @axes. Field ignored") + else: + self.issues.append("@uncertainties does not define the same " + + "number of fields than @axes") # Test individual axes is_scatter = True # true if all axes have the same size as the signal @@ -364,7 +373,7 @@ class NXdata(object): if not self.is_valid: raise InvalidNXdataError("Unable to parse invalid NXdata") - allowed_interpretations = [None, "scalar", "spectrum", "image", + allowed_interpretations = [None, "scaler", "scalar", "spectrum", "image", "rgba-image", # "hsla-image", "cmyk-image" "vertex"] @@ -374,7 +383,7 @@ class NXdata(object): if interpretation not in allowed_interpretations: nxdata_logger.warning("Interpretation %s is not valid." % interpretation + - " Valid values: " + ", ".join(allowed_interpretations)) + " Valid values: " + ", ".join(str(s) for s in allowed_interpretations)) return interpretation @property @@ -737,6 +746,28 @@ class NXdata(object): return False return True + @property + def is_volume(self): + """True in the signal is exactly 3D and interpretation + "scalar", or nothing. + + The axes length must also be consistent with the 3 dimensions + of the signal. + """ + if not self.is_valid: + raise InvalidNXdataError("Unable to parse invalid NXdata") + + if self.signal_ndim != 3: + return False + if self.interpretation not in [None, "scalar", "scaler"]: + # 'scaler' and 'scalar' for a three dimensional array indicate a scalar field in 3D + return False + volume_shape = self.signal.shape[-3:] + for i, axis in enumerate(self.axes[-3:]): + if axis is not None and len(axis) not in [volume_shape[i], 2]: + return False + return True + def is_valid_nxdata(group): # noqa """Check if a h5py group is a **valid** NX_data group. @@ -750,20 +781,19 @@ def is_valid_nxdata(group): # noqa return nxd.is_valid -def is_NXentry_with_default_NXdata(group, validate=True): - """Return True if group is a valid NXentry defining a valid default +def is_group_with_default_NXdata(group, validate=True): + """Return True if group defines a valid default NXdata. - :param group: h5py-like object. - :param bool validate: Set this to False if you are sure that the target group - is valid NXdata (i.e. :func:`silx.io.nxdata.is_valid_nxdata(target_group)` - returns True). Parameter provided for optimisation purposes.""" - if not is_group(group): - return False + .. note:: - if get_attr_as_unicode(group, "NX_class") != "NXentry": - return False + See https://github.com/silx-kit/silx/issues/2215 + :param group: h5py-like object. + :param bool validate: Set this to skip the NXdata validation, and only + check the existence of the group. + Parameter provided for optimisation purposes, to avoid double + validation if the validation is already performed separately.""" default_nxdata_name = group.attrs.get("default") if default_nxdata_name is None or default_nxdata_name not in group: return False @@ -779,10 +809,35 @@ def is_NXentry_with_default_NXdata(group, validate=True): return is_valid_nxdata(default_nxdata_group) +def is_NXentry_with_default_NXdata(group, validate=True): + """Return True if group is a valid NXentry defining a valid default + NXdata. + + :param group: h5py-like object. + :param bool validate: Set this to skip the NXdata validation, and only + check the existence of the group. + Parameter provided for optimisation purposes, to avoid double + validation if the validation is already performed separately.""" + if not is_group(group): + return False + + if get_attr_as_unicode(group, "NX_class") != "NXentry": + return False + + return is_group_with_default_NXdata(group, validate) + + def is_NXroot_with_default_NXdata(group, validate=True): """Return True if group is a valid NXroot defining a default NXentry defining a valid default NXdata. + .. note:: + + A NXroot group cannot directly define a default NXdata. If a + *@default* argument is present, it must point to a NXentry group. + This NXentry must define a valid NXdata for this function to return + True. + :param group: h5py-like object. :param bool validate: Set this to False if you are sure that the target group is valid NXdata (i.e. :func:`silx.io.nxdata.is_valid_nxdata(target_group)` @@ -831,7 +886,7 @@ def get_default(group, validate=True): if is_NXroot_with_default_NXdata(group, validate=validate): default_entry = group[group.attrs["default"]] default_data = default_entry[default_entry.attrs["default"]] - elif is_NXentry_with_default_NXdata(group, validate=validate): + elif is_group_with_default_NXdata(group, validate=validate): default_data = group[group.attrs["default"]] elif not validate or is_valid_nxdata(group): default_data = group diff --git a/silx/io/nxdata/write.py b/silx/io/nxdata/write.py index 05eef4d..e9ac3ac 100644 --- a/silx/io/nxdata/write.py +++ b/silx/io/nxdata/write.py @@ -23,11 +23,12 @@ # # ###########################################################################*/ -import h5py import os import logging + +import h5py import numpy -from silx.third_party import six +import six __authors__ = ["P. Knobel"] __license__ = "MIT" |