Example #1
0
File: base.py Project: pchj/nmrbrew
    def __init__(self, parent, *args, **kwargs):
        super(ToolBase, self).__init__(parent, *args, **kwargs)

        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())
        self.config.set_defaults({
            'is_active': True,
            'auto_run_on_config_change': True
        })

        self.config.updated.connect(self.auto_run_on_config_change)

        self.buttonBar = QWidget()

        self.configPanels = QWidget()
        self.configLayout = QVBoxLayout()
        self.configLayout.setContentsMargins(0, 0, 0, 0)

        self.configPanels.setLayout(self.configLayout)

        self._previous_config_backup_ = {}

        self._worker_thread_ = None
        self._worker_thread_lock_ = False

        self.data = {
            'spc': None,
        }

        self.current_status = 'ready'
        self.current_progress = 0

        self.progress.connect(self.progress_callback)
        self.status.connect(self.status_callback)
Example #2
0
    def __init__(self, parent, **kwargs):
        super(dialogPluginManagement, self).__init__(parent, **kwargs)

        self.setWindowTitle(tr("Manage Plugins"))

        self.config = ConfigManager()
        self.config.defaults = {
            'Plugins/Paths': settings.get('Plugins/Paths'),
            'Plugins/Disabled': settings.get('Plugins/Disabled'),
        }

        self.m = parent
        self.setFixedSize(self.sizeHint())

        self.plugins_lw = QListWidget()
        self.plugins_lw.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.plugins_lw.setItemDelegate(pluginListDelegate(self.plugins_lw))
        self.plugins_lw.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)

        page = QWidget()
        box = QGridLayout()
        paths = QHBoxLayout()

        self.pathlist = QLineEdit()
        self.config.add_handler(
            'Plugins/Paths', self.pathlist,
            (lambda x: x.split(';'), lambda x: ';'.join(x)))

        paths.addWidget(QLabel('Search Paths:'))
        paths.addWidget(self.pathlist)

        box.addLayout(paths, 0, 0)
        box.addWidget(self.plugins_lw, 1, 0)

        buttons = QVBoxLayout()

        refresh_btn = QPushButton('Refresh')
        refresh_btn.clicked.connect(self.onRefresh)
        buttons.addWidget(refresh_btn)

        activate_btn = QPushButton('Activate')
        activate_btn.clicked.connect(self.onActivate)
        buttons.addWidget(activate_btn)

        deactivate_btn = QPushButton('Dectivate')
        deactivate_btn.clicked.connect(self.onDeactivate)
        buttons.addWidget(deactivate_btn)

        buttons.addStretch()

        box.addLayout(buttons, 1, 1)
        page.setLayout(box)

        self.layout.addWidget(page)

        # Stack it all up, with extra buttons
        self.dialogFinalise()

        # Refresh the list of available plugins
        self._init_timer = QTimer.singleShot(0, self.onRefresh)
Example #3
0
def test_hook_inherited():
    class MyLineEdit(QLineEdit):
        pass

    widget = MyLineEdit()
    config = ConfigManager()
    assert config._get_hook(widget) == QLineEdit
Example #4
0
    def __init__(self, parent, *args, **kwargs):
        super(QGraphicsSceneExtend, self).__init__(parent, *args, **kwargs)

        self.m = parent.m

        self.config = ConfigManager()
        # These config settings are transient (ie. not stored between sessions)
        self.config.set_defaults({
            'mode': EDITOR_MODE_NORMAL,
            'font-family': 'Arial',
            'font-size': '12',
            'text-bold': False,
            'text-italic': False,
            'text-underline': False,
            'text-color': '#000000',
            'color-border': None,  # '#000000',
            'color-background': None,
        })

        # Pre-set these values (will be used by default)
        self.config.set('color-background', '#5555ff')

        self.background_image = QImage(
            os.path.join(utils.scriptdir, 'icons', 'grid100.png'))
        if settings.get('Editor/Show_grid'):
            self.showGrid()
        else:
            self.hideGrid()

        self.mode = EDITOR_MODE_NORMAL
        self.mode_current_object = None

        self.annotations = []
Example #5
0
    def __init__(self, *args, **kwargs):
        self.LUXEMBOURG = "LUXEMBOURG"
        self.MONACO = "MONACO"
        self.NASSAU = "NASSAU"
        self.GERMANY = "GERMANY"

        QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
        self.title = "ARIS - JIRA Interface GUI"
        self.left, self.top, self.width, self.height = (0, 30, 1600, 480)
        self.config = ConfigManager()
        self.aris_config = self.open_conf_lux()
        self.apps = os.path.join(os.path.dirname(os.getcwd()),
                                 self.aris_config["apps"][0])
        self.aris_config_no_tooltips = {
            key: val[0]
            for (key, val) in self.aris_config.items()
        }
        self.aris_config_list = [(key, value[1])
                                 for key, value in self.aris_config.items()]
        self.initUI(self)
        self.statusBar().showMessage("Ready.")

        self.scrape_ARIS_widget.clicked.connect(self.scrape_ARIS)
        self.create_TC_widget.clicked.connect(self.create_TC)
        self.sync_TC_widget.clicked.connect(self.sync_TC)
        self.config.updated.connect(self.show_config)
        self.config.updated.connect(self.save_config)
        self.cmb.activated[str].connect(self.load_preconfigured_json)
        self.event_stop = threading.Event()
        QtWidgets.QShortcut("Ctrl+C", self, activated=self.end_button_func)
Example #6
0
def test_hook_inherited():
    class MyLineEdit(QLineEdit):
        pass

    widget = MyLineEdit()
    config = ConfigManager()
    assert config._get_hook(widget) == QLineEdit
Example #7
0
def test_hook_inherited_direct():
    class MyLineEdit(QLineEdit):
        pass

    widget = MyLineEdit()
    config = ConfigManager()
    config.add_hooks(MyLineEdit, (_get_QLineEdit, _set_QLineEdit, _event_QLineEdit))
    assert config._get_hook(widget) == MyLineEdit
Example #8
0
def test_hook_inherited_direct():
    class MyLineEdit(QLineEdit):
        pass

    widget = MyLineEdit()
    config = ConfigManager()
    config.add_hooks(MyLineEdit,
                     (_get_QLineEdit, _set_QLineEdit, _event_QLineEdit))
    assert config._get_hook(widget) == MyLineEdit
Example #9
0
def test_no_hook():
    class MyTestClass:
        pass

    o = MyTestClass()
    config = ConfigManager()
    with pytest.raises(TypeError) as e:
        assert config._get_hook(o)
    assert "No handler-functions available for this" in str(e)
Example #10
0
def test_no_hook():
    class MyTestClass:
        pass

    o = MyTestClass()
    config = ConfigManager()
    with pytest.raises(TypeError) as e:
        assert config._get_hook(o)
    assert "No handler-functions available for this" in str(e)
Example #11
0
File: ui.py Project: pchj/nmrbrew
    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotateClasses, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Classes')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Sample classes')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_classes = QListWidgetAddRemove()
        self.lw_classes.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_classes)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_class = QLineEdit()

        addc = QPushButton('Add')
        addc.clicked.connect(self.onClassAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onClassAdd)

        loadc = QPushButton('Import from file')
        loadc.setIcon(
            QIcon(
                os.path.join(utils.scriptdir, 'icons',
                             'folder-open-document.png')))
        loadc.clicked.connect(self.onClassImport)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_class)
        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vboxh.addWidget(loadc)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/sample_classes', self.lw_classes,
                                (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()
Example #12
0
File: ui.py Project: pchj/nmrbrew
    def __init__(self, parent, config=None, *args, **kwargs):
        super(Preferences, self).__init__(parent, *args, **kwargs)

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())
            self.config.set_defaults(config)

        self.dialogFinalise()
Example #13
0
    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle('PyQtConfig Demo')
        self.config = ConfigManager()

        CHOICE_A = 1
        CHOICE_B = 2
        CHOICE_C = 3
        CHOICE_D = 4

        map_dict = {
            'Choice A': CHOICE_A,
            'Choice B': CHOICE_B,
            'Choice C': CHOICE_C,
            'Choice D': CHOICE_D,
        }

        self.config.set_defaults({
            'number': 13,
            'text': 'hello',
            'active': True,
            'combo': CHOICE_C,
        })

        gd = QGridLayout()

        sb = QSpinBox()
        gd.addWidget(sb, 0, 1)
        self.config.add_handler('number', sb)

        te = QLineEdit()
        gd.addWidget(te, 1, 1)
        self.config.add_handler('text', te)

        cb = QCheckBox()
        gd.addWidget(cb, 2, 1)
        self.config.add_handler('active', cb)

        cmb = QComboBox()
        cmb.addItems(map_dict.keys())
        gd.addWidget(cmb, 3, 1)
        self.config.add_handler('combo', cmb, mapper=map_dict)

        self.current_config_output = QTextEdit()
        gd.addWidget(self.current_config_output, 0, 3, 3, 1)

        self.config.updated.connect(self.show_config)

        self.show_config()

        self.window = QWidget()
        self.window.setLayout(gd)
        self.setCentralWidget(self.window)
Example #14
0
    def __init__(self, position=None, *args, **kwargs):
        super(BaseAnnotationItem, self).__init__(*args, **kwargs)
        # Config for each annotation item, holding the settings (styles, etc)
        # update-control via the toolbar using add_handler linking
        self.config = ConfigManager()
        self.config.updated.connect(self.applyStyleConfig)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemIsFocusable)

        if position:
            self.setPos(position)

        self.setZValue(-1)
Example #15
0
    def __init__(self, config_in, ncols=2, captions=None, hide_keys=None,
                 horizontal=False, show_captions=True, accept_button=False,
                 config_manager=None, radiobuttons=None, dropdownboxes=None):
        """

        :param config_in:  dictionary
        :param ncols:
        :param captions:
        :param radiobuttons: {"name_of_radiobutton": [
                                 ["orig_caption_1", orig_caption_2],
                                 default_value]
                                 ]
                            }
        """
        super(DictWidget, self).__init__()
        if captions is None:
            captions = {}
        if hide_keys is None:
            hide_keys = []
        self.config_in = config_in
        self.ncols = ncols
        self.captions = captions
        self.accept_button = accept_button
        self.hide_keys = copy.copy(hide_keys)
        self.horizontal = horizontal
        self.show_captions = show_captions
        if radiobuttons is None:
            radiobuttons = {}
        self.radiobuttons = radiobuttons
        if dropdownboxes is None:
            dropdownboxes = {}
        self.dropdownboxes = dropdownboxes

        # hide also temp keys for lists and ndarrays
        # due to load default params
        self._get_tmp_composed_keys(config_in)
        self.hide_keys.extend(self._tmp_composed_keys_list)

        if config_manager is None:
            self.config = ConfigManager()
            self.config.set_defaults(config_in)
        else:
            self.config = config_manager
        self.mainLayout = QGridLayout(self)
        self.setLayout(self.mainLayout)
        self.widgets = {}
        self.grid_i = 0
        self.init_ui()
Example #16
0
    def __init__(self, parent, *args, **kwargs):
        super(ToolBase, self).__init__(parent, *args, **kwargs)


        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())
        self.config.set_defaults({
            'auto_run_on_config_change': True
            })
        self.current_status = 'inactive'
        self.config.updated.connect(self.auto_run_on_config_change)

        self.buttonBar = QWidget()

        self.configPanels = QWidget()
        self.configLayout = QVBoxLayout()
        self.configLayout.setContentsMargins(0,0,0,0)

        self.configPanels.setLayout(self.configLayout)

        self._previous_config_backup_ = {}

        self._worker_thread_ = None
        self._worker_thread_lock_ = False

        self.view = MplView(self.parent())

        self.setup()

        self.current_progress = 0

        self.progress.connect(self.progress_callback)
        self.status.connect(self.status_callback)
Example #17
0
    def __init__(self, parent, *args, **kwargs):
        super(QGraphicsSceneExtend, self).__init__(parent, *args, **kwargs)

        self.m = parent.m

        self.config = ConfigManager()
        # These config settings are transient (ie. not stored between sessions)
        self.config.set_defaults({
            'mode': EDITOR_MODE_NORMAL,
            'font-family': 'Arial',
            'font-size': '12',
            'text-bold': False,
            'text-italic': False,
            'text-underline': False,
            'text-color': '#000000',
            'color-border': None,  # '#000000',
            'color-background': None,
        })

        # Pre-set these values (will be used by default)
        self.config.set('color-background', '#5555ff')

        self.background_image = QImage(os.path.join(utils.scriptdir, 'icons', 'grid100.png'))
        if settings.get('Editor/Show_grid'):
            self.showGrid()
        else:
            self.hideGrid()

        self.mode = EDITOR_MODE_NORMAL
        self.mode_current_object = None

        self.annotations = []
Example #18
0
File: ui.py Project: mfitzp/nmrbrew
    def __init__(self, *args, **kwargs):
        super(MetaboHunter, self).__init__(*args, **kwargs)

        self.setWindowTitle('MetaboHunter')
        # Copy in starting state
        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())

        self.config.set_defaults({
            'Metabotype': 'All',
            'Database Source': 'HMDB',
            'Sample pH': 'ph7',
            'Solvent': 'water',
            'Frequency': 'all',
            'Method': 'HighestNumberNeighbourhood',
            'Noise Threshold': 0.0001,
            'Confidence Threshold': 0.5,
            'Tolerance': 0.1,
            'convert_hmdb_ids_to_names': True,
        })

        self.lw_combos = {}

        for o in ['Metabotype', 'Database Source', 'Sample pH', 'Solvent', 'Frequency', 'Method']:
            row = QVBoxLayout()
            cl = QLabel(o)
            cb = QComboBox()

            cb.addItems(list(self.options[o].keys()))
            row.addWidget(cl)
            row.addWidget(cb)
            self.config.add_handler(o, cb, self.options[o])

            self.layout.addLayout(row)

        row = QGridLayout()
        self.lw_spin = {}
        for n, o in enumerate(['Noise Threshold', 'Confidence Threshold', 'Tolerance']):
            cl = QLabel(o)
            cb = QDoubleSpinBox()
            cb.setDecimals(4)
            cb.setRange(0, 1)
            cb.setSingleStep(0.01)
            cb.setValue(float(self.config.get(o)))
            row.addWidget(cl, 0, n)
            row.addWidget(cb, 1, n)

            self.config.add_handler(o, cb)

        self.layout.addLayout(row)

        row = QHBoxLayout()
        row.addWidget(QLabel("Convert HMDB IDs to chemical names?"))
        conv = QCheckBox()
        self.config.add_handler('convert_hmdb_ids_to_names', conv)
        row.addWidget(conv)

        self.layout.addLayout(row)

        self.dialogFinalise()
Example #19
0
    def __init__(self, settings, parent=None):
        super().__init__(parent)
        self.settings = settings
        self.serialports = []

        # port
        self.portLabel = QLabel(self.tr("COM Port:"))
        self.portComboBox = QComboBox()
        self.portLabel.setBuddy(self.portComboBox)
        self.refresh_comports(self.portComboBox)

        # baudrate
        self.baudrateLabel = QLabel(self.tr("Baudrate:"))
        self.baudrateComboBox = QComboBox()
        self.baudrateLabel.setBuddy(self.baudrateComboBox)
        for br in BAUDRATES:
            self.baudrateComboBox.addItem(str(br), br)

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

        # layout
        layout = QGridLayout()
        layout.addWidget(self.portLabel, 0, 0)
        layout.addWidget(self.portComboBox, 0, 1)
        layout.addWidget(self.baudrateLabel, 1, 0)
        layout.addWidget(self.baudrateComboBox, 1, 1)
        layout.addWidget(self.dlgbuttons, 2, 0, 1, 2)
        self.setLayout(layout)
        self.setWindowTitle(self.tr("Serial Settings"))

        # settings
        defaults = {
            PORT_SETTING: "",
            BAUDRATE_SETTING: "115200"
        }
        self.tmp_settings = ConfigManager()
        self.tmp_settings.set_defaults(defaults)
        self.tmp_settings.set_many(
            {key: self.settings.get(key) for key in defaults.keys()}
        )
        self.tmp_settings.add_handler(PORT_SETTING, self.portComboBox)
        self.tmp_settings.add_handler(BAUDRATE_SETTING, self.baudrateComboBox)
Example #20
0
File: ui.py Project: pchj/nmrbrew
class Preferences(GenericDialog):
    '''
    Application preferences dialog. This is passed a set of options and these are duplicated-stored internally.
    If the preferences dialog is exited with OK, these changes are copied and applied back to the
    global settings object. If exited with Cancel they are discarded.

    '''
    def __init__(self, parent, config=None, *args, **kwargs):
        super(Preferences, self).__init__(parent, *args, **kwargs)

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())
            self.config.set_defaults(config)

        self.dialogFinalise()
