Source code for est.gui.xas_object_definition.ascii

import logging
from typing import List

from ewoksorange.gui.qt_utils.signals import block_signals
from silx.gui import qt

from ...core.io._utils.ascii import get_all_scan_titles
from ...core.io._utils.ascii import get_scan_column_names
from ..unit.energy import EnergyUnitSelector

_logger = logging.getLogger(__name__)


[docs] class XASObjectFromAscii(qt.QWidget): """ Widget used to define a XAS object from a single ASCII file. """ editingFinished = qt.Signal() """signal emitted when edition is finished""" def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QGridLayout()) # select file self.layout().addWidget(qt.QLabel("file", self), 0, 0, 1, 1) self._inputLe = _FileQLineEdit("", self) self.layout().addWidget(self._inputLe, 0, 1, 1, 1) self._selectPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectPB, 0, 2, 1, 1) # select scan from multi-spectrum file self.layout().addWidget(qt.QLabel("scan title"), 2, 0, 1, 1) self._scanTitleName = _QAsciiColumnWidget(parent=self) self.layout().addWidget(self._scanTitleName, 2, 1, 1, 1) # select ASCII columns self._dataSelectionWidget = _QAsciiColumnsSelector(parent=self) self.layout().addWidget(self._dataSelectionWidget, 3, 0, 1, 2) # spacer spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 999, 0, 1, 1) # signal / slot connection self._selectPB.pressed.connect(self._selectFile) self._inputLe.editingFinished.connect(self._newFileSelected) self._scanTitleName.currentIndexChanged.connect(self._newScanSelected) self._dataSelectionWidget.sigInputChanged.connect(self._editingIsFinished) def _editingIsFinished(self, *args, **kwargs): self.editingFinished.emit()
[docs] def getFileSelected(self): return self._inputLe.text()
def _getNameFilters(self): return [ "Ascii (*.dat *.spec *.csv *.xmu)", "All Files (*)", ] def _selectFile(self, *args, **kwargs): dialog = qt.QFileDialog(self) dialog.setFileMode(qt.QFileDialog.ExistingFile) dialog.setNameFilters(self._getNameFilters()) if not dialog.exec_(): dialog.close() return fileSelected = dialog.selectedFiles() if len(fileSelected) == 0: return assert len(fileSelected) == 1 self.setFileSelected(fileSelected[0])
[docs] def setFileSelected(self, file_path): self._inputLe.setText(file_path) self._newFileSelected()
def _newFileSelected(self): file_path = self.getFileSelected() try: titles = get_all_scan_titles(file_path) except Exception as e: _logger.error( "Retrieving scan titles from file %r failed (%s)", file_path, e ) titles = [] self._scanTitleName.setColumnNames(titles, 0) def _newScanSelected(self, index): file_path = self.getFileSelected() scan_title = self.getScanTitle() try: col_names = get_scan_column_names(file_path, scan_title) except Exception as e: _logger.error( "Retrieving column names from file %r failed (%s)", file_path, e ) col_names = [] self._dataSelectionWidget.setColumnNames(col_names)
[docs] def getEnergyUnit(self): return self._dataSelectionWidget.getEnergyUnit()
[docs] def setEnergyUnit(self, unit): return self._dataSelectionWidget.setEnergyUnit(unit=unit)
[docs] def setEnergyColName(self, name): self._dataSelectionWidget.setEnergyColName(name)
[docs] def getEnergyColName(self): return self._dataSelectionWidget.getEnergyColName()
[docs] def setAbsColName(self, name): self._dataSelectionWidget.setAbsColName(name)
[docs] def getAbsColName(self): return self._dataSelectionWidget.getAbsColName()
[docs] def setMonitorColName(self, name): self._dataSelectionWidget.setMonitorColName(name)
[docs] def getMonitorColName(self): return self._dataSelectionWidget.getMonitorColName()
[docs] def getColumnSelected(self): return self._dataSelectionWidget.getColumnSelected()
[docs] def setScanTitle(self, scan_title): index = self._scanTitleName.findText(scan_title) if index >= 0: self._scanTitleName.setCurrentIndex(index)
[docs] def getScanTitle(self): return self._scanTitleName.currentText()
[docs] def getMinLog(self) -> bool: return self._dataSelectionWidget.getMinLog()
[docs] def setMinLog(self, value: bool) -> None: self._dataSelectionWidget.setMinLog(value)
class _FileQLineEdit(qt.QLineEdit): """QLineEdit to handle a file path""" def dropEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): for url in event.mimeData().urls(): self.setText(str(url.path())) def supportedDropActions(self): """Inherited method to redefine supported drop actions.""" return qt.Qt.CopyAction | qt.Qt.MoveAction def dragEnterEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.accept() event.setDropAction(qt.Qt.CopyAction) else: qt.QWidget.dragEnterEvent(self, event) def dragMoveEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.setDropAction(qt.Qt.CopyAction) event.accept() else: qt.QWidget.dragMoveEvent(self, event) class _QAsciiColumnsSelector(qt.QWidget): """Select several column names from a list of ASCII column names.""" sigInputChanged = qt.Signal() """Signal emitted when data selection change""" def __init__(self, parent): super().__init__(parent=parent) layout = qt.QGridLayout() self.setLayout(layout) self._energyColNamCB = _QAsciiColumnWidget(parent=self) self._energyUnitSelector = EnergyUnitSelector(parent=self) layout.addWidget(qt.QLabel("energy"), 0, 0) layout.addWidget(self._energyColNamCB, 0, 1, 1, 2) spacer = qt.QSpacerItem(20, 0, qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) layout.addItem(spacer, 0, 2) layout.addWidget(self._energyUnitSelector, 0, 3) self._absColNamCB = _QAsciiColumnWidget(parent=self) layout.addWidget(qt.QLabel("μ (numerator)"), 1, 0) layout.addWidget(self._absColNamCB, 1, 1, 1, 3) self._monitorColNamCB = _QAsciiColumnWidget(parent=self) self._monitorColNamCB.setEnabled(False) self._useMonitorCB = qt.QCheckBox("μ (denominator)") layout.addWidget(self._useMonitorCB, 2, 0) layout.addWidget(self._monitorColNamCB, 2, 1, 1, 3) self._minlogCheckbox = qt.QCheckBox("-log(numerator/denominator)", parent=self) self.layout().addWidget(self._minlogCheckbox, 3, 0, 1, 1) # connect Signal / Slot self._energyColNamCB.currentIndexChanged.connect(self._propagateSigChanged) self._absColNamCB.currentIndexChanged.connect(self._propagateSigChanged) self._monitorColNamCB.currentIndexChanged.connect(self._propagateSigChanged) self._useMonitorCB.toggled.connect(self._propagateSigChanged) self._useMonitorCB.toggled.connect(self._monitorColNamCB.setEnabled) self._energyUnitSelector.currentIndexChanged.connect(self._propagateSigChanged) self._minlogCheckbox.stateChanged.connect(self._propagateSigChanged) def _propagateSigChanged(self): self.sigInputChanged.emit() def setColumnNames(self, col_names: List[str]): with block_signals(self): self._energyColNamCB.setColumnNames(col_names, 0) self._absColNamCB.setColumnNames(col_names, 1) self._monitorColNamCB.setColumnNames(col_names, 2) self._propagateSigChanged() def getColumnSelected(self) -> dict: return { "energy": self.getEnergyColName(), "mu": self.getAbsColName(), "monitor": self.getMonitorColName(), } def getMonitorColName(self): if self.useMonitor(): return self._monitorColNamCB.currentText() else: return None def setMonitorColName(self, name): with block_signals(self): self._monitorColNamCB.setColumnName(name) self._useMonitorCB.setChecked(bool(name)) self._propagateSigChanged() def useMonitor(self): return self._useMonitorCB.isChecked() def setEnergyColName(self, name): self._energyColNamCB.setColumnName(name) def getEnergyColName(self): return self._energyColNamCB.getColumnName() def getEnergyUnit(self): return self._energyUnitSelector.getUnit() def setEnergyUnit(self, unit): return self._energyUnitSelector.setUnit(unit=unit) def setAbsColName(self, name): self._absColNamCB.setColumnName(name) def getAbsColName(self): return self._absColNamCB.getColumnName() def getMinLog(self) -> bool: return self._minlogCheckbox.isChecked() def setMinLog(self, value: bool) -> None: self._minlogCheckbox.setChecked(value) class _QAsciiColumnWidget(qt.QComboBox): """Select one column names from a list of ASCII column names.""" def __init__(self, parent): super().__init__(parent) def setColumnNames(self, columns_names: List[str], default_index: int): prev_name = self.getColumnName() self.clear() for column_name in columns_names: self.addItem(column_name) if len(columns_names) > default_index: default_name = columns_names[default_index] else: default_name = "" if not prev_name or self.findText(prev_name) < 0: prev_name = default_name self.setColumnName(prev_name, force_emit=True) def setColumnName(self, name: str, force_emit: bool = False): prev_index = self.currentIndex() index = self.findText(name) if name and index < 0: _logger.warning("ASCII column name %r not found", name) self.setCurrentIndex(index) if prev_index == index and force_emit: self.currentIndexChanged.emit(index) def getColumnName(self) -> str: return self.currentText()