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