k_weight.py 6.76 KB
Newer Older
payno's avatar
payno committed
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
29
# 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__ = "06/07/2019"

30
31
import functools
import logging
payno's avatar
payno committed
32
33

from Orange.widgets import gui
payno's avatar
payno committed
34
from Orange.widgets.settings import Setting
35
from Orange.widgets.widget import OWWidget
36
37
from Orange.widgets.widget import Input, Output
import Orange.data
payno's avatar
payno committed
38
from silx.gui import qt
39
from ewokscore.registration import Registered
payno's avatar
payno committed
40
import est.core.process.pymca.k_weight
payno's avatar
payno committed
41
from orangecontrib.est.process import _ProcessForOrangeMixIn, ProcessRunnable
payno's avatar
payno committed
42
43
44
from est.core.types import XASObject
from orangecontrib.est.progress import QProgress
from orangecontrib.est.utils import Converter
payno's avatar
payno committed
45

payno's avatar
payno committed
46
47
48
_logger = logging.getLogger(__file__)


payno's avatar
payno committed
49
50
51
52
class KWeightWindow(qt.QMainWindow):
    def __init__(self, parent=None):
        qt.QMainWindow.__init__(self, parent)

53
        # k wright widget
payno's avatar
payno committed
54
        self._k_widget = qt.QWidget(parent=self)
payno's avatar
payno committed
55
        self._k_widget.setLayout(qt.QHBoxLayout())
payno's avatar
payno committed
56
        self._k_widget.layout().addWidget(qt.QLabel("k weight"))
payno's avatar
payno committed
57
58
59
60
61
62
63
64
        self._k_spin_box = qt.QSpinBox(parent=self)
        self._k_spin_box.setRange(0, 3)
        self._k_widget.layout().addWidget(self._k_spin_box)
        dockWidget = qt.QDockWidget(parent=self)
        dockWidget.setWidget(self._k_widget)
        self.addDockWidget(qt.Qt.RightDockWidgetArea, dockWidget)
        dockWidget.setAllowedAreas(qt.Qt.RightDockWidgetArea | qt.Qt.LeftDockWidgetArea)
        dockWidget.setFeatures(qt.QDockWidget.NoDockWidgetFeatures)
65

66
67
        self.setWindowFlags(qt.Qt.Widget)

payno's avatar
payno committed
68

69
70
class KWeightOW(
    _ProcessForOrangeMixIn,
71
72
    OWWidget,
    Registered,
73
):
payno's avatar
payno committed
74
75
76
    """
    Widget used for signal extraction
    """
payno's avatar
payno committed
77

payno's avatar
payno committed
78
    name = "k weight"
payno's avatar
payno committed
79
    id = "orange.widgets.est.pymca.k_weight"
80
    description = "Progress k weight"
payno's avatar
payno committed
81
    icon = "icons/k_weight.png"
82
    priority = 2
payno's avatar
payno committed
83
84
85
86
87
    category = "esrfWidgets"
    keywords = ["spectroscopy", "signal", "k", "weight"]

    want_main_area = True
    resizing_enabled = True
88
    allows_cycle = False
89
    ewokstaskclass = est.core.process.pymca.k_weight.PyMca_k_weight
payno's avatar
payno committed
90

payno's avatar
payno committed
91
92
93
    _kWeightSetting = Setting(int(3))
    """Store the configuration of the PyMca XASClass"""

94
    class Inputs:
payno's avatar
payno committed
95
        xas_obj = Input("xas_obj", XASObject, default=True)
96
97
        # simple compatibility for some Orange widget and especialy the
        # 'spectroscopy add-on'
payno's avatar
payno committed
98
        data_table = Input("Data", Orange.data.Table)
99
100

    class Outputs:
101
        xas_obj = Output("xas_obj", XASObject)
102
103
104
        # by default we want to avoid sending 'Orange.data.Table' to avoid
        # loosing the XASObject flow process and results.

