summaryrefslogtreecommitdiff
path: root/silx/gui/hdf5/_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/hdf5/_utils.py')
-rw-r--r--silx/gui/hdf5/_utils.py461
1 files changed, 0 insertions, 461 deletions
diff --git a/silx/gui/hdf5/_utils.py b/silx/gui/hdf5/_utils.py
deleted file mode 100644
index aaab228..0000000
--- a/silx/gui/hdf5/_utils.py
+++ /dev/null
@@ -1,461 +0,0 @@
-# coding: utf-8
-# /*##########################################################################
-#
-# Copyright (c) 2016-2017 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.
-#
-# ###########################################################################*/
-"""This package provides a set of helper class and function used by the
-package `silx.gui.hdf5` package.
-"""
-
-__authors__ = ["V. Valls"]
-__license__ = "MIT"
-__date__ = "17/01/2019"
-
-
-import logging
-import os.path
-
-import silx.io.utils
-import silx.io.url
-from .. import qt
-from silx.utils.html import escape
-
-_logger = logging.getLogger(__name__)
-
-
-class Hdf5ContextMenuEvent(object):
- """Hold information provided to context menu callbacks."""
-
- def __init__(self, source, menu, hoveredObject):
- """
- Constructor
-
- :param QWidget source: Widget source
- :param QMenu menu: Context menu which will be displayed
- :param H5Node hoveredObject: Hovered H5 node
- """
- self.__source = source
- self.__menu = menu
- self.__hoveredObject = hoveredObject
-
- def source(self):
- """Source of the event
-
- :rtype: Hdf5TreeView
- """
- return self.__source
-
- def menu(self):
- """Menu which will be displayed
-
- :rtype: qt.QMenu
- """
- return self.__menu
-
- def hoveredObject(self):
- """Item content hovered by the mouse when the context menu was
- requested
-
- :rtype: H5Node
- """
- return self.__hoveredObject
-
-
-def htmlFromDict(dictionary, title=None):
- """Generate a readable HTML from a dictionary
-
- :param dict dictionary: A Dictionary
- :rtype: str
- """
- result = """<html>
- <head>
- <style type="text/css">
- ul { -qt-list-indent: 0; list-style: none; }
- li > b {display: inline-block; min-width: 4em; font-weight: bold; }
- </style>
- </head>
- <body>
- """
- if title is not None:
- result += "<b>%s</b>" % escape(title)
- result += "<ul>"
- for key, value in dictionary.items():
- result += "<li><b>%s</b>: %s</li>" % (escape(key), escape(value))
- result += "</ul>"
- result += "</body></html>"
- return result
-
-
-class Hdf5DatasetMimeData(qt.QMimeData):
- """Mimedata class to identify an internal drag and drop of a Hdf5Node."""
-
- MIME_TYPE = "application/x-internal-h5py-dataset"
-
- SILX_URI_TYPE = "application/x-silx-uri"
-
- def __init__(self, node=None, dataset=None, isRoot=False):
- qt.QMimeData.__init__(self)
- self.__dataset = dataset
- self.__node = node
- self.__isRoot = isRoot
- self.setData(self.MIME_TYPE, "".encode(encoding='utf-8'))
- if node is not None:
- h5Node = H5Node(node)
- silxUrl = h5Node.url
- self.setText(silxUrl)
- self.setData(self.SILX_URI_TYPE, silxUrl.encode(encoding='utf-8'))
-
- def isRoot(self):
- return self.__isRoot
-
- def node(self):
- return self.__node
-
- def dataset(self):
- if self.__node is not None:
- return self.__node.obj
- return self.__dataset
-
-
-class H5Node(object):
- """Adapter over an h5py object to provide missing informations from h5py
- nodes, like internal node path and filename (which are not provided by
- :mod:`h5py` for soft and external links).
-
- It also provides an abstraction to reach node type for mimicked h5py
- objects.
- """
-
- def __init__(self, h5py_item=None):
- """Constructor
-
- :param Hdf5Item h5py_item: An Hdf5Item
- """
- self.__h5py_object = h5py_item.obj
- self.__h5py_target = None
- self.__h5py_item = h5py_item
-
- def __getattr__(self, name):
- if hasattr(self.__h5py_object, name):
- attr = getattr(self.__h5py_object, name)
- return attr
- raise AttributeError("H5Node has no attribute %s" % name)
-
- def __get_target(self, obj):
- """
- Return the actual physical target of the provided object.
-
- Objects can contains links in the middle of the path, this function
- check each groups and remove this prefix in case of the link by the
- link of the path.
-
- :param obj: A valid h5py object (File, group or dataset)
- :type obj: h5py.Dataset or h5py.Group or h5py.File
- :rtype: h5py.Dataset or h5py.Group or h5py.File
- """
- elements = obj.name.split("/")
- if obj.name == "/":
- return obj
- elif obj.name.startswith("/"):
- elements.pop(0)
- path = ""
- subpath = ""
- while len(elements) > 0:
- e = elements.pop(0)
- subpath = path + "/" + e
- link = obj.parent.get(subpath, getlink=True)
- classlink = silx.io.utils.get_h5_class(link)
-
- if classlink == silx.io.utils.H5Type.EXTERNAL_LINK:
- subpath = "/".join(elements)
- external_obj = obj.parent.get(self.basename + "/" + subpath)
- return self.__get_target(external_obj)
- elif classlink == silx.io.utils.H5Type.SOFT_LINK:
- # Restart from this stat
- root_elements = link.path.split("/")
- if link.path == "/":
- path = ""
- root_elements = []
- elif link.path.startswith("/"):
- path = ""
- root_elements.pop(0)
-
- for name in reversed(root_elements):
- elements.insert(0, name)
- else:
- path = subpath
-
- return obj.file[path]
-
- @property
- def h5py_target(self):
- if self.__h5py_target is not None:
- return self.__h5py_target
- self.__h5py_target = self.__get_target(self.__h5py_object)
- return self.__h5py_target
-
- @property
- def h5py_object(self):
- """Returns the internal h5py node.
-
- :rtype: h5py.File or h5py.Group or h5py.Dataset
- """
- return self.__h5py_object
-
- @property
- def h5type(self):
- """Returns the node type, as an H5Type.
-
- :rtype: H5Node
- """
- return silx.io.utils.get_h5_class(self.__h5py_object)
-
- @property
- def ntype(self):
- """Returns the node type, as an h5py class.
-
- :rtype:
- :class:`h5py.File`, :class:`h5py.Group` or :class:`h5py.Dataset`
- """
- type_ = self.h5type
- return silx.io.utils.h5type_to_h5py_class(type_)
-
- @property
- def basename(self):
- """Returns the basename of this h5py node. It is the last identifier of
- the path.
-
- :rtype: str
- """
- return self.__h5py_object.name.split("/")[-1]
-
- @property
- def is_broken(self):
- """Returns true if the node is a broken link.
-
- :rtype: bool
- """
- if self.__h5py_item is None:
- raise RuntimeError("h5py_item is not defined")
- return self.__h5py_item.isBrokenObj()
-
- @property
- def local_name(self):
- """Returns the path from the master file root to this node.
-
- For links, this path is not equal to the h5py one.
-
- :rtype: str
- """
- if self.__h5py_item is None:
- raise RuntimeError("h5py_item is not defined")
-
- result = []
- item = self.__h5py_item
- while item is not None:
- # stop before the root item (item without parent)
- if item.parent.parent is None:
- name = item.obj.name
- if name != "/":
- result.append(item.obj.name)
- break
- else:
- result.append(item.basename)
- item = item.parent
- if item is None:
- raise RuntimeError("The item does not have parent holding h5py.File")
- if result == []:
- return "/"
- if not result[-1].startswith("/"):
- result.append("")
- result.reverse()
- name = "/".join(result)
- return name
-
- def __get_local_file(self):
- """Returns the file of the root of this tree
-
- :rtype: h5py.File
- """
- item = self.__h5py_item
- while item.parent.parent is not None:
- class_ = silx.io.utils.get_h5_class(class_=item.h5pyClass)
- if class_ == silx.io.utils.H5Type.FILE:
- break
- item = item.parent
-
- class_ = silx.io.utils.get_h5_class(class_=item.h5pyClass)
- if class_ == silx.io.utils.H5Type.FILE:
- return item.obj
- else:
- return item.obj.file
-
- @property
- def local_file(self):
- """Returns the master file in which is this node.
-
- For path containing external links, this file is not equal to the h5py
- one.
-
- :rtype: h5py.File
- :raises RuntimeException: If no file are found
- """
- return self.__get_local_file()
-
- @property
- def local_filename(self):
- """Returns the filename from the master file of this node.
-
- For path containing external links, this path is not equal to the
- filename provided by h5py.
-
- :rtype: str
- :raises RuntimeException: If no file are found
- """
- return self.local_file.filename
-
- @property
- def local_basename(self):
- """Returns the basename from the master file root to this node.
-
- For path containing links, this basename can be different than the
- basename provided by h5py.
-
- :rtype: str
- """
- class_ = self.__h5py_item.h5Class
- if class_ is not None and class_ == silx.io.utils.H5Type.FILE:
- return ""
- return self.__h5py_item.basename
-
- @property
- def physical_file(self):
- """Returns the physical file in which is this node.
-
- .. versionadded:: 0.6
-
- :rtype: h5py.File
- :raises RuntimeError: If no file are found
- """
- class_ = silx.io.utils.get_h5_class(self.__h5py_object)
- if class_ == silx.io.utils.H5Type.EXTERNAL_LINK:
- # It means the link is broken
- raise RuntimeError("No file node found")
- if class_ == silx.io.utils.H5Type.SOFT_LINK:
- # It means the link is broken
- return self.local_file
-
- physical_obj = self.h5py_target
- return physical_obj.file
-
- @property
- def physical_name(self):
- """Returns the path from the location this h5py node is physically
- stored.
-
- For broken links, this filename can be different from the
- filename provided by h5py.
-
- :rtype: str
- """
- class_ = silx.io.utils.get_h5_class(self.__h5py_object)
- if class_ == silx.io.utils.H5Type.EXTERNAL_LINK:
- # It means the link is broken
- return self.__h5py_object.path
- if class_ == silx.io.utils.H5Type.SOFT_LINK:
- # It means the link is broken
- return self.__h5py_object.path
-
- physical_obj = self.h5py_target
- return physical_obj.name
-
- @property
- def physical_filename(self):
- """Returns the filename from the location this h5py node is physically
- stored.
-
- For broken links, this filename can be different from the
- filename provided by h5py.
-
- :rtype: str
- """
- class_ = silx.io.utils.get_h5_class(self.__h5py_object)
- if class_ == silx.io.utils.H5Type.EXTERNAL_LINK:
- # It means the link is broken
- return self.__h5py_object.filename
- if class_ == silx.io.utils.H5Type.SOFT_LINK:
- # It means the link is broken
- return self.local_file.filename
-
- return self.physical_file.filename
-
- @property
- def physical_basename(self):
- """Returns the basename from the location this h5py node is physically
- stored.
-
- For broken links, this basename can be different from the
- basename provided by h5py.
-
- :rtype: str
- """
- return self.physical_name.split("/")[-1]
-
- @property
- def data_url(self):
- """Returns a :class:`silx.io.url.DataUrl` object identify this node in the file
- system.
-
- :rtype: ~silx.io.url.DataUrl
- """
- absolute_filename = os.path.abspath(self.local_filename)
- return silx.io.url.DataUrl(scheme="silx",
- file_path=absolute_filename,
- data_path=self.local_name)
-
- @property
- def url(self):
- """Returns an URL object identifying this node in the file
- system.
-
- This URL can be used in different ways.
-
- .. code-block:: python
-
- # Parsing the URL
- import silx.io.url
- dataurl = silx.io.url.DataUrl(item.url)
- # dataurl provides access to URL fields
-
- # Open a numpy array
- import silx.io
- dataset = silx.io.get_data(item.url)
-
- # Open an hdf5 object (URL targetting a file or a group)
- import silx.io
- with silx.io.open(item.url) as h5:
- ...your stuff...
-
- :rtype: str
- """
- data_url = self.data_url
- return data_url.path()