ChessAnalysisPipeline 0.0.12__py3-none-any.whl → 0.0.14__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/__init__.py +2 -0
- CHAP/common/__init__.py +7 -2
- CHAP/common/models/map.py +95 -70
- CHAP/common/processor.py +844 -153
- CHAP/common/reader.py +168 -131
- CHAP/common/writer.py +166 -96
- CHAP/edd/__init__.py +2 -0
- CHAP/edd/models.py +94 -48
- CHAP/edd/processor.py +625 -169
- CHAP/edd/utils.py +186 -6
- CHAP/pipeline.py +35 -3
- CHAP/runner.py +40 -13
- CHAP/tomo/models.py +18 -9
- CHAP/tomo/processor.py +1134 -902
- CHAP/utils/fit.py +98 -45
- CHAP/utils/general.py +196 -63
- CHAP/utils/scanparsers.py +403 -94
- {ChessAnalysisPipeline-0.0.12.dist-info → ChessAnalysisPipeline-0.0.14.dist-info}/METADATA +1 -1
- {ChessAnalysisPipeline-0.0.12.dist-info → ChessAnalysisPipeline-0.0.14.dist-info}/RECORD +23 -23
- {ChessAnalysisPipeline-0.0.12.dist-info → ChessAnalysisPipeline-0.0.14.dist-info}/WHEEL +1 -1
- {ChessAnalysisPipeline-0.0.12.dist-info → ChessAnalysisPipeline-0.0.14.dist-info}/LICENSE +0 -0
- {ChessAnalysisPipeline-0.0.12.dist-info → ChessAnalysisPipeline-0.0.14.dist-info}/entry_points.txt +0 -0
- {ChessAnalysisPipeline-0.0.12.dist-info → ChessAnalysisPipeline-0.0.14.dist-info}/top_level.txt +0 -0
CHAP/common/reader.py
CHANGED
|
@@ -6,144 +6,85 @@ Description: Module for Writers used in multiple experiment-specific
|
|
|
6
6
|
workflows.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
#
|
|
9
|
+
# System modules
|
|
10
10
|
from os.path import (
|
|
11
11
|
isfile,
|
|
12
12
|
splitext,
|
|
13
13
|
)
|
|
14
14
|
from sys import modules
|
|
15
|
-
from time import time
|
|
16
15
|
|
|
17
|
-
#
|
|
16
|
+
# Third party modules
|
|
17
|
+
import numpy as np
|
|
18
|
+
|
|
19
|
+
# Local modules
|
|
18
20
|
from CHAP import Reader
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
class BinaryFileReader(Reader):
|
|
22
|
-
"""Reader for binary files
|
|
24
|
+
"""Reader for binary files.
|
|
25
|
+
"""
|
|
23
26
|
def read(self, filename):
|
|
24
|
-
"""Return a content of a given file
|
|
27
|
+
"""Return a content of a given binary file.
|
|
25
28
|
|
|
26
|
-
:param filename: name of the
|
|
27
|
-
:
|
|
29
|
+
:param filename: The name of the binary file to read from.
|
|
30
|
+
:type filename: str
|
|
31
|
+
:return: The file content.
|
|
28
32
|
:rtype: binary
|
|
29
33
|
"""
|
|
30
|
-
|
|
31
34
|
with open(filename, 'rb') as file:
|
|
32
35
|
data = file.read()
|
|
33
36
|
return data
|
|
34
37
|
|
|
35
38
|
|
|
36
|
-
class
|
|
37
|
-
"""Reader for
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"""
|
|
41
|
-
the raw data as an NXentry.
|
|
39
|
+
class H5Reader(Reader):
|
|
40
|
+
"""Reader for h5 files.
|
|
41
|
+
"""
|
|
42
|
+
def read(self, filename, h5path='/', idx=None):
|
|
43
|
+
"""Return the data object stored at `h5path` in an h5-file.
|
|
42
44
|
|
|
43
|
-
:param filename: name of file
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
:type spec_config: dict, optional
|
|
51
|
-
:param detector_names: Detector prefixes to include raw data
|
|
52
|
-
for in the returned NXentry
|
|
53
|
-
:type detector_names: list[str]
|
|
54
|
-
:return: Data from the SPEC configuration provided
|
|
55
|
-
:rtype: nexusformat.nexus.NXentry
|
|
45
|
+
:param filename: The name of the h5-file to read from.
|
|
46
|
+
:type filename: str
|
|
47
|
+
:param h5path: The path to a specific location in the h5 file
|
|
48
|
+
to read data from, defaults to `'/'`
|
|
49
|
+
:type h5path: str, optional
|
|
50
|
+
:return: The object indicated by `filename` and `h5path`.
|
|
51
|
+
:rtype: object
|
|
56
52
|
"""
|
|
57
|
-
|
|
58
|
-
from
|
|
59
|
-
NXcollection,
|
|
60
|
-
NXdata,
|
|
61
|
-
NXentry,
|
|
62
|
-
NXfield,
|
|
63
|
-
)
|
|
64
|
-
import numpy as np
|
|
65
|
-
from CHAP.common.models.map import SpecConfig
|
|
66
|
-
|
|
67
|
-
if filename is not None:
|
|
68
|
-
if spec_config is not None:
|
|
69
|
-
raise RuntimeError('Specify either filename or spec_config '
|
|
70
|
-
'in common.SpecReader, not both')
|
|
71
|
-
# Read the map configuration from file
|
|
72
|
-
if not isfile(filename):
|
|
73
|
-
raise OSError(f'input file does not exist ({filename})')
|
|
74
|
-
extension = splitext(filename)[1]
|
|
75
|
-
if extension in ('.yml', '.yaml'):
|
|
76
|
-
reader = YAMLReader()
|
|
77
|
-
else:
|
|
78
|
-
raise RuntimeError('input file has a non-implemented '
|
|
79
|
-
f'extension ({filename})')
|
|
80
|
-
spec_config = reader.read(filename)
|
|
81
|
-
elif not isinstance(spec_config, dict):
|
|
82
|
-
raise RuntimeError('Invalid parameter spec_config in '
|
|
83
|
-
f'common.SpecReader ({spec_config})')
|
|
53
|
+
# Third party modules
|
|
54
|
+
from h5py import File
|
|
84
55
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
# Set up NXentry and add misc. CHESS-specific metadata
|
|
90
|
-
# as well as all spec_motors, scan_columns, and smb_pars
|
|
91
|
-
nxentry = NXentry(name=spec_config.experiment_type)
|
|
92
|
-
nxentry.spec_config = dumps(spec_config.dict())
|
|
93
|
-
nxentry.attrs['station'] = spec_config.station
|
|
94
|
-
nxentry.spec_scans = NXcollection()
|
|
95
|
-
for scans in spec_config.spec_scans:
|
|
96
|
-
nxscans = NXcollection()
|
|
97
|
-
nxentry.spec_scans[f'{scans.scanparsers[0].scan_name}'] = nxscans
|
|
98
|
-
nxscans.attrs['spec_file'] = str(scans.spec_file)
|
|
99
|
-
nxscans.attrs['scan_numbers'] = scans.scan_numbers
|
|
100
|
-
for scan_number in scans.scan_numbers:
|
|
101
|
-
scanparser = scans.get_scanparser(scan_number)
|
|
102
|
-
nxscans[scan_number] = NXcollection()
|
|
103
|
-
if hasattr(scanparser, 'spec_positioner_values'):
|
|
104
|
-
nxscans[scan_number].spec_motors = dumps(
|
|
105
|
-
{k:float(v) for k,v
|
|
106
|
-
in scanparser.spec_positioner_values.items()})
|
|
107
|
-
if hasattr(scanparser, 'spec_scan_data'):
|
|
108
|
-
nxscans[scan_number].scan_columns = dumps(
|
|
109
|
-
{k:list(v) for k,v
|
|
110
|
-
in scanparser.spec_scan_data.items() if len(v)})
|
|
111
|
-
if hasattr(scanparser, 'pars'):
|
|
112
|
-
nxscans[scan_number].smb_pars = dumps(
|
|
113
|
-
{k:v for k,v in scanparser.pars.items()})
|
|
114
|
-
if detector_names:
|
|
115
|
-
nxdata = NXdata()
|
|
116
|
-
nxscans[scan_number].data = nxdata
|
|
117
|
-
for detector_name in detector_names:
|
|
118
|
-
nxdata[detector_name] = NXfield(
|
|
119
|
-
value=scanparser.get_detector_data(detector_name))
|
|
120
|
-
|
|
121
|
-
return nxentry
|
|
56
|
+
data = File(filename, 'r')[h5path]
|
|
57
|
+
if idx is not None:
|
|
58
|
+
data = data[tuple(idx)]
|
|
59
|
+
return data
|
|
122
60
|
|
|
123
61
|
|
|
124
62
|
class MapReader(Reader):
|
|
125
|
-
"""Reader for CHESS sample maps
|
|
63
|
+
"""Reader for CHESS sample maps.
|
|
64
|
+
"""
|
|
126
65
|
def read(
|
|
127
66
|
self, filename=None, map_config=None, detector_names=[],
|
|
128
67
|
inputdir=None):
|
|
129
68
|
"""Take a map configuration dictionary and return a
|
|
130
|
-
representation of the map as
|
|
131
|
-
data group will contain the raw data
|
|
132
|
-
of the map.
|
|
69
|
+
representation of the map as a NeXus NXentry object. The
|
|
70
|
+
NXentry's default data group will contain the raw data
|
|
71
|
+
collected over the course of the map.
|
|
133
72
|
|
|
134
|
-
:param filename: name of file with the map configuration
|
|
135
|
-
read and pass onto the constructor of
|
|
136
|
-
`CHAP.common.models.map.MapConfig`
|
|
73
|
+
:param filename: The name of a file with the map configuration
|
|
74
|
+
to read and pass onto the constructor of
|
|
75
|
+
`CHAP.common.models.map.MapConfig`, defaults to `None`.
|
|
137
76
|
:type filename: str, optional
|
|
138
|
-
:param map_config: map configuration to be passed directly to
|
|
139
|
-
the constructor of `CHAP.common.models.map.MapConfig
|
|
77
|
+
:param map_config: A map configuration to be passed directly to
|
|
78
|
+
the constructor of `CHAP.common.models.map.MapConfig`,
|
|
79
|
+
defaults to `None`.
|
|
140
80
|
:type map_config: dict, optional
|
|
141
81
|
:param detector_names: Detector prefixes to include raw data
|
|
142
|
-
for in the returned NXentry
|
|
143
|
-
:type detector_names: list[str]
|
|
144
|
-
:return: Data from the map configuration
|
|
82
|
+
for in the returned NeXus NXentry object, defaults to `[]`.
|
|
83
|
+
:type detector_names: list[str], optional
|
|
84
|
+
:return: Data from the provided map configuration.
|
|
145
85
|
:rtype: nexusformat.nexus.NXentry
|
|
146
86
|
"""
|
|
87
|
+
# Third party modules
|
|
147
88
|
from json import dumps
|
|
148
89
|
from nexusformat.nexus import (
|
|
149
90
|
NXcollection,
|
|
@@ -152,7 +93,8 @@ class MapReader(Reader):
|
|
|
152
93
|
NXfield,
|
|
153
94
|
NXsample,
|
|
154
95
|
)
|
|
155
|
-
|
|
96
|
+
|
|
97
|
+
# Local modules
|
|
156
98
|
from CHAP.common.models.map import MapConfig
|
|
157
99
|
|
|
158
100
|
if filename is not None:
|
|
@@ -201,8 +143,8 @@ class MapReader(Reader):
|
|
|
201
143
|
attrs={'long_name': f'{dim.label} ({dim.units})',
|
|
202
144
|
'data_type': dim.data_type,
|
|
203
145
|
'local_name': dim.name})
|
|
204
|
-
if map_config.map_type == 'structured':
|
|
205
|
-
nxentry.data.attrs[f'{dim.label}_indices'] = i
|
|
146
|
+
# if map_config.map_type == 'structured':
|
|
147
|
+
# nxentry.data.attrs[f'{dim.label}_indices'] = i
|
|
206
148
|
|
|
207
149
|
# Create empty NXfields for all scalar data present in the
|
|
208
150
|
# provided map configuration
|
|
@@ -226,15 +168,13 @@ class MapReader(Reader):
|
|
|
226
168
|
# Create empty NXfields of appropriate shape for raw
|
|
227
169
|
# detector data
|
|
228
170
|
for detector_name in detector_names:
|
|
171
|
+
if not isinstance(detector_name, str):
|
|
172
|
+
detector_name = str(detector_name)
|
|
229
173
|
detector_data = map_config.get_detector_data(
|
|
230
174
|
detector_name, (0,) * len(map_config.shape))
|
|
231
175
|
nxentry.data[detector_name] = NXfield(value=np.zeros(
|
|
232
176
|
(*map_config.shape, *detector_data.shape)),
|
|
233
177
|
dtype=detector_data.dtype)
|
|
234
|
-
# data_shape = list(map_config.shape)+list(detector_data.shape)
|
|
235
|
-
# nxentry.data[detector_name] = NXfield(
|
|
236
|
-
# value=np.zeros(data_shape), shape=data_shape,
|
|
237
|
-
# dtype=detector_data.dtype)
|
|
238
178
|
|
|
239
179
|
# Read and fill in maps of raw data
|
|
240
180
|
if len(map_config.all_scalar_data) > 0 or len(detector_names) > 0:
|
|
@@ -243,6 +183,8 @@ class MapReader(Reader):
|
|
|
243
183
|
nxentry.data[data.label][map_index] = map_config.get_value(
|
|
244
184
|
data, map_index)
|
|
245
185
|
for detector_name in detector_names:
|
|
186
|
+
if not isinstance(detector_name, str):
|
|
187
|
+
detector_name = str(detector_name)
|
|
246
188
|
nxentry.data[detector_name][map_index] = \
|
|
247
189
|
map_config.get_detector_data(detector_name, map_index)
|
|
248
190
|
|
|
@@ -250,43 +192,134 @@ class MapReader(Reader):
|
|
|
250
192
|
|
|
251
193
|
|
|
252
194
|
class NexusReader(Reader):
|
|
253
|
-
"""Reader for NeXus files
|
|
195
|
+
"""Reader for NeXus files.
|
|
196
|
+
"""
|
|
254
197
|
def read(self, filename, nxpath='/'):
|
|
255
|
-
"""Return the NeXus object stored at `nxpath` in
|
|
256
|
-
file `filename`.
|
|
198
|
+
"""Return the NeXus object stored at `nxpath` in a NeXus file.
|
|
257
199
|
|
|
258
|
-
:param filename: name of the NeXus file to read from
|
|
200
|
+
:param filename: The name of the NeXus file to read from.
|
|
259
201
|
:type filename: str
|
|
260
|
-
:param nxpath: path to a specific
|
|
261
|
-
to read from, defaults to `'/'`
|
|
202
|
+
:param nxpath: The path to a specific location in the NeXus
|
|
203
|
+
file tree to read from, defaults to `'/'`
|
|
262
204
|
:type nxpath: str, optional
|
|
263
|
-
:raises nexusformat.nexus.NeXusError:
|
|
264
|
-
NeXus file or `nxpath` is not in
|
|
265
|
-
:return:
|
|
205
|
+
:raises nexusformat.nexus.NeXusError: If `filename` is not a
|
|
206
|
+
NeXus file or `nxpath` is not in its tree.
|
|
207
|
+
:return: The NeXus object indicated by `filename` and `nxpath`.
|
|
266
208
|
:rtype: nexusformat.nexus.NXobject
|
|
267
209
|
"""
|
|
268
|
-
|
|
210
|
+
# Third party modules
|
|
269
211
|
from nexusformat.nexus import nxload
|
|
270
212
|
|
|
271
213
|
nxobject = nxload(filename)[nxpath]
|
|
272
214
|
return nxobject
|
|
273
215
|
|
|
274
216
|
|
|
217
|
+
class SpecReader(Reader):
|
|
218
|
+
"""Reader for CHESS SPEC scans"""
|
|
219
|
+
def read(self, filename=None, spec_config=None, detector_names=[],
|
|
220
|
+
inputdir=None):
|
|
221
|
+
"""Take a SPEC configuration filename or dictionary and return
|
|
222
|
+
the raw data as a Nexus NXentry object.
|
|
223
|
+
|
|
224
|
+
:param filename: The name of file with the SPEC configuration
|
|
225
|
+
to read from to pass onto the constructor of
|
|
226
|
+
`CHAP.common.models.map.SpecConfig`, defaults to `None`.
|
|
227
|
+
:type filename: str, optional
|
|
228
|
+
:param spec_config: A SPEC configuration to be passed directly
|
|
229
|
+
to the constructor of `CHAP.common.models.map.SpecConfig`,
|
|
230
|
+
defaults to `None`.
|
|
231
|
+
:type spec_config: dict, optional
|
|
232
|
+
:param detector_names: Detector prefixes to include raw data
|
|
233
|
+
for in the returned NeXus NXentry object, defaults to `[]`.
|
|
234
|
+
:type detector_names: list[str], optional
|
|
235
|
+
:return: The data from the provided SPEC configuration.
|
|
236
|
+
:rtype: nexusformat.nexus.NXentry
|
|
237
|
+
"""
|
|
238
|
+
# Third party modules
|
|
239
|
+
from json import dumps
|
|
240
|
+
from nexusformat.nexus import (
|
|
241
|
+
NXcollection,
|
|
242
|
+
NXdata,
|
|
243
|
+
NXentry,
|
|
244
|
+
NXfield,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
# Local modules
|
|
248
|
+
from CHAP.common.models.map import SpecConfig
|
|
249
|
+
|
|
250
|
+
if filename is not None:
|
|
251
|
+
if spec_config is not None:
|
|
252
|
+
raise RuntimeError('Specify either filename or spec_config '
|
|
253
|
+
'in common.SpecReader, not both')
|
|
254
|
+
# Read the map configuration from file
|
|
255
|
+
if not isfile(filename):
|
|
256
|
+
raise OSError(f'input file does not exist ({filename})')
|
|
257
|
+
extension = splitext(filename)[1]
|
|
258
|
+
if extension in ('.yml', '.yaml'):
|
|
259
|
+
reader = YAMLReader()
|
|
260
|
+
else:
|
|
261
|
+
raise RuntimeError('input file has a non-implemented '
|
|
262
|
+
f'extension ({filename})')
|
|
263
|
+
spec_config = reader.read(filename)
|
|
264
|
+
elif not isinstance(spec_config, dict):
|
|
265
|
+
raise RuntimeError('Invalid parameter spec_config in '
|
|
266
|
+
f'common.SpecReader ({spec_config})')
|
|
267
|
+
|
|
268
|
+
# Validate the SPEC configuration provided by constructing a
|
|
269
|
+
# SpecConfig
|
|
270
|
+
spec_config = SpecConfig(**spec_config, inputdir=inputdir)
|
|
271
|
+
|
|
272
|
+
# Set up NXentry and add misc. CHESS-specific metadata
|
|
273
|
+
# as well as all spec_motors, scan_columns, and smb_pars
|
|
274
|
+
nxentry = NXentry(name=spec_config.experiment_type)
|
|
275
|
+
nxentry.spec_config = dumps(spec_config.dict())
|
|
276
|
+
nxentry.attrs['station'] = spec_config.station
|
|
277
|
+
nxentry.spec_scans = NXcollection()
|
|
278
|
+
for scans in spec_config.spec_scans:
|
|
279
|
+
nxscans = NXcollection()
|
|
280
|
+
nxentry.spec_scans[f'{scans.scanparsers[0].scan_name}'] = nxscans
|
|
281
|
+
nxscans.attrs['spec_file'] = str(scans.spec_file)
|
|
282
|
+
nxscans.attrs['scan_numbers'] = scans.scan_numbers
|
|
283
|
+
for scan_number in scans.scan_numbers:
|
|
284
|
+
scanparser = scans.get_scanparser(scan_number)
|
|
285
|
+
nxscans[scan_number] = NXcollection()
|
|
286
|
+
if hasattr(scanparser, 'spec_positioner_values'):
|
|
287
|
+
nxscans[scan_number].spec_motors = dumps(
|
|
288
|
+
{k:float(v) for k,v
|
|
289
|
+
in scanparser.spec_positioner_values.items()})
|
|
290
|
+
if hasattr(scanparser, 'spec_scan_data'):
|
|
291
|
+
nxscans[scan_number].scan_columns = dumps(
|
|
292
|
+
{k:list(v) for k,v
|
|
293
|
+
in scanparser.spec_scan_data.items() if len(v)})
|
|
294
|
+
if hasattr(scanparser, 'pars'):
|
|
295
|
+
nxscans[scan_number].smb_pars = dumps(
|
|
296
|
+
{k:v for k,v in scanparser.pars.items()})
|
|
297
|
+
if detector_names:
|
|
298
|
+
nxdata = NXdata()
|
|
299
|
+
nxscans[scan_number].data = nxdata
|
|
300
|
+
for detector_name in detector_names:
|
|
301
|
+
nxdata[detector_name] = NXfield(
|
|
302
|
+
value=scanparser.get_detector_data(detector_name))
|
|
303
|
+
|
|
304
|
+
return nxentry
|
|
305
|
+
|
|
306
|
+
|
|
275
307
|
class URLReader(Reader):
|
|
276
|
-
"""Reader for data available over HTTPS
|
|
308
|
+
"""Reader for data available over HTTPS.
|
|
309
|
+
"""
|
|
277
310
|
def read(self, url, headers={}, timeout=10):
|
|
278
311
|
"""Make an HTTPS request to the provided URL and return the
|
|
279
|
-
results.
|
|
312
|
+
results. Headers for the request are optional.
|
|
280
313
|
|
|
281
|
-
:param url:
|
|
314
|
+
:param url: The URL to read.
|
|
282
315
|
:type url: str
|
|
283
|
-
:param headers:
|
|
284
|
-
`{}`
|
|
316
|
+
:param headers: Headers to attach to the request,
|
|
317
|
+
defaults to `{}`
|
|
285
318
|
:type headers: dict, optional
|
|
286
|
-
:return:
|
|
319
|
+
:return: The content of the response.
|
|
287
320
|
:rtype: object
|
|
288
321
|
"""
|
|
289
|
-
|
|
322
|
+
# System modules
|
|
290
323
|
import requests
|
|
291
324
|
|
|
292
325
|
resp = requests.get(url, headers=headers, timeout=timeout)
|
|
@@ -298,15 +331,17 @@ class URLReader(Reader):
|
|
|
298
331
|
|
|
299
332
|
|
|
300
333
|
class YAMLReader(Reader):
|
|
301
|
-
"""Reader for YAML files
|
|
334
|
+
"""Reader for YAML files.
|
|
335
|
+
"""
|
|
302
336
|
def read(self, filename):
|
|
303
337
|
"""Return a dictionary from the contents of a yaml file.
|
|
304
338
|
|
|
305
|
-
:param filename: name of the YAML file to read from
|
|
306
|
-
:
|
|
339
|
+
:param filename: The name of the YAML file to read from.
|
|
340
|
+
:type filename: str
|
|
341
|
+
:return: The contents of the file.
|
|
307
342
|
:rtype: dict
|
|
308
343
|
"""
|
|
309
|
-
|
|
344
|
+
# Third party modules
|
|
310
345
|
import yaml
|
|
311
346
|
|
|
312
347
|
with open(filename) as file:
|
|
@@ -315,5 +350,7 @@ class YAMLReader(Reader):
|
|
|
315
350
|
|
|
316
351
|
|
|
317
352
|
if __name__ == '__main__':
|
|
353
|
+
# Local modules
|
|
318
354
|
from CHAP.reader import main
|
|
355
|
+
|
|
319
356
|
main()
|