payno's avatar
payno committed
105
106
    def __init__(self):
        super().__init__()
107
        self._latest_xas_obj = None
payno's avatar
payno committed
108
        layout = gui.vBox(self.mainArea, "k weight").layout()
payno's avatar
payno committed
109
110
        self._window = KWeightWindow(parent=self)
        layout.addWidget(self._window)
payno's avatar
payno committed
111

112
113
114
        # progress
        self._progress = gui.ProgressBar(self, 100)

payno's avatar
payno committed
115
116
117
118
        # manage settings
        if self._kWeightSetting != 3:
            self._window._k_spin_box.setValue(self._kWeightSetting)

payno's avatar
payno committed
119
120
121
        # signal / slot connection
        self._window._k_spin_box.valueChanged.connect(self._updateProcess)

122
        # self.handleNewSignals()
123

payno's avatar
payno committed
124
    def _updateProcess(self, *arv, **kwargs):
payno's avatar
payno committed
125
        self._update_settings()
126
127
        if self._latest_xas_obj:
            self.process(self._latest_xas_obj)
payno's avatar
payno committed
128

129
130
131
132
133
134
135
    @Inputs.data_table
    def processFrmDataTable(self, data_table):
        if data_table is None:
            return
        self.process(Converter.toXASObject(data_table=data_table))

    @Inputs.xas_obj
136
137
    def process(self, xas_obj):
        if xas_obj is None:
payno's avatar
payno committed
138
139
            return

140
        if not self._canProcess():
payno's avatar
payno committed
141
142
143
144
            _logger.warning(
                "There is some processing on going already, will"
                "not process the new dataset"
            )
145

146
        self._latest_xas_obj = xas_obj
147
        self._startProcess()
148
149

        # setup the k weight process
150
        process_obj = QPyMca_k_weight(inputs={"xas_obj": xas_obj})
151
        process_obj._advancement.sigProgress.connect(self._setProgressValue)
152
153
154
        process_obj.set_properties(
            {"_kWeightSetting": self._window._k_spin_box.value()}
        )
payno's avatar
payno committed
155

156
157
        # update the processing thread
        thread = self.getProcessingThread()
158
        thread.init(process_obj=process_obj, xas_obj=self._latest_xas_obj)
payno's avatar
payno committed
159
160
161
        self._callback_finish = functools.partial(
            self._endProcess, self._latest_xas_obj
        )
162
163
164
        thread.finished.connect(self._callback_finish)
        # start processing
        thread.start(priority=qt.QThread.LowPriority)
payno's avatar
payno committed
165

payno's avatar
payno committed
166
167
    def _update_settings(self):
        self._kWeightSetting = self._window._k_spin_box.value()
168
169
170
171
172

    def _setProgressValue(self, value):
        self._progress.widget.progressBarSet(value)


payno's avatar
payno committed
173
class QPyMca_k_weight(est.core.process.pymca.k_weight.PyMca_k_weight):
174
175
176
    """
    Normalization able to give advancement using qt.Signal and QThreadPool
    """
payno's avatar
payno committed
177

178
179
    def __init__(self, *args, **kwargs):
        est.core.process.pymca.k_weight.PyMca_k_weight.__init__(self, *args, **kwargs)
payno's avatar
payno committed
180
        self._advancement = QProgress("normalization")
181
182
183
184
185

    def _pool_process(self, xas_obj):
        self.pool = qt.QThreadPool()
        self.pool.setMaxThreadCount(5)
        for spectrum in xas_obj.spectra:
payno's avatar
payno committed
186
187
188
189
190
191
192
            assert "KWeight" in xas_obj.configuration
            runnable = ProcessRunnable(
                fct=est.core.process.pymca.k_weight.process_spectr_k,
                spectrum=spectrum,
                configuration=xas_obj.configuration,
                callback=self._advancement.increaseAdvancement,
            )
193
194
            self.pool.start(runnable)
        self.pool.waitForDone()