Exemple #1
0
    def __init__(self, ):
        super(ChangeLog, self).__init__()
        self.setWindowTitle('pyIMD :: What\'s new in pyIMD')
        self.setFixedSize(1100, 500)
        self.setWindowIcon(
            QtGui.QIcon(
                resource_path(
                    os.path.join(
                        os.path.join("ui", "icons", "pyIMD_logo_icon.ico")))))
        self.setWindowFlags(Qt.WindowCloseButtonHint)

        h_box = QVBoxLayout()
        v_box = QHBoxLayout()
        grid_h = QGridLayout()
        grid_v = QGridLayout()
        self.change_log_text = QTextBrowser()
        self.cancel_btn = QPushButton('Close', self)
        self.cancel_btn.clicked.connect(self.close_window)

        grid_v.addWidget(self.cancel_btn, 1, 1)
        v_box.addStretch()
        v_box.addLayout(grid_v)
        grid_h.addWidget(self.change_log_text)
        h_box.addLayout(grid_h)
        h_box.addLayout(v_box)
        self.setLayout(h_box)

        change_log = open(resource_path('change_log.txt')).read()
        self.change_log_text.setText(change_log)
Exemple #2
0
    def testReadPyimdProject(self):

        settings = Settings()
        # Change a settings field
        settings.figure_format = 'pdf'
        # Save changes
        settings.write_pyimd_project(resource_path('TestConfig.xml'))
        # Change back to default
        settings.figure_format = 'png'
        # Observe change back to what was saved to file
        settings.read_pyimd_project(resource_path('TestConfig.xml'))

        expected_result = {
            '_figure_units': 'cm',
            '_figure_name_pre_start_with_cell': 'FitWithCellData',
            '_calculation_mode': 'PLL',
            '_figure_name_measured_data': 'CalculatedCellMass',
            '_pre_start_with_cell_path': '',
            '_measurements_path': '',
            '_upper_parameter_bounds': [100.0, 5.0, 3, 3],
            '_conversion_factor_deg_to_rad': -57.3,
            '_initial_parameter_guess': [70.0, 2.0, 0.0, 0.0],
            '_lower_parameter_bounds': [10.0, 1.0, -3, -3],
            '_cantilever_length': 100,
            '_rolling_window_size': 1000,
            '_figure_width': 56.44,
            '_conversion_factor_hz_to_khz': 1000.0,
            '_figure_plot_every_nth_point': 1,
            '_project_folder_path': '',
            '_selected_files': [],
            '_figure_resolution_dpi': 72,
            '_correct_for_frequency_offset': False,
            '_frequency_offset_mode': 'Auto',
            '_frequency_offset_n_measurements_used': 1,
            '_frequency_offset': 0,
            '_pre_start_no_cell_path': '',
            '_read_text_data_from_line': 23,
            '_figure_name_pre_start_no_cell': 'FitNoCellData',
            '_text_data_delimiter': '\t',
            '_spring_constant': 4.0,
            '_figure_format': 'pdf',
            '_cell_position': 5,
            '_figure_height': 45.16
        }

        self.assertEqual(settings.__dict__, expected_result)