Example #21
0
    def __init__(self, parent, **kwargs):
        super(dialogPluginManagement, self).__init__(parent, **kwargs)

        self.setWindowTitle(tr("Manage Plugins"))

        self.config = ConfigManager()
        self.config.defaults = {
            'Plugins/Paths': settings.get('Plugins/Paths'),
            'Plugins/Disabled': settings.get('Plugins/Disabled'),
        }

        self.m = parent
        self.setFixedSize(self.sizeHint())

        self.plugins_lw = QListWidget()
        self.plugins_lw.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.plugins_lw.setItemDelegate(pluginListDelegate(self.plugins_lw))
        self.plugins_lw.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)

        page = QWidget()
        box = QGridLayout()
        paths = QHBoxLayout()

        self.pathlist = QLineEdit()
        self.config.add_handler('Plugins/Paths', self.pathlist, (lambda x: x.split(';'), lambda x: ';'.join(x)))

        paths.addWidget(QLabel('Search Paths:'))
        paths.addWidget(self.pathlist)

        box.addLayout(paths, 0, 0)
        box.addWidget(self.plugins_lw, 1, 0)

        buttons = QVBoxLayout()

        refresh_btn = QPushButton('Refresh')
        refresh_btn.clicked.connect(self.onRefresh)
        buttons.addWidget(refresh_btn)

        activate_btn = QPushButton('Activate')
        activate_btn.clicked.connect(self.onActivate)
        buttons.addWidget(activate_btn)

        deactivate_btn = QPushButton('Dectivate')
        deactivate_btn.clicked.connect(self.onDeactivate)
        buttons.addWidget(deactivate_btn)

        buttons.addStretch()

        box.addLayout(buttons, 1, 1)
        page.setLayout(box)

        self.layout.addWidget(page)

        # Stack it all up, with extra buttons
        self.dialogFinalise()

        # Refresh the list of available plugins
        self._init_timer = QTimer.singleShot(0, self.onRefresh)
Example #22
0
File: ui.py Project: mfitzp/nmrbrew
class Preferences(GenericDialog):
    '''
    Application preferences dialog. This is passed a set of options and these are duplicated-stored internally.
    If the preferences dialog is exited with OK, these changes are copied and applied back to the
    global settings object. If exited with Cancel they are discarded.

    '''

    def __init__(self, parent, config=None, *args, **kwargs):
        super(Preferences, self).__init__(parent, *args, **kwargs)

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())
            self.config.set_defaults(config)


        self.dialogFinalise()
Example #23
0
    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle('PyQtConfig Demo')
        self.config = ConfigManager()

        CHOICE_A = 1
        CHOICE_B = 2
        CHOICE_C = 3
        CHOICE_D = 4

        map_dict = {
            'Choice A': CHOICE_A,
            'Choice B': CHOICE_B,
            'Choice C': CHOICE_C,
            'Choice D': CHOICE_D,
        }

        self.config.set_defaults({
            'number': 13,
            'text': 'hello',
            'active': True,
            'combo': CHOICE_C,
        })

        gd = QGridLayout()

        sb = QSpinBox()
        gd.addWidget(sb, 0, 1)
        self.config.add_handler('number', sb)

        te = QLineEdit()
        gd.addWidget(te, 1, 1)
        self.config.add_handler('text', te)

        cb = QCheckBox()
        gd.addWidget(cb, 2, 1)
        self.config.add_handler('active', cb)

        cmb = QComboBox()
        cmb.addItems(map_dict.keys())
        gd.addWidget(cmb, 3, 1)
        self.config.add_handler('combo', cmb, mapper=map_dict)

        self.current_config_output = QTextEdit()
        gd.addWidget(self.current_config_output, 0, 3, 3, 1)

        self.config.updated.connect(self.show_config)

        self.show_config()

        self.window = QWidget()
        self.window.setLayout(gd)
        self.setCentralWidget(self.window)
Example #24
0
File: ui.py Project: mfitzp/nmrbrew
    def __init__(self, parent, config=None, *args, **kwargs):
        super(Preferences, self).__init__(parent, *args, **kwargs)

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())
            self.config.set_defaults(config)


        self.dialogFinalise()
Example #25
0
    def __init__(self, *args, **kwargs):
        super(Automaton, self).__init__(*args, **kwargs)

        self.setData(self, Qt.UserRole)
        self.watcher = QFileSystemWatcher()
        self.timer = QTimer()

        self.watch_window = {}

        self.latest_run = {}
        self.is_running = False

        self.config = ConfigManager()
        self.config.set_defaults({
            'mode': MODE_WATCH_FOLDER,
            'is_active': True,
            'trigger_hold': 1,
            'notebook_paths': '',
            'output_path': '{home}/{notebook_filename}_{datetime}_',
            'output_format': 'html',
            'watched_files': [],
            'watched_folder': '',
            'watch_window': 15,
            'iterate_watched_folder': True,
            'iterate_wildcard': '.csv',
            'timer_seconds': 60,
        })

        self.runner = None
        self.lock = None

        self.latest_run = {
            'timestamp': None,
            'success': None,
        }

        # Set up all the triggers
        self.watcher.fileChanged.connect(self.file_trigger_accumulator)
        self.watcher.directoryChanged.connect(self.trigger)
        self.timer.timeout.connect(self.trigger)
Example #26
0
File: ui.py Project: mfitzp/nmrbrew
    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotateClasses, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Classes')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Sample classes')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_classes = QListWidgetAddRemove()
        self.lw_classes.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_classes)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_class = QLineEdit()

        addc = QPushButton('Add')
        addc.clicked.connect(self.onClassAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onClassAdd)

        loadc = QPushButton('Import from file')
        loadc.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')))
        loadc.clicked.connect(self.onClassImport)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_class)
        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vboxh.addWidget(loadc)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/sample_classes', self.lw_classes, (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()
Example #27
0
class BaseAnnotationItem(ResizableGraphicsItem):

    handler_cache = {}
    styles = ['font-family', 'font-size', 'text-bold', 'text-italic', 'text-underline', 'text-color', 'color-border', 'color-background']

    minSize = ANNOTATION_MINIMUM_QSIZE

    def __init__(self, position=None, *args, **kwargs):
        super(BaseAnnotationItem, self).__init__(*args, **kwargs)
        # Config for each annotation item, holding the settings (styles, etc)
        # update-control via the toolbar using add_handler linking
        self.config = ConfigManager()
        self.config.updated.connect(self.applyStyleConfig)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemIsFocusable)

        if position:
            self.setPos(position)

        self.setZValue(-1)

    def delete(self):
        self.prepareGeometryChange()
        self.scene().annotations.remove(self)
        self.scene().removeItem(self)
        self.removeHandlers()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Backspace and e.modifiers() == Qt.ControlModifier:
            self.delete()
        else:
            return super(BaseAnnotationItem, self).keyPressEvent(e)

    def importStyleConfig(self, config):
        for k in self.styles:
            self.config.set(k, config.get(k))

    def addHandlers(self):
        m = self.scene().views()[0].m  # Hack; need to switch to importing this
        for k in self.styles:
            self.config.add_handler(k, m.styletoolbarwidgets[k])

    def removeHandlers(self):
        for k in self.styles:
            self.config.remove_handler(k)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemSelectedChange:
            if not value:
                self.removeHandlers()

        elif change == QGraphicsItem.ItemSelectedHasChanged:
            if value:
                self.addHandlers()

        return super(BaseAnnotationItem, self).itemChange(change, value)
Example #28
0
    def __init__(self, position=None, *args, **kwargs):
        super(BaseAnnotationItem, self).__init__(*args, **kwargs)
        # Config for each annotation item, holding the settings (styles, etc)
        # update-control via the toolbar using add_handler linking
        self.config = ConfigManager()
        self.config.updated.connect(self.applyStyleConfig)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemIsFocusable)

        if position:
            self.setPos(position)

        self.setZValue(-1)
Example #29
0
    def __init__(self, *args, **kwargs):
        super(Automaton, self).__init__(*args, **kwargs)

        self.setData(self, Qt.UserRole)
        self.watcher = QFileSystemWatcher()
        self.timer = QTimer()

        self.watch_window = {}

        self.latest_run = {}
        self.is_running = False

        self.config = ConfigManager()
        self.config.set_defaults({
            'mode': MODE_WATCH_FOLDER,
            'is_active': True,
            'trigger_hold': 1,
            'notebook_paths': '',
            'output_path': '{home}/{notebook_filename}_{datetime}_',
            'output_format': 'html',

            'watched_files': [],
            'watched_folder': '',
            'watch_window': 15,

            'iterate_watched_folder': True,
            'iterate_wildcard': '.csv',

            'timer_seconds': 60,
        })

        self.runner = None
        self.lock = None

        self.latest_run = {
            'timestamp': None,
            'success': None,
        }

        # Set up all the triggers
        self.watcher.fileChanged.connect(self.file_trigger_accumulator)
        self.watcher.directoryChanged.connect(self.trigger)
        self.timer.timeout.connect(self.trigger)
Example #30
0
File: ui.py Project: mfitzp/nmrbrew
    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotatePeaks, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Peaks')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Peaks')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_peaks = QListWidgetAddRemove()
        self.lw_peaks.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_peaks)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_start = QDoubleSpinBox()
        self.add_start.setRange(-1, 12)
        self.add_start.setDecimals(3)
        self.add_start.setSuffix('ppm')
        self.add_start.setSingleStep(0.001)

        self.add_end = QDoubleSpinBox()
        self.add_end.setRange(-1, 12)
        self.add_end.setDecimals(3)
        self.add_end.setSuffix('ppm')
        self.add_end.setSingleStep(0.001)

        addc = QPushButton('Add')
        addc.clicked.connect(self.onPeakAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onPeakAdd)

        loadc = QPushButton("Import from file")
        loadc.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')))
        loadc.clicked.connect(self.onPeakImport)


        metabh = QPushButton("Auto match via MetaboHunter")
        metabh.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'metabohunter.png')))
        metabh.clicked.connect(self.onPeakImportMetabohunter)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_start)
        vboxh.addWidget(self.add_end)

        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vbox.addWidget(loadc)
        vbox.addWidget(metabh)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/peaks', self.lw_peaks, (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()
Example #31
0
class AutomatonDialog(GenericDialog):

    mode_options = {
        'Manual': MODE_MANUAL,
        'Watch files': MODE_WATCH_FILES,
        'Watch folder': MODE_WATCH_FOLDER,
        'Timer': MODE_TIMER,
    }

    def __init__(self, parent, **kwargs):
        super(AutomatonDialog, self).__init__(parent, **kwargs)
        self.setWindowTitle("Edit Automaton")

        self.config = ConfigManager()

        gb = QGroupBox('IPython notebook(s) (*.ipynb)')
        grid = QGridLayout()
        notebook_path_le = QLineEdit()
        self.config.add_handler('notebook_paths', notebook_path_le, mapper=(lambda x: x.split(";"), lambda x: ";".join(x)))
        grid.addWidget(notebook_path_le, 0, 0, 1, 2)

        notebook_path_btn = QToolButton()
        notebook_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'document-attribute-i.png')))
        notebook_path_btn.clicked.connect(lambda: self.onNotebookBrowse(notebook_path_le))
        grid.addWidget(notebook_path_btn, 0, 2, 1, 1)
        gb.setLayout(grid)

        self.layout.addWidget(gb)

        gb = QGroupBox('Automaton mode')
        grid = QGridLayout()
        mode_cb = QComboBox()
        mode_cb.addItems(self.mode_options.keys())
        mode_cb.currentIndexChanged.connect(self.onChangeMode)
        self.config.add_handler('mode', mode_cb, mapper=self.mode_options)
        grid.addWidget(QLabel('Mode'), 0, 0)
        grid.addWidget(mode_cb, 0, 1)

        grid.addWidget(QLabel('Hold trigger'), 1, 0)
        fwatcher_hold_sb = QSpinBox()
        fwatcher_hold_sb.setRange(0, 60)
        fwatcher_hold_sb.setSuffix(' secs')
        self.config.add_handler('trigger_hold', fwatcher_hold_sb)
        grid.addWidget(fwatcher_hold_sb, 1, 1)
        gb.setLayout(grid)

        self.layout.addWidget(gb)

        self.watchfile_gb = QGroupBox('Watch files')
        grid = QGridLayout()

        watched_path_le = QLineEdit()
        grid.addWidget(watched_path_le, 0, 0, 1, 2)
        self.config.add_handler('watched_files', watched_path_le, mapper=(lambda x: x.split(";"), lambda x: ";".join(x)))

        watched_path_btn = QToolButton()
        watched_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'document-copy.png')))
        watched_path_btn.setStatusTip('Add file(s)')
        watched_path_btn.clicked.connect(lambda: self.onFilesBrowse(watched_path_le))
        grid.addWidget(watched_path_btn, 0, 2, 1, 1)

        grid.addWidget(QLabel('Watch window'), 1, 0)
        watch_window_sb = QSpinBox()
        watch_window_sb.setRange(0, 60)
        watch_window_sb.setSuffix(' secs')
        self.config.add_handler('watch_window', watch_window_sb)
        grid.addWidget(watch_window_sb, 1, 1)

        self.watchfile_gb.setLayout(grid)
        self.layout.addWidget(self.watchfile_gb)

        self.watchfolder_gb = QGroupBox('Watch folder')
        grid = QGridLayout()

        watched_path_le = QLineEdit()
        grid.addWidget(watched_path_le, 0, 0, 1, 3)
        self.config.add_handler('watched_folder', watched_path_le)

        watched_path_btn = QToolButton()
        watched_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-horizontal-open.png')))
        watched_path_btn.setStatusTip('Add folder')
        watched_path_btn.clicked.connect(lambda: self.onFolderBrowse(watched_path_le))
        grid.addWidget(watched_path_btn, 0, 3, 1, 1)

        grid.addWidget(QLabel('Iterate files in folder'), 3, 0)
        loop_folder_sb = QCheckBox()
        self.config.add_handler('iterate_watched_folder', loop_folder_sb)
        grid.addWidget(loop_folder_sb, 3, 1)

        loop_wildcard_le = QLineEdit()
        self.config.add_handler('iterate_wildcard', loop_wildcard_le)
        grid.addWidget(loop_wildcard_le, 3, 2)

        self.watchfolder_gb.setLayout(grid)
        self.layout.addWidget(self.watchfolder_gb)

        self.timer_gb = QGroupBox('Timer')
        grid = QGridLayout()

        grid.addWidget(QLabel('Run every'), 0, 0)
        watch_timer_sb = QSpinBox()
        watch_timer_sb.setRange(0, 60)
        watch_timer_sb.setSuffix(' secs')
        self.config.add_handler('timer_seconds', watch_timer_sb)
        grid.addWidget(watch_timer_sb, 0, 1)

        self.timer_gb.setLayout(grid)
        self.layout.addWidget(self.timer_gb)

        self.manual_gb = QGroupBox('Manual')  # No show
        grid = QGridLayout()
        grid.addWidget(QLabel('No configuration'), 0, 0)
        self.manual_gb.setLayout(grid)
        self.layout.addWidget(self.manual_gb)

        gb = QGroupBox('Output')
        grid = QGridLayout()
        output_path_le = QLineEdit()
        self.config.add_handler('output_path', output_path_le)
        grid.addWidget(output_path_le, 0, 0, 1, 2)

        notebook_path_btn = QToolButton()
        notebook_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-horizontal-open.png')))
        notebook_path_btn.clicked.connect(lambda: self.onFolderBrowse(notebook_path_le))
        grid.addWidget(notebook_path_btn, 0, 2, 1, 1)

        export_cb = QComboBox()
        export_cb.addItems(IPyexporter_map.keys())
        self.config.add_handler('output_format', export_cb)
        grid.addWidget(QLabel('Notebook output format'), 1, 0)
        grid.addWidget(export_cb, 1, 1)

        gb.setLayout(grid)

        self.layout.addWidget(gb)

        self.layout.addStretch()
        self.finalise()

        self.onChangeMode(mode_cb.currentIndex())

    def onNotebookBrowse(self, t):
        global _w
        filenames, _ = QFileDialog.getOpenFileNames(_w, "Load IPython notebook(s)", '', "IPython Notebooks (*.ipynb);;All files (*.*)")
        if filenames:
            self.config.set('notebook_paths', filenames)

    def onFolderBrowse(self, t):
        global _w
        filename = QFileDialog.getExistingDirectory(_w, "Select folder to watch")
        if filename:
            self.config.set('watched_folder', filename)

    def onFilesBrowse(self, t):
        global _w
        filenames, _ = QFileDialog.getOpenFileNames(_w, "Select file(s) to watch")
        if filenames:
            self.config.set('watched_files', filenames)
        
    def onChangeMode(self, i):
        for m, gb in {MODE_MANUAL: self.manual_gb, MODE_WATCH_FILES: self.watchfile_gb, MODE_WATCH_FOLDER: self.watchfolder_gb, MODE_TIMER: self.timer_gb}.items():
            if m == list(self.mode_options.items())[i][1]:
                gb.show()
            else:
                gb.hide()
        
    def sizeHint(self):
        return QSize(400, 200)
Example #32
0
class DictGui(QDialog):
# class LisaConfigWindow(QMainWindow):

    def __init__(self, config_in, ncols=2):
        super(DictGui, self).__init__()

        self.setWindowTitle('Lisa Config')
        self.config = ConfigManager()
        self.ncols = ncols
# used with other module. If it is set, lisa config is deleted
        self.reset_config = False

        CHOICE_A = "{pairwise_alpha_per_mm2: 45, return_only_object_with_seeds: true}"
        # CHOICE_A = 23

        CHOICE_B = 2
        CHOICE_C = 3
        CHOICE_D = 4

        map_dict = {
            'Graph-Cut': CHOICE_A,
            'Choice B': CHOICE_B,
            'Choice C': CHOICE_C,
            'Choice D': CHOICE_D,
        }
        config_def = {
            'working_voxelsize_mm': 2.0,
            'save_filetype': 'pklz',
            # 'manualroi': True,
            'segparams': CHOICE_A,
        }
        
        config_def.update(config_in)
        
        self.config.set_defaults(config_def)

        gd = QGridLayout()
        gd_max_i = 0
        for key, value in config_in.items():
            if type(value) is int:
                sb = QSpinBox()
                sb.setRange(-100000, 100000)
            elif type(value) is float:
                sb = QDoubleSpinBox()
            elif type(value) is str:
                sb = QLineEdit()
            elif type(value) is bool:
                sb = QCheckBox()
            else:
                logger.error("Unexpected type in config dictionary")

            row = gd_max_i / self.ncols
            col = (gd_max_i % self.ncols) * 2

            gd.addWidget(QLabel(key),row, col +1) 
            gd.addWidget(sb, row, col + 2)
            self.config.add_handler(key, sb)
            gd_max_i += 1




        # gd.addWidget(QLabel("save filetype"), 1, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 1, 2)
        # self.config.add_handler('save_filetype', te)
        #
        # gd.addWidget(QLabel("segmentation parameters"), 2, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 2, 2)
        # self.config.add_handler('segparams', te)

        # cb = QCheckBox()
        # gd.addWidget(cb, 2, 2)
        # self.config.add_handler('active', cb)

        # gd.addWidget(QLabel("segmentation parameters"), 3, 1)
        # cmb = QComboBox()
        # cmb.addItems(map_dict.keys())
        # gd.addWidget(cmb, 3, 2)
        # self.config.add_handler('segparams', cmb, mapper=map_dict)

        self.current_config_output = QTextEdit()
        # rid.setColumnMinimumWidth(3, logo.width()/2)
        text_col = (self.ncols * 2) + 3
        gd.setColumnMinimumWidth(text_col, 500)
        gd.addWidget(self.current_config_output, 1, text_col, (gd_max_i/2)-1, 1)

        btn_reset_config = QPushButton("Default", self)
        btn_reset_config.clicked.connect(self.btnResetConfig)
        gd.addWidget(btn_reset_config, 0, text_col)

        btn_save_config = QPushButton("Ok", self)
        btn_save_config.clicked.connect(self.btnSaveConfig)
        gd.addWidget(btn_save_config, (gd_max_i / 2), text_col)

        self.config.updated.connect(self.show_config)

        self.show_config()

        # my line
        self.setLayout(gd)

        # self.window = QWidget()
        # self.window.setLayout(gd)
        # self.setCentralWidget(self.window)
    def add_grid_line(self, key, value):
        pass

    def get_config_as_dict(self):
        dictionary = self.config.as_dict()
        for key, value in dictionary.items():
            from PyQt4.QtCore import pyqtRemoveInputHook
            pyqtRemoveInputHook()
            # import ipdb; ipdb.set_trace() #  noqa BREAKPOINT
            if type(value) == QString:
                value = str(value)
            dictionary[key] = value

        return dictionary

    def btnResetConfig(self, event=None):
        self.reset_config = True
        self.close()

    def btnSaveConfig(self, event=None):
        self.reset_config = False
        self.close()


    def show_config(self):
        text = str(self.get_config_as_dict())
        self.current_config_output.setText(text)
Example #33
0
class ToolBase(QObject):
    '''
    Base tool definition for inclusion in the UI. Define specific config settings;
    attach a panel widget for configuration.
    '''

    is_manual_runnable = True
    is_auto_runnable = False
    is_auto_rerunnable = True
    is_disableable = True

    progress = pyqtSignal(float)
    status = pyqtSignal(str)
    complete = pyqtSignal()

    config_panel_size = 150
    view = None

    def __init__(self, parent, *args, **kwargs):
        super(ToolBase, self).__init__(parent, *args, **kwargs)


        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())
        self.config.set_defaults({
            'auto_run_on_config_change': True
            })
        self.current_status = 'inactive'
        self.config.updated.connect(self.auto_run_on_config_change)

        self.buttonBar = QWidget()

        self.configPanels = QWidget()
        self.configLayout = QVBoxLayout()
        self.configLayout.setContentsMargins(0,0,0,0)

        self.configPanels.setLayout(self.configLayout)

        self._previous_config_backup_ = {}

        self._worker_thread_ = None
        self._worker_thread_lock_ = False

        self.view = MplView(self.parent())

        self.setup()

        self.current_progress = 0

        self.progress.connect(self.progress_callback)
        self.status.connect(self.status_callback)


    def setup(self):
        self.data = {
            'data': None,
        }
        self.view.figure.clear()
        self.view.redraw()
        self.status.emit('inactive' if self.current_status == 'inactive' else 'ready')



    def addConfigPanel(self, panel):
        self.configLayout.addWidget( panel(self) )

    def addButtonBar(self, buttons):
        '''
        Create a button bar

        Supplied with a list of QPushButton objects (already created using helper stubs; see below)

        :param buttons:
        :return:
        '''

        btnlayout = QHBoxLayout()
        btnlayout.addSpacerItem(QSpacerItem(250, 1, QSizePolicy.Maximum, QSizePolicy.Maximum))
        for btn in buttons:
            btnlayout.addWidget(btn)

        self.configLayout.addLayout(btnlayout)
        btnlayout.addSpacerItem(QSpacerItem(250, 1, QSizePolicy.Maximum, QSizePolicy.Maximum))

    def run_manual(self):
        pass


    def disable(self):
        self.status.emit('inactive')
        self.item.setFlags(Qt.NoItemFlags)

    def reset(self):
        self.config.set_many( self.config.defaults )

    def undo(self):
        self.config.set_many(self._config_backup_)

    def defaultButtons(self):

        buttons = []

        reset = QPushButton(QIcon(os.path.join(utils.scriptdir, 'icons', 'arrow-turn-180-left.png')), 'Reset to defaults')
        reset.setToolTip('Reset to defaults')
        reset.pressed.connect(self.reset)
        buttons.append(reset)

        apply = QPushButton(QIcon(os.path.join(utils.scriptdir, 'icons', 'play.png')), 'Apply')
        apply.setToolTip('Apply current settings to spectra')
        apply.pressed.connect(self.run_manual)
        buttons.append(apply)

        return buttons

    def enable(self):
        if self.current_status == 'inactive':
            self.current_status = 'ready'
            self.status.emit('ready')
            self.item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)

    def activate(self):
        self.parent().current_tool = self
        self.enable()

        self._config_backup_ = self.config.as_dict()

        self._refresh_plot_timer_ = QTimer.singleShot(0, self.plot)

        if self.view:
            self.parent().viewStack.setCurrentWidget(self.view)

        self.parent().configstack.setCurrentWidget(self.configPanels)
        self.parent().configstack.setMaximumHeight(self.config_panel_size)

    def set_active(self, active):
        self.config.set('is_active', active)

    def get_previous_tool(self):
        # Get the previous ACTIVE tool in the tool table
        n = self.parent().tools.index(self)
        for tool in self.parent().tools[n-1::-1]:
            if tool.current_status != 'inactive':
                return tool

        else:
            return None

    def get_next_tool(self):
        # Get the previous ACTIVE tool in the tool table
        n = self.parent().tools.index(self)
        for tool in self.parent().tools[n+1:]:
            if tool.current_status != 'inactive':
                return tool

        else:
            return None



    def get_previous_data(self):
        t = self.get_previous_tool()
        if t and 'data' in t.data:
            return t.data['data']
        else:
            return None

    def plot(self, **kwargs):
        pass
        #if 'spc' in self.data:
        #    self.parent().spectraViewer.plot(self.data['spc'], **kwargs)

    def get_plotitem(self):
        return self.parent().spectraViewer.spectraViewer.plotItem

    def auto_run_on_config_change(self):
        if self.is_auto_runnable and self.current_status == 'ready' and self.config.get('auto_run_on_config_change'):
            self.run_manual()

    def run(self, fn):
        '''
        Run the target function, passing in the current spectra, and config settings (as dict)
        :param fn:
        :return:
        '''
        if self._worker_thread_lock_:
            return False # Can't run

        self.progress.emit(0)
        self.status.emit('active')

        data = self.get_previous_data()

        self._worker_thread_lock_ = True

        kwargs = {
            'config': self.config.as_dict(),
            'progress_callback': self.progress.emit,
        }
        if data:
            kwargs.update(deepcopy(data))

        # Close any open figures; ensure new axes.
        plt.close()

        self._worker_thread_ = Worker(fn = fn, **kwargs)

        self._worker_thread_.signals.finished.connect(self.finished)
        self._worker_thread_.signals.result.connect(self.result)
        self._worker_thread_.signals.error.connect(self.error)

        self.parent().threadpool.start(self._worker_thread_)


    def error(self, error):
        self.progress.emit(1.0)
        self.status.emit('error')
        logging.error(error)
        self._worker_thread_lock_ = False



    def result(self, result):

        # Apply post-processing
        if 'fig' in result and result['fig']:
            fig = result['fig']
            fig.set_size_inches(self.view.get_size_inches(fig.get_dpi()))
            fig.set_tight_layout(False)
            fig.tight_layout(pad=0.5, rect=[0.25, 0.10, 0.75, 0.90])
            self.view.figure = fig
            self.view.redraw()

        self.data = result
        self.plot()

        self.progress.emit(1)
        self.status.emit('complete')

    def finished(self):
        # Cleanup
        self._worker_thread_lock_ = False
        self.complete.emit()


    def progress_callback(self, progress):
        self.current_progress = progress
        self.item.setData(Qt.UserRole + 2, progress)

    def status_callback(self, status):
        self.current_status = status
        self.item.setData(Qt.UserRole + 3, status)
Example #34
0
def test_hook_direct():
    widget = QLineEdit()
    config = ConfigManager()
    assert config._get_hook(widget) == QLineEdit
Example #35
0
def test_hook_direct():
    widget = QLineEdit()
    config = ConfigManager()
    assert config._get_hook(widget) == QLineEdit
Example #36
0
class QGraphicsSceneExtend(QGraphicsScene):

    def __init__(self, parent, *args, **kwargs):
        super(QGraphicsSceneExtend, self).__init__(parent, *args, **kwargs)

        self.m = parent.m

        self.config = ConfigManager()
        # These config settings are transient (ie. not stored between sessions)
        self.config.set_defaults({
            'mode': EDITOR_MODE_NORMAL,
            'font-family': 'Arial',
            'font-size': '12',
            'text-bold': False,
            'text-italic': False,
            'text-underline': False,
            'text-color': '#000000',
            'color-border': None,  # '#000000',
            'color-background': None,
        })

        # Pre-set these values (will be used by default)
        self.config.set('color-background', '#5555ff')

        self.background_image = QImage(os.path.join(utils.scriptdir, 'icons', 'grid100.png'))
        if settings.get('Editor/Show_grid'):
            self.showGrid()
        else:
            self.hideGrid()

        self.mode = EDITOR_MODE_NORMAL
        self.mode_current_object = None

        self.annotations = []

    def mousePressEvent(self, e):
    
        if self.config.get('mode') != EDITOR_MODE_NORMAL:

            for i in self.selectedItems():
                i.setSelected(False)

            if self.config.get('mode') == EDITOR_MODE_TEXT:
                tw = AnnotationTextItem(position=e.scenePos())

            elif self.config.get('mode') == EDITOR_MODE_REGION:
                tw = AnnotationRegionItem(position=e.scenePos())

            elif self.config.get('mode') == EDITOR_MODE_ARROW:
                tw = AnnotationRegionItem(position=e.scenePos())

            self.addItem(tw)
            self.mode_current_object = tw
            tw._createFromMousePressEvent(e)
            tw.importStyleConfig(self.config)

            self.annotations.append(tw)

        else:
            for i in self.selectedItems():
                i.setSelected(False)
        
            super(QGraphicsSceneExtend, self).mousePressEvent(e)

    def mouseMoveEvent(self, e):
        if self.config.get('mode') == EDITOR_MODE_TEXT and self.mode_current_object:
            self.mode_current_object._resizeFromMouseMoveEvent(e)

        elif self.config.get('mode') == EDITOR_MODE_REGION and self.mode_current_object:
            self.mode_current_object._resizeFromMouseMoveEvent(e)

        else:
            super(QGraphicsSceneExtend, self).mouseMoveEvent(e)

    def mouseReleaseEvent(self, e):
        if self.config.get('mode'):
            self.mode_current_object.setSelected(True)
            self.mode_current_object.setFocus()

            self.config.set('mode', EDITOR_MODE_NORMAL)
            self.mode_current_object = None

        super(QGraphicsSceneExtend, self).mouseReleaseEvent(e)

    def showGrid(self):
        self.setBackgroundBrush(QBrush(self.background_image))

    def hideGrid(self):
        self.setBackgroundBrush(QBrush(None))

    def onSaveAsImage(self):
        filename, _ = QFileDialog.getSaveFileName(self.m, 'Save current figure', '', "Tagged Image File Format (*.tif);;\
                                                                                     Portable Network Graphics (*.png)")
        if filename:
            self.saveAsImage(filename)

    def saveAsImage(self, f):
        self.image = QImage(self.sceneRect().size().toSize(), QImage.Format_ARGB32)
        self.image.fill(Qt.white)
        painter = QPainter(self.image)
        self.render(painter)
        self.image.save(f)

    def addApp(self, app, position=None):
        i = ToolItem(self, app, position=position)
        self.addItem(i)
        #i.onShow()

        return i

    def removeApp(self, app):
        i = app.editorItem
        i.hide()
        self.removeItem(i)
        app.editorItem = None

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('application/x-pathomx-app') or e.mimeData().hasFormat('text/uri-list'):
            e.accept()
        else:
            e.ignore()

    def dragMoveEvent(self, e):
        e.accept()

    def dropEvent(self, e):
        scenePos = e.scenePos() - QPointF(32, 32)

        if e.mimeData().hasFormat('application/x-pathomx-app'):
            try:
                app_id = str(e.mimeData().data('application/x-pathomx-app'), 'utf-8')  # Python 3 
            except:
                app_id = str(e.mimeData().data('application/x-pathomx-app'))  # Python 2

            e.setDropAction(Qt.CopyAction)
            a = app_launchers[app_id](self.m, position=scenePos, auto_focus=False)
            #self.centerOn(a.editorItem)
            e.accept()

        elif e.mimeData().hasFormat('text/uri-list'):
            for ufn in e.mimeData().urls():
                fn = ufn.path()
                fnn, ext = os.path.splitext(fn)
                ext = ext.strip('.')
                if ext in file_handlers:
                    a = file_handlers[ext](position=scenePos, auto_focus=False, filename=fn)
                    self.centerOn(a.editorItem)
                    e.accept()

    def getXMLAnnotations(self, root):

    # Iterate over the entire set (in order) creating a XML representation of the MatchDef and Style
        for annotation in self.annotations:

            ase = et.SubElement(root, "Annotation")
            ase.set('type', type(annotation).__name__)

            ase.set('x', str(annotation.x()))
            ase.set('y', str(annotation.y()))
            ase.set('width', str(annotation.rect().width()))
            ase.set('height', str(annotation.rect().height()))

            if hasattr(annotation, 'text'):
                text = et.SubElement(ase, "Text")
                text.text = annotation.text.toPlainText()

            ase = annotation.config.getXMLConfig(ase)

        return root

    def setXMLAnnotations(self, root):

        ANNOTATION_TYPES = {
            'AnnotationTextItem': AnnotationTextItem,
            'AnnotationRegionItem': AnnotationRegionItem,
        }

        for ase in root.findall('Annotation'):

            # Validate the class definition before creating it
            if ase.get('type') in ANNOTATION_TYPES:

                pos = QPointF(float(ase.get('x')), float(ase.get('y')))
                aobj = ANNOTATION_TYPES[ase.get('type')](position=pos)
                aobj.setRect(QRectF(0, 0, float(ase.get('width')), float(ase.get('height'))))

                to = ase.find('Text')
                if to is not None:
                    aobj.text.setPlainText(to.text)

                self.addItem(aobj)
                self.annotations.append(aobj)
                aobj.config.setXMLConfig(ase)
                aobj.applyStyleConfig()
