Source code for mrsprint.settings

#! python
# -*- coding: utf-8 -*-

"""Module responsible for the configuration of settings of all other modules.

Authors:
    * Victor Hugo de Mello Pessoa <victor.pessoa@usp.br>
    * Daniel Cosmo Pizetta <daniel.pizetta@usp.br>

Since:
    2017/07/01

Todo:
    Insert log inside functions.

"""


import logging
import os

import h5py
import pyqtgraph.parametertree as pt
from pyqtgraph.Qt import QtCore, QtGui

from mrsprint.gui.mw_settings import Ui_Settings
from mrsprint.simulator.simulator import Simulator
from mrsprint.subject.sample import SampleConfig, SampleElementConfig
from mrsprint.system.gradient import Gradient
from mrsprint.system.magnet import MagnetConfig
from mrsprint.system.rf import RF

_logger = logging.getLogger(__name__)


[docs]class Settings(QtGui.QMainWindow): """Main window for settings. Todo: Include restore default settings. Create a better check for values. """ def __init__(self, *args, **kwargs): super(Settings, self).__init__(*args, **kwargs) self.ui = Ui_Settings() self.ui.setupUi(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.sample_config_group = SampleConfig() self.sample_element_config_group = SampleElementConfig() self.magnet_config_group = MagnetConfig() self.gradient_group = Gradient() self.rf_group = RF() self.simulator_group = Simulator() self.tree = pt.ParameterTree(self) self.tree.addParameters(self.sample_config_group) self.tree.addParameters(self.sample_element_config_group) self.tree.addParameters(self.magnet_config_group) self.tree.addParameters(self.gradient_group) self.tree.addParameters(self.rf_group) self.tree.addParameters(self.simulator_group) self.ui.verticalLayoutSettings.addWidget(self.tree) self.ui.actionSettingsOpen.triggered.connect(lambda: self.openFile()) self.ui.actionSettingsSave.triggered.connect(lambda: self.save(self.ui.lineEditSettings.text())) self.ui.actionSettingsSaveAs.triggered.connect(lambda: self.saveFile()) self.ui.actionSettingsImport.triggered.connect(lambda: self.openFile(set_file=False)) self.ui.actionSettingsExport.triggered.connect(lambda: self.saveFile(set_file=False)) self.ui.buttonBoxSettings.accepted.connect(lambda: self.save(self.ui.lineEditSettings.text())) self.ui.buttonBoxSettings.rejected.connect(self.close)
[docs] def check(self): """Evaluate if parameters are between its limits before saving them. Returns: bool: True if OK. Todo: Reduce complexity and check all value limits. """ error_message = "" # sample if self.sample_config_group.maxSizeX.value() < self.sample_config_group.SizeX.value(): error_message += "'Size X Max' must be greater than or equal to 'Size X Default'\n" if self.sample_config_group.maxSizeY.value() < self.sample_config_group.SizeY.value(): error_message += "'Size Y Max' must be greater than or equal to 'Size Y Default'\n" if self.sample_config_group.maxSizeZ.value() < self.sample_config_group.SizeZ.value(): error_message += "'Size Z Max' must be greater than or equal to 'Size Z Default'\n" if self.sample_config_group.maxN.value() < self.sample_config_group.Nx.value(): error_message += "'Max Number of points' must be greater than 'Nx Default'" if self.sample_config_group.maxN.value() < self.sample_config_group.Ny.value(): error_message += "'Max Number of points' must be greater than 'Ny Default'" if self.sample_config_group.maxN.value() < self.sample_config_group.Nz.value(): error_message += "'Max Number of points' must be greater than 'Nz Default'" if (self.sample_element_config_group.maxT1.value() < self.sample_element_config_group.t1.value() or self.sample_element_config_group.t1.value() < self.sample_element_config_group.minT1.value()): error_message += "'T1 Default' must be in between 'T1 Max Value' and 'T1 Min Value'\n" if (self.sample_element_config_group.maxT2.value() < self.sample_element_config_group.t2.value() or self.sample_element_config_group.t2.value() < self.sample_element_config_group.minT2.value()): error_message += "'T2 Default' must be in between 'T2 Max Value' and 'T2 Min Value'\n" if (self.sample_element_config_group.maxRho.value() < self.sample_element_config_group.rho.value() or self.sample_element_config_group.rho.value() < self.sample_element_config_group.minRho.value()): error_message += "'Rho Default' must be in between 'Rho Max Value' and 'Rho Min Value'\n" if error_message: error_dialog = QtGui.QMessageBox() error_dialog.setWindowTitle("Settings error") error_dialog.setText("It was found the following error(s):\n" + error_message) error_dialog.exec() _logger.warning('Settings error: %s', error_message) return False else: return True
[docs] def saveFile(self, set_file=True): """Open a dialog to select the config file to be saved.""" if not self.check(): return file_dialog = QtGui.QFileDialog(caption="Save ...") file_dialog.setNameFilter("*.hd5") file_dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave) if file_dialog.exec(): file_path = file_dialog.selectedFiles()[0] file_path = os.path.splitext(str(file_path))[0] + '.hd5' if file_path: self.save(file_path, set_file)
[docs] def save(self, file_path, set_file=True): """Save a HDF5 settings file. Args: file_path (str): Path to a file containing the settings. set_file (bool): set path file if true, otherwise just export. """ if not file_path: self.saveFile() file_ = h5py.File(file_path, 'w') settings_group = file_.create_group("SettingsGroup") simulator = [param.value() for param in self.simulator_group] if simulator[0] == "From Start": simulator[0] = 0 elif simulator[0] == "Steady State": simulator[0] = 1 if simulator[1] == "All Points": simulator[1] = 0 elif simulator[1] == "End Points": simulator[1] = 1 # Creating datasets settings_group.create_dataset("sample_config", data=[param.value() for param in self.sample_config_group]) settings_group.create_dataset("sample_element_config", data=[param.value() for param in self.sample_element_config_group]) settings_group.create_dataset("magnet_config", data=[param.value() for param in self.magnet_config_group]) settings_group.create_dataset("gradient", data=[param.value() for param in self.gradient_group]) settings_group.create_dataset("rf", data=[param.value() for param in self.rf_group]) settings_group.create_dataset("simulator", data=simulator) file_.flush() file_.close() if set_file: _logger.info('Saving settings file: %s', file_path) self.ui.lineEditSettings.setText(file_path) else: _logger.info('Exporting settings file: %s', file_path)
[docs] def openFile(self, set_file=True): """Open a dialog to select the config file to be opened.""" file_dialog = QtGui.QFileDialog(caption="Open ...") file_dialog.setNameFilter("*.hd5") file_dialog.setAcceptMode(QtGui.QFileDialog.AcceptOpen) if file_dialog.exec(): file_path = file_dialog.selectedFiles()[0] if file_path: self.open(file_path, set_file)
[docs] def blockUnblockSignals(self, value): """Block or unblock signals defined by value. Args: value (bool): True to block, false otherwise. """ self.tree.blockSignals(value) self.sample_config_group.blockSignals(value) self.sample_element_config_group.blockSignals(value) self.magnet_config_group.blockSignals(value) self.gradient_group.blockSignals(value) self.rf_group.blockSignals(value) self.simulator_group.blockSignals(value)
[docs] def open(self, file_path, set_file=True): """Open a HDF5 settings file. Args: file_path (str): Path to a file containing the settings. set_file (bool): set path file if true, otherwise just import. """ if not file_path: self.openFile() file_ = h5py.File(file_path, 'r') settings_group = file_.require_group("SettingsGroup") self.blockUnblockSignals(True) # Reading datasets sample_config_value = settings_group.require_dataset("sample_config", exact=True, shape=(10,), dtype=float).value sample_element_config_value = settings_group.require_dataset("sample_element_config", exact=True, shape=(9,), dtype=float).value magnet_config_value = settings_group.require_dataset("magnet_config", exact=True, shape=(13,), dtype=float).value gradient_value = settings_group.require_dataset("gradient", exact=True, shape=(6,), dtype=float).value rf_value = settings_group.require_dataset("rf", exact=True, shape=(6,), dtype=float).value simulator = settings_group.require_dataset("simulator", exact=True, shape=(13,), dtype=float).value file_.close() simulator_value = [] if simulator[0] == 0: simulator_value += ["From Start"] elif simulator[0] == 1: simulator_value += ["Steady State"] if simulator[1] == 0: simulator_value += ["All Points"] elif simulator[1] == 1: simulator_value += ["End Points"] for i in range(2, len(simulator)): simulator_value.append(simulator[i]) # Updating changes groups = [self.magnet_config_group, self.sample_config_group, self.sample_element_config_group, self.magnet_config_group, self.rf_group, self.simulator_group] values = [magnet_config_value, sample_config_value, sample_element_config_value, gradient_value, rf_value, simulator_value] for j in range(len(groups)): i = 0 _logger.debug('Group: %s', groups[j].name()) for param in groups[j]: try: _logger.debug('Parameter: %s = %s', param.name(), param.value()) param.setValue(values[j][i]) i += 1 except Exception: pass if set_file: _logger.info('Opening settings file: %s', file_path) self.ui.lineEditSettings.setText(file_path) else: _logger.info('Importing settings file: %s', file_path) self.blockUnblockSignals(False)
if __name__ == '__main__': app = QtGui.QApplication([]) window = Settings() window.show() window.resize(450, 600) app.exec_()