backgroundSubstractionWidget.py 4.58 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 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__ = ["J. Garriga"]
__license__ = "MIT"
29
__date__ = "08/08/2019"
30
31

from silx.gui import qt
32
from silx.gui.colors import Colormap
33
34
from silx.gui.plot.StackView import StackViewMainWindow

35
from darfix.core.imageOperations import background_substraction, hot_pixel_removal
36

37
from .utils import ChooseDimensionWidget
Henri Payno's avatar
Henri Payno committed
38
from .operationThread import OperationThread
39
40
41


class BackgroundSubstractionWidget(qt.QWidget):
42
43
44
45
    """
    Widget to apply background substraction from a dataset.
    The dataset should have raw data and dark data.
    """
46
    signalComputed = qt.Signal()
47
48
49
50

    def __init__(self, parent=None):
        qt.QWidget.__init__(self, parent)

51
52
        self._thread = OperationThread(background_substraction)

53
54
55
        self.setLayout(qt.QVBoxLayout())

        self._sv = StackViewMainWindow()
56
        self._sv.setColormap(Colormap(name='viridis', normalization='linear'))
57
58
        self._chooseDimensionWidget = ChooseDimensionWidget(self)
        self._chooseDimensionWidget.hide()
59
        self._computeB = qt.QPushButton("Compute background substraction")
60
        self.layout().addWidget(self._sv)
61
        self.layout().addWidget(self._chooseDimensionWidget)
62
        self.layout().addWidget(self._computeB)
63

64
        self._computeB.clicked.connect(self.computeBS)
65
66
        self._chooseDimensionWidget.filterChanged.connect(self._filterStack)
        self._chooseDimensionWidget.stateDisabled.connect(self._wholeStack)
67

68
69
70
71
72
73
    def hideButton(self):
        self._computeB.hide()

    def showButton(self):
        self._computeB.show()

74
    def computeBS(self):
75
        """
76
77
        Function that starts the thread to compute the background
        substraction.
78
        """
79
80
81
        self._thread.setArgs(self.dataset.data, self.dataset.dark_frames)
        self._thread.finished.connect(self._updateData)
        self._thread.start()
82
        self._computeB.setEnabled(False)
83
84
85
86
87
88

    def _updateData(self):
        """
        Updates the stack with the data computed in the thread
        """
        self._thread.finished.disconnect(self._updateData)
89
        self._computeB.setEnabled(True)
90
        self.dataset.data = self._thread.data
91
        self.dataset.data = hot_pixel_removal(self.dataset.data)
92
93
        assert self.dataset.data is not None
        self.setStack(self.dataset.data)
94
        self.signalComputed.emit()
95
96
97
98
99
100
101
102
103

    def setDataset(self, dataset):
        """
        Dataset setter. Saves the dataset and updates the stack with the dataset
        data

        :param Dataset dataset: dataset
        """
        self.dataset = dataset
104
        self.setStack(dataset.data)
105
        if self.dataset.reshaped_data() is not None:
106
107
            self._chooseDimensionWidget.show()
            self._chooseDimensionWidget.setDimensions(self.dataset.dims)
108

109
110
111
    def clearStack(self):
        self._sv.setStack(None)

112
    def _filterStack(self, dim=0, val=0):
113
114
115
116
117
        data = self.dataset.reshaped_data(dim, val)
        if data.shape[0]:
            self.setStack(data)
        else:
            self.setStack(None)
118
119
120
121

    def _wholeStack(self):
        self.setStack(self.dataset.data)

122
123
    def setStack(self, *arg, **kwargs):
        """
124
125
        Sets the data passed as aguments in the stack.
        Mantains the current frame showed in the view.
126
        """
127
        nframe = self._sv.getFrameNumber()
128
        self._sv.setStack(*arg, **kwargs)
129
        self._sv.setFrameNumber(nframe)