Example #37
0
File: ui.py Project: pchj/nmrbrew
class AnnotateClasses(GenericDialog):
    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotateClasses, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Classes')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Sample classes')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_classes = QListWidgetAddRemove()
        self.lw_classes.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_classes)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_class = QLineEdit()

        addc = QPushButton('Add')
        addc.clicked.connect(self.onClassAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onClassAdd)

        loadc = QPushButton('Import from file')
        loadc.setIcon(
            QIcon(
                os.path.join(utils.scriptdir, 'icons',
                             'folder-open-document.png')))
        loadc.clicked.connect(self.onClassImport)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_class)
        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vboxh.addWidget(loadc)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/sample_classes', self.lw_classes,
                                (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()

    def onClassAdd(self):
        c = self.config.get(
            'annotation/sample_classes'
        )[:]  # Create new list to force refresh on reassign
        c.append((self.add_label.text(), self.add_class.text()))
        self.config.set('annotation/sample_classes', c)

    def onClassRemove(self):
        i = self.lw_classes.removeItemAt(self.lw_classes.currentRow())
        # c = self.map_list_fwd(i.text())

    def onClassImport(self):
        filename, _ = QFileDialog.getOpenFileName(
            self.parent(), 'Load classifications from file', '',
            "All compatible files (*.csv *.txt *.tsv);;Comma Separated Values (*.csv);;Plain Text Files (*.txt);;Tab Separated Values (*.tsv);;All files (*.*)"
        )
        if filename:
            c = self.config.get(
                'annotation/sample_classes'
            )[:]  # Create new list to force refresh on reassign

            with open(filename, 'rU') as f:
                reader = csv.reader(f, delimiter=b',', dialect='excel')
                for row in reader:
                    if row not in c:
                        c.append(row[:2])

            self.config.set('annotation/sample_classes', c)

    def map_list_fwd(self, s):
        " Receive text name, return the indexes "
        return self.fwd_map_cache[s]

    def map_list_rev(self, x):
        " Receive the indexes, return the label"
        s = "%s\t%s" % tuple(x)
        self.fwd_map_cache[s] = x
        return s
Example #38
0
File: ui.py Project: pchj/nmrbrew
class AnnotatePeaks(GenericDialog):
    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotatePeaks, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Peaks')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Peaks')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_peaks = QListWidgetAddRemove()
        self.lw_peaks.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_peaks)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_start = QDoubleSpinBox()
        self.add_start.setRange(-1, 12)
        self.add_start.setDecimals(3)
        self.add_start.setSuffix('ppm')
        self.add_start.setSingleStep(0.001)

        self.add_end = QDoubleSpinBox()
        self.add_end.setRange(-1, 12)
        self.add_end.setDecimals(3)
        self.add_end.setSuffix('ppm')
        self.add_end.setSingleStep(0.001)

        addc = QPushButton('Add')
        addc.clicked.connect(self.onPeakAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onPeakAdd)

        loadc = QPushButton("Import from file")
        loadc.setIcon(
            QIcon(
                os.path.join(utils.scriptdir, 'icons',
                             'folder-open-document.png')))
        loadc.clicked.connect(self.onPeakImport)

        metabh = QPushButton("Auto match via MetaboHunter")
        metabh.setIcon(
            QIcon(os.path.join(utils.scriptdir, 'icons', 'metabohunter.png')))
        metabh.clicked.connect(self.onPeakImportMetabohunter)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_start)
        vboxh.addWidget(self.add_end)

        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vbox.addWidget(loadc)
        vbox.addWidget(metabh)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/peaks', self.lw_peaks,
                                (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()

    def onPeakAdd(self):
        c = self.config.get(
            'annotation/peaks'
        )[:]  # Create new list to force refresh on reassign
        c.append((self.add_label.text(), float(self.add_start.value()),
                  float(self.add_end.value())))
        self.config.set('annotation/peaks', c)

    def onPeakRemove(self):
        i = self.lw_peaks.removeItemAt(self.lw_peaks.currentRow())
        # c = self.map_list_fwd(i.text())

    def onPeakImport(self):
        filename, _ = QFileDialog.getOpenFileName(
            self.parent(), 'Load peak annotations from file', '',
            "All compatible files (*.csv *.txt *.tsv);;Comma Separated Values (*.csv);;Plain Text Files (*.txt);;Tab Separated Values (*.tsv);;All files (*.*)"
        )
        if filename:
            c = self.config.get(
                'annotation/peaks'
            )[:]  # Create new list to force refresh on reassign

            with open(filename, 'rU') as f:
                reader = csv.reader(f, delimiter=b',', dialect='excel')
                for row in reader:
                    if row not in c:
                        c.append(row[0], float(row[1]), float(row[2]))

            self.config.set('annotation/peaks', c)

    def onPeakImportMetabohunter(self):
        c = self.config.get(
            'annotation/peaks'
        )[:]  # Create new list to force refresh on reassign
        t = self.parent().current_tool

        dlg = MetaboHunter(self)
        if dlg.exec_():

            if 'spc' in t.data:
                # We have a spectra; calcuate mean; reduce size if required
                spc = t.data['spc']
                n = spc.data.shape[1]
                ppm = spc.ppm
                spcd = np.mean(spc.data, axis=0)

                # Set a hard limit on the size of data we submit to be nice.
                if n > 3000:
                    # Calculate the division required to be under the limit
                    d = np.ceil(float(n) / 3000)
                    # Trim axis to multiple of divisor
                    trim = (n // d) * d
                    spcd = spcd[:trim]
                    ppm = ppm[:trim]
                    # Mean d shape
                    spcd = np.mean(spcd.reshape(-1, d), axis=1)
                    ppm = np.mean(ppm.reshape(-1, d), axis=1)

            # Submit with settings
            hmdbs = metabohunter.request(
                ppm,
                spcd,
                metabotype=dlg.config.get('Metabotype'),
                database=dlg.config.get('Database Source'),
                ph=dlg.config.get('Sample pH'),
                solvent=dlg.config.get('Solvent'),
                frequency=dlg.config.get('Frequency'),
                method=dlg.config.get('Method'),
                noise=dlg.config.get('Noise Threshold'),
                confidence=dlg.config.get('Confidence Threshold'),
                tolerance=dlg.config.get('Tolerance'))

            ha = np.array(hmdbs)
            unique_hmdbs = set(hmdbs)
            if None in unique_hmdbs:
                unique_hmdbs.remove(None)

            # Extract out regions
            for hmdb in unique_hmdbs:
                hb = np.diff(ha == hmdb)

                # These are needed to ensure markers are there for objects starting and ending on array edge
                if ha[0] == hmdb:
                    hb[0] == True

                if ha[-1] == hmdb:
                    hb[-1] == True

                idx = np.nonzero(hb)[0]
                idx = idx.reshape(-1, 2)

                if dlg.config.get(
                        'convert_hmdb_ids_to_names'
                ) and hmdb in METABOHUNTER_HMDB_NAME_MAP.keys():
                    label = METABOHUNTER_HMDB_NAME_MAP[hmdb]
                else:
                    label = hmdb

                # Now we have an array of all start, stop positions for this item
                for start, stop in idx:
                    c.append((label, ppm[start], ppm[stop]))

        self.config.set('annotation/peaks', c)

    def map_list_fwd(self, s):
        " Receive text name, return the indexes "
        return self.fwd_map_cache[s]

    def map_list_rev(self, x):
        " Receive the indexes, return the label"
        s = "%s\t%.2f\t%.2f" % tuple(x)
        self.fwd_map_cache[s] = x
        return s
Example #39
0
class QGraphicsSceneExtend(QGraphicsScene):
    def __init__(self, parent, *args, **kwargs):
        super(QGraphicsSceneExtend, self).__init__(parent, *args, **kwargs)

        self.m = parent.m

        self.config = ConfigManager()
        # These config settings are transient (ie. not stored between sessions)
        self.config.set_defaults({
            'mode': EDITOR_MODE_NORMAL,
            'font-family': 'Arial',
            'font-size': '12',
            'text-bold': False,
            'text-italic': False,
            'text-underline': False,
            'text-color': '#000000',
            'color-border': None,  # '#000000',
            'color-background': None,
        })

        # Pre-set these values (will be used by default)
        self.config.set('color-background', '#5555ff')

        self.background_image = QImage(
            os.path.join(utils.scriptdir, 'icons', 'grid100.png'))
        if settings.get('Editor/Show_grid'):
            self.showGrid()
        else:
            self.hideGrid()

        self.mode = EDITOR_MODE_NORMAL
        self.mode_current_object = None

        self.annotations = []

    def mousePressEvent(self, e):
        if self.config.get('mode') != EDITOR_MODE_NORMAL:

            for i in self.selectedItems():
                i.setSelected(False)

            if self.config.get('mode') == EDITOR_MODE_TEXT:
                tw = AnnotationTextItem(position=e.scenePos())

            elif self.config.get('mode') == EDITOR_MODE_REGION:
                tw = AnnotationRegionItem(position=e.scenePos())

            elif self.config.get('mode') == EDITOR_MODE_ARROW:
                tw = AnnotationRegionItem(position=e.scenePos())

            self.addItem(tw)
            self.mode_current_object = tw
            tw._createFromMousePressEvent(e)
            tw.importStyleConfig(self.config)

            self.annotations.append(tw)

        else:
            super(QGraphicsSceneExtend, self).mousePressEvent(e)

    def mouseMoveEvent(self, e):
        if self.config.get(
                'mode') == EDITOR_MODE_TEXT and self.mode_current_object:
            self.mode_current_object._resizeFromMouseMoveEvent(e)

        elif self.config.get(
                'mode') == EDITOR_MODE_REGION and self.mode_current_object:
            self.mode_current_object._resizeFromMouseMoveEvent(e)

        else:
            super(QGraphicsSceneExtend, self).mouseMoveEvent(e)

    def mouseReleaseEvent(self, e):
        if self.config.get('mode'):
            self.mode_current_object.setSelected(True)
            self.mode_current_object.setFocus()

            self.config.set('mode', EDITOR_MODE_NORMAL)
            self.mode_current_object = None

        super(QGraphicsSceneExtend, self).mouseReleaseEvent(e)

    def showGrid(self):
        self.setBackgroundBrush(QBrush(self.background_image))

    def hideGrid(self):
        self.setBackgroundBrush(QBrush(None))

    def onSaveAsImage(self):
        filename, _ = QFileDialog.getSaveFileName(
            self.m, 'Save current figure', '',
            "Tagged Image File Format (*.tif);;\
                                                                                     Portable Network Graphics (*.png)"
        )
        if filename:
            self.saveAsImage(filename)

    def saveAsImage(self, f):
        self.image = QImage(self.sceneRect().size().toSize(),
                            QImage.Format_ARGB32)
        self.image.fill(Qt.white)
        painter = QPainter(self.image)
        self.render(painter)
        self.image.save(f)

    def addApp(self, app, position=None):
        i = ToolItem(self, app, position=position)
        self.addItem(i)
        return i

    def removeApp(self, app):
        i = app.editorItem
        i.hide()
        self.removeItem(i)
        app.editorItem = None

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('application/x-pathomx-app') or e.mimeData(
        ).hasFormat('text/uri-list'):
            e.accept()
        else:
            e.ignore()

    def dragMoveEvent(self, e):
        e.accept()

    def dropEvent(self, e):
        scenePos = e.scenePos() - QPointF(32, 32)

        if e.mimeData().hasFormat('application/x-pathomx-app'):
            try:
                app_id = str(e.mimeData().data('application/x-pathomx-app'),
                             'utf-8')  # Python 3
            except:
                app_id = str(
                    e.mimeData().data('application/x-pathomx-app'))  # Python 2

            e.setDropAction(Qt.CopyAction)
            a = app_launchers[app_id](self.m,
                                      position=scenePos,
                                      auto_focus=False)
            #self.centerOn(a.editorItem)
            e.accept()

        elif e.mimeData().hasFormat('text/uri-list'):
            for ufn in e.mimeData().urls():
                fn = ufn.path()
                fnn, ext = os.path.splitext(fn)
                ext = ext.strip('.')
                if ext in file_handlers:
                    a = file_handlers[ext](position=scenePos,
                                           auto_focus=False,
                                           filename=fn)
                    self.centerOn(a.editorItem)
                    e.accept()

    def getXMLAnnotations(self, root):

        # Iterate over the entire set (in order) creating a XML representation of the MatchDef and Style
        for annotation in self.annotations:

            ase = et.SubElement(root, "Annotation")
            ase.set('type', type(annotation).__name__)

            ase.set('x', str(annotation.x()))
            ase.set('y', str(annotation.y()))
            ase.set('width', str(annotation.rect().width()))
            ase.set('height', str(annotation.rect().height()))

            if hasattr(annotation, 'text'):
                text = et.SubElement(ase, "Text")
                text.text = annotation.text.toPlainText()

            ase = annotation.config.getXMLConfig(ase)

        return root

    def setXMLAnnotations(self, root):

        ANNOTATION_TYPES = {
            'AnnotationTextItem': AnnotationTextItem,
            'AnnotationRegionItem': AnnotationRegionItem,
        }

        for ase in root.findall('Annotation'):

            # Validate the class definition before creating it
            if ase.get('type') in ANNOTATION_TYPES:

                pos = QPointF(float(ase.get('x')), float(ase.get('y')))
                aobj = ANNOTATION_TYPES[ase.get('type')](position=pos)
                aobj.setRect(
                    QRectF(0, 0, float(ase.get('width')),
                           float(ase.get('height'))))

                to = ase.find('Text')
                if to is not None:
                    aobj.text.setPlainText(to.text)

                self.addItem(aobj)
                self.annotations.append(aobj)
                aobj.config.setXMLConfig(ase)
                aobj.applyStyleConfig()
Example #40
0
File: ui.py Project: pchj/nmrbrew
class MetaboHunter(GenericDialog):

    options = {
        'Metabotype': {
            'All': 'All',
            'Drug': 'Drug',
            'Food additive': 'Food additive',
            'Mammalian': 'Mammalian',
            'Microbial': 'Microbial',
            'Plant': 'Plant',
            'Synthetic/Industrial chemical': 'Synthetic/Industrial chemical',
        },
        'Database Source': {
            'Human Metabolome Database (HMDB)': 'HMDB',
            'Madison Metabolomics Consortium Database (MMCD)': 'MMCD',
        },
        'Sample pH': {
            '10.00 - 10.99': 'ph7',
            '7.00 - 9.99': 'ph7',
            '6.00 - 6.99': 'ph6',
            '5.00 - 5.99': 'ph5',
            '4.00 - 4.99': 'ph4',
            '3.00 - 3.99': 'ph3',
        },
        'Solvent': {
            'All': 'all',
            'Water': 'water',
            'CDCl3': 'cdcl3',
            'CD3OD': '5d3od',
            '5% DMSO': '5dmso',
        },
        'Frequency': {
            'All': 'all',
            '600 MHz': '600',
            '500 MHz': '500',
            '400 MHz': '400',
        },
        'Method': {
            'MH1: Highest number of matched peaks':
            'HighestNumber',
            'MH2: Highest number of matched peaks with shift tolerance':
            'HighestNumberNeighbourhood',
            'MH3: Greedy selection of metabolites with disjoint peaks':
            'Greedy2',
            'MH4: Highest number of matched peaks with intensities':
            'HighestNumberHeights',
            'MH5: Greedy selection of metabolites with disjoint peaks and heights':
            'Greedy2Heights',
        },
    }

    def __init__(self, *args, **kwargs):
        super(MetaboHunter, self).__init__(*args, **kwargs)

        self.setWindowTitle('MetaboHunter')
        # Copy in starting state
        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())

        self.config.set_defaults({
            'Metabotype': 'All',
            'Database Source': 'HMDB',
            'Sample pH': 'ph7',
            'Solvent': 'water',
            'Frequency': 'all',
            'Method': 'HighestNumberNeighbourhood',
            'Noise Threshold': 0.0001,
            'Confidence Threshold': 0.5,
            'Tolerance': 0.1,
            'convert_hmdb_ids_to_names': True,
        })

        self.lw_combos = {}

        for o in [
                'Metabotype', 'Database Source', 'Sample pH', 'Solvent',
                'Frequency', 'Method'
        ]:
            row = QVBoxLayout()
            cl = QLabel(o)
            cb = QComboBox()

            cb.addItems(list(self.options[o].keys()))
            row.addWidget(cl)
            row.addWidget(cb)
            self.config.add_handler(o, cb, self.options[o])

            self.layout.addLayout(row)

        row = QGridLayout()
        self.lw_spin = {}
        for n, o in enumerate(
            ['Noise Threshold', 'Confidence Threshold', 'Tolerance']):
            cl = QLabel(o)
            cb = QDoubleSpinBox()
            cb.setDecimals(4)
            cb.setRange(0, 1)
            cb.setSingleStep(0.01)
            cb.setValue(float(self.config.get(o)))
            row.addWidget(cl, 0, n)
            row.addWidget(cb, 1, n)

            self.config.add_handler(o, cb)

        self.layout.addLayout(row)

        row = QHBoxLayout()
        row.addWidget(QLabel("Convert HMDB IDs to chemical names?"))
        conv = QCheckBox()
        self.config.add_handler('convert_hmdb_ids_to_names', conv)
        row.addWidget(conv)

        self.layout.addLayout(row)

        self.dialogFinalise()
Example #41
0
File: base.py Project: pchj/nmrbrew
class ToolBase(QObject):
    '''
    Base tool definition for inclusion in the UI. Define specific config settings;
    attach a panel widget for configuration.
    '''

    is_manual_runnable = True

    is_auto_runnable = True
    is_auto_rerunnable = True
    is_disableable = True

    progress = pyqtSignal(float)
    status = pyqtSignal(str)

    config_panel_size = 250
    view_widget = 'SpectraViewer'

    def __init__(self, parent, *args, **kwargs):
        super(ToolBase, self).__init__(parent, *args, **kwargs)

        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())
        self.config.set_defaults({
            'is_active': True,
            'auto_run_on_config_change': True
        })

        self.config.updated.connect(self.auto_run_on_config_change)

        self.buttonBar = QWidget()

        self.configPanels = QWidget()
        self.configLayout = QVBoxLayout()
        self.configLayout.setContentsMargins(0, 0, 0, 0)

        self.configPanels.setLayout(self.configLayout)

        self._previous_config_backup_ = {}

        self._worker_thread_ = None
        self._worker_thread_lock_ = False

        self.data = {
            'spc': None,
        }

        self.current_status = 'ready'
        self.current_progress = 0

        self.progress.connect(self.progress_callback)
        self.status.connect(self.status_callback)

    def addConfigPanel(self, panel):
        self.configLayout.addWidget(panel(self))

    def addButtonBar(self, buttons):
        '''
        Create a button bar

        Supplied with a list of QPushButton objects (already created using helper stubs; see below)

        :param buttons:
        :return:
        '''

        btnlayout = QHBoxLayout()
        btnlayout.addSpacerItem(
            QSpacerItem(250, 1, QSizePolicy.Maximum, QSizePolicy.Maximum))
        for btn in buttons:
            btnlayout.addWidget(btn)

        self.configLayout.addLayout(btnlayout)
        btnlayout.addSpacerItem(
            QSpacerItem(250, 1, QSizePolicy.Maximum, QSizePolicy.Maximum))

    def run_manual(self):
        pass

    def disable(self):
        self.status.emit('inactive')
        self.config.set('is_active', False)
        self.item.setFlags(Qt.NoItemFlags)

    def reset(self):
        self.config.set_many(self.config.defaults)

    def undo(self):
        self.config.set_many(self._config_backup_)

    def deftaultButtons(self):

        buttons = []

        if self.is_disableable:
            disable = QPushButton(
                QIcon(os.path.join(utils.scriptdir, 'icons', 'cross.png')),
                'Disable')
            disable.setToolTip('Disable this tool')
            disable.pressed.connect(self.disable)
            buttons.append(disable)

        reset = QPushButton(
            QIcon(
                os.path.join(utils.scriptdir, 'icons',
                             'arrow-turn-180-left.png')), 'Reset to defaults')
        reset.setToolTip('Reset to defaults')
        reset.pressed.connect(self.reset)
        buttons.append(reset)

        undo = QPushButton(
            QIcon(
                os.path.join(utils.scriptdir, 'icons',
                             'arrow-turn-180-left.png')), 'Undo')
        undo.setToolTip('Undo recent changes')
        undo.pressed.connect(self.undo)
        buttons.append(undo)

        if self.is_auto_runnable:
            auto = QPushButton(
                QIcon(os.path.join(utils.scriptdir, 'icons', 'lightning.png')),
                'Auto')
            auto.setToolTip('Auto-update spectra when settings change')
            auto.setCheckable(True)
            auto.pressed.connect(self.run_manual)
            self.config.add_handler('auto_run_on_config_change', auto)
            buttons.append(auto)

        if self.is_manual_runnable:
            apply = QPushButton(
                QIcon(os.path.join(utils.scriptdir, 'icons', 'play.png')),
                'Apply')
            apply.setToolTip('Apply current settings to spectra')
            apply.pressed.connect(self.run_manual)
            buttons.append(apply)

        return buttons

    def enable(self):
        if self.current_status == 'inactive':
            self.status.emit('ready')
            self.item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)

        self.config.set('is_active', True)

    def activate(self):
        self.parent().current_tool = self
        self.enable()

        self._config_backup_ = self.config.as_dict()

        self._refresh_plot_timer_ = QTimer.singleShot(0, self.plot)

        self.parent().viewStack.setCurrentWidget(self.parent().spectraViewer)

        self.parent().configstack.setCurrentWidget(self.configPanels)
        self.parent().configstack.setMaximumHeight(self.config_panel_size)

    def set_active(self, active):
        self.config.set('is_active', active)

    def get_previous_tool(self):
        # Get the previous ACTIVE tool in the tool table
        n = self.parent().tools.index(self)
        for tool in self.parent().tools[n - 1::-1]:
            if tool.current_status != 'inactive':
                return tool

        else:
            return None

    def get_previous_spc(self):
        t = self.get_previous_tool()
        if t:
            return t.data['spc']
        else:
            return None

    def plot(self, **kwargs):
        if 'spc' in self.data:
            self.parent().spectraViewer.plot(self.data['spc'], **kwargs)

    def get_plotitem(self):
        return self.parent().spectraViewer.spectraViewer.plotItem

    def auto_run_on_config_change(self):
        pass
        #if self.is_auto_runnable and self.config.get('is_active') and self.config.get('auto_run_on_config_change'):
        #    self.run_manual()

    def run(self, fn):
        '''
        Run the target function, passing in the current spectra, and config settings (as dict)
        :param fn:
        :return:
        '''
        if self._worker_thread_lock_:
            return False  # Can't run

        self.progress.emit(0)
        self.status.emit('active')

        spc = self.get_previous_spc()

        self._worker_thread_lock_ = True

        print(self.config.as_dict())
        self._worker_thread_ = Worker(fn=fn,
                                      **{
                                          'spc': deepcopy(spc),
                                          'config': self.config.as_dict(),
                                          'progress_callback':
                                          self.progress.emit,
                                      })

        self._worker_thread_.signals.finished.connect(self.finished)
        self._worker_thread_.signals.result.connect(self.result)
        self._worker_thread_.signals.error.connect(self.error)

        self.parent().threadpool.start(self._worker_thread_)

    def error(self, error):
        self.progress.emit(1.0)
        self.status.emit('error')
        logging.error(error)
        self._worker_thread_lock_ = False

    def result(self, result):
        self.progress.emit(1)
        self.status.emit('complete')

        # Apply post-processing
        if 'spc' in result:
            result['spc'] = self.post_process_spc(result['spc'])

        self.data = result
        self.plot()

    def finished(self):
        # Cleanup
        self._worker_thread_lock_ = False

    def progress_callback(self, progress):
        self.current_progress = progress
        self.item.setData(Qt.UserRole + 2, progress)

    def status_callback(self, status):
        self.current_status = status
        self.item.setData(Qt.UserRole + 3, status)

    def post_process_spc(self, spc):
        '''
        Apply post-processing to the spectra before loading into the data store, e.g. for outlier
        detection, stats etc.

        :param spc:
        :return:
        '''

        # Outliers

        def identify_outliers(data, m=2):
            return abs(data - np.mean(data, axis=0)) < (m *
                                                        np.std(data, axis=0))

        # Identify outliers on a point by point basis. Count up 'outliers' and score ratio of points that are
        # outliers for each specra > 5% (make this configurable) is an outlier.
        spc.outliers = np.sum(~identify_outliers(spc.data), axis=1) / float(
            spc.data.shape[1])
        return spc