Exemple #3
0
    def __init__(self, parent=None):
        super(QuickInstructions, self).__init__(parent)
        # self.setAttribute(Qt.WA_DeleteOnClose) # Deletes instance on window close
        self.setWindowTitle('pyIMD :: Quick instructions')
        self.display_on_startup = 2
        self.resize(400, 370)
        self.setWindowIcon(
            QtGui.QIcon(
                resource_path(
                    os.path.join(
                        os.path.join("ui", "icons", "pyIMD_logo_icon.ico")))))
        grid = QGridLayout()
        grid.setContentsMargins(5, 5, 5, 5)
        ok = QPushButton('Ok')
        ok.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogApplyButton))
        ok.setMaximumWidth(100)
        ok.clicked.connect(self.close)
        self.chk = QCheckBox('Display quick instructions at startup')
        self.chk.setFont(QFont('Arial', 9, QFont.Bold))
        self.chk.setChecked(1)
        self.chk.clicked.connect(self.on_display_qi)

        self.quick_instructions = QTextEdit(self)
        self.quick_instructions.setText(
            '<h3>Quick Instructions</h3> '
            'Edit the settings first according to your experimental setup. Second select '
            'the directory containing your experimental data and determine the file name '
            'to measurement relationship as well as the measurement mode the data was '
            'recorded with.'
            '<br><br>Controls:'
            '<ul>'
            '<li><b>Ctrl+N (Cmd+N):</b> Create a new pyIMD project.'
            '</li>'
            '<li><b>Ctrl+O (Cmd+O):</b> Open an existing pyIMD project'
            '</li>'
            '<li><b>Ctrl+S (Cmd+S):</b> Save the current pyIMD project'
            '</li>'
            '<li><b>Ctrl+P (Cmd+P):</b> Open the settings dialog to change the project '
            'parameters</li></ul>'
            'Hints:'
            '<ul><li>Create a pyIMD project for all your experiments first and save '
            'the pyIMD projects before running them individually. The projects can then '
            'be run sequentially using the batch mode (Batch processing tab).'
            '</li>'
            '<li>Select multiple data files holding the Ctrl button during selection after'
            'clicking on <i>Select directory</i> or Ctrl+N.</li><'
            '</ul>'
            'You can open this window any time from the Help menu.</ul>')
        self.quick_instructions.setReadOnly(1)
        self.quick_instructions.setFont(QFont('Arial', 9))
        grid.addWidget(self.quick_instructions, 0, 0, 1, 0)
        grid.addWidget(ok, 1, 1)
        grid.addWidget(self.chk, 1, 0)
        self.setLayout(grid)
Exemple #4
0
    def close_application(self, event):
        """
        Opens a message box to handle program exit properly asking the user if the project should be saved first.

        Args:
            event(`QCloseEvent`):                   A QCloseEvent

        Returns:
            status_code (`int`):                    0 when process finished correctly, otherwise >0
        """
        self.settings.setValue('display_on_startup',
                               self.qi.display_on_startup)

        msg_box = QMessageBox()
        msg_box.setWindowIcon(
            QtGui.QIcon(
                resource_path(
                    os.path.join("ui", "icons", "pyIMD_logo_icon.ico"))))
        msg_box.setWindowTitle('pyIMD :: Quit Program')
        msg_box.setText(
            'Do you want to save changes before quitting the program?')
        save_btn = QPushButton('Save')
        save_btn.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogSaveButton))
        msg_box.addButton(save_btn, QMessageBox.YesRole)
        no_save_btn = QPushButton('Don\'t save')
        no_save_btn.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogNoButton))
        msg_box.addButton(no_save_btn, QMessageBox.NoRole)
        abort_btn = QPushButton('Cancel')
        abort_btn.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogCancelButton))
        msg_box.addButton(abort_btn, QMessageBox.RejectRole)
        ret = msg_box.exec_()

        if ret == 0:
            self.save_project()
            if not event:
                self.close()
            else:
                event.accept()
        elif ret == 1:
            if not event:
                self.close()
            else:
                event.accept()
        else:
            self.print_to_console("Program quit aborted")
            if not event:
                return
            else:
                event.ignore()
