pre_edge.py 7.8 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
# 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.
#
# ###########################################################################*/
25
"""wrapper to the larch pre-edge process"""
payno's avatar
payno committed
26

payno's avatar
payno committed
27
from est.core.types import Spectrum, XASObject
payno's avatar
payno committed
28
from est.core.process.process import Process
29
30
from est.core.process.process import _NexusSpectrumDef, _NexusDatasetDef
from est.core.utils.symbol import MU_CHAR
payno's avatar
payno committed
31
32
from larch.xafs.pre_edge import pre_edge
import logging
payno's avatar
payno committed
33

payno's avatar
payno committed
34
35
36
37
38
39
40
_logger = logging.getLogger(__name__)

_DEBUG = True
if _DEBUG:
    from larch.symboltable import Group


payno's avatar
payno committed
41
42
43
44
45
46
47
48
def process_spectr_pre_edge(
    spectrum,
    configuration,
    overwrite=True,
    callbacks=None,
    output=None,
    output_dict=None,
):
payno's avatar
payno committed
49
50
    """

51
52
53
54
55
56
    :param spectrum: spectrum to process
    :type: :class:`.Spectrum`
    :param configuration: configuration of the pymca normalization
    :type: dict
    :param overwrite: False if we want to return a new Spectrum instance
    :type: bool
57
    :param callbacks: callbacks to execute.
payno's avatar
payno committed
58
59
    :param output: list to store the result, needed for pool processing
    :type: multiprocessing.manager.list
60
61
62
    :param output_dict: key is: input spectrum, value is index in the output
                        list.
    :type: dict
payno's avatar
payno committed
63
64
65
    :return: processed spectrum
    :rtype: tuple (configuration, spectrum)
    """
payno's avatar
payno committed
66
    _logger.debug("start pre_edge on spectrum (%s, %s)" % (spectrum.x, spectrum.y))
payno's avatar
payno committed
67
68
    assert isinstance(spectrum, Spectrum)
    if spectrum.energy is None or spectrum.mu is None:
payno's avatar
payno committed
69
70
71
        _logger.error(
            "Energy and or Mu is/are not specified, unable to " "compute pre edge"
        )
payno's avatar
payno committed
72
        return None, None
73
    _conf = configuration
payno's avatar
payno committed
74
75
    if "pre_edge" in _conf:
        _conf = _conf["pre_edge"]
payno's avatar
payno committed
76
    opts = {}
payno's avatar
payno committed
77
78
79
80
81
82
83
    for opt_name in (
        "z",
        "edge",
        "e0",
        "pre1",
        "pre2",
        "norm1",
84
85
86
87
        "nnorm",
        "nvict",
        "step",
        "make_flat",
payno's avatar
payno committed
88
89
90
91
92
        "norm2",
        "order",
        "leexiang",
        "tables",
        "fit_erfc",
93
        "make_flat",
payno's avatar
payno committed
94
    ):
95
96
        if opt_name in _conf:
            opts[opt_name] = _conf[opt_name]
payno's avatar
payno committed
97
98

    if _DEBUG is True:
99
100
101
        assert isinstance(
            spectrum, Group
        ), f"spectrum is expected to be an instance of {type(Group)}. Not {type(spectrum)}"
payno's avatar
payno committed
102
103
104
    if overwrite:
        _spectrum = spectrum
    else:
105
        _spectrum = Spectrum().load_frm_dict(spectrum=spectrum)
106

107
    pre_edge(_spectrum, group=_spectrum, **opts)
108
109
110
    if callbacks:
        for callback in callbacks:
            callback()
payno's avatar
payno committed
111
112
113
114
115
116
117
118
119
120
121
122

    return configuration, _spectrum


def larch_pre_edge(xas_obj):
    """

    :param xas_obj: object containing the configuration and spectra to process
    :type: Union[XASObject, dict]
    :return: spectra dict
    :rtype: XASObject
    """
payno's avatar
payno committed
123
124
    mback_obj = Larch_pre_edge(inputs={"xas_obj": xas_obj})
    return mback_obj.run()
payno's avatar
payno committed
125

payno's avatar
payno committed
126

127
class Larch_pre_edge(
128
129
130
131
132
    Process,
    name="pre_edge",
    input_names=["xas_obj"],
    output_names=["xas_obj"],
    optional_input_names=["pre_edge"],
133
):
134
    def set_properties(self, properties):
payno's avatar
payno committed
135
136
        if "_larchSettings" in properties:
            self._settings = properties["_larchSettings"]
payno's avatar
payno committed
137

138
139
    def run(self):
        xas_obj = self.inputs.xas_obj
140
        if xas_obj is None:
141
            raise ValueError("xas_obj should be provided")