Example #42
0
class dialogPluginManagement(ui.GenericDialog):

    def populate_plugin_list(self):

        disabled_plugins = self.config.get('Plugins/Disabled')

        while self.plugins_lw.count() > 0:  # Empty list
            self.plugins_lw.takeItem(0)

        for id, plugin in plugin_metadata.items():
            item = QListWidgetItem()

            item.plugin_metadata = plugin
            item.plugin_shortname = id

            if 'image' in plugin:
                item.setData(Qt.DecorationRole, plugin['image'])

            item.setData(Qt.DisplayRole, "%s (v%s)" % (plugin['name'], plugin['version']))
            item.setData(Qt.UserRole, plugin['description'])
            item.setData(Qt.UserRole + 1, plugin['author'])
            if plugin['path'] not in disabled_plugins:
                item.setData(Qt.UserRole + 2, "Active")

            self.plugins_lw.addItem(item)

    def onActivate(self):
        items = self.plugins_lw.selectedItems()
        disabled_plugins = self.config.get('Plugins/Disabled')

        for i in items:
            plugin_path = plugin_metadata[i.plugin_shortname]['path']
            if plugin_path in disabled_plugins:
                disabled_plugins.remove(plugin_path)

        self.config.set('Plugins/Disabled', disabled_plugins)
        self.populate_plugin_list()

    def onDeactivate(self):
        items = self.plugins_lw.selectedItems()
        disabled_plugins = self.config.get('Plugins/Disabled')

        for i in items:
            plugin_path = plugin_metadata[i.plugin_shortname]['path']
            if plugin_path not in disabled_plugins:
                disabled_plugins.append(plugin_path)

        self.config.set('Plugins/Disabled', disabled_plugins)
        self.populate_plugin_list()

    def onRefresh(self):
        get_available_plugins(self.config.get('Plugins/Paths')[:], include_deactivated=True)
        self.populate_plugin_list()

    def __init__(self, parent, **kwargs):
        super(dialogPluginManagement, self).__init__(parent, **kwargs)

        self.setWindowTitle(tr("Manage Plugins"))

        self.config = ConfigManager()
        self.config.defaults = {
            'Plugins/Paths': settings.get('Plugins/Paths'),
            'Plugins/Disabled': settings.get('Plugins/Disabled'),
        }

        self.m = parent
        self.setFixedSize(self.sizeHint())

        self.plugins_lw = QListWidget()
        self.plugins_lw.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.plugins_lw.setItemDelegate(pluginListDelegate(self.plugins_lw))
        self.plugins_lw.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)

        page = QWidget()
        box = QGridLayout()
        paths = QHBoxLayout()

        self.pathlist = QLineEdit()
        self.config.add_handler('Plugins/Paths', self.pathlist, (lambda x: x.split(';'), lambda x: ';'.join(x)))

        paths.addWidget(QLabel('Search Paths:'))
        paths.addWidget(self.pathlist)

        box.addLayout(paths, 0, 0)
        box.addWidget(self.plugins_lw, 1, 0)

        buttons = QVBoxLayout()

        refresh_btn = QPushButton('Refresh')
        refresh_btn.clicked.connect(self.onRefresh)
        buttons.addWidget(refresh_btn)

        activate_btn = QPushButton('Activate')
        activate_btn.clicked.connect(self.onActivate)
        buttons.addWidget(activate_btn)

        deactivate_btn = QPushButton('Dectivate')
        deactivate_btn.clicked.connect(self.onDeactivate)
        buttons.addWidget(deactivate_btn)

        buttons.addStretch()

        box.addLayout(buttons, 1, 1)
        page.setLayout(box)

        self.layout.addWidget(page)

        # Stack it all up, with extra buttons
        self.dialogFinalise()

        # Refresh the list of available plugins
        self._init_timer = QTimer.singleShot(0, self.onRefresh)

    def sizeHint(self):
        return QSize(600, 300)
Example #43
0
class Automaton(QStandardItem):
    def __init__(self, *args, **kwargs):
        super(Automaton, self).__init__(*args, **kwargs)

        self.setData(self, Qt.UserRole)
        self.watcher = QFileSystemWatcher()
        self.timer = QTimer()

        self.watch_window = {}

        self.latest_run = {}
        self.is_running = False

        self.config = ConfigManager()
        self.config.set_defaults({
            'mode': MODE_WATCH_FOLDER,
            'is_active': True,
            'trigger_hold': 1,
            'notebook_paths': '',
            'output_path': '{home}/{notebook_filename}_{datetime}_',
            'output_format': 'html',
            'watched_files': [],
            'watched_folder': '',
            'watch_window': 15,
            'iterate_watched_folder': True,
            'iterate_wildcard': '.csv',
            'timer_seconds': 60,
        })

        self.runner = None
        self.lock = None

        self.latest_run = {
            'timestamp': None,
            'success': None,
        }

        # Set up all the triggers
        self.watcher.fileChanged.connect(self.file_trigger_accumulator)
        self.watcher.directoryChanged.connect(self.trigger)
        self.timer.timeout.connect(self.trigger)

    def startup(self):
        if self.config.get('is_active') == False:
            return False

        if self.config.get('mode') == MODE_TIMER:
            self.timer.setInterval(self.config.get('timer_seconds') * 1000)
            self.timer.start()

        elif self.config.get('mode') == MODE_WATCH_FILES:
            current_paths = self.watcher.files() + self.watcher.directories()
            if current_paths:
                self.watcher.removePaths(current_paths)
            self.watch_window = {}
            self.watcher.addPaths(self.config.get('watched_files'))

        elif self.config.get('mode') == MODE_WATCH_FOLDER:
            current_paths = self.watcher.files() + self.watcher.directories()
            if current_paths:
                self.watcher.removePaths(current_paths)
            self.watcher.addPath(self.config.get('watched_folder'))

    def shutdown(self):
        if self.config.get('mode') == MODE_TIMER:
            self.timer.stop()

        elif self.config.get('mode') == MODE_WATCH_FILES or self.config.get(
                'mode') == MODE_WATCH_FOLDER:
            current_paths = self.watcher.files() + self.watcher.directories()
            if current_paths:
                self.watcher.removePaths(current_paths)
            self.watch_window = {}

    def load_notebook(self, filename):
        try:
            with open(filename) as f:
                nb = reads(f.read(), 'json')
        except:
            return None
        else:
            return nb

    def file_trigger_accumulator(self, f):
        # Accumulate triggers from changed files: if 3 files are specified to watch
        # we only want to fire once _all_ files have changed (within the given watch window)
        current_time = datetime.now()
        self.watch_window[f] = current_time  # timestamp
        self.watch_window = {
            k: v
            for k, v in self.watch_window.items() if current_time -
            timedelta(seconds=self.config.get('watch_window')) < v
        }

        if set(self.watch_window.keys()) == set(self.watcher.files() +
                                                self.watcher.directories()):
            self.trigger()

    def trigger(self, e=None):
        if self.config.get('is_active') == False:
            return False
        # Filesystemwatcher triggered
        # Get the file and folder information; make available in vars object for run
        if self.lock is None:
            self.is_running = True
            self.update()
            self.lock = QTimer.singleShot(
                self.config.get('trigger_hold') * 1000, self.run)
            # Shutdown so we don't get in infinite loops
            self.shutdown()

    def run(self, vars={}):

        default_vars = {
            'home': os.path.expanduser('~'),
            'version': VERSION_STRING,
        }

        default_vars_and_config = dict(
            list(default_vars.items()) + list(self.config.config.items()))

        if self.runner == None:
            # Postpone init to trigger for responsiveness on add/remove
            self.runner = NotebookRunner(None, pylab=True, mpl_inline=True)

        if self.config.get('mode') == MODE_WATCH_FOLDER and self.config.get(
                'iterate_watched_folder'):
            for (dirpath, dirnames,
                 filenames) in os.walk(self.config.get('watched_folder')):
                break

            filenames = [
                f for f in filenames
                if self.config.get('iterate_wildcard') in f
            ]
            logging.info('Watched folder contains %d files; looping' %
                         len(filenames))
            # Filenames contains the list of files in the folder
        else:
            filenames = [None]

        self.latest_run['timestamp'] = datetime.now()

        try:
            for f in filenames:
                now = datetime.now()
                current_vars = {
                    'datetime': now.strftime("%Y-%m-%d %H.%M.%S"),
                    'date': now.date().strftime("%Y-%m-%d"),
                    'time': now.time().strftime("%H.%M.%S"),
                    'filename': f,
                }
                vars = dict(
                    list(default_vars_and_config.items()) +
                    list(current_vars.items()))

                for nb_path in self.config.get('notebook_paths'):
                    nb = self.load_notebook(nb_path)

                    if nb:
                        # Add currently running notebook path to vars
                        vars['notebook_path'] = nb_path
                        vars['notebook_filename'] = os.path.basename(nb_path)

                        vars['output_path'] = self.config.get(
                            'output_path').format(**vars)
                        parent_folder = os.path.dirname(vars['output_path'])
                        if parent_folder:
                            try:
                                utils.mkdir_p(parent_folder)
                            except:  # Can't create folder
                                self.latest_run['success'] = False
                                raise

                        self.run_notebook(nb, vars)

                    else:
                        raise NotebookNotFound(nb_path)

        except:
            self.latest_run['success'] = False
            traceback.print_exc()
            exctype, value = sys.exc_info()[:2]
            logging.error("%s\n%s\n%s" %
                          (exctype, value, traceback.format_exc()))

        finally:
            self.is_running = False
            self.lock = None
            self.update()
            # Restart
            self.startup()

    def run_notebook(self, nb, vars={}):
        if len(nb['worksheets']) == 0:
            nb['worksheets'] = [NotebookNode({'cells': [], 'metadata': {}})]

        start = nb['worksheets'][0]['cells']
        start.insert(
            0,
            Struct(
                **{
                    'cell_type': 'code',
                    'language': 'python',
                    'outputs': [],
                    'collapsed': False,
                    'prompt_number': -1,
                    'input': 'qtipy=%s' % vars,
                    'metadata': {},
                }))
        self.runner.nb = nb

        try:
            self.runner.run_notebook()
        except:
            self.latest_run['success'] = False
            raise
        else:
            self.latest_run['success'] = True
        finally:
            ext = dict(
                html='html',
                slides='slides',
                latex='latex',
                markdown='md',
                python='py',
                rst='rst',
            )

            output, resources = IPyexport(
                IPyexporter_map[self.config.get('output_format')],
                self.runner.nb)
            output_path = vars['output_path'] + 'notebook.%s' % ext[
                self.config.get('output_format')]
            logging.info("Exporting updated notebook to %s" % output_path)
            with open(output_path, "w") as f:
                f.write(output)

    def update(self):
        global _w
        _w.viewer.update(self.index())
