Commit cd0c230f authored by payno's avatar payno
Browse files

Merge branch 'fix_2' into 'master'

Fix 2

See merge request !4
parents b171273a 9b0c89c2
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
__authors__ = ["H. Payno"]
__license__ = "MIT"
__date__ = "15/10/2018"
from silx.gui import qt
from . import OverwritingOperation
class ThreadedOperation(qt.QThread):
"""Thread able to run an operation on a dedicated thread"""
def __init__(self, operation=None, dry_run=False, cache_data=None):
qt.QThread.__init__(self)
self.init(operation, dry_run, cache_data)
def init(self, operation, dry_run=False, cache_data=None):
self._operation = operation
self._dry_run = dry_run
self._cache_data = cache_data
def run(self):
if self._dry_run is True:
assert isinstance(self._operation, OverwritingOperation)
self._operation.dry_run(self._cache_data)
else:
self._operation.compute()
......@@ -29,15 +29,18 @@ __license__ = "MIT"
__date__ = "15/10/2018"
import numpy
from silx.gui import qt
class _BaseOperation(object):
class _BaseOperation(qt.QObject):
"""
Operation to be applied on an experiment
"""
# TODO would be nice to have required operations to be processed before this
# one
sigProgress = qt.Signal(int)
"""Advancement of the operation in percentage"""
def __init__(self, experiment, name, can_overwrite_data=False):
"""
......@@ -49,6 +52,7 @@ class _BaseOperation(object):
:param must_be_unique: If true then can only be applied once to the
experiment
"""
qt.QObject.__init__(self)
self._name = name
self._experiment = experiment
self._can_overwrite_data = can_overwrite_data
......@@ -73,6 +77,14 @@ class _BaseOperation(object):
def registerOperation(self):
self._experiment.addOperation(self)
def updateProgress(self, progress):
"""
:param float progress: percentage of advancement
"""
assert type(progress) is int
self.sigProgress.emit(progress)
class OverwritingOperation(_BaseOperation):
"""
......
......@@ -95,6 +95,7 @@ class IntensityMapping(_MappingBase):
self._resetIntensityMap()
self._resetDim()
for x in range(self.data.shape[2]):
self.updateProgress(int(x / self.data.shape[2] * 100.0))
for y in range(self.data.shape[1]):
# TODO: do this operation using a grid or something close
# but would have to find a way to write at the same position...
......
......@@ -110,12 +110,13 @@ class Shift(OverwritingOperation):
def _compute(self, data):
res = []
iImg = 0
for img in self.data[:]:
nImg = self.data.shape[0]
print(nImg)
for iImg, img in enumerate(self.data[:]):
self.updateProgress(int(iImg / nImg * 100.0))
_dx = self.dx * iImg
_dy = self.dy * iImg
res.append(image.shift_img(img, dx=_dx, dy=_dy))
iImg += 1.0
data = numpy.asarray(res)
return data
......
......@@ -31,9 +31,11 @@ __date__ = "08/10/2018"
from silx.gui import qt
from silx.gui.plot import Plot2D
from id06workflow.core.experiment.operation.shift import Shift as ShiftOperation
from id06workflow.core.experiment.operation.ThreadedOperation import ThreadedOperation
from id06workflow.core.experiment import Experiment
from silx.gui.plot.StackView import StackViewMainWindow
from id06workflow.gui.settings import DEFAULT_COLORMAP
from functools import partial
import logging
_logger = logging.getLogger(__file__)
......@@ -43,8 +45,13 @@ class ShiftCorrectionWidget(qt.QWidget):
"""
Used to apply a shift correction on data
"""
sigProgress = qt.Signal(float)
"""Advancement of the applied shift in percentage"""
def __init__(self, parent):
self._experiment = None
self._operation_thread = ThreadedOperation()
qt.QWidget.__init__(self, parent)
self.setLayout(qt.QVBoxLayout())
self.layout().addWidget(
......@@ -75,6 +82,7 @@ class ShiftCorrectionWidget(qt.QWidget):
self.getDy = self._control.getDy
self.getDz = self._control.getDz
self.getShift = self._control.getShift
self.isProcessing = self._operation_thread.isRunning
def setShift(self, dx, dy, dz):
self._control.setShift(dx=dx, dy=dy, dz=dz)
......@@ -84,19 +92,37 @@ class ShiftCorrectionWidget(qt.QWidget):
"""Update stack plot view from the current shift"""
# TODO: the call to shift volume should be done in an other thread
# and show some information on advancement
if self._operation_thread.isRunning() is True:
_logger.error('Cannot process shift until the current one is finished')
_shift = self.getShift()
if _shift == self._lastShift:
self.setProgress(100)
return
else:
self.setProgress(0)
self._operation.dx = _shift[0]
self._operation.dy = _shift[1]
self._operation.dz = _shift[2]
self._shiftedData = self._operation.dry_run()
self._stack.setStack(self._shiftedData)
self._sumPlot.addImage(self._shiftedData.sum(axis=0))
self._lastShift = _shift
self._operation_thread.init(operation=self._operation,
dry_run=True)
self._callback = partial(self._update_post_processing, _shift)
self._operation_thread.finished.connect(self._callback)
self._operation.sigProgress.connect(self.setProgress)
self._operation_thread.start()
def _update_post_processing(self, _shift):
self._operation_thread.finished.disconnect(self._callback)
self._stack.setStack(self._shiftedData)
self._sumPlot.addImage(self._shiftedData.sum(axis=0))
self._lastShift = _shift
self.setProgress(100)
def setExperiment(self, experiment):
if self._operation_thread.isRunning() is True:
_logger.error('Cannot process shift until the current one is finished')
self._experiment = experiment
self._operation = ShiftOperation(experiment=self._experiment)
......@@ -110,6 +136,10 @@ class ShiftCorrectionWidget(qt.QWidget):
def getOperation(self):
return self._operation
def setProgress(self, progress):
assert type(progress) is int
self.sigProgress.emit(progress)
class _DxDyDzWidget(qt.QWidget):
"""
......
......@@ -32,8 +32,10 @@ from Orange.widgets.widget import OWWidget
from Orange.canvas.registry.description import InputSignal, OutputSignal
from id06workflow.core.experiment import Experiment
from id06workflow.core.experiment.operation.mapping import IntensityMapping
from id06workflow.core.experiment.operation.ThreadedOperation import ThreadedOperation
from id06workflow.core.types import _Image
from id06workflow.gui.mapping import MappingPlot
from functools import partial
import logging
_logger = logging.getLogger(__file__)
......@@ -63,15 +65,33 @@ class MappingOW(OWWidget):
super().__init__()
layout = gui.vBox(self.mainArea, 'noise removal').layout()
self._progress = gui.ProgressBar(self, 100)
self._plot = MappingPlot(parent=self)
layout.addWidget(self._plot)
self._processing_thread = ThreadedOperation()
def _setProgressValue(self, value):
self._progress.widget.progressBarSet(value)
def _process(self, experiment):
if experiment is None:
return
if self._processing_thread.isRunning():
_logger.error('Mapping thread is already running, cannot take another'
'job yet')
return
operation = IntensityMapping(experiment=experiment)
operation.compute()
operation.sigProgress.connect(self._setProgressValue)
self._processing_thread.init(operation)
callback = partial(self._post_processing, operation, experiment)
self._processing_thread.finished.connect(callback)
self._processing_thread.start()
def _post_processing(self, operation, experiment):
self.send("image",
_Image(img=operation.intensity_map, name='intensity_map'))
self.send("image",
......
......@@ -66,6 +66,8 @@ class ShiftCorrectionOW(OWWidget):
def __init__(self):
super().__init__()
self._widget = ShiftCorrectionWidget(parent=self)
self._progress = gui.ProgressBar(self, 100)
self._widget.sigProgress.connect(self._setProgressValue)
layout = gui.vBox(self.mainArea, 'data selection').layout()
layout.addWidget(self._widget)
layout.addWidget(self._widget)
......@@ -86,6 +88,9 @@ class ShiftCorrectionOW(OWWidget):
# expose API
self.setShift = self._widget.setShift
def _setProgressValue(self, value):
self._progress.widget.progressBarSet(value)
def _process(self, experiment):
assert isinstance(experiment, (Experiment, type(None)))
if experiment.dataset is None or experiment.dataset.is_valid() is False:
......@@ -98,6 +103,11 @@ class ShiftCorrectionOW(OWWidget):
self.show()
def validate(self):
if self._widget.isProcessing() is True:
_logger.error('you should wait the end of the processing before'
'validation')
return
self._progress.finish()
if self._editedExperiment is not None:
self._widget._updateShift()
if self._widget.getShift() != (0, 0, 0):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment