Exemplo n.º 1
0
    def draw(self, dataset, zoom_reset=False):
        """
        Draw 1D or 2D dataset corresponding to the current dataset.

        Parameters
        ----------
        zoom_reset: bool, optional
            True if the x and y range must be reset to the full range when redrawing.
        """

        self.dataset = dataset
        if self._autorange:
            zoom_reset = True

        # Create the main plotItem
        if not hasattr(self, 'p'):
            vb = CustomViewBox(ndim=dataset.ndim, prefs=dataset.preferences)
            self.p = self.addPlot(row=0, col=0, viewBox=vb)

        # Draw main data
        scp.debug_('>>>>>>>>>> Draw')
        self._draw(zoom_reset=zoom_reset)

        # Draw processed
        self._draw_processed(zoom_reset=zoom_reset)

        self._autorange = False
Exemplo n.º 2
0
    def removeDataset(self, name=None):
        # Confirm
        if '/original' in name:
            name = name.split('/')[0]
            if not confirm_msg(self.parent, 'Remove', f'Removing the main (original) datset will '
                                                      f'remove all other datasets present in `{name}`.\n'
                                                      f'Is-it what you want?'):
                return
        elif not confirm_msg(self.parent, 'Remove', f'Do you really want to remove the `{name}` dataset?'):
            return
        scp.debug_(f'remove: {name}')
        self.sigDatasetChanged.emit(None, 'deselect')
        if name in self.project.projects_names and self.project[name].implements('Project'):
            # its the whole subproject to be removed
            self.project.remove_project(name)
        else:
            try:
                subproject, name = name.split('/')
                subproject.remove_dataset(name)
            except:
                self.project.remove_dataset(name)

        self.dataset = None
        self.dirty = True
        # Signal
        self.sigProjectChanged.emit('dataset removed')
Exemplo n.º 3
0
    def saveProject(self, *args, **kwargs):
        if not kwargs.pop('force', False):
            if not self.dirty:
                return
        scp.debug_('Saving project')
        # we need to save only the original data as they will be recalculaded anyway when reloaded
        proj = self.project.copy()
        for name in proj.projects_names:
            for datasetname in proj[name].datasets_names:
                if 'original' not in datasetname:
                    proj[name].remove_dataset(datasetname)
                else:
                    proj[name][datasetname].processeddata = None
                    proj[name][datasetname].processedmask = False
                    transposed = self.project[name][datasetname].transposed # we take the flag on the self.project
                    # has it is not copied
                    if transposed:
                        proj[name][datasetname].transpose(inplace=True)

        if proj.directory is None:
            proj._directory = self._directory
        if kwargs.get('saveas') or proj.name == 'untitled':
            proj.save_as(self._directory / 'untitled.pscp', Qt_parent=self.parent)
            self.sigProjectChanged.emit('renamed')
        else:
            proj.save()
        scp.preferences.last_project = Path(proj.directory) / proj.name
        self.dirty = False
Exemplo n.º 4
0
    def getProcessingActions(self, params):

        # Brute force method: if any of the processing parameters change, we reevaluate all processing step (will
        # be refined later)

        proc = params.param('processing')
        actions = []

        for item in proc:
            if not item.value():
                # item not checked, we do not take it into account
                continue

            actions.append([item.opts['action']])

            parameters = {}
            if not item.name().startswith('define regions'):
                if item.childs:
                    for children in item.childs:
                        parameters[children.name()] = children.value()
            else:
                parameters['kind'] = item.param('kind').value()
                parameters['range'] = [
                    list(eval(val.value().split('> ')[1]))
                    for val in item.param('regiongroup').children()
                ]

            actions[-1].append(parameters)

        scp.debug_('ACTIONS: ')
        scp.debug_(actions)

        return actions
Exemplo n.º 5
0
    def __init__(self, **opts):

        opts['type'] = 'group'
        opts['addText'] = "Add new ..."
        super().__init__(**opts)

        scp.debug_('New region group added')
        self.sigChildAdded.connect(self.addRegion)
        self.current_index = 0
Exemplo n.º 6
0
    def addNew(self, key):

        item = self.processors[key]
        name = f"{key}#{self.current_index}"
        item['title'] = f"{key}{' '*(20 - len(key))}"
        item['name'] = name

        child = self.insertChild(len(self.childs) - 1, item)
        scp.debug_(f"New processor added: {name}")
        self.current_index += 1
        return child
