xas_input.py 8.83 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
29
30
# 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/11/2019"


31
import logging
32
from Orange.widgets import gui
33
from Orange.widgets.settings import Setting
34
from silx.gui import qt
35
from silx.io.url import DataUrl
payno's avatar
payno committed
36
import est.core.io
37
import est.core.process.ignoreprocess
38
import est.core.process.io
39
from est.gui.xas_object_definition import XASObjectWindow
40
from ewoksorange.bindings.owwidgets import OWEwoksWidgetNoThread
41

42
43
_logger = logging.getLogger(__file__)

payno's avatar
payno committed
44

45
class XASInputOW(
46
47
    OWEwoksWidgetNoThread,
    ewokstaskclass=est.core.process.io.ReadXasObject,
48
):
49
50
51
    """
    Widget used for signal extraction
    """
payno's avatar
payno committed
52

53
    name = "xas input"
54
    id = "orange.widgets.xas.utils.xas_input"
55
    description = "Read .dat file and convert it to spectra"
56
57
58
59
    icon = "icons/input.png"
    priority = 0
    category = "esrfWidgets"
    keywords = ["spectroscopy", "signal", "input", "file"]
60

61
62
63
    want_main_area = True
    resizing_enabled = True

64
    _spec_file_setting = Setting(tuple())
65
66
67
    _spectra_url_setting = Setting(str())
    _energy_url_setting = Setting(str())
    _configuration_url_setting = Setting(str())
68
    _dimensions_setting = Setting(tuple())
69
    _energy_unit_settings = Setting(str())
70
71
72
73
    _I0_url_setting = Setting(str())
    _I1_url_setting = Setting(str())
    _I2_url_setting = Setting(str())
    _mu_ref_url_setting = Setting(str())
74
75
76
77
78
79

    def __init__(self):
        super().__init__()
        self._inputWindow = qt.QWidget(parent=self)
        self._inputWindow.setLayout(qt.QGridLayout())

80
        self._inputDialog = XASObjectWindow(parent=self)
81
        self._inputWindow.layout().addWidget(self._inputDialog, 0, 0, 1, 2)
82

83
84
85
86
87
        # add the apply button
        types = qt.QDialogButtonBox.Ok
        self._buttons = qt.QDialogButtonBox(parent=self)
        self._buttons.setStandardButtons(types)
        self.layout().addWidget(self._buttons)
88

89
90
91
92
        spacer = qt.QWidget(parent=self)
        spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
        self._inputWindow.layout().addWidget(spacer, 2, 0)

payno's avatar
payno committed
93
        layout = gui.vBox(self.mainArea, "input").layout()
94
95
        layout.addWidget(self._inputWindow)

96
97
        try:
            self._loadSettings()
payno's avatar
PEP8    
payno committed
98
        except Exception:
99
            pass
100

101
        # expose api
102
        self.apply = self._emitNewFile
103

104
        # signal / slot connection
105
106
        self._buttons.accepted.connect(self.hide)
        self._buttons.accepted.connect(self._emitNewFile)
107
        self._inputDialog.getMainWindow().editingFinished.connect(self._storeSettings)
108
        self.setFileSelected = self._inputDialog.setDatFile
109
110

    def _emitNewFile(self, *args, **kwargs):
111
112
113
        try:
            xas_obj = self._inputDialog.buildXASObject()
        except ValueError as e:
payno's avatar
payno committed
114
            qt.QMessageBox.warning(self, "", str(e))
115
        else:
116
            self.Outputs.xas_obj.send(xas_obj)
117

118
    def _loadSettings(self):
payno's avatar
payno committed
119
        input_type = est.io.InputType.hdf5_spectra
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

        if len(self._spec_file_setting) == 0:
            input_spec_file = None
            input_energy_col_name = None
            input_abs_col_name = None
            input_monitor_col_name = None
            scan_title = None
        else:
            (
                input_spec_file,
                input_energy_col_name,
                input_abs_col_name,
                input_monitor_col_name,
                scan_title,
            ) = self._spec_file_setting
        if input_spec_file is not None:
            if input_spec_file.endswith(".xmu"):
payno's avatar
payno committed
137
                input_type = est.io.InputType.xmu_spectrum
138
                self._inputDialog.setXmuFile(input_spec_file)
139
            else:
payno's avatar
payno committed
140
                input_type = est.io.InputType.dat_spectrum
141
142
143
144
145
146
147
148
149
                self._inputDialog.setDatFile(input_spec_file)
                if input_energy_col_name is not None:
                    self._inputDialog.setEnergyColName(input_energy_col_name)
                if input_abs_col_name is not None:
                    self._inputDialog.setAbsColName(input_abs_col_name)
                if scan_title is not None:
                    self._inputDialog.setScanTitle(scan_title)
                if input_monitor_col_name is not None:
                    self._inputDialog.setMonitorColName(input_monitor_col_name)
150
151

        def load_url(url_path, setter):
payno's avatar
payno committed
152
            if url_path != "":
153
154
155
                if isinstance(url_path, DataUrl):
                    url = url_path
                else:
156
                    url = DataUrl(url_path)
157
158

                try:
159
160
                    if url and url.is_valid():
                        setter(url.path())
payno's avatar
PEP8    
payno committed
161
                except Exception:
payno's avatar
payno committed
162
                    logging.info("fail to load ", url_path)
163
164
165
166

        load_url(self._spectra_url_setting, self._inputDialog.setSpectraUrl)
        load_url(self._energy_url_setting, self._inputDialog.setEnergyUrl)
        load_url(self._configuration_url_setting, self._inputDialog.setConfigurationUrl)
167
168
169
170
171
172
173

        advanceHDF5Info = self._inputDialog.getAdvanceHdf5Information()
        load_url(self._I0_url_setting, advanceHDF5Info.setI0Url)
        load_url(self._I1_url_setting, advanceHDF5Info.setI1Url)
        load_url(self._I2_url_setting, advanceHDF5Info.setI2Url)
        load_url(self._mu_ref_url_setting, advanceHDF5Info.setMuRefUrl)

174
175
176
177
        if len(self._dimensions_setting) == 3:
            self._inputDialog.setDimensions(self._dimensions_setting)
        else:
            assert len(self._dimensions_setting) == 0
payno's avatar
payno committed
178
        self._inputDialog.getMainWindow().setEnergyUnit(self._energy_unit_settings)
179
180
181
182
183

        # set up
        self._inputDialog.setCurrentType(input_type)

    def _storeSettings(self):
184
        # handle single file input
185
186
187
188
189
190
191
192
        self._spec_file_setting = (
            self._inputDialog.getMainWindow().getDatFile(),
            self._inputDialog.getMainWindow().getEnergyColName(),
            self._inputDialog.getMainWindow().getAbsColName(),
            self._inputDialog.getMainWindow().getMonitorColName(),
            self._inputDialog.getMainWindow().getScanTitle(),
        )

193
        # handle spectra
194
        spectra_url = self._inputDialog.getMainWindow().getSpectraUrl()
195
196
197
198
        if spectra_url is not None:
            spectra_url = spectra_url.path()
        self._spectra_url_setting = spectra_url
        # handle energy
199
        energy_url = self._inputDialog.getMainWindow().getEnergyUrl()
200
201
202
203
204
        if energy_url is not None:
            assert energy_url.is_valid()
            energy_url = energy_url.path()
        self._energy_url_setting = energy_url
        # handle configuration
205
        configuration_url = self._inputDialog.getMainWindow().getConfigurationUrl()
206
207
208
        if configuration_url is not None:
            configuration_url = configuration_url.path()
        self._configuration_url_setting = configuration_url
209
        # save settings
210
        self._dimensions_setting = self._inputDialog.getMainWindow().getDimensions()
211
        # save energy
payno's avatar
payno committed
212
213
214
        self._energy_unit_settings = str(
            self._inputDialog.getMainWindow().getEnergyUnit()
        )
215
216
        # handle extra information like I0...
        advanceHDF5Info = self._inputDialog.getAdvanceHdf5Information()
217
218
219
220
221
222
223
224
225
226
227
228
        i0_url = advanceHDF5Info.getI0Url()
        if i0_url is not None:
            self._I0_url_setting = i0_url.path()
        i1_url = advanceHDF5Info.getI1Url()
        if i1_url is not None:
            self._I1_url_setting = i1_url.path()
        i2_url = advanceHDF5Info.getI2Url()
        if i2_url is not None:
            self._I2_url_setting = i2_url.path()
        mu_ref_url = advanceHDF5Info.getMuRefUrl()
        if mu_ref_url is not None:
            self._mu_ref_url_setting = mu_ref_url.path()
229
230
231

    def sizeHint(self):
        return qt.QSize(400, 200)