Exemple #5
0
    def __init__(self, parent=None):
        super(ConcatenateFiles, self).__init__(parent)
        self.setWindowTitle('pyIMD :: Concatenate data files')
        self.resize(150, 150)
        self.setWindowIcon(
            QtGui.QIcon(
                resource_path(
                    os.path.join(
                        os.path.join("ui", "icons", "pyIMD_logo_icon.ico")))))
        self.directory = []
        grid = QGridLayout()
        grid.setContentsMargins(5, 5, 5, 5)

        self.intro_label = QLabel(
            'Concatenate measurement data saved in multiple files into a single one.'
        )
        self.time_label = QLabel(
            'Enter the acquisition time interval (in seconds):')
        self.time_interval_edit = QLineEdit(self)
        self.time_interval_edit.textChanged.connect(
            self.on_time_interval_changed)
        validator = QtGui.QDoubleValidator()
        self.time_interval_edit.setValidator(validator)

        self.directory_label = QLabel(
            'Select directory containing all files to be concatenated:')
        self.directory_edit = QLineEdit(self)
        self.directory_edit.setStyleSheet("background-color: transparent; ")
        self.directory_edit.setReadOnly(1)
        self.directory_edit.textChanged.connect(self.on_directory_changed)
        self.select_dir_btn = QPushButton('Directory')
        self.select_dir_btn.clicked.connect(self.on_dir_selection)

        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        buttons.accepted.connect(self.on_accept)
        buttons.rejected.connect(self.reject)

        grid.addWidget(self.intro_label, 0, 0, 1, 2)
        grid.addWidget(self.directory_label, 1, 0)
        grid.addWidget(self.select_dir_btn, 1, 1)
        grid.addWidget(self.directory_edit, 2, 0, 1, 2)
        grid.addWidget(self.time_label, 3, 0)
        grid.addWidget(self.time_interval_edit, 3, 1)

        grid.addWidget(buttons, 5, 1)
        self.setLayout(grid)