Example #44
0
File: ui.py Project: mfitzp/nmrbrew
class AnnotatePeaks(GenericDialog):

    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotatePeaks, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Peaks')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Peaks')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_peaks = QListWidgetAddRemove()
        self.lw_peaks.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_peaks)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_start = QDoubleSpinBox()
        self.add_start.setRange(-1, 12)
        self.add_start.setDecimals(3)
        self.add_start.setSuffix('ppm')
        self.add_start.setSingleStep(0.001)

        self.add_end = QDoubleSpinBox()
        self.add_end.setRange(-1, 12)
        self.add_end.setDecimals(3)
        self.add_end.setSuffix('ppm')
        self.add_end.setSingleStep(0.001)

        addc = QPushButton('Add')
        addc.clicked.connect(self.onPeakAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onPeakAdd)

        loadc = QPushButton("Import from file")
        loadc.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')))
        loadc.clicked.connect(self.onPeakImport)


        metabh = QPushButton("Auto match via MetaboHunter")
        metabh.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'metabohunter.png')))
        metabh.clicked.connect(self.onPeakImportMetabohunter)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_start)
        vboxh.addWidget(self.add_end)

        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vbox.addWidget(loadc)
        vbox.addWidget(metabh)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/peaks', self.lw_peaks, (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()

    def onPeakAdd(self):
        c = self.config.get('annotation/peaks')[:]  # Create new list to force refresh on reassign
        c.append( (self.add_label.text(), float(self.add_start.value()), float(self.add_end.value()) ) )
        self.config.set('annotation/peaks', c)

    def onPeakRemove(self):
        i = self.lw_peaks.removeItemAt(self.lw_peaks.currentRow())
        # c = self.map_list_fwd(i.text())

    def onPeakImport(self):
        filename, _ = QFileDialog.getOpenFileName(self.parent(), 'Load peak annotations from file', '', "All compatible files (*.csv *.txt *.tsv);;Comma Separated Values (*.csv);;Plain Text Files (*.txt);;Tab Separated Values (*.tsv);;All files (*.*)")
        if filename:
            c = self.config.get('annotation/peaks')[:]  # Create new list to force refresh on reassign

            with open(filename, 'rU') as f:
                reader = csv.reader(f, delimiter=b',', dialect='excel')
                for row in reader:
                    if row not in c:
                        c.append( row[0], float(row[1]), float(row[2]) )

            self.config.set('annotation/peaks', c)

    def onPeakImportMetabohunter(self):
        c = self.config.get('annotation/peaks')[:]  # Create new list to force refresh on reassign
        t = self.parent().current_tool

        dlg = MetaboHunter(self)
        if dlg.exec_():

            if 'spc' in t.data:
                # We have a spectra; calcuate mean; reduce size if required
                spc = t.data['spc']
                n = spc.data.shape[1]
                ppm = spc.ppm
                spcd = np.mean(spc.data, axis=0)

                # Set a hard limit on the size of data we submit to be nice.
                if n > 3000:
                    # Calculate the division required to be under the limit
                    d = np.ceil(float(n)/3000)
                    # Trim axis to multiple of divisor
                    trim = (n//d)*d
                    spcd = spcd[:trim]
                    ppm = ppm[:trim]
                    # Mean d shape
                    spcd = np.mean( spcd.reshape(-1,d), axis=1)
                    ppm = np.mean( ppm.reshape(-1,d), axis=1)

            # Submit with settings
            hmdbs = metabohunter.request(ppm, spcd,
                  metabotype=dlg.config.get('Metabotype'),
                  database=dlg.config.get('Database Source'),
                  ph=dlg.config.get('Sample pH'),
                  solvent=dlg.config.get('Solvent'),
                  frequency=dlg.config.get('Frequency'),
                  method=dlg.config.get('Method'),
                  noise=dlg.config.get('Noise Threshold'),
                  confidence=dlg.config.get('Confidence Threshold'),
                  tolerance=dlg.config.get('Tolerance')
            )

            ha = np.array(hmdbs)
            unique_hmdbs = set(hmdbs)
            if None in unique_hmdbs:
                unique_hmdbs.remove(None)

            # Extract out regions
            for hmdb in unique_hmdbs:
                hb = np.diff(ha == hmdb)

                # These are needed to ensure markers are there for objects starting and ending on array edge
                if ha[0] == hmdb:
                    hb[0] == True

                if ha[-1] == hmdb:
                    hb[-1] == True

                idx = np.nonzero(hb)[0]
                idx = idx.reshape(-1,2)

                if dlg.config.get('convert_hmdb_ids_to_names') and hmdb in METABOHUNTER_HMDB_NAME_MAP.keys():
                    label = METABOHUNTER_HMDB_NAME_MAP[hmdb]
                else:
                    label = hmdb

                # Now we have an array of all start, stop positions for this item
                for start, stop in idx:
                    c.append( (label, ppm[start], ppm[stop]) )


        self.config.set('annotation/peaks', c)

    def map_list_fwd(self, s):
        " Receive text name, return the indexes "
        return self.fwd_map_cache[s]

    def map_list_rev(self, x):
        " Receive the indexes, return the label"
        s = "%s\t%.2f\t%.2f" % tuple(x)
        self.fwd_map_cache[s] = x
        return s
Example #45
0
# ReadTheDocs
ON_RTD = os.environ.get('READTHEDOCS', None) == 'True'
if not ON_RTD:

    # Application settings
    settings = QSettingsManager()
    settings.set_defaults({
        'core/is_setup': False,
        'core/current_version': '0.0.1',
        'core/latest_version': '0.0.1',
        'core/last_time_version_checked': 0,
        'core/offered_registration': False,
    })

    # GLobal processing settings (e.g. peak annotations, class groups, etc.)
    config = ConfigManager()
    config.set_defaults({
        'annotation/peaks': [], # [(label, peak, tolerance)
        'annotation/sample_classes': {},  # {'sample_id': 'class_name' }
        'annotation/class_colors': {}, # {'class_name': color }
    })


    STATUS_QCOLORS = {
        'ready': QColor(255, 255, 255),
        'active': QColor(255, 165, 0),
        'error': QColor(255, 0, 0),
        'inactive': QColor(255, 255, 255),
        'complete': QColor(0, 255, 0),
    }
Example #46
0
class LisaConfigWindow(QDialog):
# class LisaConfigWindow(QMainWindow):

    def __init__(self, config_in, ncols=2):
        super(LisaConfigWindow, self).__init__()

        self.setWindowTitle('Lisa Config')
        self.config = ConfigManager()
        self.ncols = ncols
# used with other module. If it is set, lisa config is deleted
        self.reset_config = False

        CHOICE_A = "{pairwise_alpha_per_mm2: 45, return_only_object_with_seeds: true}"
        # CHOICE_A = 23

        CHOICE_B = 2
        CHOICE_C = 3
        CHOICE_D = 4

        map_dict = {
            'Graph-Cut': CHOICE_A,
            'Choice B': CHOICE_B,
            'Choice C': CHOICE_C,
            'Choice D': CHOICE_D,
        }
        config_def = {
            'working_voxelsize_mm': 2.0,
            'save_filetype': 'pklz',
            # 'manualroi': True,
            'segparams': CHOICE_A,
        }
        
        config_def.update(config_in)
        
        self.config.set_defaults(config_def)

        gd = QGridLayout()
        gd_max_i = 0
        for key, value in config_in.iteritems():
            if type(value) is int:
                sb = QSpinBox()
                sb.setRange(-100000, 100000)
            elif type(value) is float:
                sb = QDoubleSpinBox()
            elif type(value) is str:
                sb = QLineEdit()
            elif type(value) is bool:
                sb = QCheckBox()
            else:
                logger.error("Unexpected type in config dictionary")

            row = gd_max_i / self.ncols
            col = (gd_max_i % self.ncols) * 2

            gd.addWidget(QLabel(key),row, col +1) 
            gd.addWidget(sb, row, col + 2)
            self.config.add_handler(key, sb)
            gd_max_i += 1




        # gd.addWidget(QLabel("save filetype"), 1, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 1, 2)
        # self.config.add_handler('save_filetype', te)
        #
        # gd.addWidget(QLabel("segmentation parameters"), 2, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 2, 2)
        # self.config.add_handler('segparams', te)

        # cb = QCheckBox()
        # gd.addWidget(cb, 2, 2)
        # self.config.add_handler('active', cb)

        # gd.addWidget(QLabel("segmentation parameters"), 3, 1)
        # cmb = QComboBox()
        # cmb.addItems(map_dict.keys())
        # gd.addWidget(cmb, 3, 2)
        # self.config.add_handler('segparams', cmb, mapper=map_dict)

        self.current_config_output = QTextEdit()
        # rid.setColumnMinimumWidth(3, logo.width()/2)
        text_col = (self.ncols * 2) + 3
        gd.setColumnMinimumWidth(text_col, 500)
        gd.addWidget(self.current_config_output, 1, text_col, (gd_max_i/2)-1, 1)

        btn_reset_config = QPushButton("Reset and quit", self)
        btn_reset_config.clicked.connect(self.btnResetConfig)
        gd.addWidget(btn_reset_config, 0, text_col)

        btn_save_config = QPushButton("Save and quit", self)
        btn_save_config.clicked.connect(self.btnSaveConfig)
        gd.addWidget(btn_save_config, (gd_max_i / 2), text_col)

        self.config.updated.connect(self.show_config)

        self.show_config()

        # my line
        self.setLayout(gd)

        # self.window = QWidget()
        # self.window.setLayout(gd)
        # self.setCentralWidget(self.window)
    def add_grid_line(self, key, value):
        pass

    def get_config_as_dict(self):
        dictionary = self.config.as_dict()
        for key, value in dictionary.iteritems():
            from PyQt4.QtCore import pyqtRemoveInputHook
            pyqtRemoveInputHook()
            # import ipdb; ipdb.set_trace() #  noqa BREAKPOINT
            if type(value) == PyQt4.QtCore.QString:
                value = str(value)
            dictionary[key] = value

        return dictionary

    def btnResetConfig(self, event=None):
        self.reset_config = True
        self.close()

    def btnSaveConfig(self, event=None):
        self.reset_config = False
        self.close()


    def show_config(self):
        text = str(self.get_config_as_dict())
        self.current_config_output.setText(text)
Example #47
0
class SerialDialog(QDialog):

    def __init__(self, settings, parent=None):
        super().__init__(parent)
        self.settings = settings
        self.serialports = []

        # port
        self.portLabel = QLabel(self.tr("COM Port:"))
        self.portComboBox = QComboBox()
        self.portLabel.setBuddy(self.portComboBox)
        self.refresh_comports(self.portComboBox)

        # baudrate
        self.baudrateLabel = QLabel(self.tr("Baudrate:"))
        self.baudrateComboBox = QComboBox()
        self.baudrateLabel.setBuddy(self.baudrateComboBox)
        for br in BAUDRATES:
            self.baudrateComboBox.addItem(str(br), br)

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

        # layout
        layout = QGridLayout()
        layout.addWidget(self.portLabel, 0, 0)
        layout.addWidget(self.portComboBox, 0, 1)
        layout.addWidget(self.baudrateLabel, 1, 0)
        layout.addWidget(self.baudrateComboBox, 1, 1)
        layout.addWidget(self.dlgbuttons, 2, 0, 1, 2)
        self.setLayout(layout)
        self.setWindowTitle(self.tr("Serial Settings"))

        # settings
        defaults = {
            PORT_SETTING: "",
            BAUDRATE_SETTING: "115200"
        }
        self.tmp_settings = ConfigManager()
        self.tmp_settings.set_defaults(defaults)
        self.tmp_settings.set_many(
            {key: self.settings.get(key) for key in defaults.keys()}
        )
        self.tmp_settings.add_handler(PORT_SETTING, self.portComboBox)
        self.tmp_settings.add_handler(BAUDRATE_SETTING, self.baudrateComboBox)

    def accept(self):
        d = self.tmp_settings.as_dict()
        self.settings.set_many(d)
        super().accept()

    def refresh_comports(self, combobox):
        self.serialports = serial_ports()
        for port in self.serialports:
            combobox.addItem(port)

    @property
    def port(self):
        return self.portComboBox.currentText()

    @port.setter
    def port(self, value):
        if value in self.serialports:
            self.portComboBox.setCurrentIndex(
                self.portComboBox.findText(value))
        else:
            raise ValueError("serial port '%s' not available" % value)

    @property
    def baudrate(self):
        return self.baudrateComboBox.currentData()
Example #48
0
File: ui.py Project: pchj/nmrbrew
    def __init__(self, *args, **kwargs):
        super(MetaboHunter, self).__init__(*args, **kwargs)

        self.setWindowTitle('MetaboHunter')
        # Copy in starting state
        self.config = ConfigManager()
        self.config.hooks.update(custom_pyqtconfig_hooks.items())

        self.config.set_defaults({
            'Metabotype': 'All',
            'Database Source': 'HMDB',
            'Sample pH': 'ph7',
            'Solvent': 'water',
            'Frequency': 'all',
            'Method': 'HighestNumberNeighbourhood',
            'Noise Threshold': 0.0001,
            'Confidence Threshold': 0.5,
            'Tolerance': 0.1,
            'convert_hmdb_ids_to_names': True,
        })

        self.lw_combos = {}

        for o in [
                'Metabotype', 'Database Source', 'Sample pH', 'Solvent',
                'Frequency', 'Method'
        ]:
            row = QVBoxLayout()
            cl = QLabel(o)
            cb = QComboBox()

            cb.addItems(list(self.options[o].keys()))
            row.addWidget(cl)
            row.addWidget(cb)
            self.config.add_handler(o, cb, self.options[o])

            self.layout.addLayout(row)

        row = QGridLayout()
        self.lw_spin = {}
        for n, o in enumerate(
            ['Noise Threshold', 'Confidence Threshold', 'Tolerance']):
            cl = QLabel(o)
            cb = QDoubleSpinBox()
            cb.setDecimals(4)
            cb.setRange(0, 1)
            cb.setSingleStep(0.01)
            cb.setValue(float(self.config.get(o)))
            row.addWidget(cl, 0, n)
            row.addWidget(cb, 1, n)

            self.config.add_handler(o, cb)

        self.layout.addLayout(row)

        row = QHBoxLayout()
        row.addWidget(QLabel("Convert HMDB IDs to chemical names?"))
        conv = QCheckBox()
        self.config.add_handler('convert_hmdb_ids_to_names', conv)
        row.addWidget(conv)

        self.layout.addLayout(row)

        self.dialogFinalise()
Example #49
0
    def __init__(self, config_in, ncols=2):
        super(LisaConfigWindow, self).__init__()

        self.setWindowTitle('Lisa Config')
        self.config = ConfigManager()
        self.ncols = ncols
# used with other module. If it is set, lisa config is deleted
        self.reset_config = False

        CHOICE_A = "{pairwise_alpha_per_mm2: 45, return_only_object_with_seeds: true}"
        # CHOICE_A = 23

        CHOICE_B = 2
        CHOICE_C = 3
        CHOICE_D = 4

        map_dict = {
            'Graph-Cut': CHOICE_A,
            'Choice B': CHOICE_B,
            'Choice C': CHOICE_C,
            'Choice D': CHOICE_D,
        }
        config_def = {
            'working_voxelsize_mm': 2.0,
            'save_filetype': 'pklz',
            # 'manualroi': True,
            'segparams': CHOICE_A,
        }
        
        config_def.update(config_in)
        
        self.config.set_defaults(config_def)

        gd = QGridLayout()
        gd_max_i = 0
        for key, value in config_in.iteritems():
            if type(value) is int:
                sb = QSpinBox()
                sb.setRange(-100000, 100000)
            elif type(value) is float:
                sb = QDoubleSpinBox()
            elif type(value) is str:
                sb = QLineEdit()
            elif type(value) is bool:
                sb = QCheckBox()
            else:
                logger.error("Unexpected type in config dictionary")

            row = gd_max_i / self.ncols
            col = (gd_max_i % self.ncols) * 2

            gd.addWidget(QLabel(key),row, col +1) 
            gd.addWidget(sb, row, col + 2)
            self.config.add_handler(key, sb)
            gd_max_i += 1




        # gd.addWidget(QLabel("save filetype"), 1, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 1, 2)
        # self.config.add_handler('save_filetype', te)
        #
        # gd.addWidget(QLabel("segmentation parameters"), 2, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 2, 2)
        # self.config.add_handler('segparams', te)

        # cb = QCheckBox()
        # gd.addWidget(cb, 2, 2)
        # self.config.add_handler('active', cb)

        # gd.addWidget(QLabel("segmentation parameters"), 3, 1)
        # cmb = QComboBox()
        # cmb.addItems(map_dict.keys())
        # gd.addWidget(cmb, 3, 2)
        # self.config.add_handler('segparams', cmb, mapper=map_dict)

        self.current_config_output = QTextEdit()
        # rid.setColumnMinimumWidth(3, logo.width()/2)
        text_col = (self.ncols * 2) + 3
        gd.setColumnMinimumWidth(text_col, 500)
        gd.addWidget(self.current_config_output, 1, text_col, (gd_max_i/2)-1, 1)

        btn_reset_config = QPushButton("Reset and quit", self)
        btn_reset_config.clicked.connect(self.btnResetConfig)
        gd.addWidget(btn_reset_config, 0, text_col)

        btn_save_config = QPushButton("Save and quit", self)
        btn_save_config.clicked.connect(self.btnSaveConfig)
        gd.addWidget(btn_save_config, (gd_max_i / 2), text_col)

        self.config.updated.connect(self.show_config)

        self.show_config()

        # my line
        self.setLayout(gd)
Example #50
0
File: ui.py Project: mfitzp/nmrbrew
class AnnotateClasses(GenericDialog):

    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotateClasses, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Classes')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Sample classes')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_classes = QListWidgetAddRemove()
        self.lw_classes.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_classes)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_class = QLineEdit()

        addc = QPushButton('Add')
        addc.clicked.connect(self.onClassAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onClassAdd)

        loadc = QPushButton('Import from file')
        loadc.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-open-document.png')))
        loadc.clicked.connect(self.onClassImport)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_class)
        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vboxh.addWidget(loadc)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/sample_classes', self.lw_classes, (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()

    def onClassAdd(self):
        c = self.config.get('annotation/sample_classes')[:]  # Create new list to force refresh on reassign
        c.append( (self.add_label.text(), self.add_class.text()) )
        self.config.set('annotation/sample_classes', c)

    def onClassRemove(self):
        i = self.lw_classes.removeItemAt(self.lw_classes.currentRow())
        # c = self.map_list_fwd(i.text())

    def onClassImport(self):
        filename, _ = QFileDialog.getOpenFileName(self.parent(), 'Load classifications from file', '', "All compatible files (*.csv *.txt *.tsv);;Comma Separated Values (*.csv);;Plain Text Files (*.txt);;Tab Separated Values (*.tsv);;All files (*.*)")
        if filename:
            c = self.config.get('annotation/sample_classes')[:]  # Create new list to force refresh on reassign

            with open(filename, 'rU') as f:
                reader = csv.reader(f, delimiter=b',', dialect='excel')
                for row in reader:
                    if row not in c:
                        c.append(row[:2])

            self.config.set('annotation/sample_classes', c)

    def map_list_fwd(self, s):
        " Receive text name, return the indexes "
        return self.fwd_map_cache[s]

    def map_list_rev(self, x):
        " Receive the indexes, return the label"
        s = "%s\t%s" % tuple(x)
        self.fwd_map_cache[s] = x
        return s
