ChessAnalysisPipeline 0.0.5__py3-none-any.whl → 0.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ChessAnalysisPipeline might be problematic. Click here for more details.
- CHAP/TaskManager.py +214 -0
- CHAP/common/models/integration.py +392 -249
- CHAP/common/models/map.py +350 -198
- CHAP/common/processor.py +227 -189
- CHAP/common/reader.py +52 -39
- CHAP/common/utils/fit.py +1197 -991
- CHAP/common/utils/general.py +629 -372
- CHAP/common/utils/material.py +158 -121
- CHAP/common/utils/scanparsers.py +735 -339
- CHAP/common/writer.py +31 -25
- CHAP/edd/models.py +63 -49
- CHAP/edd/processor.py +130 -109
- CHAP/edd/reader.py +1 -1
- CHAP/edd/writer.py +1 -1
- CHAP/inference/processor.py +35 -28
- CHAP/inference/reader.py +1 -1
- CHAP/inference/writer.py +1 -1
- CHAP/pipeline.py +14 -28
- CHAP/processor.py +44 -75
- CHAP/reader.py +49 -40
- CHAP/runner.py +73 -32
- CHAP/saxswaxs/processor.py +1 -1
- CHAP/saxswaxs/reader.py +1 -1
- CHAP/saxswaxs/writer.py +1 -1
- CHAP/server.py +130 -0
- CHAP/sin2psi/processor.py +1 -1
- CHAP/sin2psi/reader.py +1 -1
- CHAP/sin2psi/writer.py +1 -1
- CHAP/tomo/__init__.py +1 -4
- CHAP/tomo/models.py +53 -31
- CHAP/tomo/processor.py +1326 -900
- CHAP/tomo/reader.py +4 -2
- CHAP/tomo/writer.py +4 -2
- CHAP/writer.py +47 -41
- {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/METADATA +1 -1
- ChessAnalysisPipeline-0.0.6.dist-info/RECORD +52 -0
- ChessAnalysisPipeline-0.0.5.dist-info/RECORD +0 -50
- {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/LICENSE +0 -0
- {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/WHEEL +0 -0
- {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/entry_points.txt +0 -0
- {ChessAnalysisPipeline-0.0.5.dist-info → ChessAnalysisPipeline-0.0.6.dist-info}/top_level.txt +0 -0
CHAP/edd/processor.py
CHANGED
|
@@ -1,34 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
#-*- coding: utf-8 -*-
|
|
3
3
|
#pylint: disable=
|
|
4
|
-
|
|
4
|
+
"""
|
|
5
5
|
File : processor.py
|
|
6
6
|
Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
|
|
7
7
|
Description: Module for Processors used only by EDD experiments
|
|
8
|
-
|
|
8
|
+
"""
|
|
9
9
|
|
|
10
10
|
# system modules
|
|
11
|
-
import
|
|
11
|
+
from json import dumps
|
|
12
|
+
|
|
13
|
+
# third party modules
|
|
14
|
+
import numpy as np
|
|
12
15
|
|
|
13
16
|
# local modules
|
|
14
17
|
from CHAP.processor import Processor
|
|
15
|
-
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class MCACeriaCalibrationProcessor(Processor):
|
|
18
|
-
|
|
19
|
-
diffraction angle and linear correction parameters for MCA
|
|
20
|
-
for an EDD experimental setup.
|
|
21
|
-
|
|
21
|
+
"""A Processor using a CeO2 scan to obtain tuned values for the
|
|
22
|
+
bragg diffraction angle and linear correction parameters for MCA
|
|
23
|
+
channel energies for an EDD experimental setup.
|
|
24
|
+
"""
|
|
22
25
|
|
|
23
26
|
def _process(self, data):
|
|
24
|
-
|
|
25
|
-
the MCA channel energies.
|
|
27
|
+
"""Return tuned values for 2&theta and linear correction
|
|
28
|
+
parameters for the MCA channel energies.
|
|
26
29
|
|
|
27
|
-
:param data: input configuration for the raw data & tuning
|
|
30
|
+
:param data: input configuration for the raw data & tuning
|
|
31
|
+
procedure
|
|
28
32
|
:type data: list[dict[str,object]]
|
|
29
|
-
:return: original configuration dictionary with tuned values
|
|
33
|
+
:return: original configuration dictionary with tuned values
|
|
34
|
+
added
|
|
30
35
|
:rtype: dict[str,float]
|
|
31
|
-
|
|
36
|
+
"""
|
|
32
37
|
|
|
33
38
|
calibration_config = self.get_config(data)
|
|
34
39
|
|
|
@@ -38,22 +43,23 @@ class MCACeriaCalibrationProcessor(Processor):
|
|
|
38
43
|
calibration_config.slope_calibrated = slope
|
|
39
44
|
calibration_config.intercept_calibrated = intercept
|
|
40
45
|
|
|
41
|
-
return
|
|
46
|
+
return calibration_config.dict()
|
|
42
47
|
|
|
43
48
|
def get_config(self, data):
|
|
44
|
-
|
|
49
|
+
"""Get an instance of the configuration object needed by this
|
|
45
50
|
`Processor` from a returned value of `Reader.read`
|
|
46
51
|
|
|
47
|
-
:param data: Result of `Reader.read` where at least one item
|
|
48
|
-
value `'MCACeriaCalibrationConfig'` for the
|
|
52
|
+
:param data: Result of `Reader.read` where at least one item
|
|
53
|
+
has the value `'MCACeriaCalibrationConfig'` for the
|
|
54
|
+
`'schema'` key.
|
|
49
55
|
:type data: list[dict[str,object]]
|
|
50
|
-
:raises Exception: If a valid config object cannot be
|
|
51
|
-
`data`.
|
|
52
|
-
:return: a valid instance of a configuration object with field
|
|
53
|
-
taken from `data`.
|
|
56
|
+
:raises Exception: If a valid config object cannot be
|
|
57
|
+
constructed from `data`.
|
|
58
|
+
:return: a valid instance of a configuration object with field
|
|
59
|
+
values taken from `data`.
|
|
54
60
|
:rtype: MCACeriaCalibrationConfig
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
"""
|
|
62
|
+
# local modules
|
|
57
63
|
from CHAP.edd.models import MCACeriaCalibrationConfig
|
|
58
64
|
|
|
59
65
|
calibration_config = False
|
|
@@ -65,37 +71,39 @@ class MCACeriaCalibrationProcessor(Processor):
|
|
|
65
71
|
break
|
|
66
72
|
|
|
67
73
|
if not calibration_config:
|
|
68
|
-
raise
|
|
74
|
+
raise ValueError(
|
|
75
|
+
'No MCA ceria calibration configuration found in input data')
|
|
69
76
|
|
|
70
|
-
return
|
|
77
|
+
return MCACeriaCalibrationConfig(**calibration_config)
|
|
71
78
|
|
|
72
79
|
def calibrate(self, calibration_config):
|
|
73
|
-
|
|
74
|
-
spectrum until the computed strain is sufficiently
|
|
75
|
-
peak locations to determine linear
|
|
76
|
-
channel energies.
|
|
80
|
+
"""Iteratively calibrate 2&theta by fitting selected peaks of
|
|
81
|
+
an MCA spectrum until the computed strain is sufficiently
|
|
82
|
+
small. Use the fitted peak locations to determine linear
|
|
83
|
+
correction parameters for the MCA's channel energies.
|
|
77
84
|
|
|
78
|
-
:param calibration_config: object configuring the CeO2
|
|
79
|
-
procedure
|
|
85
|
+
:param calibration_config: object configuring the CeO2
|
|
86
|
+
calibration procedure
|
|
80
87
|
:type calibration_config: MCACeriaCalibrationConfig
|
|
81
|
-
:return: calibrated values of 2&theta and linear correction
|
|
82
|
-
for MCA channel energies : tth, slope,
|
|
88
|
+
:return: calibrated values of 2&theta and linear correction
|
|
89
|
+
parameters for MCA channel energies : tth, slope,
|
|
90
|
+
intercept
|
|
83
91
|
:rtype: float, float, float
|
|
84
|
-
|
|
92
|
+
"""
|
|
93
|
+
# third party modules
|
|
94
|
+
from scipy.constants import physical_constants
|
|
85
95
|
|
|
96
|
+
# local modules
|
|
86
97
|
from CHAP.common.utils.fit import Fit, FitMultipeak
|
|
87
|
-
import numpy as np
|
|
88
|
-
from scipy.constants import physical_constants
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
# We'll work in keV and A, not eV and m.
|
|
100
|
+
hc = 1e7 * physical_constants['Planck constant in eV/Hz'][0] \
|
|
101
|
+
* physical_constants['speed of light in vacuum'][0]
|
|
93
102
|
|
|
94
103
|
# Collect raw MCA data of interest
|
|
95
104
|
mca_data = calibration_config.mca_data()
|
|
96
|
-
mca_bin_energies =
|
|
97
|
-
|
|
98
|
-
/ calibration_config.num_bins))
|
|
105
|
+
mca_bin_energies = np.arange(0, calibration_config.num_bins) \
|
|
106
|
+
* (calibration_config.max_energy_kev/calibration_config.num_bins)
|
|
99
107
|
|
|
100
108
|
# Mask out the corrected MCA data for fitting
|
|
101
109
|
mca_mask = calibration_config.mca_mask()
|
|
@@ -103,22 +111,24 @@ class MCACeriaCalibrationProcessor(Processor):
|
|
|
103
111
|
fit_mca_intensities = mca_data[mca_mask]
|
|
104
112
|
|
|
105
113
|
# Correct raw MCA data for variable flux at different energies
|
|
106
|
-
flux_correct =
|
|
114
|
+
flux_correct = \
|
|
115
|
+
calibration_config.flux_correction_interpolation_function()
|
|
107
116
|
mca_intensity_weights = flux_correct(fit_mca_energies)
|
|
108
|
-
fit_mca_intensities = fit_mca_intensities
|
|
117
|
+
fit_mca_intensities = fit_mca_intensities/mca_intensity_weights
|
|
109
118
|
|
|
110
|
-
# Get the HKLs and lattice spacings that will be used for
|
|
119
|
+
# Get the HKLs and lattice spacings that will be used for
|
|
120
|
+
# fitting
|
|
111
121
|
tth = calibration_config.tth_initial_guess
|
|
112
122
|
fit_hkls, fit_ds = calibration_config.fit_ds()
|
|
113
123
|
c_1 = fit_hkls[:,0]**2 + fit_hkls[:,1]**2 + fit_hkls[:,2]**2
|
|
114
124
|
|
|
115
125
|
for iter_i in range(calibration_config.max_iter):
|
|
116
126
|
|
|
117
|
-
|
|
127
|
+
# Perform the uniform fit first
|
|
118
128
|
|
|
119
|
-
# Get expected peak energy locations for this iteration's
|
|
120
|
-
# value of tth
|
|
121
|
-
fit_lambda = 2.0
|
|
129
|
+
# Get expected peak energy locations for this iteration's
|
|
130
|
+
# starting value of tth
|
|
131
|
+
fit_lambda = 2.0*fit_ds*np.sin(0.5*np.radians(tth))
|
|
122
132
|
fit_E0 = hc / fit_lambda
|
|
123
133
|
|
|
124
134
|
# Run the uniform fit
|
|
@@ -130,21 +140,24 @@ class MCACeriaCalibrationProcessor(Processor):
|
|
|
130
140
|
fit_type='uniform',
|
|
131
141
|
plot=False)
|
|
132
142
|
|
|
133
|
-
# Extract values of interest from the best values for the
|
|
134
|
-
# parameters
|
|
135
|
-
uniform_fit_centers = [
|
|
143
|
+
# Extract values of interest from the best values for the
|
|
144
|
+
# uniform fit parameters
|
|
145
|
+
uniform_fit_centers = [
|
|
146
|
+
best_values[f'peak{i+1}_center']
|
|
147
|
+
for i in range(len(calibration_config.fit_hkls))]
|
|
136
148
|
# uniform_a = best_values['scale_factor']
|
|
137
149
|
# uniform_strain = np.log(
|
|
138
|
-
# (uniform_a
|
|
150
|
+
# (uniform_a
|
|
139
151
|
# / calibration_config.lattice_parameter_angstrom))
|
|
140
152
|
# uniform_tth = tth * (1.0 + uniform_strain)
|
|
141
153
|
# uniform_rel_rms_error = (np.linalg.norm(residual)
|
|
142
154
|
# / np.linalg.norm(fit_mca_intensities))
|
|
143
155
|
|
|
144
|
-
|
|
156
|
+
# Next, perform the unconstrained fit
|
|
145
157
|
|
|
146
|
-
# Use the peak locations found in the uniform fit as the
|
|
147
|
-
# guesses for peak locations in the unconstrained
|
|
158
|
+
# Use the peak locations found in the uniform fit as the
|
|
159
|
+
# initial guesses for peak locations in the unconstrained
|
|
160
|
+
# fit
|
|
148
161
|
best_fit, residual, best_values, best_errors, redchi, success = \
|
|
149
162
|
FitMultipeak.fit_multipeak(
|
|
150
163
|
fit_mca_intensities,
|
|
@@ -156,24 +169,23 @@ class MCACeriaCalibrationProcessor(Processor):
|
|
|
156
169
|
# Extract values of interest from the best values for the
|
|
157
170
|
# unconstrained fit parameters
|
|
158
171
|
unconstrained_fit_centers = np.array(
|
|
159
|
-
[best_values[f'peak{i+1}_center']
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
172
|
+
[best_values[f'peak{i+1}_center']
|
|
173
|
+
for i in range(len(calibration_config.fit_hkls))])
|
|
174
|
+
unconstrained_a = 0.5*hc*np.sqrt(c_1) \
|
|
175
|
+
/ (unconstrained_fit_centers*abs(np.sin(0.5*np.radians(tth))))
|
|
163
176
|
unconstrained_strains = np.log(
|
|
164
|
-
|
|
165
|
-
/ calibration_config.lattice_parameter_angstrom))
|
|
177
|
+
unconstrained_a/calibration_config.lattice_parameter_angstrom)
|
|
166
178
|
unconstrained_strain = np.mean(unconstrained_strains)
|
|
167
|
-
unconstrained_tth = tth * (1.0
|
|
168
|
-
unconstrained_rel_rms_error = (
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
unconstrained_tth = tth * (1.0+unconstrained_strain)
|
|
180
|
+
unconstrained_rel_rms_error = (
|
|
181
|
+
np.linalg.norm(residual)/np.linalg.norm(fit_mca_intensities))
|
|
171
182
|
|
|
172
183
|
# Update tth for the next iteration of tuning
|
|
173
184
|
prev_tth = tth
|
|
174
185
|
tth = unconstrained_tth
|
|
175
186
|
|
|
176
|
-
# Stop tuning tth at this iteration if differences are
|
|
187
|
+
# Stop tuning tth at this iteration if differences are
|
|
188
|
+
# small enough
|
|
177
189
|
if abs(tth - prev_tth) < calibration_config.tune_tth_tol:
|
|
178
190
|
break
|
|
179
191
|
|
|
@@ -187,45 +199,48 @@ class MCACeriaCalibrationProcessor(Processor):
|
|
|
187
199
|
slope = fit.best_values['slope']
|
|
188
200
|
intercept = fit.best_values['intercept']
|
|
189
201
|
|
|
190
|
-
return
|
|
202
|
+
return float(tth), float(slope), float(intercept)
|
|
203
|
+
|
|
191
204
|
|
|
192
205
|
class MCADataProcessor(Processor):
|
|
193
|
-
|
|
194
|
-
shape & metadata associated with a map
|
|
195
|
-
|
|
196
|
-
calibration.
|
|
197
|
-
|
|
206
|
+
"""A Processor to return data from an MCA, restuctured to
|
|
207
|
+
incorporate the shape & metadata associated with a map
|
|
208
|
+
configuration to which the MCA data belongs, and linearly
|
|
209
|
+
transformed according to the results of a ceria calibration.
|
|
210
|
+
"""
|
|
198
211
|
|
|
199
212
|
def _process(self, data):
|
|
200
|
-
|
|
201
|
-
calibrated MCA data collected over the map.
|
|
213
|
+
"""Process configurations for a map and MCA detector(s), and
|
|
214
|
+
return the calibrated MCA data collected over the map.
|
|
202
215
|
|
|
203
|
-
:param data: input map configuration and results of ceria
|
|
216
|
+
:param data: input map configuration and results of ceria
|
|
217
|
+
calibration
|
|
204
218
|
:type data: list[dict[str,object]]
|
|
205
219
|
:return: calibrated and flux-corrected MCA data
|
|
206
220
|
:rtype: nexusformat.nexus.NXentry
|
|
207
|
-
|
|
221
|
+
"""
|
|
208
222
|
|
|
209
223
|
map_config, calibration_config = self.get_configs(data)
|
|
210
224
|
nxroot = self.get_nxroot(map_config, calibration_config)
|
|
211
225
|
|
|
212
|
-
return
|
|
226
|
+
return nxroot
|
|
213
227
|
|
|
214
228
|
def get_configs(self, data):
|
|
215
|
-
|
|
229
|
+
"""Get instances of the configuration objects needed by this
|
|
216
230
|
`Processor` from a returned value of `Reader.read`
|
|
217
231
|
|
|
218
|
-
:param data: Result of `Reader.read` where at least one item
|
|
219
|
-
value `'MapConfig'` for the `'schema'` key, and at
|
|
220
|
-
|
|
232
|
+
:param data: Result of `Reader.read` where at least one item
|
|
233
|
+
has the value `'MapConfig'` for the `'schema'` key, and at
|
|
234
|
+
least one item has the value `'MCACeriaCalibrationConfig'`
|
|
235
|
+
for the `'schema'` key.
|
|
221
236
|
:type data: list[dict[str,object]]
|
|
222
|
-
:raises Exception: If valid config objects cannot be
|
|
223
|
-
`data`.
|
|
224
|
-
:return: valid instances of the configuration objects with
|
|
225
|
-
taken from `data`.
|
|
237
|
+
:raises Exception: If valid config objects cannot be
|
|
238
|
+
constructed from `data`.
|
|
239
|
+
:return: valid instances of the configuration objects with
|
|
240
|
+
field values taken from `data`.
|
|
226
241
|
:rtype: tuple[MapConfig, MCACeriaCalibrationConfig]
|
|
227
|
-
|
|
228
|
-
|
|
242
|
+
"""
|
|
243
|
+
# local modules
|
|
229
244
|
from CHAP.common.models.map import MapConfig
|
|
230
245
|
from CHAP.edd.models import MCACeriaCalibrationConfig
|
|
231
246
|
|
|
@@ -241,17 +256,20 @@ class MCADataProcessor(Processor):
|
|
|
241
256
|
calibration_config = item.get('data')
|
|
242
257
|
|
|
243
258
|
if not map_config:
|
|
244
|
-
raise
|
|
259
|
+
raise ValueError('No map configuration found in input data')
|
|
245
260
|
if not calibration_config:
|
|
246
|
-
raise
|
|
261
|
+
raise ValueError('No MCA ceria calibration configuration found in '
|
|
262
|
+
'input data')
|
|
247
263
|
|
|
248
|
-
return(MapConfig(**map_config),
|
|
264
|
+
return (MapConfig(**map_config),
|
|
265
|
+
MCACeriaCalibrationConfig(**calibration_config))
|
|
249
266
|
|
|
250
267
|
def get_nxroot(self, map_config, calibration_config):
|
|
251
|
-
|
|
252
|
-
MCA data will be calibrated and
|
|
253
|
-
|
|
254
|
-
|
|
268
|
+
"""Get a map of the MCA data collected by the scans in
|
|
269
|
+
`map_config`. The MCA data will be calibrated and
|
|
270
|
+
flux-corrected according to the parameters included in
|
|
271
|
+
`calibration_config`. The data will be returned along with
|
|
272
|
+
relevant metadata in the form of a NeXus structure.
|
|
255
273
|
|
|
256
274
|
:param map_config: the map configuration
|
|
257
275
|
:type map_config: MapConfig
|
|
@@ -259,16 +277,15 @@ class MCADataProcessor(Processor):
|
|
|
259
277
|
:type calibration_config: MCACeriaCalibrationConfig
|
|
260
278
|
:return: a map of the calibrated and flux-corrected MCA data
|
|
261
279
|
:rtype: nexusformat.nexus.NXroot
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
from CHAP.common import MapProcessor
|
|
265
|
-
|
|
280
|
+
"""
|
|
281
|
+
# third party modules
|
|
266
282
|
from nexusformat.nexus import (NXdata,
|
|
267
283
|
NXdetector,
|
|
268
|
-
NXentry,
|
|
269
284
|
NXinstrument,
|
|
270
285
|
NXroot)
|
|
271
|
-
|
|
286
|
+
|
|
287
|
+
# local modules
|
|
288
|
+
from CHAP.common import MapProcessor
|
|
272
289
|
|
|
273
290
|
nxroot = NXroot()
|
|
274
291
|
|
|
@@ -277,17 +294,17 @@ class MCADataProcessor(Processor):
|
|
|
277
294
|
|
|
278
295
|
nxentry.instrument = NXinstrument()
|
|
279
296
|
nxentry.instrument.detector = NXdetector()
|
|
280
|
-
nxentry.instrument.detector.calibration_configuration =
|
|
297
|
+
nxentry.instrument.detector.calibration_configuration = dumps(
|
|
298
|
+
calibration_config.dict())
|
|
281
299
|
|
|
282
300
|
nxentry.instrument.detector.data = NXdata()
|
|
283
301
|
nxdata = nxentry.instrument.detector.data
|
|
284
302
|
nxdata.raw = np.empty((*map_config.shape, calibration_config.num_bins))
|
|
285
303
|
nxdata.raw.attrs['units'] = 'counts'
|
|
286
|
-
nxdata.channel_energy =
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
+ calibration_config.intercept_calibrated)
|
|
304
|
+
nxdata.channel_energy = calibration_config.slope_calibrated \
|
|
305
|
+
* np.arange(0, calibration_config.num_bins) \
|
|
306
|
+
* (calibration_config.max_energy_kev/calibration_config.num_bins) \
|
|
307
|
+
+ calibration_config.intercept_calibrated
|
|
291
308
|
nxdata.channel_energy.attrs['units'] = 'keV'
|
|
292
309
|
|
|
293
310
|
for scans in map_config.spec_scans:
|
|
@@ -313,11 +330,15 @@ class MCADataProcessor(Processor):
|
|
|
313
330
|
nxentry.data.attrs['axes'],
|
|
314
331
|
f'{calibration_config.detector_name}_channel_energy']
|
|
315
332
|
else:
|
|
316
|
-
nxentry.data.attrs['axes'] += [
|
|
333
|
+
nxentry.data.attrs['axes'] += [
|
|
334
|
+
f'{calibration_config.detector_name}_channel_energy']
|
|
317
335
|
nxentry.data.attrs['signal'] = calibration_config.detector_name
|
|
318
336
|
|
|
319
|
-
return
|
|
337
|
+
return nxroot
|
|
338
|
+
|
|
320
339
|
|
|
321
340
|
if __name__ == '__main__':
|
|
341
|
+
# local modules
|
|
322
342
|
from CHAP.processor import main
|
|
343
|
+
|
|
323
344
|
main()
|
CHAP/edd/reader.py
CHANGED
CHAP/edd/writer.py
CHANGED
CHAP/inference/processor.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
#-*- coding: utf-8 -*-
|
|
3
|
-
#pylint: disable=
|
|
4
|
-
|
|
5
|
-
File : processor.py
|
|
6
|
-
Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
|
|
7
|
-
Description: Processor module
|
|
8
|
-
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
#-*- coding: utf-8 -*-
|
|
3
|
+
#pylint: disable=
|
|
4
|
+
"""
|
|
5
|
+
File : processor.py
|
|
6
|
+
Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
|
|
7
|
+
Description: Processor module
|
|
8
|
+
"""
|
|
9
9
|
|
|
10
10
|
# system modules
|
|
11
11
|
from time import time
|
|
@@ -13,14 +13,12 @@ from time import time
|
|
|
13
13
|
# local modules
|
|
14
14
|
from CHAP import Processor
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
class TFaaSImageProcessor(Processor):
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'''
|
|
18
|
+
"""A Processor to get predictions from TFaaS inference server."""
|
|
19
|
+
|
|
20
20
|
def process(self, data, url, model, verbose=False):
|
|
21
|
-
|
|
22
|
-
process data API
|
|
23
|
-
'''
|
|
21
|
+
"""process data API"""
|
|
24
22
|
|
|
25
23
|
t0 = time()
|
|
26
24
|
self.logger.info(f'Executing "process" with url {url} model {model}')
|
|
@@ -29,40 +27,49 @@ class TFaaSImageProcessor(Processor):
|
|
|
29
27
|
|
|
30
28
|
self.logger.info(f'Finished "process" in {time()-t0:.3f} seconds\n')
|
|
31
29
|
|
|
32
|
-
return
|
|
30
|
+
return data
|
|
33
31
|
|
|
34
32
|
def _process(self, data, url, model, verbose):
|
|
35
|
-
|
|
33
|
+
"""Print and return the input data.
|
|
36
34
|
|
|
37
|
-
:param data: Input image data, either file name or actual
|
|
35
|
+
:param data: Input image data, either file name or actual
|
|
36
|
+
image data
|
|
38
37
|
:type data: object
|
|
39
38
|
:return: `data`
|
|
40
39
|
:rtype: object
|
|
41
|
-
|
|
40
|
+
"""
|
|
41
|
+
# system modules
|
|
42
|
+
from pathlib import Path
|
|
42
43
|
|
|
44
|
+
# local modules
|
|
43
45
|
from MLaaS.tfaas_client import predictImage
|
|
44
|
-
from pathlib import Path
|
|
45
46
|
|
|
46
47
|
self.logger.info(f'input data {type(data)}')
|
|
47
48
|
if isinstance(data, str) and Path(data).is_file():
|
|
48
|
-
|
|
49
|
-
data = predictImage(url,
|
|
49
|
+
img_file = data
|
|
50
|
+
data = predictImage(url, img_file, model, verbose)
|
|
50
51
|
else:
|
|
52
|
+
# third party modules
|
|
53
|
+
from requests import Session
|
|
54
|
+
|
|
51
55
|
rdict = data[0]
|
|
52
|
-
import requests
|
|
53
56
|
img = rdict['data']
|
|
54
|
-
session =
|
|
57
|
+
session = Session()
|
|
55
58
|
rurl = url + '/predict/image'
|
|
56
|
-
payload =
|
|
57
|
-
files =
|
|
58
|
-
self.logger.info(
|
|
59
|
-
|
|
59
|
+
payload = {'model': model}
|
|
60
|
+
files = {'image': img}
|
|
61
|
+
self.logger.info(
|
|
62
|
+
f'HTTP request {rurl} with image file and {payload} payload')
|
|
63
|
+
req = session.post(rurl, files=files, data=payload)
|
|
60
64
|
data = req.content
|
|
61
65
|
data = data.decode('utf-8').replace('\n', '')
|
|
62
66
|
self.logger.info(f'HTTP response {data}')
|
|
63
67
|
|
|
64
|
-
return
|
|
68
|
+
return data
|
|
69
|
+
|
|
65
70
|
|
|
66
71
|
if __name__ == '__main__':
|
|
72
|
+
# local modules
|
|
67
73
|
from CHAP.processor import main
|
|
74
|
+
|
|
68
75
|
main()
|
CHAP/inference/reader.py
CHANGED
CHAP/inference/writer.py
CHANGED
CHAP/pipeline.py
CHANGED
|
@@ -4,21 +4,19 @@
|
|
|
4
4
|
"""
|
|
5
5
|
File : pipeline.py
|
|
6
6
|
Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
|
|
7
|
-
Description:
|
|
7
|
+
Description:
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# system modules
|
|
11
11
|
import logging
|
|
12
12
|
from time import time
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class Pipeline():
|
|
15
|
-
"""
|
|
16
|
-
Pipeline represent generic Pipeline class
|
|
17
|
-
"""
|
|
16
|
+
"""Pipeline represent generic Pipeline class"""
|
|
18
17
|
def __init__(self, items=None, kwds=None):
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
"""Pipeline class constructor
|
|
19
|
+
|
|
22
20
|
:param items: list of objects
|
|
23
21
|
:param kwds: list of method args for individual objects
|
|
24
22
|
"""
|
|
@@ -31,12 +29,10 @@ class Pipeline():
|
|
|
31
29
|
self.logger.propagate = False
|
|
32
30
|
|
|
33
31
|
def execute(self):
|
|
34
|
-
"""
|
|
35
|
-
execute API
|
|
36
|
-
"""
|
|
32
|
+
"""execute API"""
|
|
37
33
|
|
|
38
34
|
t0 = time()
|
|
39
|
-
self.logger.info(
|
|
35
|
+
self.logger.info('Executing "execute"\n')
|
|
40
36
|
|
|
41
37
|
data = None
|
|
42
38
|
for item, kwargs in zip(self.items, self.kwds):
|
|
@@ -52,33 +48,23 @@ class Pipeline():
|
|
|
52
48
|
|
|
53
49
|
self.logger.info(f'Executed "execute" in {time()-t0:.3f} seconds')
|
|
54
50
|
|
|
51
|
+
|
|
55
52
|
class PipelineObject():
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def __init__(self, reader, writer, processor, fitter):
|
|
60
|
-
"""
|
|
61
|
-
PipelineObject class constructor
|
|
62
|
-
"""
|
|
53
|
+
"""PipelineObject represent generic Pipeline class"""
|
|
54
|
+
def __init__(self, reader, writer, processor):
|
|
55
|
+
"""PipelineObject class constructor"""
|
|
63
56
|
self.reader = reader
|
|
64
57
|
self.writer = writer
|
|
65
58
|
self.processor = processor
|
|
66
59
|
|
|
67
60
|
def read(self, filename):
|
|
68
|
-
"""
|
|
69
|
-
read object API
|
|
70
|
-
"""
|
|
61
|
+
"""read object API"""
|
|
71
62
|
return self.reader.read(filename)
|
|
72
63
|
|
|
73
64
|
def write(self, data, filename):
|
|
74
|
-
"""
|
|
75
|
-
write object API
|
|
76
|
-
"""
|
|
65
|
+
"""write object API"""
|
|
77
66
|
return self.writer.write(data, filename)
|
|
78
67
|
|
|
79
68
|
def process(self, data):
|
|
80
|
-
"""
|
|
81
|
-
process object API
|
|
82
|
-
"""
|
|
69
|
+
"""process object API"""
|
|
83
70
|
return self.processor.process(data)
|
|
84
|
-
|