142
143
        self._xas_obj = self.getXasObject(xas_obj=xas_obj)
        _xas_obj = self._xas_obj
144
145
146
        if self.inputs.pre_edge:
            self.setConfiguration(self.inputs.pre_edge)
            _xas_obj.configuration["pre_edge"] = self.inputs.pre_edge
payno's avatar
payno committed
147

148
        self.progress = 0.0
payno's avatar
payno committed
149
        self._pool_process(xas_obj=_xas_obj)
150
        self.progress = 100.0
payno's avatar
payno committed
151
152
153
        self.register_process(
            _xas_obj,
            data_keys=(
154
                _NexusDatasetDef(
Wout De Nolf's avatar
flake8    
Wout De Nolf committed
155
                    "flat", units="{}(E)".format(MU_CHAR), units_latex=r"\mu(E)"
156
                ),
157
158
159
160
161
162
163
                _NexusDatasetDef("dmude"),
                _NexusDatasetDef("edge_step_poly"),
                _NexusDatasetDef("norm"),
                _NexusDatasetDef("norm_area"),
                _NexusDatasetDef("post_edge"),
                _NexusDatasetDef("pre_edge_details"),
                _NexusDatasetDef("e0", "eV"),
164
                _NexusDatasetDef(
Wout De Nolf's avatar
flake8    
Wout De Nolf committed
165
                    "Mu", units="{}(E)".format(MU_CHAR), units_latex=r"\mu(E)"
166
                ),
167
                _NexusDatasetDef("energy", "eV"),
168
                _NexusDatasetDef(
Wout De Nolf's avatar
flake8    
Wout De Nolf committed
169
                    "mu_ref", units="{}(E)".format(MU_CHAR), units_latex=r"\mu(E)"
170
                ),
171
172
173
                _NexusDatasetDef("I0"),
                _NexusDatasetDef("I1"),
                _NexusDatasetDef("I2"),
payno's avatar
payno committed
174
            ),
175
            plots=(
payno's avatar
payno committed
176
                _NexusSpectrumDef(
payno's avatar
payno committed
177
178
179
180
                    signal="Mu",
                    axes=("energy",),
                    auxiliary_signals=None,
                    silx_style={"signal_scale_type": "linear"},
181
                    title="Mu",
Wout De Nolf's avatar
flake8    
Wout De Nolf committed
182
                    title_latex=r"\mu",
payno's avatar
payno committed
183
184
                ),
                _NexusSpectrumDef(
payno's avatar
payno committed
185
186
187
188
189
190
191
192
193
194
195
196
197
                    signal="Mu",
                    axes=("energy",),
                    auxiliary_signals=("I0", "I1", "I2"),
                    silx_style={
                        "y_axis": ("I0", "I1", "I2"),
                        "signal_scale_type": "linear",
                    },
                ),
                _NexusSpectrumDef(
                    signal="Mu",
                    axes=("energy",),
                    auxiliary_signals=("mu_ref",),
                    silx_style={"signal_scale_type": "linear"},
198
                    title="Mu vs Mu ref",
Wout De Nolf's avatar
flake8    
Wout De Nolf committed
199
                    title_latex=r"\mu \quad vs \quad \mu_{ref}",
payno's avatar
payno committed
200
201
202
203
204
205
                ),
                _NexusSpectrumDef(
                    signal="flat",
                    axes=("energy",),
                    auxiliary_signals=None,
                    silx_style={"signal_scale_type": "linear"},
206
                    title="Mu flat",
Wout De Nolf's avatar
flake8    
Wout De Nolf committed
207
                    title_latex=r"\mu_{flat}",
payno's avatar
payno committed
208
                ),
payno's avatar
payno committed
209
210
            ),
        )
211
        self.outputs.xas_obj = _xas_obj.to_dict()
payno's avatar
payno committed
212
213
214
215
        return _xas_obj

    def _pool_process(self, xas_obj):
        assert isinstance(xas_obj, XASObject)
216
217
218
219
220
221
222
223
224
        n_s = len(xas_obj.spectra.data.flat)
        for i_s, spectrum in enumerate(xas_obj.spectra):
            process_spectr_pre_edge(
                spectrum=spectrum,
                configuration=xas_obj.configuration,
                callbacks=self.callbacks,
                overwrite=True,
            )
            self.progress = i_s / n_s * 100.0
payno's avatar
payno committed
225
226
227
228
229
230

    def definition(self):
        return "pre_edge calculation"

    def program_version(self):
        import larch.version
payno's avatar
payno committed
231
232

        return larch.version.version_data()["larch"]
payno's avatar
payno committed
233

234
235
    @staticmethod
    def program_name():
payno's avatar
payno committed
236
        return "larch_pre_edge"
payno's avatar
payno committed
237

238
    __call__ = run