Exemplo n.º 7
0
    def initialize(self, dataset):

        if dataset is None:
            self._dataset = None
            self._params = None
            return

        scp.debug_('initialize controller')
        self.isInitializing = True
        params = self.params

        if params is None or not dataset.state:
            ndim = dataset._squeeze_ndim
            processing = ProcessGroup(
                name='processing',
                title='Processing pipeline',
                children=[getProcessors('basis')['output']])
            params = [processing]

            scp.debug_('create group')

            # Create tree of Parameter objects
            params = Parameter.create(name='params',
                                      type='group',
                                      children=params)
            params._parent = self
            self.setParameters(params, showTop=False)

        if dataset.state:
            scp.debug_('Restore state')
            # was already saved before. Restore it
            params.restoreState(dataset.state, blockSignals=True)

        # actualise
        scp.debug_('Save state')
        dataset.state = params.saveState()
        dataset = self.performProcessing(dataset, params)
        for item in params.param('processing'):
            item.opts['expanded'] = False
        self._params = params

        # set the current dataset
        self._dataset = dataset

        # connects events
        self._params.sigTreeStateChanged.connect(self.change)

        self.isInitializing = False
        scp.debug_('Initialisation finished')
Exemplo n.º 8
0
    def emitSelectDataset(self, *args, **kwargs):
        """
        When an item is clicked in the project window, some actions can be
        performed, e.g., plot the corresponding data.

        """
        sel = self.currentItem()
        if sel:
            # make a plot of the data
            id = sel.text(2)
            name = sel.text(0)
            if sel.text(1) == "Project":
                if name == self.project.name:
                    return
                name = f'{name}/original'
            scp.debug_(f'---------------------- Dataset {name}({id}) selected')
            self.sigDatasetSelected.emit(name)
Exemplo n.º 9
0
    def __init__(self, parent):
        QtCore.QObject.__init__(self)
        self._parent = parent

        # Autosave feature
        self.autosaveTimer = QtCore.QTimer()
        self.autosaveTimer.setInterval(30000)
        self.autosaveTimer.timeout.connect(self.saveProject)

        # Open last_project
        last_project = scp.preferences.last_project
        if last_project:
            last_project = Path(last_project).with_suffix(".pscp")
        if scp.preferences.autoload_project and last_project is not None and last_project.exists():
            scp.debug_(f'Open last project {last_project}')
            self.project = last_project
        else:
            self.openProject(new=True)
Exemplo n.º 10
0
 def updateDataset(self, dataset):
     if 'untitled' not in dataset.name:
         # the parent subproject should be specified
         subproj = dataset.name.split('/')[0]
         if dataset.name in self.project[subproj].datasets_names:
             # In this case just update : but warning the dataset id must be the same the previous one.
             scp.debug_(f'Update dataset: {dataset.name}')
             id = self.project[subproj]._datasets[dataset.name].id
             dataset._id = id
             self.project[subproj]._datasets[dataset.name] = dataset
             if self.dataset.name == dataset.name:
                 self.sigDatasetChanged.emit(dataset, 'updated')
         else:
             scp.debug_(f'Add dataset {dataset.name} to project')
             self.project[subproj].add_dataset(dataset)
             self.sigProjectChanged.emit('dataset added')
             #self.sigDatasetChanged.emit(dataset, 'added')
         self.dirty = True
Exemplo n.º 11
0
    def addDataset(self, dataset=None):
        scp.debug_('Add a dataset')
        # Read the  dataset
        try:
            if not dataset:
                dataset = scp.read(Qt_parent=self.parent, default_filter='omnic')
            if dataset is None:  # still not determined.
                return
        except Exception as e:
            scp.error_(e)

        # Create a subproject with this dataset
        subproj = scp.Project()
        self.project.add_project(subproj, dataset.name)
        subproj.add_dataset(dataset, f'{dataset.name}/original')

        # Signal
        self.dirty = True
        self.sigProjectChanged.emit('dataset added')
Exemplo n.º 12
0
    def change(self, params, changes):

        dataset = self.dataset

        if self.isProcessing or self.isInitializing or dataset is None:
            return

        state = params.saveState()

        if dataset.state != state:
            dataset.state = state
            self.parent.project.dirty = True
            # variable
        elif changes[0][1] != 'contextMenu':
            return

        for param, change, data in changes:

            if change == 'parent' and data is None:
                # when an element is removed
                self.parent.plotwidget.draw(dataset, False)
                return

            # Name of the parameter or group changed
            name = param.name()
            scp.debug_(f'{name} changed `{changes}`')

            # parents?
            top_group = param
            top_parent = param.parent()
            if top_parent is None:
                return
            while top_parent.name() != 'params':
                top_group = top_parent
                top_parent = top_parent.parent()

            # actions
            if top_group.name() == 'processing':
                scp.debug_('processing changed -> execute actions')
                self.processingChanged(dataset, params, param, change, data)

            return