Example #51
0
class BaseAnnotationItem(ResizableGraphicsItem):

    handler_cache = {}
    styles = [
        'font-family', 'font-size', 'text-bold', 'text-italic',
        'text-underline', 'text-color', 'color-border', 'color-background'
    ]

    minSize = ANNOTATION_MINIMUM_QSIZE

    def __init__(self, position=None, *args, **kwargs):
        super(BaseAnnotationItem, self).__init__(*args, **kwargs)
        # Config for each annotation item, holding the settings (styles, etc)
        # update-control via the toolbar using add_handler linking
        self.config = ConfigManager()
        self.config.updated.connect(self.applyStyleConfig)

        self.setFlag(QGraphicsItem.ItemIsMovable)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemIsFocusable)

        if position:
            self.setPos(position)

        self.setZValue(-1)

    def delete(self):
        self.prepareGeometryChange()
        self.scene().annotations.remove(self)
        self.scene().removeItem(self)
        self.removeHandlers()

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Backspace and e.modifiers() == Qt.ControlModifier:
            self.delete()
        else:
            return super(BaseAnnotationItem, self).keyPressEvent(e)

    def importStyleConfig(self, config):
        for k in self.styles:
            self.config.set(k, config.get(k))

    def addHandlers(self):
        m = self.scene().views()[0].m  # Hack; need to switch to importing this
        for k in self.styles:
            self.config.add_handler(k, m.styletoolbarwidgets[k])

    def removeHandlers(self):
        for k in self.styles:
            self.config.remove_handler(k)

    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemSelectedChange:
            if not value:
                self.removeHandlers()

        elif change == QGraphicsItem.ItemSelectedHasChanged:
            if value:
                self.addHandlers()

        return super(BaseAnnotationItem, self).itemChange(change, value)
Example #52
0
File: ui.py Project: pchj/nmrbrew
    def __init__(self, parent, config=None, *args, **kwargs):
        super(AnnotatePeaks, self).__init__(parent, *args, **kwargs)

        self.setWindowTitle('Annotate Peaks')

        if config:
            # Copy in starting state
            self.config = ConfigManager()
            self.config.hooks.update(custom_pyqtconfig_hooks.items())

            self.config.set_defaults(config)

        self.fwd_map_cache = {}

        # Correlation variables
        gb = QGroupBox('Peaks')
        vbox = QVBoxLayout()
        # Populate the list boxes
        self.lw_peaks = QListWidgetAddRemove()
        self.lw_peaks.setSelectionMode(QAbstractItemView.ExtendedSelection)
        vbox.addWidget(self.lw_peaks)

        vboxh = QHBoxLayout()

        self.add_label = QLineEdit()
        self.add_start = QDoubleSpinBox()
        self.add_start.setRange(-1, 12)
        self.add_start.setDecimals(3)
        self.add_start.setSuffix('ppm')
        self.add_start.setSingleStep(0.001)

        self.add_end = QDoubleSpinBox()
        self.add_end.setRange(-1, 12)
        self.add_end.setDecimals(3)
        self.add_end.setSuffix('ppm')
        self.add_end.setSingleStep(0.001)

        addc = QPushButton('Add')
        addc.clicked.connect(self.onPeakAdd)

        remc = QPushButton('Remove selected')
        remc.clicked.connect(self.onPeakAdd)

        loadc = QPushButton("Import from file")
        loadc.setIcon(
            QIcon(
                os.path.join(utils.scriptdir, 'icons',
                             'folder-open-document.png')))
        loadc.clicked.connect(self.onPeakImport)

        metabh = QPushButton("Auto match via MetaboHunter")
        metabh.setIcon(
            QIcon(os.path.join(utils.scriptdir, 'icons', 'metabohunter.png')))
        metabh.clicked.connect(self.onPeakImportMetabohunter)

        vboxh.addWidget(self.add_label)
        vboxh.addWidget(self.add_start)
        vboxh.addWidget(self.add_end)

        vboxh.addWidget(addc)

        vbox.addWidget(remc)
        vbox.addLayout(vboxh)
        vbox.addWidget(loadc)
        vbox.addWidget(metabh)

        gb.setLayout(vbox)

        self.layout.addWidget(gb)

        self.config.add_handler('annotation/peaks', self.lw_peaks,
                                (self.map_list_fwd, self.map_list_rev))

        self.dialogFinalise()
Example #53
0
class Automaton(QStandardItem):

    def __init__(self, *args, **kwargs):
        super(Automaton, self).__init__(*args, **kwargs)

        self.setData(self, Qt.UserRole)
        self.watcher = QFileSystemWatcher()
        self.timer = QTimer()

        self.watch_window = {}

        self.latest_run = {}
        self.is_running = False

        self.config = ConfigManager()
        self.config.set_defaults({
            'mode': MODE_WATCH_FOLDER,
            'is_active': True,
            'trigger_hold': 1,
            'notebook_paths': '',
            'output_path': '{home}/{notebook_filename}_{datetime}_',
            'output_format': 'html',

            'watched_files': [],
            'watched_folder': '',
            'watch_window': 15,

            'iterate_watched_folder': True,
            'iterate_wildcard': '.csv',

            'timer_seconds': 60,
        })

        self.runner = None
        self.lock = None

        self.latest_run = {
            'timestamp': None,
            'success': None,
        }

        # Set up all the triggers
        self.watcher.fileChanged.connect(self.file_trigger_accumulator)
        self.watcher.directoryChanged.connect(self.trigger)
        self.timer.timeout.connect(self.trigger)

    def startup(self):
        if self.config.get('is_active') == False:
            return False
    
        if self.config.get('mode') == MODE_TIMER:
            self.timer.setInterval(self.config.get('timer_seconds') * 1000)
            self.timer.start()

        elif self.config.get('mode') == MODE_WATCH_FILES:
            current_paths = self.watcher.files() + self.watcher.directories()
            if current_paths:
                self.watcher.removePaths(current_paths)
            self.watch_window = {}
            self.watcher.addPaths(self.config.get('watched_files'))

        elif self.config.get('mode') == MODE_WATCH_FOLDER:
            current_paths = self.watcher.files() + self.watcher.directories()
            if current_paths:
                self.watcher.removePaths(current_paths)
            self.watcher.addPath(self.config.get('watched_folder'))

    def shutdown(self):
        if self.config.get('mode') == MODE_TIMER:
            self.timer.stop()

        elif self.config.get('mode') == MODE_WATCH_FILES or self.config.get('mode') == MODE_WATCH_FOLDER:
            current_paths = self.watcher.files() + self.watcher.directories()
            if current_paths:
                self.watcher.removePaths(current_paths)
            self.watch_window = {}
        
    def load_notebook(self, filename):
        try:
            with open(filename) as f:
                nb = reads(f.read(), 'json')
        except:
            return None
        else:
            return nb

    def file_trigger_accumulator(self, f):
        # Accumulate triggers from changed files: if 3 files are specified to watch
        # we only want to fire once _all_ files have changed (within the given watch window)
        current_time = datetime.now()
        self.watch_window[f] = current_time  # timestamp
        self.watch_window = {k: v for k, v in self.watch_window.items() if current_time - timedelta(seconds=self.config.get('watch_window')) < v}

        if set(self.watch_window.keys()) == set(self.watcher.files() + self.watcher.directories()):
            self.trigger()

    def trigger(self, e=None):
        if self.config.get('is_active') == False:
            return False
        # Filesystemwatcher triggered
        # Get the file and folder information; make available in vars object for run
        if self.lock is None:
            self.is_running = True
            self.update()
            self.lock = QTimer.singleShot(self.config.get('trigger_hold') * 1000, self.run)
            # Shutdown so we don't get in infinite loops
            self.shutdown()

    def run(self, vars={}):

        default_vars = {
            'home': os.path.expanduser('~'),
            'version': VERSION_STRING,
        }

        default_vars_and_config = dict(list(default_vars.items()) + list(self.config.config.items()))

        if self.runner == None:
            # Postpone init to trigger for responsiveness on add/remove
            self.runner = NotebookRunner(None, pylab=True, mpl_inline=True)

        if self.config.get('mode') == MODE_WATCH_FOLDER and self.config.get('iterate_watched_folder'):
            for (dirpath, dirnames, filenames) in os.walk(self.config.get('watched_folder')):
                break

            filenames = [f for f in filenames if self.config.get('iterate_wildcard') in f]
            logging.info('Watched folder contains %d files; looping' % len(filenames))
            # Filenames contains the list of files in the folder
        else:
            filenames = [None]

        self.latest_run['timestamp'] = datetime.now()

        try:
            for f in filenames:
                now = datetime.now()
                current_vars = {
                    'datetime': now.strftime("%Y-%m-%d %H.%M.%S"),
                    'date': now.date().strftime("%Y-%m-%d"),
                    'time': now.time().strftime("%H.%M.%S"),
                    'filename': f,
                }
                vars = dict(list(default_vars_and_config.items()) + list(current_vars.items()))

                for nb_path in self.config.get('notebook_paths'):
                    nb = self.load_notebook(nb_path)

                    if nb:
                        # Add currently running notebook path to vars
                        vars['notebook_path'] = nb_path
                        vars['notebook_filename'] = os.path.basename(nb_path)

                        vars['output_path'] = self.config.get('output_path').format(**vars)
                        parent_folder = os.path.dirname(vars['output_path'])
                        if parent_folder:
                            try:
                                utils.mkdir_p(parent_folder)
                            except:  # Can't create folder
                                self.latest_run['success'] = False
                                raise

                        self.run_notebook(nb, vars)

                    else:
                        raise NotebookNotFound(nb_path)

        except:
            self.latest_run['success'] = False
            traceback.print_exc()
            exctype, value = sys.exc_info()[:2]
            logging.error("%s\n%s\n%s" % (exctype, value, traceback.format_exc()))

        finally:
            self.is_running = False
            self.lock = None
            self.update()
            # Restart
            self.startup()            

    def run_notebook(self, nb, vars={}):
        if len(nb['worksheets']) == 0:
            nb['worksheets'] = [NotebookNode({'cells': [], 'metadata': {}})]

        start = nb['worksheets'][0]['cells']
        start.insert(0, Struct(**{
            'cell_type': 'code',
            'language': 'python',
            'outputs': [],
            'collapsed': False,
            'prompt_number': -1,
            'input': 'qtipy=%s' % vars,
            'metadata': {},
        }))
        self.runner.nb = nb

        try:
            self.runner.run_notebook()
        except:
            self.latest_run['success'] = False
            raise
        else:
            self.latest_run['success'] = True
        finally:
            ext = dict(
                html='html',
                slides='slides',
                latex='latex',
                markdown='md',
                python='py',
                rst='rst',
            )

            output, resources = IPyexport(IPyexporter_map[self.config.get('output_format')], self.runner.nb)
            output_path = vars['output_path'] + 'notebook.%s' % ext[self.config.get('output_format')]
            logging.info("Exporting updated notebook to %s" % output_path)
            with open(output_path, "w") as f:
                f.write(output)

    def update(self):
        global _w
        _w.viewer.update(self.index())
Example #54
0
    def __init__(self, config_in, ncols=2):
        super(DictGui, self).__init__()

        self.setWindowTitle('Lisa Config')
        self.config = ConfigManager()
        self.ncols = ncols
        # used with other module. If it is set, lisa config is deleted
        self.reset_config = False

        CHOICE_A = "{pairwise_alpha_per_mm2: 45, return_only_object_with_seeds: true}"
        # CHOICE_A = 23

        CHOICE_B = 2
        CHOICE_C = 3
        CHOICE_D = 4

        map_dict = {
            'Graph-Cut': CHOICE_A,
            'Choice B': CHOICE_B,
            'Choice C': CHOICE_C,
            'Choice D': CHOICE_D,
        }
        config_def = {
            'working_voxelsize_mm': 2.0,
            'save_filetype': 'pklz',
            # 'manualroi': True,
            'segparams': CHOICE_A,
        }

        config_def.update(config_in)

        self.config.set_defaults(config_def)

        gd = QGridLayout()
        gd_max_i = 0
        for key, value in config_in.items():
            if type(value) is int:
                sb = QSpinBox()
                sb.setRange(-100000, 100000)
            elif type(value) is float:
                sb = QDoubleSpinBox()
            elif type(value) is str:
                sb = QLineEdit()
            elif type(value) is bool:
                sb = QCheckBox()
            else:
                logger.error("Unexpected type in config dictionary")

            row = gd_max_i / self.ncols
            col = (gd_max_i % self.ncols) * 2

            gd.addWidget(QLabel(key), row, col + 1)
            gd.addWidget(sb, row, col + 2)
            self.config.add_handler(key, sb)
            gd_max_i += 1

        # gd.addWidget(QLabel("save filetype"), 1, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 1, 2)
        # self.config.add_handler('save_filetype', te)
        #
        # gd.addWidget(QLabel("segmentation parameters"), 2, 1)
        # te = QLineEdit()
        # gd.addWidget(te, 2, 2)
        # self.config.add_handler('segparams', te)

        # cb = QCheckBox()
        # gd.addWidget(cb, 2, 2)
        # self.config.add_handler('active', cb)

        # gd.addWidget(QLabel("segmentation parameters"), 3, 1)
        # cmb = QComboBox()
        # cmb.addItems(map_dict.keys())
        # gd.addWidget(cmb, 3, 2)
        # self.config.add_handler('segparams', cmb, mapper=map_dict)

        self.current_config_output = QTextEdit()
        # rid.setColumnMinimumWidth(3, logo.width()/2)
        text_col = (self.ncols * 2) + 3
        gd.setColumnMinimumWidth(text_col, 500)
        gd.addWidget(self.current_config_output, 1, text_col,
                     (gd_max_i / 2) - 1, 1)

        btn_reset_config = QPushButton("Default", self)
        btn_reset_config.clicked.connect(self.btnResetConfig)
        gd.addWidget(btn_reset_config, 0, text_col)

        btn_save_config = QPushButton("Ok", self)
        btn_save_config.clicked.connect(self.btnSaveConfig)
        gd.addWidget(btn_save_config, (gd_max_i / 2), text_col)

        self.config.updated.connect(self.show_config)

        self.show_config()

        # my line
        self.setLayout(gd)
