Commit 35f81d24 authored by payno's avatar payno

[orange add-on] use the XASObjectDialog in the input_xas. Allow to select a...

[orange add-on] use the XASObjectDialog in the input_xas. Allow to select a .dat file (single spectrum) or spectra from .hdf5
parent 30724e83
......@@ -31,11 +31,13 @@ __date__ = "06/11/2019"
from Orange.widgets import gui
from Orange.widgets.widget import OWWidget
from silx.gui import qt
from silx.io.url import DataUrl
from xas.core.types import XASObject
from xas.gui.xas_object_definition import XASObjectDialog
import xas.io
from Orange.widgets.settings import Setting
import os
import logging
import xas.io
_logger = logging.getLogger(__file__)
......@@ -57,6 +59,9 @@ class XASInputOW(OWWidget):
outputs = [("spectra", XASObject)]
_input_file_setting = Setting(str())
_spectra_url_setting = Setting(str())
_energy_url_setting = Setting(str())
_configuration_url_setting = Setting(str())
process_function = xas.io.read_pymca_xas_from_file
......@@ -65,14 +70,11 @@ class XASInputOW(OWWidget):
self._inputWindow = qt.QWidget(parent=self)
self._inputWindow.setLayout(qt.QGridLayout())
self._inputWindow.layout().addWidget(qt.QLabel('file', parent=self), 0, 0)
self._inputLe = qt.QLineEdit('', parent=self)
self._inputWindow.layout().addWidget(self._inputLe, 0, 1)
self._selectPB = qt.QPushButton('select', parent=self)
self._inputWindow.layout().addWidget(self._selectPB, 0, 2)
self._inputDialog = XASObjectDialog(parent=self)
self._inputWindow.layout().addWidget(self._inputDialog, 0, 0, 1, 2)
self._startPB = qt.QPushButton('restart', parent=self)
self._inputWindow.layout().addWidget(self._startPB, 1, 1, 1, 2)
self._inputWindow.layout().addWidget(self._startPB, 1, 1, 1, 1)
spacer = qt.QWidget(parent=self)
spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
......@@ -81,51 +83,51 @@ class XASInputOW(OWWidget):
layout = gui.vBox(self.mainArea, 'input').layout()
layout.addWidget(self._inputWindow)
# signal / slot connection
self._selectPB.pressed.connect(self._selectFile)
self._inputLe.editingFinished.connect(self._emitNewFile)
self._startPB.pressed.connect(self._emitNewFile)
# deal with setting
if os.path.isfile(self._input_file_setting):
self.setFileSelected(self._input_file_setting)
self._manageSettings()
# expose api
self.restart = self._emitNewFile
def _selectFile(self, *args, **kwargs):
old = self.blockSignals(True)
dialog = qt.QFileDialog(self)
dialog.setFileMode(qt.QFileDialog.ExistingFile)
dialog.setNameFilters(["spectra (*.dat)",
"spectra and configruation (*.h5 *.hdf *.hdf5)"])
if not dialog.exec_():
dialog.close()
return
fileSelected = dialog.selectedFiles()
if len(fileSelected) == 0:
return
else:
assert len(fileSelected) == 1
self.setFileSelected(fileSelected[0])
self.blockSignals(old)
def setFileSelected(self, file_path):
self._inputLe.setText(file_path)
# signal / slot connection
self._startPB.pressed.connect(self._emitNewFile)
self._inputDialog.editingFinished.connect(self._storeSettings)
def _emitNewFile(self, *args, **kwargs):
self._input_file_setting = self._inputLe.text()
if not os.path.isfile(self._input_file_setting):
mess = self._input_file_setting + 'is not a valid file path'
_logger.warning(mess)
return
try:
xas_obj = self._inputDialog.buildXASObject()
except ValueError as e:
qt.QMessageBox.warning(self, '', str(e))
else:
try:
xas_obj = XASInputOW.read_pymca_xas_from_file(file_path=self._input_file_setting)
except ... as e:
_logger.error(e)
else:
self.send("spectra", xas_obj)
self.send("spectra", xas_obj)
def _manageSettings(self):
input_type = xas.io.InputType.multiple_spectra
if os.path.isfile(self._input_file_setting):
self._inputDialog.setDatFile(self._input_file_setting)
input_type = xas.io.InputType.single_spectrum
def load_url(url_path, setter):
if url_path != '':
try:
url = DataUrl(url_path)
if url and url.is_valid():
setter(url.path())
except ... as e:
logging.info('fail to load ', url_path)
load_url(self._spectra_url_setting, self._inputDialog.setSpectraUrl)
load_url(self._energy_url_setting, self._inputDialog.setEnergyUrl)
load_url(self._configuration_url_setting, self._inputDialog.setConfigurationUrl)
# set up
self._inputDialog.setCurrentType(input_type)
def _storeSettings(self):
self._input_file_setting = self._inputDialog.getDatFile()
self._spectra_url_setting = self._inputDialog.getSpectraUrl()
self._energy_url_setting = self._inputDialog.getEnergyUrl()
self._configuration_url_setting = self._inputDialog.getConfigurationUrl()
def sizeHint(self):
return qt.QSize(400, 200)
......@@ -29,10 +29,10 @@ __date__ = "03/07/2019"
from silx.gui.dialog.DataFileDialog import DataFileDialog
from silx.io.url import DataUrl
from silx.gui import qt
import os
from xas.io import read_pymca_xas, read_pymca_xas_from_file, InputType
import logging
from xas.io import read_pymca_xas_from_file, InputType
_logger = logging.getLogger(__name__)
......@@ -50,15 +50,23 @@ class _InputType(qt.QWidget):
# expose API
self.currentChanged = self._inputTypeCB.currentIndexChanged
def getCurrentType(self):
def getInputType(self):
"""Return the current input type"""
return InputType.from_value(self._inputTypeCB.currentText())
def setInputType(self, input_type):
_input_type = InputType.from_value(input_type)
idx = self._inputTypeCB.findText(_input_type.value)
assert idx >= 0
self._inputTypeCB.setCurrentIndex(idx)
class XASObjectDialog(qt.QWidget):
"""
Interface used to select inputs for defining a XASObject
"""
editingFinished = qt.Signal()
def __init__(self, parent=None):
qt.QWidget.__init__(self, parent)
self.setLayout(qt.QGridLayout())
......@@ -79,15 +87,52 @@ class XASObjectDialog(qt.QWidget):
# connect signal / slot
self._inputType.currentChanged.connect(self._updateWidgetVisibility)
self._datDialog._inputLe.textChanged.connect(self._editingIsFinished)
self._h5Dialog.editingFinished.connect(self._editingIsFinished)
# expose API
self.getCurrentType = self._inputType.getInputType
self.setCurrentType = self._inputType.setInputType
self.setDatFile = self._datDialog.setFileSelected
self.getDatFile = self._datDialog.getFileSelected
self.setSpectraUrl = self._h5Dialog.setSpectraUrl
self.getSpectraUrl = self._h5Dialog.getSpectraUrl
self.setEnergyUrl = self._h5Dialog.setEnergyUrl
self.getEnergyUrl = self._h5Dialog.getEnergyUrl
self.setConfigurationUrl = self._h5Dialog.setConfigurationUrl
self.getConfigurationUrl = self._h5Dialog.getConfigurationUrl
# default setting
self._updateWidgetVisibility()
def _updateWidgetVisibility(self):
self._datDialog.setVisible(self._inputType.getCurrentType() == InputType.single_spectrum)
self._h5Dialog.setVisible(self._inputType.getCurrentType() == InputType.multiple_spectra)
self._datDialog.setVisible(self._inputType.getInputType() == InputType.single_spectrum)
self._h5Dialog.setVisible(self._inputType.getInputType() == InputType.multiple_spectra)
def buildXASObject(self):
if self.getCurrentType() == InputType.single_spectrum:
return read_pymca_xas_from_file(file_path=self._datDialog.getFileSelected())
elif self.getCurrentType() == InputType.multiple_spectra:
spectra_url = self._h5Dialog.getSpectraUrl()
energy_url = self._h5Dialog.getEnergyUrl()
def check_url(url_path, name):
if url_path in (None, ''):
raise ValueError(' '.join(('No', name, 'url defined')))
url = DataUrl(path=url_path)
if not url.is_valid():
raise ValueError(' '.join((name, 'url is invalid. Does the file / path still exists ?')))
check_url(spectra_url, 'spectra')
check_url(energy_url, 'energy / channel')
return read_pymca_xas(spectra_url=self._h5Dialog.getSpectraUrl(),
channel_url=self._h5Dialog.getEnergyUrl(),
config_url=self._h5Dialog.getConfigurationUrl())
else:
raise ValueError('unmanaged input type')
def _editingIsFinished(self, *args, **kwargs):
self.editingFinished.emit()
class _XASObjectFrmDat(qt.QWidget):
......@@ -104,20 +149,15 @@ class _XASObjectFrmDat(qt.QWidget):
self._selectPB = qt.QPushButton('select', parent=self)
self.layout().addWidget(self._selectPB, 0, 2)
self._startPB = qt.QPushButton('restart', parent=self)
self.layout().addWidget(self._startPB, 1, 1, 1, 2)
spacer = qt.QWidget(parent=self)
spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
self.layout().addWidget(spacer, 2, 0)
# signal / slot connection
self._selectPB.pressed.connect(self._selectFile)
self._inputLe.editingFinished.connect(self._processXASObject)
self._startPB.pressed.connect(self._processXASObject)
# expose api
self.restart = self._processXASObject
self.getFileSelected = self._inputLe.text
def _selectFile(self, *args, **kwargs):
old = self.blockSignals(True)
......@@ -141,20 +181,6 @@ class _XASObjectFrmDat(qt.QWidget):
def setFileSelected(self, file_path):
self._inputLe.setText(file_path)
def _processXASObject(self, *args, **kwargs):
self._input_file_setting = self._inputLe.text()
if not os.path.isfile(self._input_file_setting):
mess = self._input_file_setting + 'is not a valid file path'
_logger.warning(mess)
return
else:
try:
xas_obj = read_pymca_xas_from_file(file_path=self._input_file_setting)
except ... as e:
_logger.error(e)
else:
return xas_obj
class _URLSelector(qt.QWidget):
def __init__(self, parent, name, layout=None, position=None):
......@@ -171,13 +197,13 @@ class _URLSelector(qt.QWidget):
# expose API
self.getUrlPath = self._qLineEdit.text
self.setUrlPath = self._qLineEdit.setText
# connect signal / slot
self._qPushButton.clicked.connect(self._selectFile)
def _selectFile(self, *args, **kwargs):
dialog = DataFileDialog(self)
# dialog.setNameFilters(["".join((self.name, "(*.h5 *.hdf *.hdf5)")),])
if not dialog.exec_():
dialog.close()
......@@ -191,6 +217,7 @@ class _XASObjFrmH5(qt.QWidget):
"""
Interface used to define a XAS object from h5 files and data path
"""
editingFinished = qt.Signal()
def __init__(self, parent=None):
qt.QWidget.__init__(self, parent)
self.setLayout(qt.QGridLayout())
......@@ -205,6 +232,32 @@ class _XASObjFrmH5(qt.QWidget):
layout=self.layout(),
position=(2, 0))
# connect signal / slot
self._spectraSelector._qLineEdit.textChanged.connect(self._editingIsFinished)
self._energySelector._qLineEdit.textChanged.connect(self._editingIsFinished)
self._configSelector._qLineEdit.textChanged.connect(self._editingIsFinished)
def getSpectraUrl(self):
return self._spectraSelector.getUrlPath()
def getEnergyUrl(self):
return self._energySelector.getUrlPath()
def getConfigurationUrl(self):
return self._configSelector.getUrlPath()
def setSpectraUrl(self, url):
self._spectraSelector.setUrlPath(url)
def setEnergyUrl(self, url):
self._energySelector.setUrlPath(url)
def setConfigurationUrl(self, url):
self._configSelector.setUrlPath(url)
def _editingIsFinished(self, *args, **kwargs):
self.editingFinished.emit()
if __name__ == '__main__':
app = qt.QApplication([])
......
......@@ -89,7 +89,11 @@ def read_pymca_xas(spectra_url, channel_url, config_url=None):
def get_url(original_url, name):
url_ = original_url
if type(url_) is str:
url_ = DataUrl(file_path=url_, scheme='PyMca')
try:
url_ = DataUrl(path=url_)
except:
url_ = DataUrl(file_path=url_, scheme='PyMca')
if not isinstance(url_, DataUrl):
raise TypeError('given input for, ', name, 'is invalid')
return url_
......@@ -97,6 +101,8 @@ def read_pymca_xas(spectra_url, channel_url, config_url=None):
_spectra_url = get_url(original_url=spectra_url, name='spectra')
_energy_url = get_url(original_url=channel_url, name='energy')
_config_url = config_url
if _config_url == '':
_config_url = None
if not (_config_url is None or isinstance(_config_url, DataUrl)):
raise TypeError('given input for configuration is invalid')
......@@ -105,7 +111,7 @@ def read_pymca_xas(spectra_url, channel_url, config_url=None):
return None
if data_url.scheme() in ('PyMca', 'PyMca5'):
assert name in ('spectra', 'energy')
energy, mu = read_spectrum(spectra_url.file_path())
energy, mu = read_spectrum(data_url.file_path())
if name == 'spectra':
return mu.reshape(mu.shape[0], 1, 1)
else:
......@@ -117,7 +123,6 @@ def read_pymca_xas(spectra_url, channel_url, config_url=None):
_logger.warning('invalid url for', name, ', will not load it')
spectra = load_data(_spectra_url, name='spectra')
energy = load_data(_energy_url, name='energy')
configuration = load_data(_config_url, name='configuration')
......
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