def open(filename): # pylint:disable=redefined-builtin """ Open a file as an `h5py`-like object. Format supported: - h5 files, if `h5py` module is installed - SPEC files exposed as a NeXus layout - raster files exposed as a NeXus layout (if `fabio` is installed) - fio files exposed as a NeXus layout - Numpy files ('npy' and 'npz' files) The filename can be trailled an HDF5 path using the separator `::`. In this case the object returned is a proxy to the target node, implementing the `close` function and supporting `with` context. The file is opened in read-only mode. :param str filename: A filename which can containt an HDF5 path by using `::` separator. :raises: IOError if the file can't be loaded or path can't be found :rtype: h5py-like node """ url = silx.io.url.DataUrl(filename) if url.scheme() in [None, "file", "silx"]: # That's a local file if not url.is_valid(): raise IOError("URL '%s' is not valid" % filename) h5_file = _open_local_file(url.file_path()) elif url.scheme() in ["fabio"]: raise IOError("URL '%s' containing fabio scheme is not supported" % filename) else: # That's maybe an URL supported by h5pyd uri = urllib.parse.urlparse(filename) if h5pyd is None: raise IOError("URL '%s' unsupported. Try to install h5pyd." % filename) path = uri.path endpoint = "%s://%s" % (uri.scheme, uri.netloc) if path.startswith("/"): path = path[1:] return h5pyd.File(path, 'r', endpoint=endpoint) if url.data_slice(): raise IOError("URL '%s' containing slicing is not supported" % filename) if url.data_path() in [None, "/", ""]: # The full file is requested return h5_file else: # Only a children is requested if url.data_path() not in h5_file: msg = "File '%s' does not contain path '%s'." % (filename, url.data_path()) raise IOError(msg) node = h5_file[url.data_path()] proxy = _MainNode(node, h5_file) return proxy
def open(filename): # pylint:disable=redefined-builtin """ Open a file as an `h5py`-like object. Format supported: - h5 files, if `h5py` module is installed - SPEC files exposed as a NeXus layout - raster files exposed as a NeXus layout (if `fabio` is installed) - Numpy files ('npy' and 'npz' files) The filename can be trailled an HDF5 path using the separator `::`. In this case the object returned is a proxy to the target node, implementing the `close` function and supporting `with` context. The file is opened in read-only mode. :param str filename: A filename which can containt an HDF5 path by using `::` separator. :raises: IOError if the file can't be loaded or path can't be found :rtype: h5py-like node """ url = silx.io.url.DataUrl(filename) if url.scheme() in [None, "file", "silx"]: # That's a local file if not url.is_valid(): raise IOError("URL '%s' is not valid" % filename) h5_file = _open_local_file(url.file_path()) elif url.scheme() in ["fabio"]: raise IOError("URL '%s' containing fabio scheme is not supported" % filename) else: # That's maybe an URL supported by h5pyd uri = six.moves.urllib.parse.urlparse(filename) if h5pyd is None: raise IOError("URL '%s' unsupported. Try to install h5pyd." % filename) path = uri.path endpoint = "%s://%s" % (uri.scheme, uri.netloc) if path.startswith("/"): path = path[1:] return h5pyd.File(path, 'r', endpoint=endpoint) if url.data_slice(): raise IOError("URL '%s' containing slicing is not supported" % filename) if url.data_path() in [None, "/", ""]: # The full file is requested return h5_file else: # Only a children is requested if url.data_path() not in h5_file: msg = "File '%s' does not contain path '%s'." % (filename, url.data_path()) raise IOError(msg) node = h5_file[url.data_path()] proxy = _MainNode(node, h5_file) return proxy
def testSelectNXdataAccepted_Activate(self): if fabio is None: self.skipTest("fabio is missing") dialog = self.createDialog() browser = utils.findChildren(dialog, qt.QWidget, name="browser")[0] dialog.show() self.qWaitForWindowExposed(dialog) self.assertTrue(dialog.isVisible()) filename = _tmpDirectory + "/data.h5" dialog.selectFile(os.path.dirname(filename)) self.qWaitForPendingActions(dialog) # select, then double click on the file index = browser.rootIndex().model().index(filename) browser.selectIndex(index) browser.activated.emit(index) self.qWaitForPendingActions(dialog) # select, then double click on the file index = browser.rootIndex().model().indexFromH5Object( dialog._AbstractDataFileDialog__h5["/nxdata"]) browser.selectIndex(index) browser.activated.emit(index) self.qWaitForPendingActions(dialog) button = utils.findChildren(dialog, qt.QPushButton, name="open")[0] self.assertTrue(button.isEnabled()) self.mouseClick(button, qt.Qt.LeftButton) url = silx.io.url.DataUrl(dialog.selectedUrl()) self.assertEqual(url.data_path(), "/nxdata") self.assertFalse(dialog.isVisible()) self.assertEqual(dialog.result(), qt.QDialog.Accepted)
def testSelectNXdataAccepted_Activate(self): dialog = self.createDialog() browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0] dialog.show() self.qWaitForWindowExposed(dialog) self.assertTrue(dialog.isVisible()) filename = _tmpDirectory + "/data.h5" dialog.selectFile(os.path.dirname(filename)) self.qWaitForPendingActions(dialog) # select, then double click on the file index = browser.rootIndex().model().index(filename) browser.selectIndex(index) browser.activated.emit(index) self.qWaitForPendingActions(dialog) # select, then double click on the file index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/nxdata"]) browser.selectIndex(index) browser.activated.emit(index) self.qWaitForPendingActions(dialog) button = testutils.findChildren(dialog, qt.QPushButton, name="open")[0] self.assertTrue(button.isEnabled()) self.mouseClick(button, qt.Qt.LeftButton) url = silx.io.url.DataUrl(dialog.selectedUrl()) self.assertEqual(url.data_path(), "/nxdata") self.assertFalse(dialog.isVisible()) self.assertEqual(dialog.result(), qt.QDialog.Accepted)
def testSelectRoot_Activate(self): if fabio is None: self.skipTest("fabio is missing") dialog = self.createDialog() browser = utils.findChildren(dialog, qt.QWidget, name="browser")[0] dialog.show() self.qWaitForWindowExposed(dialog) self.assertTrue(dialog.isVisible()) filename = _tmpDirectory + "/data.h5" dialog.selectFile(os.path.dirname(filename)) self.qWaitForPendingActions(dialog) # select, then double click on the file index = browser.rootIndex().model().index(filename) browser.selectIndex(index) browser.activated.emit(index) self.qWaitForPendingActions(dialog) button = utils.findChildren(dialog, qt.QPushButton, name="open")[0] self.assertTrue(button.isEnabled()) self.mouseClick(button, qt.Qt.LeftButton) url = silx.io.url.DataUrl(dialog.selectedUrl()) self.assertTrue(url.data_path() is not None) self.assertFalse(dialog.isVisible()) self.assertEquals(dialog.result(), qt.QDialog.Accepted)
def testBadSubpath(self): dialog = self.createDialog() self.qWaitForPendingActions(dialog) browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0] filename = _tmpDirectory + "/data.h5" url = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/foobar") dialog.selectUrl(url.path()) self.qWaitForPendingActions(dialog) self.assertIsNotNone(dialog._selectedData()) # an existing node is browsed, but the wrong path is selected index = browser.rootIndex() obj = index.model().data(index, role=Hdf5TreeModel.H5PY_OBJECT_ROLE) self.assertEqual(obj.name, "/group") url = silx.io.url.DataUrl(dialog.selectedUrl()) self.assertEqual(url.data_path(), "/group")
def testBadSubpath(self): dialog = self.createDialog() self.qWaitForPendingActions(dialog) browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0] filename = _tmpDirectory + "/data.h5" url = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/foobar") dialog.selectUrl(url.path()) self.qWaitForPendingActions(dialog) self.assertIsNotNone(dialog._selectedData()) # an existing node is browsed, but the wrong path is selected index = browser.rootIndex() obj = index.model().data(index, role=Hdf5TreeModel.H5PY_OBJECT_ROLE) self.assertEqual(obj.name, "/group") url = silx.io.url.DataUrl(dialog.selectedUrl()) self.assertEqual(url.data_path(), "/group")
def testSelectRoot_Activate(self): dialog = self.createDialog() browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0] dialog.show() self.qWaitForWindowExposed(dialog) self.assertTrue(dialog.isVisible()) filename = _tmpDirectory + "/data.h5" dialog.selectFile(os.path.dirname(filename)) self.qWaitForPendingActions(dialog) # select, then double click on the file index = browser.rootIndex().model().index(filename) browser.selectIndex(index) browser.activated.emit(index) self.qWaitForPendingActions(dialog) button = testutils.findChildren(dialog, qt.QPushButton, name="open")[0] self.assertTrue(button.isEnabled()) self.mouseClick(button, qt.Qt.LeftButton) url = silx.io.url.DataUrl(dialog.selectedUrl()) self.assertTrue(url.data_path() is not None) self.assertFalse(dialog.isVisible()) self.assertEqual(dialog.result(), qt.QDialog.Accepted)
def get_data(url): """Returns a numpy data from an URL. Examples: >>> # 1st frame from an EDF using silx.io.open >>> data = silx.io.get_data("silx:/users/foo/image.edf::/scan_0/instrument/detector_0/data[0]") >>> # 1st frame from an EDF using fabio >>> data = silx.io.get_data("fabio:/users/foo/image.edf::[0]") Yet 2 schemes are supported by the function. - If `silx` scheme is used, the file is opened using :meth:`silx.io.open` and the data is reach using usually NeXus paths. - If `fabio` scheme is used, the file is opened using :meth:`fabio.open` from the FabIO library. No data path have to be specified, but each frames can be accessed using the data slicing. This shortcut of :meth:`silx.io.open` allow to have a faster access to the data. .. seealso:: :class:`silx.io.url.DataUrl` :param Union[str,silx.io.url.DataUrl]: A data URL :rtype: Union[numpy.ndarray, numpy.generic] :raises ImportError: If the mandatory library to read the file is not available. :raises ValueError: If the URL is not valid or do not match the data :raises IOError: If the file is not found or in case of internal error of :meth:`fabio.open` or :meth:`silx.io.open`. In this last case more informations are displayed in debug mode. """ if not isinstance(url, silx.io.url.DataUrl): url = silx.io.url.DataUrl(url) if not url.is_valid(): raise ValueError("URL '%s' is not valid" % url.path()) if not os.path.exists(url.file_path()): raise IOError("File '%s' not found" % url.file_path()) if url.scheme() == "silx": data_path = url.data_path() data_slice = url.data_slice() with open(url.file_path()) as h5: if data_path not in h5: raise ValueError("Data path from URL '%s' not found" % url.path()) data = h5[data_path] if not silx.io.is_dataset(data): raise ValueError("Data path from URL '%s' is not a dataset" % url.path()) if data_slice is not None: data = h5py_read_dataset(data, index=data_slice) else: # works for scalar and array data = h5py_read_dataset(data) elif url.scheme() == "fabio": import fabio data_slice = url.data_slice() if data_slice is None: data_slice = (0, ) if data_slice is None or len(data_slice) != 1: raise ValueError( "Fabio slice expect a single frame, but %s found" % data_slice) index = data_slice[0] if not isinstance(index, int): raise ValueError( "Fabio slice expect a single integer, but %s found" % data_slice) try: fabio_file = fabio.open(url.file_path()) except Exception: logger.debug("Error while opening %s with fabio", url.file_path(), exc_info=True) raise IOError( "Error while opening %s with fabio (use debug for more information)" % url.path()) if fabio_file.nframes == 1: if index != 0: raise ValueError( "Only a single frame available. Slice %s out of range" % index) data = fabio_file.data else: data = fabio_file.getframe(index).data # There is no explicit close fabio_file = None else: raise ValueError("Scheme '%s' not supported" % url.scheme()) return data
def get_data(url): """Returns a numpy data from an URL. Examples: >>> # 1st frame from an EDF using silx.io.open >>> data = silx.io.get_data("silx:/users/foo/image.edf::/scan_0/instrument/detector_0/data[0]") >>> # 1st frame from an EDF using fabio >>> data = silx.io.get_data("fabio:/users/foo/image.edf::[0]") Yet 2 schemes are supported by the function. - If `silx` scheme is used, the file is opened using :meth:`silx.io.open` and the data is reach using usually NeXus paths. - If `fabio` scheme is used, the file is opened using :meth:`fabio.open` from the FabIO library. No data path have to be specified, but each frames can be accessed using the data slicing. This shortcut of :meth:`silx.io.open` allow to have a faster access to the data. .. seealso:: :class:`silx.io.url.DataUrl` :param Union[str,silx.io.url.DataUrl]: A data URL :rtype: Union[numpy.ndarray, numpy.generic] :raises ImportError: If the mandatory library to read the file is not available. :raises ValueError: If the URL is not valid or do not match the data :raises IOError: If the file is not found or in case of internal error of :meth:`fabio.open` or :meth:`silx.io.open`. In this last case more informations are displayed in debug mode. """ if not isinstance(url, silx.io.url.DataUrl): url = silx.io.url.DataUrl(url) if not url.is_valid(): raise ValueError("URL '%s' is not valid" % url.path()) if not os.path.exists(url.file_path()): raise IOError("File '%s' not found" % url.file_path()) if url.scheme() == "silx": data_path = url.data_path() data_slice = url.data_slice() with open(url.file_path()) as h5: if data_path not in h5: raise ValueError("Data path from URL '%s' not found" % url.path()) data = h5[data_path] if not silx.io.is_dataset(data): raise ValueError("Data path from URL '%s' is not a dataset" % url.path()) if data_slice is not None: data = data[data_slice] else: # works for scalar and array data = data[()] elif url.scheme() == "fabio": import fabio data_slice = url.data_slice() if data_slice is None: data_slice = (0, ) if data_slice is None or len(data_slice) != 1: raise ValueError("Fabio slice expect a single frame, but %s found" % data_slice) index = data_slice[0] if not isinstance(index, int): raise ValueError("Fabio slice expect a single integer, but %s found" % data_slice) try: fabio_file = fabio.open(url.file_path()) except Exception: logger.debug("Error while opening %s with fabio", url.file_path(), exc_info=True) raise IOError("Error while opening %s with fabio (use debug for more information)" % url.path()) if fabio_file.nframes == 1: if index != 0: raise ValueError("Only a single frame availalbe. Slice %s out of range" % index) data = fabio_file.data else: data = fabio_file.getframe(index).data # There is no explicit close fabio_file = None else: raise ValueError("Scheme '%s' not supported" % url.scheme()) return data