Exemplo n.º 13
0
    def propagateActions(self, dataset, actions):
        if actions is None or actions == [None]:
            # Only output, but set to None
            return

        # input
        new = dataset.copy()

        # apply actions
        nprocess = 0
        for action in actions:
            if action is None:
                continue

            nprocess += 1
            scp.debug_(f'Action running: {action}')
            cmdtxt = action[0].split('.')

            if len(cmdtxt) > 1:
                # call from a library or a script to import
                lib = import_module(cmdtxt[0])
                f = cmdtxt[1]
            else:
                lib = self
                f = cmdtxt[0]
            func = getattr(lib, f)
            kwargs = action[1]
            new = func(new, **kwargs)

        if nprocess and new is not None:
            dataset.processeddata = new.data
            dataset.processedmask = new.mask
            if new.transposed:
                # in this case the original data must also be transposed
                dataset.transpose(inplace=True)
        else:
            dataset.processeddata = None
            dataset.processedmask = False

        return dataset
Exemplo n.º 14
0
    def addRegion(self, param, child, pos):

        kind = self.parent().param('kind').value()

        if child.value() == 'undefined':
            # dimension
            dim = self.parent().parent().parent().parent().dataset.dims[-1]
            # default span
            rangex = np.array(self.parent().parent().parent().parent().parent.
                              plotwidget.p.getAxis('bottom').range)
            x = rangex.mean()
            w = rangex.ptp() / 50
            span = (x - w, x + w)
        else:
            dim, span = child.value().split('> ')
            span = eval(span)

        # add it
        self.parent().regions.addRegion(child, kind=kind, span=span, dim=dim)
        scp.debug_(
            f'> new {kind} region added to the regions (index: {self.current_index})'
        )
Exemplo n.º 15
0
    def onDatasetChanged(self, dataset, change=None):

        if dataset is None or change == 'select':
            if hasattr(self.parent, 'plotwidget'):
                self.parent.plotwidget.close()
                del self.parent.plotwidget
                self.parent.dplot.hideTitleBar()
            self.clear()
            if change != 'select':
                return

        scp.debug_(f'Update controller: {dataset.name}')

        # Update the controller
        if change == 'select':
            self._params = None

        self.initialize(dataset)

        # Redraw
        self.parent.setupPlot(title=dataset.name)
        self.parent.plotwidget.draw(dataset, zoom_reset=True)
Exemplo n.º 16
0
    def restoreState(self, state, **kwargs):

        # remove processing children but output. They will be restored latter
        state_children = OrderedDict()
        for key in list(state['children'].keys())[:]:
            item = state['children'][key]
            if key != 'output':
                state_children[key] = item
                del state['children'][key]

        super().restoreState(state, **kwargs)

        # now we can add the define region entries
        for key in state_children.keys():
            item, _ = key.split('#')
            child = self.addNew(item)
            child.setOpts(value=state_children[key]['value'])
            child.setOpts(expanded=state_children[key]['expanded'])
            if item == 'define regions':
                # set the stored kind to this new child
                child.param('kind').setValue(
                    state_children[key]['children']['kind']['value'])
                if child.param('kind').value() != 'undefined':
                    child.param('kind').setOpts(readonly=True)
                # now we need to add the children ranges
                try:
                    for item in state_children[key]['children']['regiongroup'][
                            'children'].values():
                        span = child.param('regiongroup').addNew(
                            span=item['value'])
                        span.parent().setOpts(
                            expanded=state_children[key]['children']
                            ['regiongroup']['expanded'])
                except KeyError:
                    continue

        scp.debug_('ProcessGroup restored')