Example #55
0
    def __init__(self, parent, **kwargs):
        super(AutomatonDialog, self).__init__(parent, **kwargs)
        self.setWindowTitle("Edit Automaton")

        self.config = ConfigManager()

        gb = QGroupBox('IPython notebook(s) (*.ipynb)')
        grid = QGridLayout()
        notebook_path_le = QLineEdit()
        self.config.add_handler('notebook_paths', notebook_path_le, mapper=(lambda x: x.split(";"), lambda x: ";".join(x)))
        grid.addWidget(notebook_path_le, 0, 0, 1, 2)

        notebook_path_btn = QToolButton()
        notebook_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'document-attribute-i.png')))
        notebook_path_btn.clicked.connect(lambda: self.onNotebookBrowse(notebook_path_le))
        grid.addWidget(notebook_path_btn, 0, 2, 1, 1)
        gb.setLayout(grid)

        self.layout.addWidget(gb)

        gb = QGroupBox('Automaton mode')
        grid = QGridLayout()
        mode_cb = QComboBox()
        mode_cb.addItems(self.mode_options.keys())
        mode_cb.currentIndexChanged.connect(self.onChangeMode)
        self.config.add_handler('mode', mode_cb, mapper=self.mode_options)
        grid.addWidget(QLabel('Mode'), 0, 0)
        grid.addWidget(mode_cb, 0, 1)

        grid.addWidget(QLabel('Hold trigger'), 1, 0)
        fwatcher_hold_sb = QSpinBox()
        fwatcher_hold_sb.setRange(0, 60)
        fwatcher_hold_sb.setSuffix(' secs')
        self.config.add_handler('trigger_hold', fwatcher_hold_sb)
        grid.addWidget(fwatcher_hold_sb, 1, 1)
        gb.setLayout(grid)

        self.layout.addWidget(gb)

        self.watchfile_gb = QGroupBox('Watch files')
        grid = QGridLayout()

        watched_path_le = QLineEdit()
        grid.addWidget(watched_path_le, 0, 0, 1, 2)
        self.config.add_handler('watched_files', watched_path_le, mapper=(lambda x: x.split(";"), lambda x: ";".join(x)))

        watched_path_btn = QToolButton()
        watched_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'document-copy.png')))
        watched_path_btn.setStatusTip('Add file(s)')
        watched_path_btn.clicked.connect(lambda: self.onFilesBrowse(watched_path_le))
        grid.addWidget(watched_path_btn, 0, 2, 1, 1)

        grid.addWidget(QLabel('Watch window'), 1, 0)
        watch_window_sb = QSpinBox()
        watch_window_sb.setRange(0, 60)
        watch_window_sb.setSuffix(' secs')
        self.config.add_handler('watch_window', watch_window_sb)
        grid.addWidget(watch_window_sb, 1, 1)

        self.watchfile_gb.setLayout(grid)
        self.layout.addWidget(self.watchfile_gb)

        self.watchfolder_gb = QGroupBox('Watch folder')
        grid = QGridLayout()

        watched_path_le = QLineEdit()
        grid.addWidget(watched_path_le, 0, 0, 1, 3)
        self.config.add_handler('watched_folder', watched_path_le)

        watched_path_btn = QToolButton()
        watched_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-horizontal-open.png')))
        watched_path_btn.setStatusTip('Add folder')
        watched_path_btn.clicked.connect(lambda: self.onFolderBrowse(watched_path_le))
        grid.addWidget(watched_path_btn, 0, 3, 1, 1)

        grid.addWidget(QLabel('Iterate files in folder'), 3, 0)
        loop_folder_sb = QCheckBox()
        self.config.add_handler('iterate_watched_folder', loop_folder_sb)
        grid.addWidget(loop_folder_sb, 3, 1)

        loop_wildcard_le = QLineEdit()
        self.config.add_handler('iterate_wildcard', loop_wildcard_le)
        grid.addWidget(loop_wildcard_le, 3, 2)

        self.watchfolder_gb.setLayout(grid)
        self.layout.addWidget(self.watchfolder_gb)

        self.timer_gb = QGroupBox('Timer')
        grid = QGridLayout()

        grid.addWidget(QLabel('Run every'), 0, 0)
        watch_timer_sb = QSpinBox()
        watch_timer_sb.setRange(0, 60)
        watch_timer_sb.setSuffix(' secs')
        self.config.add_handler('timer_seconds', watch_timer_sb)
        grid.addWidget(watch_timer_sb, 0, 1)

        self.timer_gb.setLayout(grid)
        self.layout.addWidget(self.timer_gb)

        self.manual_gb = QGroupBox('Manual')  # No show
        grid = QGridLayout()
        grid.addWidget(QLabel('No configuration'), 0, 0)
        self.manual_gb.setLayout(grid)
        self.layout.addWidget(self.manual_gb)

        gb = QGroupBox('Output')
        grid = QGridLayout()
        output_path_le = QLineEdit()
        self.config.add_handler('output_path', output_path_le)
        grid.addWidget(output_path_le, 0, 0, 1, 2)

        notebook_path_btn = QToolButton()
        notebook_path_btn.setIcon(QIcon(os.path.join(utils.scriptdir, 'icons', 'folder-horizontal-open.png')))
        notebook_path_btn.clicked.connect(lambda: self.onFolderBrowse(notebook_path_le))
        grid.addWidget(notebook_path_btn, 0, 2, 1, 1)

        export_cb = QComboBox()
        export_cb.addItems(IPyexporter_map.keys())
        self.config.add_handler('output_format', export_cb)
        grid.addWidget(QLabel('Notebook output format'), 1, 0)
        grid.addWidget(export_cb, 1, 1)

        gb.setLayout(grid)

        self.layout.addWidget(gb)

        self.layout.addStretch()
        self.finalise()

        self.onChangeMode(mode_cb.currentIndex())
Example #56
0
class DictWidget(QtGui.QWidget):
    def __init__(self, config_in, ncols=2, captions=None, hide_keys=None,
                 horizontal=False, show_captions=True, accept_button=False,
                 config_manager=None, radiobuttons=None, dropdownboxes=None):
        """

        :param config_in:  dictionary
        :param ncols:
        :param captions:
        :param radiobuttons: {"name_of_radiobutton": [
                                 ["orig_caption_1", orig_caption_2],
                                 default_value]
                                 ]
                            }
        """
        super(DictWidget, self).__init__()
        if captions is None:
            captions = {}
        if hide_keys is None:
            hide_keys = []
        self.config_in = config_in
        self.ncols = ncols
        self.captions = captions
        self.accept_button = accept_button
        self.hide_keys = copy.copy(hide_keys)
        self.horizontal = horizontal
        self.show_captions = show_captions
        if radiobuttons is None:
            radiobuttons = {}
        self.radiobuttons = radiobuttons
        if dropdownboxes is None:
            dropdownboxes = {}
        self.dropdownboxes = dropdownboxes

        # hide also temp keys for lists and ndarrays
        # due to load default params
        self._get_tmp_composed_keys(config_in)
        self.hide_keys.extend(self._tmp_composed_keys_list)

        if config_manager is None:
            self.config = ConfigManager()
            self.config.set_defaults(config_in)
        else:
            self.config = config_manager
        self.mainLayout = QGridLayout(self)
        self.setLayout(self.mainLayout)
        self.widgets = {}
        self.grid_i = 0
        self.init_ui()

    def _get_tmp_composed_keys(self, cfg):
        """
        Get list of temporary keys for lists and ndarrays. This keys are used for reconstruction.

        vytvoří to seznam pomocných klíčů pro seznamy a ndarray
        :param cfg:
        :return:
        """
        self._tmp_composed_keys_dict = {}
        self._tmp_composed_keys_list = []
        toappend = {}
        for key, value in cfg.iteritems():
            if key in self.dropdownboxes.keys():
                continue
            if key in self.radiobuttons.keys():
                continue
            if type(value) in (list, np.ndarray):
                self._tmp_composed_keys_dict[key] = []
                array = np.asarray(value)
                key_array_i = 0
                for val in array.tolist():
                    # key_i = (key, key_array_i)
                    key_i = ComposedDictMetadata((key, key_array_i))
                    self._tmp_composed_keys_dict[key].append(key_i)
                    self._tmp_composed_keys_list.append(key_i)
                    key_array_i += 1
                    toappend[key_i] = val
        cfg.update(toappend)

    def _create_dropdownbox(self, key, value):
        # atomic_widget = QWidget()
        row, col = self.__calculate_new_grid_position()
        # layout = QBoxLayout(self.horizontal)
        atomic_widget = QComboBox()
        # atomic_widget.addItem("C")
        # atomic_widget.addItem("C++")
        values = self.dropdownboxes[key]
        # values = self.dropdownboxes[key][0]
        if value is not None and value in values:
            # vali = atomic_widget.findText(value)
            atomic_widget.findText(value)
        atomic_widget.addItems(values)
        # this does not work. I used findText()
        # atomic_widget.setCurrentIndex(vali)
        # layout.addWidget(cb)

        # atomic_widget.setLayout(layout)
        return atomic_widget

    def _create_radiobutton(self, key, value):
        atomic_widget = QWidget()
        layout = QBoxLayout(self.horizontal)
        for i, rbkey in enumerate(self.radiobuttons[key][0]):
            b1 = QRadioButton("Button1")
            if i == self.radiobuttons[key][1]:
                b1.setChecked(True)
            # b1.toggled.connect(lambda:self.btnstate(self.b1))
            layout.addWidget(b1)
        atomic_widget.setLayout(layout)
        return atomic_widget

    def init_ui(self):
        # self.widgets = {}
        # self.grid_i = 0
        grid = self.mainLayout

        for key, value in self.config_in.iteritems():

            if key in self.hide_keys:
                continue
            if key in self.captions.keys():
                caption = self.captions[key]
            else:
                caption = key

            atomic_widget = self.__get_widget_for_primitive_types(key, value)
            if atomic_widget is None:
                if type(value) in (list, np.ndarray):
                    array = np.asarray(value)
                    atomic_widget = self._create_sub_grid_from_ndarray(key, array)
                    row, col = self.__calculate_new_grid_position()
                    grid.addWidget(QLabel(caption), row, col + 1)
                    grid.addLayout(atomic_widget, row, col + 2)
                    continue
                else:
                    logger.error("Unexpected type in config dictionary")

                continue

            # import ipdb; ipdb.set_trace()
            row, col = self.__calculate_new_grid_position()
            grid.addWidget(QLabel(caption), row, col + 1)
            grid.addWidget(atomic_widget, row, col + 2)

        # gd.setColumnMinimumWidth(text_col, 500)

        if self.accept_button:
            btn_accept = QPushButton("Accept", self)
            btn_accept.clicked.connect(self.btn_accept)
            text_col = (self.ncols * 2) + 3
            grid.addWidget(btn_accept, (self.grid_i / 2), text_col)

        self.config.updated.connect(self.on_config_update)

    # def __add_line
    def __get_widget_for_primitive_types(self, key, value):

        """
        return right widget and connect the value with config_manager
        :param key:
        :param value:
        :return:
        """

        if key in self.dropdownboxes.keys():
            atomic_widget = self._create_dropdownbox(key,value)
            self.config.add_handler(key, atomic_widget)
        elif key in self.radiobuttons.keys():
            atomic_widget = self._create_radiobutton(key,value)
            self.config.add_handler(key, atomic_widget)
        elif type(value) is int:
            atomic_widget = QSpinBox()
            atomic_widget.setRange(-100000, 100000)
            self.config.add_handler(key, atomic_widget)
        elif type(value) is float:
            atomic_widget = QDoubleSpinBox()
            atomic_widget.setDecimals(6)
            atomic_widget.setMaximum(1000000000)
            self.config.add_handler(key, atomic_widget)
        elif type(value) is str:
            atomic_widget = QLineEdit()
            self.config.add_handler(key, atomic_widget)
        elif type(value) is bool:
            atomic_widget = QCheckBox()
            self.config.add_handler(key, atomic_widget)
        else:
            return None
        return atomic_widget

    def _create_sub_grid_from_ndarray(self, key, ndarray):
        hgrid = QGridLayout(self)
        hgrid_i = 0
        for val in ndarray.tolist():
            # key_i = key + str(hgrid_i)
            key_i = (key, hgrid_i)
            atomic_widget = self.__get_widget_for_primitive_types(key_i, val)

            hgrid.addWidget(atomic_widget, 0, hgrid_i)
            hgrid_i += 1

        return hgrid

    def __calculate_new_grid_position(self):
        row = self.grid_i / self.ncols
        col = (self.grid_i % self.ncols) * 2
        self.grid_i += 1
        if self.horizontal:
            return col, row
        return row, col

    def btn_accept(self):
        print ("btn_accept: " + str(self.config_as_dict()))

    def on_config_update(self):
        pass

    def config_as_dict(self):
        def _primitive_type(value):
            if type(value) == PyQt4.QtCore.QString:
                value = str(value)
            return value

        dictionary = self.config.as_dict()
        dictionary = copy.copy(dictionary)
        for key, value in dictionary.iteritems():
            from PyQt4.QtCore import pyqtRemoveInputHook
            #pyqtRemoveInputHook()
            # import ipdb; ipdb.set_trace() #  noqa BREAKPOINT
            # if type(key) == tuple:
            if type(key) == ComposedDictMetadata:

                dict_key, value_index = key
                dict_key = (dict_key)
                # if dict_key not in dictionary.keys():
                #     dictionary[dict_key] = {}

                dictionary[dict_key][value_index] = _primitive_type(value)

            else:
                dictionary[key] = _primitive_type(value)

        for key in dictionary.keys():
            # if type(key) == tuple:
            if type(key) == ComposedDictMetadata:
                dictionary.pop(key)

        # for key, value in dictionary.iteritems():
        #     if type(key) == tuple:
        #         dictionary

        return dictionary
Example #57
0
    def __init__(self):
        super(MainWindow, self).__init__()

        self.setWindowTitle('PyQtConfig Demo')
        self.vis = ConfigManager()
        #
        # CHOICE_A = 1
        # CHOICE_B = 2
        # CHOICE_C = 3
        # CHOICE_D = 4
        #
        # map_dict = {
        #     'Choice A': CHOICE_A,
        #     'Choice B': CHOICE_B,
        #     'Choice C': CHOICE_C,
        #     'Choice D': CHOICE_D,
        # }

        self.vis.set_defaults({
            'text1': 'hello1',
            'text2': 'hello2',
            'text3': 'hello3',
            'text4': 'hello4',
        })

        # self.vis.set_defaults({
        #     'number': 13,
        #     'text': 'hello',
        #     'active': True,
        #     'combo': CHOICE_C,
        # })

        gd = QGridLayout()
        #
        # sb = QSpinBox()
        # gd.addWidget(sb, 0, 1)
        # self.vis.add_handler('number', sb)
        #
        # te = QLineEdit()
        # gd.addWidget(te, 1, 1)
        # self.vis.add_handler('text', te)
        #
        # cb = QCheckBox()
        # gd.addWidget(cb, 2, 1)
        # self.vis.add_handler('active', cb)
        #
        # cmb = QComboBox()
        # cmb.addItems(map_dict.keys())
        # gd.addWidget(cmb, 3, 1)
        # self.vis.add_handler('combo', cmb, mapper=map_dict)
        #
        # self.current_config_output = QTextEdit()
        # gd.addWidget(self.current_config_output, 0, 3, 3, 1)

        i=0
        print self.vis.as_dict()
        for item in self.vis.as_dict().keys():
            te = QLineEdit()
            te.setEnabled(False)
            self.vis.add_handler(item,te)
            gd.addWidget(te,i,1)
            i=i+1

        # self.vis.updated.connect(self.show_config)

        # self.show_config()

        self.window = QWidget()
        self.window.setLayout(gd)
        self.setCentralWidget(self.window)