Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add motor info to QNexuswidget #1088

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ docs/_build/
# cython generated files
src/PyMca5/PyMcaGraph/ctools/_ctools/cython/*.c
src/PyMca5/PyMcaPhysics/xas/_xas/cython/*.c
src/PyMca5/PyMcaMath/mva/_cython_kmeans/*.c

# PyCharm meta data
.idea/
Expand Down
22 changes: 22 additions & 0 deletions src/PyMca5/PyMcaCore/NexusTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,28 @@ def getPositionersGroup(h5file, path):
positioners = group
return positioners

def getStartingPositionersGroup(h5file, path):
"""
Retrieve the start positioners group associated to a path
retrieving them from the same entry.

It assumes they are either in:

- NXentry/NXinstrument/positioners_start or
Comment on lines +518 to +520
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
It assumes they are either in:
- NXentry/NXinstrument/positioners_start or
This method assumes the positioner group is NXentry/NXinstrument/positioners_start.


"""
entry_path = getEntryName(path, h5file=h5file)
instrument = getNXClassGroups(h5file, entry_path, ["NXinstrument", b"NXinstrument"], single=True)
positioners = None
if len(instrument):
instrument = instrument[0]
for key in instrument.keys():
if key in ["positioners_start", b"positioners_start"]:
positioners = instrument[key]
if not isGroup(positioners):
positioners = None
return positioners

def getMeasurementGroup(h5file, path):
"""
Retrieve the measurement group associated to a path
Expand Down
110 changes: 110 additions & 0 deletions src/PyMca5/PyMcaGui/io/hdf5/NexusInfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import h5py

from PyMca5.PyMcaGui import PyMcaQt as qt
from PyMca5.PyMcaCore.NexusTools import getStartingPositionersGroup

from . import HDF5Info


class NexusMotorInfoWidget(qt.QWidget):
def __init__(self, parent):
super().__init__(parent)

self.mainLayout = qt.QVBoxLayout(self)
self.mainLayout.setContentsMargins(0, 0, 0, 0)
self.mainLayout.setSpacing(2)

self.label = qt.QLabel(self)
self.label.setText("Number of motors: 0")

column_names = ["Name", "Value", "Units"]
self._column_names = column_names

self.table = qt.QTableWidget(self)
self.table.setColumnCount(len(column_names))
for i in range(len(column_names)):
item = self.table.horizontalHeaderItem(i)
if item is None:
item = qt.QTableWidgetItem(column_names[i], qt.QTableWidgetItem.Type)
item.setText(column_names[i])
self.table.setHorizontalHeaderItem(i, item)
self.table.setSortingEnabled(True)

self.mainLayout.addWidget(self.label)
self.mainLayout.addWidget(self.table)

def setInfoDict(self, ddict):
if "motors" in ddict:
self._setInfoDict(ddict["motors"])
else:
self._setInfoDict(ddict)

def _setInfoDict(self, ddict):
nrows = len(ddict.get(self._column_names[0], []))
self.label.setText("Number of motors: %d" % nrows)
self.table.setRowCount(nrows)

if not nrows:
self.hide()
return

for row in range(nrows):
for col, label in enumerate(self._column_names):
text = str(ddict[label][row])
item = self.table.item(row, col)
if item is None:
item = qt.QTableWidgetItem(text, qt.QTableWidgetItem.Type)
item.setFlags(qt.Qt.ItemIsSelectable | qt.Qt.ItemIsEnabled)
self.table.setItem(row, col, item)
else:
item.setText(text)

for col in range(len(self._column_names)):
self.table.resizeColumnToContents(col)


class NexusInfoWidget(HDF5Info.HDF5InfoWidget):

def _build(self):
super()._build()
self.motorInfoWidget = NexusMotorInfoWidget(self)
self.addTab(self.motorInfoWidget, "Motors")

def setInfoDict(self, ddict):
super().setInfoDict(ddict)
self.motorInfoWidget.setInfoDict(ddict)


def getInfo(hdf5File, node):
"""
hdf5File is and HDF5 file-like insance
node is the posix path to the node
"""
info = HDF5Info.getInfo(hdf5File, node)
info["motors"] = get_motor_positions(hdf5File, node)
return info


def get_motor_positions(hdf5File, node):
node = hdf5File[node]

nxentry_name = node.name.split("/")[1]
if not nxentry_name:
return dict()

nxentry = hdf5File[nxentry_name]
if not isinstance(nxentry, h5py.Group):
return dict()

nxpositioners = getStartingPositionersGroup(hdf5File, nxentry_name)
if nxpositioners is None or not isinstance(nxpositioners, h5py.Group):
return dict()

positions = [
(name, dset[()], dset.attrs.get("units", ""))
for name, dset in nxpositioners.items()
if isinstance(dset, h5py.Dataset) and dset.ndim == 0
]
column_names = "Name", "Value", "Units"

return dict(zip(column_names, zip(*positions)))
8 changes: 5 additions & 3 deletions src/PyMca5/PyMcaGui/io/hdf5/QNexusWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
QString = str

from . import HDF5Widget
from . import HDF5Info
from . import NexusInfo
from . import HDF5CounterTable
from . import HDF5McaTable
from . import QNexusWidgetActions
Expand Down Expand Up @@ -123,7 +123,7 @@ def __init__(self, parent=None, mca=False, buttons=False):
self._autoCntList = []
self._autoAliasList = []
self._defaultModel = HDF5Widget.FileModel()
self.getInfo = HDF5Info.getInfo
self.getInfo = NexusInfo.getInfo
self._modelDict = {}
self._widgetDict = {}
self._lastWidgetId = None
Expand Down Expand Up @@ -507,8 +507,9 @@ def showInfoWidget(self, filename, name, dset=False):
phynxFile = self.data._sourceObjectList[fileIndex]
else:
phynxFile = HDF5Widget.h5open(filename)

info = self.getInfo(phynxFile, name)
widget = HDF5Info.HDF5InfoWidget()
widget = NexusInfo.NexusInfoWidget()
widget.notifyCloseEventToWidget(self)
title = os.path.basename(filename)
title += " %s" % name
Expand All @@ -531,6 +532,7 @@ def sourceObjectDestroyed(weakrefReference):
del self._widgetDict[wid]
widget._sourceObjectWeakReference = weakref.ref(phynxFile,
sourceObjectDestroyed)

widget.setInfoDict(info)
# todo: this first `if` block can be dropped when silx is a hard dependency
if dset and Hdf5NodeView is None:
Expand Down
Loading