Exemple #6
0
    def __init__(self):
        super(IMDWindow, self).__init__()
        uic.loadUi(resource_path(os.path.join('ui', 'main_window.ui')), self)
        self.setWindowTitle(
            'pyIMD: Inertial mass determination [build: v%s %s]' %
            (__version__, __operating_system__))
        self.setWindowIcon(
            QtGui.QIcon(
                resource_path(
                    os.path.join(
                        os.path.join("ui", "icons", "pyIMD_logo_icon.ico")))))

        # Add AppUserModelID for windows systems
        if sys.platform == 'win32':
            app_id = u'ethz.csb.pyCAME.v%s' % __version__
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                app_id)

        # Init QSettings for cross-platform temp settings file in ini format
        self.settings = QSettings(QSettings.IniFormat, QSettings.SystemScope,
                                  'CSB', 'pyIMD')

        self.menuBar.setNativeMenuBar(False)
        self.settings_dialog = None
        self.about_window = None
        self.file_list = []
        self.current_batch_project_file = []
        self.last_selected_path = ''
        self.show()
        self.console_edit.setReadOnly(True)
        self.radio_btn_name_array = ['autoRadio', 'pllRadio', 'contSweepRadio']
        self.opening_mode = 0  # intended to be used to distinguish if the ui is started as stand alone or not.
        self.task_done = False
        self.executor = ThreadPoolExecutor(max_workers=4)

        # Settings
        self.__settings = {
            "figure_format": FIGURE_FORMAT,
            "figure_width": FIGURE_WIDTH,
            "figure_height": FIGURE_HEIGHT,
            "figure_units": FIGURE_UNITS,
            "figure_resolution_dpi": FIGURE_RESOLUTION_DPI,
            "figure_name_pre_start_no_cell": FIGURE_NAME_PRE_START_NO_CELL,
            "figure_name_pre_start_with_cell": FIGURE_NAME_PRE_START_WITH_CELL,
            "figure_name_measured_data": FIGURE_NAME_MEASURED_DATA,
            "figure_plot_every_nth_point": FIGURE_PLOT_EVERY_NTH_POINT,
            "conversion_factor_hz_to_khz": CONVERSION_FACTOR_HZ_TO_KHZ,
            "conversion_factor_deg_to_rad": CONVERSION_FACTOR_DEG_TO_RAD,
            "spring_constant": SPRING_CONSTANT,
            "cantilever_length": CANTILEVER_LENGTH,
            "cell_position": CELL_POSITION,
            "initial_parameter_guess": INITIAL_PARAMETER_GUESS,
            "lower_parameter_bounds": LOWER_PARAMETER_BOUNDS,
            "upper_parameter_bounds": UPPER_PARAMETER_BOUNDS,
            "rolling_window_size": ROLLING_WINDOW_SIZE,
            "correct_for_frequency_offset": CORRECT_FOR_FREQUENCY_OFFSET,
            "frequency_offset_mode": FREQUENCY_OFFSET_MODE,
            "frequency_offset_n_measurements_used":
            FREQUENCY_OFFSET_N_MEASUREMENTS_USED,
            "frequency_offset": FREQUENCY_OFFSET,
            "read_text_data_from_line": READ_TEXT_DATA_FROM_LINE,
            "text_data_delimiter": repr(TEXT_DATA_DELIMITER).replace("'", "")
        }

        self.settings_dialog = SettingsDialog(self.__settings)
        self.settings_dialog.settings_has_changed_signal.connect(
            self.on_settings_changed)
        self.settings_dialog.set_values()
        self.setup_console_connection()
        self.selectDirBtn.clicked.connect(self.select_data_files)
        self.selectDirBtn.setShortcut("Ctrl+N")

        data_items = [
            'Measured data', 'Pre start no cell data',
            'Pre start with cell data', 'Pre start frequency shift',
            'Calculated cell mass'
        ]
        for i in range(0, len(data_items)):
            self.dataList.addItem(str(data_items[i]))
        self.dataList.itemSelectionChanged.connect(
            self.on_data_list_selection_changed)
        self.noCellDataBox.currentIndexChanged.connect(
            self.on_combo_box_changed)
        self.withCellDataBox.currentIndexChanged.connect(
            self.on_combo_box_changed)
        self.measuredDataBox.currentIndexChanged.connect(
            self.on_combo_box_changed)
        self.runCalculationBtn.clicked.connect(self.run_calculation)
        self.projectFilesBtn.clicked.connect(self.select_batch_files)
        self.runBatchBtn.clicked.connect(self.run_batch_calculation)

        self.actionView_Console.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogApplyButton))
        self.actionView_Console.setShortcut("Ctrl+C")
        self.actionView_Console.setStatusTip('Show / hide console console')
        self.actionView_Console.triggered.connect(self.show_console)

        self.actionQuit.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogCloseButton))
        self.actionQuit.setShortcut("Ctrl+Q")
        self.actionQuit.setStatusTip('Quit the application')
        self.actionQuit.triggered.connect(self.close_application)

        self.actionSave_project.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DialogSaveButton))
        self.actionSave_project.setShortcut("Ctrl+S")
        self.actionSave_project.setStatusTip('Save a pyIMD project')
        self.actionSave_project.triggered.connect(self.save_project)

        self.actionOpen_project.setIcon(QApplication.style().standardIcon(
            QStyle.SP_DirOpenIcon))
        self.actionOpen_project.setShortcut("Ctrl+O")
        self.actionOpen_project.setStatusTip('Open a pyIMD project')
        self.actionOpen_project.triggered.connect(self.open_project)

        self.actionSettings.setIcon(QApplication.style().standardIcon(
            QStyle.SP_FileDialogDetailedView))
        self.actionSettings.setShortcut("Ctrl+P")
        self.actionSettings.setStatusTip(
            'Configure pyIMD calculation settings')
        self.actionSettings.triggered.connect(self.show_settings_dialog)

        tools_menu = self.menuBar.addMenu('Tools')
        action_concat = tools_menu.addAction("Concatenate files")
        self.concatenation = ConcatenateFiles()
        action_concat.triggered.connect(self.on_concatenation)

        self.about_window = About()
        self.actionAbout.setShortcut("Ctrl+A")
        self.actionAbout.triggered.connect(self.on_about)

        self.qi = QuickInstructions()
        self.actionQuick_instructions.setStatusTip(
            'Hints about how to use this program')
        self.actionQuick_instructions.triggered.connect(
            self.on_quick_instructions)

        self.change_log = ChangeLog()
        self.actionChange_log.setStatusTip('See what change recently')
        self.actionChange_log.triggered.connect(self.on_change_log)

        self.actionRead_documentation.setStatusTip('Show online documentation')
        self.actionRead_documentation.triggered.connect(
            self.on_read_documentation)

        sys.stderr = Stream(stream_signal=self.on_update_text)

        self.batchFileListWidget.setSelectionMode(QListWidget.MultiSelection)
        self.tabWidget.setTabEnabled(2, False)
        self.tabWidget.setCurrentIndex(0)

        self.graphicsView.plotItem.ctrlMenu = None
        self.imd_icon = QGraphicsSvgItem(
            resource_path(
                os.path.join(os.path.join("ui", "icons",
                                          "pyIMD_logo_vect.svg"))))
        self.imd_icon.scale(1, -1)

        self.graphicsView.addItem(self.imd_icon)
        self.graphicsView.hideAxis('bottom')
        self.graphicsView.hideAxis('left')

        self.logger = self.get_logger_object(__name__)
        self.logger.setLevel(logging.INFO)

        self.imd = InertialMassDetermination()

        try:
            if self.settings.value('display_on_startup') is None:
                self.settings.setValue('display_on_startup', 2)
                self.qi.show()

            elif int(self.settings.value('display_on_startup')) == 2:
                self.qi.show()
        except Exception as e:
            self.print_to_console(
                'Could not load quick instruction window due to corrupt settings.ini file'
                + str(e))