Exemplo n.º 17
0
def test_logger(caplog):
    logger = logging.getLogger("SpectroChemPy")
    logger.propagate = True
    caplog.set_level(DEBUG)

    # We can set the level using strings
    set_loglevel("DEBUG")
    assert logger.handlers[0].level == INFO  # DEBUG only on the file
    assert logger.handlers[1].level == DEBUG

    set_loglevel(WARNING)
    assert logger.handlers[0].level == WARNING
    assert logger.handlers[1].level == WARNING

    error_("\n" + "*" * 80 + "\n")
    debug_("debug in WARNING level - should not appear")
    info_("info in WARNING level - should not appear")
    warning_("OK this is a Warning")
    error_("OK This is an Error")

    error_("\n" + "*" * 80 + "\n")

    set_loglevel(INFO)
    assert logger.handlers[0].level == INFO
    assert logger.handlers[1].level == INFO

    debug_("debug in INFO level - should not appear on stdout")
    info_("OK - info in INFO level")
    warning_("OK this is a Warning")
    error_("OK This is an Error")

    error_("\n" + "*" * 80 + "\n")

    set_loglevel("DEBUG")
    assert logger.handlers[0].level == INFO
    assert logger.handlers[1].level == DEBUG

    debug_("OK - debug in DEBUG level")
    info_("OK - info in DEBUG level")
    assert caplog.records[-1].levelname == "INFO"
    assert caplog.records[-1].message.endswith("OK - info in DEBUG level")
    warning_("OK this is a Warning")
    assert caplog.records[-1].levelname == "WARNING"
    assert caplog.records[-1].message.endswith("OK this is a Warning")
    error_("OK This is an Error")
    assert caplog.records[-1].levelname == "ERROR"
    assert caplog.records[-1].message.endswith("OK This is an Error")
Exemplo n.º 18
0
def test_logger(caplog):
    logger = logging.getLogger('SpectroChemPy')
    logger.propagate = True
    caplog.set_level(logging.DEBUG)

    # We can set the level using strings
    set_loglevel("DEBUG")
    assert logger.level == logging.DEBUG

    set_loglevel(WARNING)
    assert logger.level == logging.WARNING

    error_('\n' + '*' * 80 + '\n')
    debug_('debug in WARNING level - should not appear')
    info_('info in WARNING level - should not appear')
    warning_('OK this is a Warning')
    error_('OK This is an Error')

    error_('\n' + '*' * 80 + '\n')

    set_loglevel(INFO)
    assert logger.level == logging.INFO

    debug_('debug in INFO level - should not appear')
    info_('OK - info in INFO level')
    warning_('OK this is a Warning')
    error_('OK This is an Error')

    error_('\n' + '*' * 80 + '\n')

    set_loglevel('DEBUG')
    assert logger.level == logging.DEBUG

    debug_('OK - debug in DEBUG level')
    info_('OK - info in DEBUG level')
    assert caplog.records[-1].levelname == 'INFO'
    assert caplog.records[-1].message == 'OK - info in DEBUG level'
    warning_('OK this is a Warning')
    assert caplog.records[-1].levelname == 'WARNING'
    assert caplog.records[-1].message == 'OK this is a Warning'
    error_('OK This is an Error')
    assert caplog.records[-1].levelname == 'ERROR'
    assert caplog.records[-1].message == 'OK This is an Error'
Exemplo n.º 19
0
    pass

# %% [markdown]
# ## API Configuration
#
# Many options of the API can be set up

# %%
scp.set_loglevel(scp.INFO)

# %% [markdown]
# In the above cell, we have set the **log** level to display ``info`` messages, such as this one:

# %%
scp.info_('this is an info message!')
scp.debug_('this is a debug message!')

# %% [markdown]
# Only the info message is displayed, as expected.
#
# If we change it to ``DEBUG``, we should get the two messages

# %%
scp.set_loglevel(scp.DEBUG)

scp.info_('this is an info message!')
scp.debug_('this is a debug message!')

# %% [markdown]
# Let's now come back to a standard level of message for the rest of the Tutorial.
Exemplo n.º 20
0
# %% [markdown]
# And  finally, the next instructions reset the loglevel to `WARNING` level (default), and print it.
# As seen below, no message `changed default log_level to ...` is delivered

# %%
scp.set_loglevel("WARNING")  # reset to default
print(f"New loglevel: {scp.get_loglevel()}")

# %% [markdown]
# It is also possible to issue such messages in scripts. In the cell below, we set the loglevel to `INFO` and try to
# print two types of messages:

# %%
scp.set_loglevel("INFO")
scp.info_("this is an info message!")
scp.debug_("this is a debug message!")

# %% [markdown]
# As expected, only the info message was displayed.
#
# If we change the loglevel to ``DEBUG``, then the two messages will be printed:

# %%
scp.set_loglevel(scp.DEBUG)
scp.info_("this is an info message!")
scp.debug_("this is a debug message!")

# %% [markdown]
# Finally, we come back to the standard level of message for the rest of the Tutorial -- in this case neither `DEBUG`
# nor `INFO` messages will be printed.
Exemplo n.º 21
0
 def editname(self, *args):
     # TODO: editing name
     scp.debug_(args)