params.py 4.69 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
31
32
33
34
35
36
37
# 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.
#
# ###########################################################################*/
"""
material for radio and sinogram normalization
"""


__authors__ = [
    "H. Payno",
]
__license__ = "MIT"
__date__ = "25/06/2021"


from silx.utils.enum import Enum as _Enum
38
39
from tomoscan.normalization import Method

40
41
42
import typing


43
44
45
46
47
48
49
50
51
class _ValueSource(_Enum):
    MONITOR = "intensity monitor"
    MANUAL_ROI = "manual ROI"
    AUTO_ROI = "automatic ROI"
    DATASET = "from dataset"
    MANUAL_SCALAR = "scalar"
    NONE = "none"


52
class _ValueCalculationFct(_Enum):
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    MEAN = "mean"
    MEDIAN = "median"


class _DatasetScope(_Enum):
    LOCAL = "local"
    GLOBAL = "global"


class _DatasetInfos:
    def __init__(self):
        self._scope = _DatasetScope.GLOBAL
        self._file_path = None
        self._data_path = None

    @property
    def scope(self) -> _DatasetScope:
        return self._scope

    @scope.setter
    def scope(self, scope: typing.Union[str, _DatasetScope]):
        self._scope = _DatasetScope.from_value(scope)

    @property
    def file_path(self):
        return self._file_path

    @file_path.setter
    def file_path(self, file_path):
        self._file_path = file_path

    @property
    def data_path(self):
        return self._data_path

    @data_path.setter
    def data_path(self, data_path: str):
        self._data_path = data_path


class _ROIInfo:
    def __init__(self, x_min=None, x_max=None, y_min=None, y_max=None):
        self.x_min = x_min
        self.x_max = x_max
        self.y_min = y_min
        self.y_max = y_max


101
class IntensityNormalizationParams:
102
    """Information regarding the intensity normalization to be done"""
103

104
    def __init__(self, method=Method.NONE, source=_ValueSource.NONE, extra_infos=None):
Henri Payno's avatar
Henri Payno committed
105
106
107
108
109
110
111
        self._method = Method.NONE
        self._source = _ValueSource.NONE
        self._extra_infos = {}

        self.method = method
        self.extra_infos = extra_infos if extra_infos is not None else {}
        self.source = source
112
113
114
115
116
117
118
119
120
121
122

    @property
    def method(self):
        return self._method

    @method.setter
    def method(self, method: typing.Union[str, Method, None]):
        if method is None:
            method = Method.NONE
        self._method = Method.from_value(method)

123
124
125
126
127
128
129
130
131
132
    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, source):
        if source is None:
            source = _ValueSource.NONE
        self._source = _ValueSource.from_value(source)

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    @property
    def extra_infos(self):
        return self._extra_infos

    @extra_infos.setter
    def extra_infos(self, extra_infos: dict):
        if not isinstance(extra_infos, dict):
            raise TypeError("extra infos is expected to be a dictionary")
        elif "method" in extra_infos:
            raise KeyError("'method' is a reserved key name")
        else:
            self._extra_infos = extra_infos

    def to_dict(self):
        _dict = self._extra_infos
148
149
        _dict["method"] = self.method.value
        _dict["source"] = self.source.value
150
151
152
153
154
155
156
157
158
159
160
161
162
        return _dict

    @staticmethod
    def from_dict(dict_):
        params = IntensityNormalizationParams()
        params.load_from_dict(dict_=dict_)
        return params

    def load_from_dict(self, dict_):
        tmp_dict = dict_.copy()
        if "method" in tmp_dict:
            self.method = tmp_dict["method"]
            del tmp_dict["method"]
163
164
165
        if "source" in tmp_dict:
            self.source = tmp_dict["source"]
            del tmp_dict["source"]
166
        self.extra_infos = tmp_dict