Exemple #7
0
                event.accept()
        else:
            self.print_to_console("Program quit aborted")
            if not event:
                return
            else:
                event.ignore()

    def closeEvent(self, event):
        """
        Application close event override of QMainWindow closeEvent

        Args:
            event (`QCloseEvent`):                  A QCloseEvent

        Returns:
            status_code (`int`):                   O when process finished correctly otherwise >0
        """
        self.close_application(event)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = IMDWindow()
    app_icon = QtGui.QIcon()
    app_icon.addFile(
        resource_path(os.path.join("icons", "pyIMD_logo_icon.ico")),
        QSize(256, 256))
    app.setWindowIcon(app_icon)
    sys.exit(app.exec_())
Exemple #8
0
    def __init__(self, ):
        super(About, self).__init__()
        self.setWindowTitle('pyIMD :: About')
        self.setFixedSize(320, 450)
        self.setWindowFlags(Qt.WindowCloseButtonHint)
        about_icon = QIcon()
        about_icon.addPixmap(self.style().standardPixmap(
            QStyle.SP_FileDialogInfoView))
        self.setWindowIcon(about_icon)

        self.le = QLabel()
        self.build = QLabel("[build: v%s %s bit]" %
                            (__version__, __operating_system__))
        self.author = QLabel(
            "pyIMD: Inertial mass determination. \nWritten by Andreas P. Cuny and Gotthold\nFläschner"
        )
        self.license = QLabel("Licensed under the GPL v3 license.")
        self.copyright = QLabel(
            "\u00a9 Copyright  Andreas P. Cuny \n2018-2019. All rights reserved. \
                                \nCSB Laboratory @ ETH Zurich\nMattenstrasse 26 \n4058 Basel Switzerland"
        )
        self.dependencies = QTextBrowser()
        self.dependencies.setHtml(
            "The authors appreciate and use the following 3rd parties libraries: <br> \
                                <br>Python v3.5, under the <a href=https://docs.python.org/3/license.html>PSF License</a> \
                                <br>lxml, under the <a href=https://github.com/lxml/lxml/blob/master/LICENSES.txt>BSD 3-Clause License</a> \
                                <br>numpy v1.14.5, under the <a href=https://docs.scipy.org/doc/numpy-1.10.0/license.html>BSD 3-Clause License</a> \
                                <br>scipy v1.1.0, under the <a href=https://docs.scipy.org/doc/numpy-1.10.0/license.html>BSD 3-Clause License</a> \
                                <br>pandas v0.23.3, under the <a href=https://pandas.pydata.org/pandas-docs/stable/getting_started/overview.html>BSD 3-Clause License</a> \
                                <br>nptdms v0.12.0, under the <a href=https://github.com/adamreeve/npTDMS>GPL v3 License</a> \
                                <br>tqdm v4.23.4, under the <a href=https://github.com/tqdm/tqdm/blob/master/LICENCE>MIT License</a> \
                                <br>plotnine v0.3.0, under the <a href=https://github.com/has2k1/plotnine/blob/master/LICENSE>GPL v2 License</a> \
                                <br>PyQT5, under the <a href=https://www.riverbankcomputing.com/static/Docs/PyQt5/introduction.html#license>GPL v3 License</a> \
                                <br>xmltodict, under the <a href=https://github.com/martinblech/xmltodict/blob/master/LICENSE>MIT License</a> \
                                <br>matplotlib, under the <a href=https://matplotlib.org/devel/license.html>PSF License</a>\
                                <br>pyqtgraph, under the <a href=https://github.com/pyqtgraph/pyqtgraph/blob/develop/LICENSE.txt>MIT License</a>\
                                <br>xmlunittest, under the <a href=https://github.com/Exirel/python-xmlunittest/blob/master/LICENSE>MIT License</a>"
        )
        self.dependencies.setReadOnly(True)
        self.dependencies.setOpenExternalLinks(True)
        self.le.setAlignment(Qt.AlignCenter)
        self.build.setAlignment(Qt.AlignCenter)

        font_b = QtGui.QFont()
        font_b.setPointSize(9)
        self.build.setFont(font_b)
        font = QtGui.QFont()
        font.setPointSize(11)
        self.author.setFont(font)
        self.copyright.setFont(font)
        self.dependencies.setFont(font_b)

        logo = QtGui.QPixmap(
            resource_path(
                os.path.join(os.path.join("ui", "icons", "pyIMD_logo.png"))))
        logo = logo.scaled(250, 250, Qt.KeepAspectRatio)
        self.le.setPixmap(logo)

        v_box = QVBoxLayout()
        v_box.addWidget(self.le)
        v_box.addWidget(self.build)
        v_box.addWidget(self.license)
        v_box.addStretch()
        v_box.addWidget(self.author)
        v_box.addStretch()
        v_box.addWidget(self.copyright)
        v_box.addWidget(self.dependencies)
        v_box.addStretch()
        self.setLayout(v_box)

        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.white)
        self.setPalette(p)
