brukerapi 0.1.9__py3-none-any.whl → 0.2.0__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.
brukerapi/schemas.py CHANGED
@@ -1,34 +1,15 @@
1
- from typing import Dict
2
- from .jcampdx import JCAMPDX
3
- from .exceptions import *
4
- import numpy as np
5
- import re
6
1
  from copy import deepcopy
7
2
  from pathlib import Path
8
- import json
9
3
 
4
+ import numpy as np
5
+
6
+ from .exceptions import ConditionNotMet, MissingProperty
10
7
 
11
- config_paths = {
12
- 'core': Path(__file__).parents[0] / "config",
13
- 'custom': Path(__file__).parents[0] / "config"
14
- }
8
+ config_paths = {"core": Path(__file__).parents[0] / "config", "custom": Path(__file__).parents[0] / "config"}
15
9
 
16
10
  # properties required for loading of the data array for each dataset type
17
11
  REQUIRED_PROPERTIES = {
18
- "fid": [
19
- "numpy_dtype",
20
- "channels",
21
- "block_size",
22
- "acq_lenght",
23
- "scheme_id",
24
- "block_count",
25
- "encoding_space",
26
- "permute",
27
- "k_space",
28
- "encoded_dim",
29
- "shape_storage",
30
- "dim_type"
31
- ],
12
+ "fid": ["numpy_dtype", "channels", "block_size", "acq_lenght", "scheme_id", "block_count", "encoding_space", "permute", "k_space", "encoded_dim", "shape_storage", "dim_type"],
32
13
  "2dseq": [
33
14
  "pv_version",
34
15
  "numpy_dtype",
@@ -42,31 +23,17 @@ REQUIRED_PROPERTIES = {
42
23
  "num_slice_packages",
43
24
  "slope",
44
25
  "offset",
45
- "dim_type"
46
- ],
47
- "rawdata": [
48
- "numpy_dtype",
49
- "job_desc",
50
- "channels",
51
- "shape_storage"
26
+ "dim_type",
52
27
  ],
53
- "traj": [
54
- "numpy_dtype",
55
- "scheme_id",
56
- "traj_type",
57
- "shape_storage",
58
- "permute",
59
- "final"
60
- ]
28
+ "rawdata": ["numpy_dtype", "job_desc", "channels", "shape_storage"],
29
+ "traj": ["numpy_dtype", "scheme_id", "traj_type", "shape_storage", "permute", "final"],
61
30
  }
62
31
 
63
32
 
64
- class Schema():
65
- """Base class for all schemes
33
+ class Schema:
34
+ """Base class for all schemes"""
66
35
 
67
- """
68
36
  def __init__(self, dataset):
69
-
70
37
  # chceck if dataset contains all the required properties
71
38
  for property in REQUIRED_PROPERTIES[dataset.type]:
72
39
  if not hasattr(dataset, property):
@@ -86,38 +53,33 @@ class Schema():
86
53
 
87
54
  def value_filter(self, value):
88
55
  if isinstance(value, str):
89
- if value=='Yes':
56
+ if value == "Yes":
90
57
  return True
91
- elif value == 'No':
58
+ if value == "No":
92
59
  return False
93
- else:
94
- return value
95
- else:
96
60
  return value
61
+ return value
97
62
 
98
63
  def validate_conditions(self):
99
- for condition in self._meta['conditions']:
64
+ for condition in self._meta["conditions"]:
100
65
  # substitute parameters in expression string
101
66
  for sub_params in self._sub_params:
102
- condition = condition.replace(sub_params,
103
- "self._sub_params[\'%s\']" %
104
- sub_params)
105
- if not eval(condition):
106
- raise ConditionNotMet(condition)
67
+ condition_f = condition.replace(sub_params, f"self._sub_params['{sub_params}']")
68
+ if not eval(condition_f):
69
+ raise ConditionNotMet(condition_f)
107
70
 
108
71
  def _get_ra_k_space_info(self, layouts, slice_full):
109
-
110
72
  k_space = []
111
73
  k_space_offset = []
112
74
 
113
- for slc_, size_ in zip(slice_full, layouts['k_space']):
75
+ for slc_, size_ in zip(slice_full, layouts["k_space"]):
114
76
  if isinstance(slc_, slice):
115
77
  start = slc_.start if slc_.start else 0
116
78
  stop = slc_.stop if slc_.stop else size_
117
79
  elif isinstance(slc_, int):
118
80
  start = slc_
119
81
  stop = slc_ + 1
120
- k_space.append(stop-start)
82
+ k_space.append(stop - start)
121
83
  k_space_offset.append(start)
122
84
  return tuple(k_space), np.array(k_space_offset)
123
85
 
@@ -138,22 +100,21 @@ class SchemaFid(Schema):
138
100
  :return: layouts: dict
139
101
  """
140
102
 
141
- layouts = {'storage': (self._dataset.block_size,) + (self._dataset.block_count,)}
142
- layouts['encoding_space'] = self._dataset.encoding_space
143
- layouts['permute'] = self._dataset.permute
144
- layouts['encoding_permuted'] = tuple(np.array(layouts['encoding_space'])[np.array(layouts['permute'])])
145
- layouts['inverse_permute'] = self.permutation_inverse(layouts['permute'])
146
- layouts['k_space'] = self._dataset.k_space
103
+ layouts = {"storage": (self._dataset.block_size,) + (self._dataset.block_count,)}
104
+ layouts["encoding_space"] = self._dataset.encoding_space
105
+ layouts["permute"] = self._dataset.permute
106
+ layouts["encoding_permuted"] = tuple(np.array(layouts["encoding_space"])[np.array(layouts["permute"])])
107
+ layouts["inverse_permute"] = self.permutation_inverse(layouts["permute"])
108
+ layouts["k_space"] = self._dataset.k_space
147
109
 
148
110
  if "EPI" in self._dataset.scheme_id:
149
- layouts['acquisition_position'] = (self._dataset.block_size - self._dataset.acq_lenght, self._dataset.acq_lenght)
111
+ layouts["acquisition_position"] = (self._dataset.block_size - self._dataset.acq_lenght, self._dataset.acq_lenght)
150
112
  else:
151
- layouts['acquisition_position'] = (0, self._dataset.acq_lenght)
113
+ layouts["acquisition_position"] = (0, self._dataset.acq_lenght)
152
114
 
153
115
  return layouts
154
116
 
155
117
  def deserialize(self, data, layouts):
156
-
157
118
  data = self._acquisition_trim(data, layouts)
158
119
 
159
120
  data = data[0::2, ...] + 1j * data[1::2, ...]
@@ -168,44 +129,41 @@ class SchemaFid(Schema):
168
129
  data = self._permute_to_kspace(data, layouts)
169
130
 
170
131
  # Typically for RARE, or EPI
171
- data = self._reorder_fid_lines(data, dir='FW')
132
+ data = self._reorder_fid_lines(data, dir="FW")
172
133
 
173
- if 'EPI' in self._dataset.scheme_id:
134
+ if "EPI" in self._dataset.scheme_id:
174
135
  data = self._mirror_odd_lines(data)
175
136
 
176
137
  return data
177
138
 
178
139
  def _acquisition_trim(self, data, layouts):
140
+ acquisition_offset = layouts["acquisition_position"][0]
141
+ acquisition_length = layouts["acquisition_position"][1]
142
+ block_length = self.layouts["storage"][0]
179
143
 
180
- acquisition_offset = layouts['acquisition_position'][0]
181
- acquisition_length = layouts['acquisition_position'][1]
182
- block_length = self.layouts['storage'][0]
183
-
184
- if acquisition_offset>0:
144
+ if acquisition_offset > 0:
185
145
  # trim on channel level acquisition
186
- blocks = layouts['storage'][-1]
146
+ blocks = layouts["storage"][-1]
187
147
  channels = self._dataset.channels
188
- acquisition_offset=acquisition_offset//channels
148
+ acquisition_offset = acquisition_offset // channels
189
149
  acquisition_length = acquisition_length // channels
190
- data = np.reshape(data, (-1, channels, blocks), order='F')
191
- return np.reshape(data[acquisition_offset:acquisition_offset+acquisition_length,:,:],(acquisition_length * channels, blocks), order='F')
192
- else:
193
- # trim on acq level
194
- if acquisition_length != block_length:
195
- return data[0:acquisition_length,:]
196
- else:
197
- return data
150
+ data = np.reshape(data, (-1, channels, blocks), order="F")
151
+ return np.reshape(data[acquisition_offset : acquisition_offset + acquisition_length, :, :], (acquisition_length * channels, blocks), order="F")
152
+ # trim on acq level
153
+ if acquisition_length != block_length:
154
+ return data[0:acquisition_length, :]
155
+ return data
198
156
 
199
157
  def _acquisitions_to_encode(self, data, layouts):
200
- return np.reshape(data, layouts['encoding_space'], order='F')
158
+ return np.reshape(data, layouts["encoding_space"], order="F")
201
159
 
202
160
  def _encode_to_permute(self, data, layouts):
203
- return np.transpose(data, layouts['permute'])
161
+ return np.transpose(data, layouts["permute"])
204
162
 
205
163
  def _permute_to_kspace(self, data, layouts):
206
- return np.reshape(data, layouts['k_space'], order='F')
164
+ return np.reshape(data, layouts["k_space"], order="F")
207
165
 
208
- def _reorder_fid_lines(self,data, dir='FW'):
166
+ def _reorder_fid_lines(self, data, dir="FW"):
209
167
  """
210
168
  Function to sort phase encoding lines using PVM_EncSteps1
211
169
  :param data ndarray in k-space layout:
@@ -215,27 +173,26 @@ class SchemaFid(Schema):
215
173
 
216
174
  # Create local copies of variables
217
175
  try:
218
- PVM_EncSteps1 = self._dataset['PVM_EncSteps1'].value
176
+ PVM_EncSteps1 = self._dataset["PVM_EncSteps1"].value
219
177
  except KeyError:
220
178
  return data
221
179
 
222
180
  # Order encoding steps for sorting
223
181
  PVM_EncSteps1_sorted = np.argsort(PVM_EncSteps1)
224
182
 
225
- if dir == 'BW':
183
+ if dir == "BW":
226
184
  PVM_EncSteps1_sorted = self.permutation_inverse(PVM_EncSteps1_sorted)
227
185
 
228
-
229
- if np.array_equal(PVM_EncSteps1_sorted,PVM_EncSteps1):
186
+ if np.array_equal(PVM_EncSteps1_sorted, PVM_EncSteps1):
230
187
  return data
231
188
 
232
189
  for index in np.ndindex(data.shape[2:]):
233
- index = list(index)
234
- index.insert(0,slice(0,data.shape[1]))
235
- index.insert(0,slice(0, data.shape[0]))
236
- index = tuple(index)
237
- tmp = data[index]
238
- data[index] = tmp[:,PVM_EncSteps1_sorted]
190
+ index_f = list(index)
191
+ index_f.insert(0, slice(0, data.shape[1]))
192
+ index_f.insert(0, slice(0, data.shape[0]))
193
+ index_f = tuple(index_f)
194
+ tmp = data[index_f]
195
+ data[index_f] = tmp[:, PVM_EncSteps1_sorted]
239
196
 
240
197
  return data
241
198
 
@@ -245,84 +202,80 @@ class SchemaFid(Schema):
245
202
 
246
203
  for index in np.ndindex(data.shape[2:]):
247
204
  index_odd = list(index)
248
- index_odd.insert(0,slice(1,data.shape[1],2))
249
- index_odd.insert(0,slice(0, data.shape[0]))
205
+ index_odd.insert(0, slice(1, data.shape[1], 2))
206
+ index_odd.insert(0, slice(0, data.shape[0]))
250
207
  index_odd = tuple(index_odd)
251
208
  tmp = data[index_odd]
252
- data[index_odd] = tmp[::-1,:]
209
+ data[index_odd] = tmp[::-1, :]
253
210
  return data
254
211
 
255
212
  def serialize(self, data, layouts):
256
-
257
- if 'EPI' in self._dataset.scheme_id:
213
+ if "EPI" in self._dataset.scheme_id:
258
214
  data = self._mirror_odd_lines(data)
259
215
 
260
- data = self._reorder_fid_lines(data, dir='BW')
216
+ data = self._reorder_fid_lines(data, dir="BW")
261
217
 
262
- data = np.reshape(data, layouts['encoding_permuted'], order='F')
218
+ data = np.reshape(data, layouts["encoding_permuted"], order="F")
263
219
 
264
- data = np.transpose(data, layouts['inverse_permute'])
220
+ data = np.transpose(data, layouts["inverse_permute"])
265
221
 
266
- data = np.reshape(data, (layouts['acquisition_position'][1]//2, layouts['storage'][1]), order='F')
222
+ data = np.reshape(data, (layouts["acquisition_position"][1] // 2, layouts["storage"][1]), order="F")
267
223
 
268
- data_ = np.zeros(layouts['storage'], dtype=self._dataset.numpy_dtype, order='F')
224
+ data_ = np.zeros(layouts["storage"], dtype=self._dataset.numpy_dtype, order="F")
269
225
 
270
- if layouts['acquisition_position'][0]>0:
271
- channels = layouts['k_space'][self._dataset.dim_type.index('channel')]
272
- data = np.reshape(data, (-1,channels, data.shape[-1]),order='F')
273
- data_ = np.reshape(data_, (-1,channels, data_.shape[-1]),order='F')
274
- data_[layouts['acquisition_position'][0]//channels::2,:,:] = data.real
275
- data_[layouts['acquisition_position'][0]//channels+1::2,:,:] = data.imag
276
- data = np.reshape(data, (-1, data.shape[-1]),order='F')
277
- data_ = np.reshape(data_, (-1, data_.shape[-1]),order='F')
278
- elif layouts['acquisition_position'][1] != layouts['storage'][0]:
279
- data_[0:layouts['acquisition_position'][1]:2,:] = data.real
280
- data_[1:layouts['acquisition_position'][1]+1:2,:] = data.imag
226
+ if layouts["acquisition_position"][0] > 0:
227
+ channels = layouts["k_space"][self._dataset.dim_type.index("channel")]
228
+ data = np.reshape(data, (-1, channels, data.shape[-1]), order="F")
229
+ data_ = np.reshape(data_, (-1, channels, data_.shape[-1]), order="F")
230
+ data_[layouts["acquisition_position"][0] // channels :: 2, :, :] = data.real
231
+ data_[layouts["acquisition_position"][0] // channels + 1 :: 2, :, :] = data.imag
232
+ data = np.reshape(data, (-1, data.shape[-1]), order="F")
233
+ data_ = np.reshape(data_, (-1, data_.shape[-1]), order="F")
234
+ elif layouts["acquisition_position"][1] != layouts["storage"][0]:
235
+ data_[0 : layouts["acquisition_position"][1] : 2, :] = data.real
236
+ data_[1 : layouts["acquisition_position"][1] + 1 : 2, :] = data.imag
281
237
  else:
282
- data_[0::2,:] = data.real
283
- data_[1::2,:] = data.imag
238
+ data_[0::2, :] = data.real
239
+ data_[1::2, :] = data.imag
284
240
 
285
241
  return data_
286
242
 
287
243
  def ra(self, slice_):
288
-
289
244
  layouts, layouts_ra = self.get_ra_layouts(slice_)
290
245
 
291
246
  """
292
247
  random access
293
248
  """
294
- array_ra = np.zeros(layouts_ra['storage'], dtype=self.numpy_dtype)
295
- fp = np.memmap(self._dataset.path, dtype=self.numpy_dtype, mode='r',
296
- shape=layouts['storage'], order='F')
249
+ array_ra = np.zeros(layouts_ra["storage"], dtype=self.numpy_dtype)
250
+ fp = np.memmap(self._dataset.path, dtype=self.numpy_dtype, mode="r", shape=layouts["storage"], order="F")
297
251
 
298
- for index_ra in np.ndindex(layouts_ra['k_space'][1:]):
252
+ for index_ra in np.ndindex(layouts_ra["k_space"][1:]):
299
253
  # index of line in the original k_space
300
- index_full = tuple(i + o for i, o in zip(index_ra, layouts_ra['k_space_offset'][1:]))
301
-
254
+ index_full = tuple(i + o for i, o in zip(index_ra, layouts_ra["k_space_offset"][1:]))
255
+ index_ra_f = index_ra
302
256
  # index of line in the subarray
303
257
  # index_full = self.index_to_data(layouts, (0,) + index_full)
304
258
  try:
305
259
  index_full = self.index_to_data(layouts, (0,) + index_full)
306
- except:
260
+ except IndexError:
307
261
  print(index_full)
308
262
  index_full = self.index_to_data(layouts, (0,) + index_full)
309
263
 
310
264
  # index of line in the subarray
311
265
  # index_ra = self.index_to_data(layouts_ra, (0,)+index_ra)
312
266
  try:
313
- index_ra = self.index_to_data(layouts_ra, (0,)+index_ra)
314
- except:
267
+ index_ra_f = self.index_to_data(layouts_ra, (0,) + index_ra)
268
+ except IndexError:
315
269
  print(index_ra)
316
- index_ra = self.index_to_data(layouts_ra, (0,) + index_ra)
317
-
270
+ index_ra_f = self.index_to_data(layouts_ra, (0,) + index_ra)
318
271
 
319
272
  try:
320
- array_ra[index_ra] = np.array(fp[index_full])
321
- except:
273
+ array_ra[index_ra_f] = np.array(fp[index_full])
274
+ except IndexError:
322
275
  print(index_full)
323
276
 
324
- layouts_ra['k_space'] = (layouts_ra['k_space'][0]//2,)+layouts_ra['k_space'][1:]
325
- layouts_ra['encoding_space'] = (layouts_ra['encoding_space'][0]//2,)+layouts_ra['encoding_space'][1:]
277
+ layouts_ra["k_space"] = (layouts_ra["k_space"][0] // 2,) + layouts_ra["k_space"][1:]
278
+ layouts_ra["encoding_space"] = (layouts_ra["encoding_space"][0] // 2,) + layouts_ra["encoding_space"][1:]
326
279
 
327
280
  array_ra = self.reshape_fw(array_ra, layouts_ra)
328
281
 
@@ -332,28 +285,26 @@ class SchemaFid(Schema):
332
285
 
333
286
  def get_ra_layouts(self, slice_):
334
287
  layouts = deepcopy(self.layouts)
335
- layouts['k_space'] = (layouts['k_space'][0]*2,)+layouts['k_space'][1:]
336
- layouts['encoding_space'] = (layouts['encoding_space'][0]*2,)+layouts['encoding_space'][1:]
337
- layouts['inverse_permute'] = tuple(self.permutation_inverse(layouts['permute']))
338
- layouts['encoding_permute'] = tuple(layouts['encoding_space'][i] for i in layouts['permute'])
339
- layouts['channel_index'] = self.dim_type.index('channel')
340
- layouts['channels'] = layouts['k_space'][layouts['channel_index']]
341
- layouts['acquisition_position_ch'] = (layouts['acquisition_position'][0]//layouts['channels'],
342
- layouts['acquisition_position'][1]//layouts['channels'])
343
- layouts['storage_clear'] = (layouts['acquisition_position'][1], layouts['storage'][1])
344
- layouts['storage_clear_ch'] = (layouts['storage_clear'][0]//layouts['channels'], layouts['channels'],
345
- layouts['storage'][1])
346
- layouts['storage_ch'] = (layouts['storage'][0]//layouts['channels'], layouts['channels'], layouts['storage'][1])
288
+ layouts["k_space"] = (layouts["k_space"][0] * 2,) + layouts["k_space"][1:]
289
+ layouts["encoding_space"] = (layouts["encoding_space"][0] * 2,) + layouts["encoding_space"][1:]
290
+ layouts["inverse_permute"] = tuple(self.permutation_inverse(layouts["permute"]))
291
+ layouts["encoding_permute"] = tuple(layouts["encoding_space"][i] for i in layouts["permute"])
292
+ layouts["channel_index"] = self.dim_type.index("channel")
293
+ layouts["channels"] = layouts["k_space"][layouts["channel_index"]]
294
+ layouts["acquisition_position_ch"] = (layouts["acquisition_position"][0] // layouts["channels"], layouts["acquisition_position"][1] // layouts["channels"])
295
+ layouts["storage_clear"] = (layouts["acquisition_position"][1], layouts["storage"][1])
296
+ layouts["storage_clear_ch"] = (layouts["storage_clear"][0] // layouts["channels"], layouts["channels"], layouts["storage"][1])
297
+ layouts["storage_ch"] = (layouts["storage"][0] // layouts["channels"], layouts["channels"], layouts["storage"][1])
347
298
 
348
299
  layouts_ra = deepcopy(layouts)
349
300
 
350
- layouts_ra['k_space'], layouts_ra['k_space_offset'] = self._get_ra_k_space_info(layouts, slice_)
351
- layouts_ra['channels'] = layouts_ra['k_space'][layouts_ra['channel_index']]
352
- layouts_ra['acquisition_position'] = (0,self.get_acquisition_length(channels=layouts_ra['channels'])) # delete offset
301
+ layouts_ra["k_space"], layouts_ra["k_space_offset"] = self._get_ra_k_space_info(layouts, slice_)
302
+ layouts_ra["channels"] = layouts_ra["k_space"][layouts_ra["channel_index"]]
303
+ layouts_ra["acquisition_position"] = (0, self.get_acquisition_length(channels=layouts_ra["channels"])) # delete offset
353
304
  # delete offset
354
305
 
355
- layouts_ra['encoding_space'], layouts_ra['storage'] = self._get_e_ra(layouts, layouts_ra)
356
- layouts_ra['encoding_permute'] = tuple(layouts_ra['encoding_space'][i] for i in layouts['permute'])
306
+ layouts_ra["encoding_space"], layouts_ra["storage"] = self._get_e_ra(layouts, layouts_ra)
307
+ layouts_ra["encoding_permute"] = tuple(layouts_ra["encoding_space"][i] for i in layouts["permute"])
357
308
 
358
309
  return layouts, layouts_ra
359
310
 
@@ -364,54 +315,49 @@ class SchemaFid(Schema):
364
315
 
365
316
  def encode_extrema_update(self, min_enc_index, max_enc_index, enc_index):
366
317
  for i in range(len(min_enc_index)):
367
- if enc_index[i] < min_enc_index[i]:
368
- min_enc_index[i] = enc_index[i]
369
- if enc_index[i] > max_enc_index[i]:
370
- max_enc_index[i] = enc_index[i]
318
+ min_enc_index[i] = min(min_enc_index[i], enc_index[i])
319
+ max_enc_index[i] = max(max_enc_index[i], enc_index[i])
371
320
 
372
321
  def index_to_data(self, layout, index):
373
-
374
322
  # kspace to linear
375
- channel = index[layout['channel_index']]+1
376
- index = np.ravel_multi_index(index, layout['k_space'], order='F')
323
+ index = np.ravel_multi_index(index, layout["k_space"], order="F")
377
324
 
378
325
  # linear to encoding permuted
379
- index = np.unravel_index(index, layout['encoding_permute'], order='F')
380
- #permute
381
- index = tuple(index[i] for i in layout['inverse_permute'])
326
+ index = np.unravel_index(index, layout["encoding_permute"], order="F")
327
+ # permute
328
+ index = tuple(index[i] for i in layout["inverse_permute"])
382
329
  # encoding space to linear
383
- index = np.ravel_multi_index(index, layout['encoding_space'], order='F')
384
- if layout['acquisition_position'][0]>0:
385
- index = np.unravel_index(index, layout['storage_clear_ch'], order='F')
386
- index = (index[0] + layout['acquisition_position_ch'][0],)+index[1:]
387
- index = np.ravel_multi_index(index, layout['storage_ch'], order='F')
388
- elif layout['acquisition_position'][1] != layout['storage'][0]:
389
- index = np.unravel_index(index, layout['storage_clear'], order='F')
390
- index = np.ravel_multi_index(index, layout['storage'], order='F')
330
+ index = np.ravel_multi_index(index, layout["encoding_space"], order="F")
331
+ if layout["acquisition_position"][0] > 0:
332
+ index = np.unravel_index(index, layout["storage_clear_ch"], order="F")
333
+ index = (index[0] + layout["acquisition_position_ch"][0],) + index[1:]
334
+ index = np.ravel_multi_index(index, layout["storage_ch"], order="F")
335
+ elif layout["acquisition_position"][1] != layout["storage"][0]:
336
+ index = np.unravel_index(index, layout["storage_clear"], order="F")
337
+ index = np.ravel_multi_index(index, layout["storage"], order="F")
391
338
 
392
- index = np.unravel_index(index, layout['storage'], order='F')
339
+ index = np.unravel_index(index, layout["storage"], order="F")
393
340
 
394
- index = (slice(index[0], index[0]+layout['k_space'][0]),index[1])
341
+ index = (slice(index[0], index[0] + layout["k_space"][0]), index[1])
395
342
 
396
343
  return index
397
344
 
398
345
  def _get_e_ra(self, layout_full, layout_ra):
399
- min_enc_index, max_enc_index = self._extrema_init(layout_full['encoding_space'][1:])
346
+ min_enc_index, max_enc_index = self._extrema_init(layout_full["encoding_space"][1:])
400
347
  storage_ra = []
401
- for index_ra in np.ndindex(layout_ra['k_space'][1:]):
402
- index_full = (0,)+tuple(i + o for i, o in zip(index_ra, layout_ra['k_space_offset'][1:]))
403
- channel = index_full[layout_full['channel_index']]+1
348
+ for index_ra in np.ndindex(layout_ra["k_space"][1:]):
349
+ index_full = (0,) + tuple(i + o for i, o in zip(index_ra, layout_ra["k_space_offset"][1:]))
404
350
 
405
351
  """
406
352
  index_k_to_encode
407
353
  """
408
354
 
409
- index_full = np.ravel_multi_index(index_full, layout_full['k_space'], order='F')
355
+ index_full = np.ravel_multi_index(index_full, layout_full["k_space"], order="F")
410
356
 
411
357
  # linear to encoding permuted
412
- index_full = np.unravel_index(index_full, layout_full['encoding_permute'], order='F')
358
+ index_full = np.unravel_index(index_full, layout_full["encoding_permute"], order="F")
413
359
  # permute
414
- index_full = tuple(index_full[i] for i in layout_full['inverse_permute'])
360
+ index_full = tuple(index_full[i] for i in layout_full["inverse_permute"])
415
361
 
416
362
  """
417
363
  Update encoding space extrema
@@ -421,104 +367,107 @@ class SchemaFid(Schema):
421
367
  """
422
368
  index_encode_to_data
423
369
  """
424
- index_full = np.ravel_multi_index(index_full, layout_full['encoding_space'], order='F')
425
- index_full = np.unravel_index(index_full, layout_full['storage_clear'], order='F')
426
- if not index_full[1] in storage_ra:
370
+ index_full = np.ravel_multi_index(index_full, layout_full["encoding_space"], order="F")
371
+ index_full = np.unravel_index(index_full, layout_full["storage_clear"], order="F")
372
+ if index_full[1] not in storage_ra:
427
373
  storage_ra.append(index_full[1])
428
374
 
429
375
  encoding_space_ra = max_enc_index - min_enc_index + 1
430
- encoding_space_ra = (layout_full['encoding_space'][0],) + tuple(encoding_space_ra)
376
+ encoding_space_ra = (layout_full["encoding_space"][0],) + tuple(encoding_space_ra)
431
377
 
432
- storage_ra = (self.get_acquisition_length(channels=layout_ra['channels']), len(storage_ra))
378
+ storage_ra = (self.get_acquisition_length(channels=layout_ra["channels"]), len(storage_ra))
433
379
 
434
380
  return encoding_space_ra, storage_ra
435
381
 
436
382
  def index_k_to_encode(self, layout, index):
437
- index = np.ravel_multi_index(index, layout['k_space'], order='F')
383
+ index = np.ravel_multi_index(index, layout["k_space"], order="F")
438
384
  # linear to encoding permuted
439
- index = np.unravel_index(index, layout['encoding_permute'], order='F')
440
- #permute
441
- index = tuple(index[i] for i in layout['inverse_permute'])
385
+ index = np.unravel_index(index, layout["encoding_permute"], order="F")
386
+ # permute
387
+ index = tuple(index[i] for i in layout["inverse_permute"])
442
388
  return index
443
389
 
444
390
  def index_encode_to_data(self, layout, index):
445
- channel = index[layout['channel_index']]+1
391
+ channel = index[layout["channel_index"]] + 1
446
392
 
447
- index = np.ravel_multi_index(index, layout['encoding_space'], order='F')
448
- index = np.unravel_index(index, layout['storage'], order='F')
393
+ index = np.ravel_multi_index(index, layout["encoding_space"], order="F")
394
+ index = np.unravel_index(index, layout["storage"], order="F")
449
395
 
450
- if layout['acquisition_position'][0]>0:
451
- first = index[0] + (layout['acquisition_position'][0]// layout['channels']) * channel
396
+ if layout["acquisition_position"][0] > 0:
397
+ first = index[0] + (layout["acquisition_position"][0] // layout["channels"]) * channel
452
398
  else:
453
399
  first = index[0]
454
- index = (slice(first,first+layout['k_space'][0]),index[1])
400
+ index = (slice(first, first + layout["k_space"][0]), index[1])
455
401
  return index
456
402
 
457
403
 
458
404
  class SchemaTraj(Schema):
459
-
460
405
  @property
461
406
  def layouts(self):
462
-
463
407
  layouts = {}
464
408
 
465
- layouts['storage'] = self._dataset.shape_storage
466
- layouts['final'] = self._dataset.final
467
- layouts['permute'] = self._dataset.permute
409
+ layouts["storage"] = self._dataset.shape_storage
410
+ layouts["final"] = self._dataset.final
411
+ layouts["permute"] = self._dataset.permute
468
412
 
469
413
  return layouts
470
414
 
471
415
  def deserialize(self, data, layouts):
472
- data = np.transpose(data, layouts['permute'])
473
- return np.reshape(data, layouts['final'], order='F')
416
+ data = np.transpose(data, layouts["permute"])
417
+ return np.reshape(data, layouts["final"], order="F")
474
418
 
475
419
  def serialize(self, data, layouts):
476
- data = np.transpose(data, layouts['traj_permute'])
477
- return np.reshape(data, layouts['traj'], order='F')
420
+ data = np.transpose(data, layouts["traj_permute"])
421
+ return np.reshape(data, layouts["traj"], order="F")
478
422
 
479
423
 
480
424
  class SchemaRawdata(Schema):
481
-
482
425
  @property
483
426
  def layouts(self):
484
- layouts={}
485
- layouts['raw']=(int(self._dataset.job_desc[0]/2), self._dataset.channels , int(self._dataset.job_desc[3]))
486
- layouts['shape_storage'] = (2, int(self._dataset.job_desc[0]/2), self._dataset.channels , int(self._dataset.job_desc[
487
- 3]))
488
- layouts['final'] = layouts['raw']
427
+ layouts = {}
428
+ layouts["raw"] = (int(self._dataset.job_desc[0] / 2), self._dataset.channels, int(self._dataset.job_desc[3]))
429
+ layouts["shape_storage"] = (int(self._dataset.job_desc[0]), self._dataset.channels, int(self._dataset.job_desc[3]))
430
+ layouts["final"] = layouts["raw"]
489
431
  return layouts
490
432
 
491
433
  def deserialize(self, data, layouts):
492
- return data[0::2,...] + 1j * data[1::2,...]
434
+ return data[0::2, ...] + 1j * data[1::2, ...]
435
+
436
+ def serialize(self, data, layouts):
437
+ # storage array
438
+ data_ = np.zeros(layouts["shape_storage"], dtype=self._dataset.numpy_dtype, order="F")
439
+
440
+ # interlace real and imag along first axis
441
+ data_[0::2, ...] = data.real
442
+ data_[1::2, ...] = data.imag
493
443
 
494
- def seralize(self, data, layouts):
495
- data_ = np.zeros(layouts['shape_storage'], dtype=self.numpy_dtype, order='F')
496
- data_[0,...] = data.real
497
- data_[1, ...] = data.imag
498
444
  return data_
499
445
 
500
446
 
501
- class SchemaSer(Schema):
447
+ # Compatibility alias for previous misspelling:
448
+ SchemaRawdata.seralize = SchemaRawdata.serialize
449
+
502
450
 
451
+ class SchemaSer(Schema):
503
452
  @property
504
453
  def layouts(self):
505
454
  if self._layouts is not None:
506
455
  return self._layouts
507
456
 
508
- PVM_SpecMatrix = self._dataset.get_value('PVM_SpecMatrix')
509
- PVM_Matrix = self._dataset.get_value('PVM_Matrix')
510
- PVM_EncNReceivers = self._dataset.get_value('PVM_EncNReceivers')
511
- layouts={}
512
- layouts['raw']=(PVM_SpecMatrix,PVM_EncNReceivers , PVM_Matrix[0], PVM_Matrix[1])
457
+ PVM_SpecMatrix = self._dataset.get_value("PVM_SpecMatrix")
458
+ PVM_Matrix = self._dataset.get_value("PVM_Matrix")
459
+ PVM_EncNReceivers = self._dataset.get_value("PVM_EncNReceivers")
460
+ layouts = {}
461
+ layouts["raw"] = (PVM_SpecMatrix, PVM_EncNReceivers, PVM_Matrix[0], PVM_Matrix[1])
513
462
  return layouts
514
463
 
515
464
  def deserialize(self, data):
516
465
  data = data[0::2] + 1j * data[1::2]
517
- data = np.reshape(data, self.layouts['raw'], order='F')
466
+ data = np.reshape(data, self.layouts["raw"], order="F")
518
467
  return data
519
468
 
520
469
  def serialize(self, data):
521
- raise NotImplemented
470
+ raise NotImplementedError
522
471
 
523
472
 
524
473
  class Schema2dseq(Schema):
@@ -534,29 +483,28 @@ class Schema2dseq(Schema):
534
483
  @property
535
484
  def layouts(self):
536
485
  return {
537
- "shape_fg" : self._dataset.shape_fg,
538
- "shape_frames" : self._dataset.shape_frames,
539
- "shape_block" : self._dataset.shape_block,
540
- "shape_storage" : self._dataset.shape_storage,
541
- "shape_final": self._dataset.shape_final
486
+ "shape_fg": self._dataset.shape_fg,
487
+ "shape_frames": self._dataset.shape_frames,
488
+ "shape_block": self._dataset.shape_block,
489
+ "shape_storage": self._dataset.shape_storage,
490
+ "shape_final": self._dataset.shape_final,
542
491
  }
543
492
 
544
493
  def get_rel_fg_index(self, fg_type):
545
494
  try:
546
495
  return self.fg_list.index(fg_type)
547
- except:
548
- raise KeyError('Framegroup {} not found in fg_list'.format(fg_type))
496
+ except MissingProperty:
497
+ raise KeyError(f"Framegroup {fg_type} not found in fg_list") from MissingProperty
549
498
 
550
499
  def scale(self):
551
- self._dataset.data = np.reshape(self._dataset.data, self._dataset.shape_storage, order='F')
552
- self._dataset.data = self._scale_frames(self._dataset.data, self.layouts, 'FW')
553
- self._dataset.data = np.reshape(self._dataset.data, self._dataset.shape_final, order='F')
500
+ self._dataset.data = np.reshape(self._dataset.data, self._dataset.shape_storage, order="F")
501
+ self._dataset.data = self._scale_frames(self._dataset.data, self.layouts, "FW")
502
+ self._dataset.data = np.reshape(self._dataset.data, self._dataset.shape_final, order="F")
554
503
 
555
504
  def deserialize(self, data, layouts):
556
-
557
505
  # scale
558
- if self._dataset._state['scale']:
559
- data = self._scale_frames(data, layouts, 'FW')
506
+ if self._dataset._state["scale"]:
507
+ data = self._scale_frames(data, layouts, "FW")
560
508
 
561
509
  # frames -> frame_groups
562
510
  data = self._frames_to_framegroups(data, layouts)
@@ -573,24 +521,24 @@ class Schema2dseq(Schema):
573
521
  """
574
522
 
575
523
  # dataset is created with scale state set to False
576
- if self._dataset._state['scale'] is False:
524
+ if self._dataset._state["scale"] is False:
577
525
  return data
578
526
 
579
527
  # get a float copy of the data array
580
528
  data = data.astype(float)
581
529
 
582
- slope = self._dataset.slope if not 'mask' in layouts.keys() else self._dataset.slope[layouts['mask'].flatten(order='F')]
583
- offset = self._dataset.offset if not 'mask' in layouts.keys() else self._dataset.offset[layouts['mask'].flatten(order='F')]
530
+ slope = self._dataset.slope if "mask" not in layouts else self._dataset.slope[layouts["mask"].flatten(order="F")]
531
+ offset = self._dataset.offset if "mask" not in layouts else self._dataset.offset[layouts["mask"].flatten(order="F")]
584
532
 
585
533
  for frame in range(data.shape[-1]):
586
- if dir == 'FW':
534
+ if dir == "FW":
587
535
  data[..., frame] *= float(slope[frame])
588
536
  data[..., frame] += float(offset[frame])
589
- elif dir == 'BW':
537
+ elif dir == "BW":
590
538
  data[..., frame] /= float(slope[frame])
591
539
  data[..., frame] -= float(offset[frame])
592
540
 
593
- if dir == 'BW':
541
+ if dir == "BW":
594
542
  data = np.round(data)
595
543
 
596
544
  return data
@@ -604,40 +552,40 @@ class Schema2dseq(Schema):
604
552
  :return:
605
553
  """
606
554
  if mask:
607
- return np.reshape(data, (-1,) + layouts['shape_fg'], order='F')
608
- else:
609
- return np.reshape(data, layouts['shape_final'], order='F')
555
+ return np.reshape(data, (-1,) + layouts["shape_fg"], order="F")
556
+ return np.reshape(data, layouts["shape_final"], order="F")
610
557
 
611
558
  def serialize(self, data, layout):
612
559
  data = self._framegroups_to_frames(data, layout)
613
- data = self._scale_frames(data, layout, 'BW')
560
+ data = self._scale_frames(data, layout, "BW")
614
561
  return data
615
562
 
616
563
  def _frames_to_vector(self, data):
617
- return data.flatten(order='F')
564
+ return data.flatten(order="F")
618
565
 
619
566
  def _framegroups_to_frames(self, data, layouts):
620
- if layouts.get('mask'):
621
- return np.reshape(data, (-1,) + layouts['shape_fg'], order='F')
622
- else:
623
- return np.reshape(data, layouts['shape_storage'], order='F')
567
+ if layouts.get("mask"):
568
+ return np.reshape(data, (-1,) + layouts["shape_fg"], order="F")
569
+ return np.reshape(data, layouts["shape_storage"], order="F")
624
570
 
625
571
  """
626
572
  Random access
627
573
  """
574
+
628
575
  def ra(self, slice_):
629
576
  """
630
- Random access to the data matrix
631
- :param slice_:
632
- :return:
577
+ Random access to the data matrix.
578
+
579
+ :param tuple slice_: Slice object(s) to select data in each dimension.
580
+ :return: Selected subset of the data.
581
+ :rtype: np.ndarray
633
582
  """
634
583
 
635
584
  layouts, layouts_ra = self._get_ra_layouts(slice_)
636
585
 
637
- array_ra = np.zeros(layouts_ra['shape_storage'], dtype=self.numpy_dtype)
586
+ array_ra = np.zeros(layouts_ra["shape_storage"], dtype=self.numpy_dtype)
638
587
 
639
- fp = np.memmap(self._dataset.path, dtype=self.numpy_dtype, mode='r',
640
- shape=layouts['shape_storage'], order='F')
588
+ fp = np.memmap(self._dataset.path, dtype=self.numpy_dtype, mode="r", shape=layouts["shape_storage"], order="F")
641
589
 
642
590
  for slice_ra, slice_full in self._generate_ra_indices(layouts_ra, layouts):
643
591
  array_ra[slice_ra] = np.array(fp[slice_full])
@@ -649,48 +597,43 @@ class Schema2dseq(Schema):
649
597
  return np.squeeze(array_ra, axis=singletons)
650
598
 
651
599
  def _get_ra_layouts(self, slice_full):
652
-
653
600
  layouts = deepcopy(self.layouts)
654
601
  layouts_ra = deepcopy(layouts)
655
602
 
656
- layouts_ra['mask'] = np.zeros(layouts['shape_fg'], dtype=bool, order='F')
657
- layouts_ra['mask'][slice_full[self.encoded_dim:]] = True
658
- layouts_ra['shape_fg'], layouts_ra['offset_fg'] = self._get_ra_shape(layouts_ra['mask'])
659
- layouts_ra['shape_frames'] = (np.prod(layouts_ra['shape_fg'],dtype=int),)
660
- layouts_ra['shape_storage'] = layouts_ra['shape_block'] + layouts_ra['shape_frames']
661
- layouts_ra['shape_final'] = layouts_ra['shape_block'] + layouts_ra['shape_fg']
603
+ layouts_ra["mask"] = np.zeros(layouts["shape_fg"], dtype=bool, order="F")
604
+ layouts_ra["mask"][slice_full[self.encoded_dim :]] = True
605
+ layouts_ra["shape_fg"], layouts_ra["offset_fg"] = self._get_ra_shape(layouts_ra["mask"])
606
+ layouts_ra["shape_frames"] = (np.prod(layouts_ra["shape_fg"], dtype=int),)
607
+ layouts_ra["shape_storage"] = layouts_ra["shape_block"] + layouts_ra["shape_frames"]
608
+ layouts_ra["shape_final"] = layouts_ra["shape_block"] + layouts_ra["shape_fg"]
662
609
 
663
610
  return layouts, layouts_ra
664
611
 
665
612
  def _get_ra_shape(self, mask):
666
-
667
613
  axes = []
668
614
  for axis in range(mask.ndim):
669
- axes.append(tuple(i for i in range(mask.ndim) if i!=axis))
615
+ axes.append(tuple(i for i in range(mask.ndim) if i != axis))
670
616
 
671
617
  ra_shape = []
672
618
  ra_offset = []
673
619
  for axis in axes:
674
- ra_shape.append(np.count_nonzero(np.count_nonzero(mask,axis=axis)))
620
+ ra_shape.append(np.count_nonzero(np.count_nonzero(mask, axis=axis)))
675
621
  ra_offset.append(np.argmax(np.count_nonzero(mask, axis=axis)))
676
622
 
677
623
  return tuple(ra_shape), np.array(ra_offset)
678
624
 
679
625
  def _generate_ra_indices(self, layouts_ra, layouts):
680
-
681
- for index_ra in np.ndindex(layouts_ra['shape_final'][self.encoded_dim:]):
682
- index = tuple(np.array(index_ra) + layouts_ra['offset_fg'])
626
+ for index_ra in np.ndindex(layouts_ra["shape_final"][self.encoded_dim :]):
627
+ index = tuple(np.array(index_ra) + layouts_ra["offset_fg"])
683
628
  index = tuple(0 for i in range(self.encoded_dim)) + index
684
- index_ra = tuple(0 for i in range(self.encoded_dim)) + index_ra
629
+ index_ra_f = tuple(0 for i in range(self.encoded_dim)) + index_ra
685
630
 
686
- index_ra = np.ravel_multi_index(index_ra, layouts_ra['shape_final'], order='F')
687
- index = np.ravel_multi_index(index, layouts['shape_final'], order='F')
631
+ index_ra_f = np.ravel_multi_index(index_ra_f, layouts_ra["shape_final"], order="F")
632
+ index = np.ravel_multi_index(index, layouts["shape_final"], order="F")
688
633
 
689
- index_ra = np.unravel_index(index_ra, layouts_ra['shape_storage'], order='F')
690
- index = np.unravel_index(index, layouts['shape_storage'], order='F')
634
+ index_ra_f = np.unravel_index(index_ra_f, layouts_ra["shape_storage"], order="F")
635
+ index = np.unravel_index(index, layouts["shape_storage"], order="F")
691
636
 
692
- slice_ra = tuple(slice(None) for i in range(self.encoded_dim)) + index_ra[self.encoded_dim:]
693
- slice_full = tuple(slice(None) for i in range(self.encoded_dim)) + index[self.encoded_dim:]
637
+ slice_ra = tuple(slice(None) for i in range(self.encoded_dim)) + index_ra_f[self.encoded_dim :]
638
+ slice_full = tuple(slice(None) for i in range(self.encoded_dim)) + index[self.encoded_dim :]
694
639
  yield slice_ra, slice_full
695
-
696
-