Exemple #9
0
    def testWritePyimdProject(self):
        # Create the inertial mass determination object
        settings = Settings()
        # Save the project
        settings.write_pyimd_project(resource_path('TestConfig.xml'))

        with open(
                'TestConfig.xml',
                'rb',
        ) as myfile:
            data = myfile.read()

        # Everything starts with `assertXmlDocument`
        root = self.assertXmlDocument(data)

        # Check
        self.assertXmlNode(root, tag='PyIMDSettings')
        self.assertXpathValues(root, './GeneralSettings/figure_format/text()',
                               'png')
        self.assertXpathValues(root, './GeneralSettings/figure_width/text()',
                               '56.44')
        self.assertXpathValues(root, './GeneralSettings/figure_height/text()',
                               '45.16')
        self.assertXpathValues(root, './GeneralSettings/figure_units/text()',
                               'cm')
        self.assertXpathValues(
            root, './GeneralSettings/figure_resolution_dpi/text()', '72')
        self.assertXpathValues(
            root, './GeneralSettings/figure_name_pre_start_no_cell/text()',
            'FitNoCellData')
        self.assertXpathValues(
            root, './GeneralSettings/figure_name_pre_start_with_cell/text()',
            'FitWithCellData')
        self.assertXpathValues(
            root, './GeneralSettings/figure_name_measured_data/text()',
            'CalculatedCellMass')
        self.assertXpathValues(
            root, './GeneralSettings/figure_plot_every_nth_point/text()', '1')
        self.assertXpathValues(
            root, './GeneralSettings/conversion_factor_hz_to_khz/text()',
            '1000.0')
        self.assertXpathValues(
            root, './GeneralSettings/conversion_factor_deg_to_rad/text()',
            '-57.3')
        self.assertXpathValues(root,
                               './GeneralSettings/spring_constant/text()',
                               '4.0')
        self.assertXpathValues(root,
                               './GeneralSettings/cantilever_length/text()',
                               '100')
        self.assertXpathValues(root, './GeneralSettings/cell_position/text()',
                               '9.5')
        self.assertXpathValues(
            root, './GeneralSettings/initial_parameter_guess/text()',
            '[70.0, 2.0, 0.0, 0.0]')
        self.assertXpathValues(
            root, './GeneralSettings/lower_parameter_bounds/text()',
            '[10.0, 1.0, -3, -3]')
        self.assertXpathValues(
            root, './GeneralSettings/upper_parameter_bounds/text()',
            '[100.0, 5.0, 3, 3]')
        self.assertXpathValues(root,
                               './GeneralSettings/rolling_window_size/text()',
                               '1000')
        self.assertXpathValues(root,
                               './GeneralSettings/frequency_offset/text()',
                               '0')
        self.assertXpathValues(
            root, './GeneralSettings/read_text_data_from_line/text()', '23')
        self.assertXpathValues(root,
                               './GeneralSettings/text_data_delimiter/text()',
                               '\t')
        self.assertXpathValues(
            root, './ProjectSettings/selected_files/File/text()',
            ('20190110_ShowCase_PLL_A.txt', '20190110_ShowCase_PLL_B.txt',
             '20190110_ShowCase_PLL_LongTerm.txt'))
        self.assertXpathValues(root,
                               './ProjectSettings/project_folder_path/text()',
                               '')
        self.assertXpathValues(
            root, './ProjectSettings/pre_start_no_cell_path/text()', '')
        self.assertXpathValues(
            root, './ProjectSettings/pre_start_with_cell_path/text()', '')
        self.assertXpathValues(root,
                               './ProjectSettings/measurements_path/text()',
                               '')
        self.assertXpathValues(root,
                               './ProjectSettings/calculation_mode/text()',
                               'PLL')

        self.assertXpathsUniqueValue(root, ('./leaf/@id', ))
        self.assertXpathValues(root, './leaf/@active', ('on', 'off'))
Exemple #10
0
    def __init__(self, settings_dictionary):
        """
        Settings user interface (UI) constructor.

        Returns:
            QDialog (`obj`):     Settings ui object
        """
        super(SettingsDialog, self).__init__()
        uic.loadUi(resource_path(os.path.join('ui', 'setting_dialog.ui')),
                   self)
        self.setWindowTitle('pyIMD :: Settings')
        self.settingsIcon = QIcon()
        self.settingsIcon.addPixmap(
            self.style().standardPixmap(QStyle.SP_FileDialogDetailedView),
            QIcon.Disabled, QIcon.Off)
        self.setWindowIcon(self.settingsIcon)
        self.frequency_offset_spin.setMinimum(1)
        self.frequency_offset_spin.setMaximum(10**9)
        self.settings_dictionary = settings_dictionary

        # Establish connections
        self.defaultBtn.clicked.connect(self.set_defaults)
        self.commitBtn.clicked.connect(self.commit_parameters)
        self.cancelBtn.clicked.connect(self.close_settings_dialog)
        self.do_offset_corr_chkbox.clicked.connect(
            self.on_toggle_frequency_offset)
        self.offsetGroupBox.setEnabled(False)
        self.frequency_offset_edit.setEnabled(False)
        self.frequency_offset_mode_auto.setChecked(True)
        self.frequency_offset_mode_auto.toggled.connect(
            self.on_frequency_offset_mode_auto)
        self.frequency_offset_mode_manual.toggled.connect(
            self.on_frequency_offset_mode_manual)

        double_validator = QDoubleValidator()
        self.figure_width_edit.setValidator(double_validator)
        self.figure_width_edit.textChanged.connect(self.check_state)
        self.figure_height_edit.setValidator(double_validator)
        self.figure_height_edit.textChanged.connect(self.check_state)
        self.figure_resolution_edit.setValidator(double_validator)
        self.figure_resolution_edit.textChanged.connect(self.check_state)
        self.conversion_factor_hz_edit.setValidator(double_validator)
        self.conversion_factor_hz_edit.textChanged.connect(self.check_state)
        self.conversion_factor_deg_edit.setValidator(double_validator)
        self.conversion_factor_deg_edit.textChanged.connect(self.check_state)
        self.spring_constant_edit.setValidator(double_validator)
        self.spring_constant_edit.textChanged.connect(self.check_state)
        self.cantilever_length_edit.setValidator(double_validator)
        self.cantilever_length_edit.textChanged.connect(self.check_state)
        self.cell_position_edit.setValidator(double_validator)
        self.cell_position_edit.textChanged.connect(self.check_state)
        self.read_text_data_from_line_edit.setValidator(double_validator)
        self.read_text_data_from_line_edit.textChanged.connect(
            self.check_state)
        self.figure_plot_every_nth_point_edit.setValidator(double_validator)
        self.figure_plot_every_nth_point_edit.textChanged.connect(
            self.check_state)
        self.rolling_window_size_edit.setValidator(double_validator)
        self.rolling_window_size_edit.textChanged.connect(self.check_state)
        self.frequency_offset_edit.setValidator(double_validator)
        self.frequency_offset_edit.textChanged.connect(self.check_state)

        reg_ex = QRegExp("[0-9-a-z-A-Z_]+")
        self.figure_name_wo_cell_edit.setValidator(
            QRegExpValidator(reg_ex, self.figure_name_wo_cell_edit))
        self.figure_name_wo_cell_edit.textChanged.connect(self.check_state)
        self.figure_name_w_cell_edit.setValidator(
            QRegExpValidator(reg_ex, self.figure_name_w_cell_edit))
        self.figure_name_w_cell_edit.textChanged.connect(self.check_state)
        self.figure_name_data_edit.setValidator(
            QRegExpValidator(reg_ex, self.figure_name_data_edit))
        self.figure_name_data_edit.textChanged.connect(self.check_state)

        self.figure_unit_edit.setValidator(
            QRegExpValidator(QRegExp("[a-z-A-Z_]+"),
                             self.figure_name_wo_cell_edit))
        self.figure_unit_edit.textChanged.connect(self.check_state)

        self.figure_format_edit.setValidator(
            QRegExpValidator(QRegExp(".+[a-z-A-Z_]"),
                             self.figure_name_wo_cell_edit))
        self.figure_format_edit.textChanged.connect(self.check_state)
        self.text_data_delimiter_edit.setValidator(
            QRegExpValidator(QRegExp("(?:\\\{1}\w*)"),
                             self.text_data_delimiter_edit))
        self.text_data_delimiter_edit.textChanged.connect(self.check_state)

        self.intial_param_guess_edit.setValidator(
            QRegExpValidator(QRegExp("(?:\\[\d+.+,\s*)+\d+.+\\]{1}"),
                             self.intial_param_guess_edit))
        self.intial_param_guess_edit.textChanged.connect(self.check_state)

        self.lower_param_bound_edit.setValidator(
            QRegExpValidator(QRegExp("(?:\\[\d+.+,\s*)+\d+.+\\]{1}"),
                             self.lower_param_bound_edit))
        self.lower_param_bound_edit.textChanged.connect(self.check_state)

        self.upper_param_bound_edit.setValidator(
            QRegExpValidator(QRegExp("(?:\\[\d+.+,\s*)+\d+.+\\]{1}"),
                             self.upper_param_bound_edit))
        self.upper_param_bound_edit.textChanged.connect(self.check_state)