brukerapi 0.1.10__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/cli.py +20 -29
- brukerapi/config/properties_fid_core.json +63 -6
- brukerapi/config/properties_rawdata_core.json +16 -9
- brukerapi/config/properties_rawdata_custom.json +65 -1
- brukerapi/data.py +2 -3
- brukerapi/dataset.py +159 -158
- brukerapi/exceptions.py +57 -84
- brukerapi/folders.py +183 -169
- brukerapi/jcampdx.py +221 -235
- brukerapi/mergers.py +15 -22
- brukerapi/schemas.py +218 -278
- brukerapi/splitters.py +94 -81
- brukerapi/utils.py +35 -36
- {brukerapi-0.1.10.dist-info → brukerapi-0.2.0.dist-info}/METADATA +23 -6
- brukerapi-0.2.0.dist-info/RECORD +25 -0
- brukerapi-0.1.10.dist-info/RECORD +0 -25
- {brukerapi-0.1.10.dist-info → brukerapi-0.2.0.dist-info}/WHEEL +0 -0
- {brukerapi-0.1.10.dist-info → brukerapi-0.2.0.dist-info}/entry_points.txt +0 -0
- {brukerapi-0.1.10.dist-info → brukerapi-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {brukerapi-0.1.10.dist-info → brukerapi-0.2.0.dist-info}/top_level.txt +0 -0
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
|
|
10
5
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
6
|
+
from .exceptions import ConditionNotMet, MissingProperty
|
|
7
|
+
|
|
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
|
-
"
|
|
54
|
-
|
|
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==
|
|
56
|
+
if value == "Yes":
|
|
90
57
|
return True
|
|
91
|
-
|
|
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[
|
|
64
|
+
for condition in self._meta["conditions"]:
|
|
100
65
|
# substitute parameters in expression string
|
|
101
66
|
for sub_params in self._sub_params:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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[
|
|
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 = {
|
|
142
|
-
layouts[
|
|
143
|
-
layouts[
|
|
144
|
-
layouts[
|
|
145
|
-
layouts[
|
|
146
|
-
layouts[
|
|
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[
|
|
111
|
+
layouts["acquisition_position"] = (self._dataset.block_size - self._dataset.acq_lenght, self._dataset.acq_lenght)
|
|
150
112
|
else:
|
|
151
|
-
layouts[
|
|
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=
|
|
132
|
+
data = self._reorder_fid_lines(data, dir="FW")
|
|
172
133
|
|
|
173
|
-
if
|
|
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
|
|
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[
|
|
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=
|
|
191
|
-
return np.reshape(data[acquisition_offset:acquisition_offset+acquisition_length
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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[
|
|
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[
|
|
161
|
+
return np.transpose(data, layouts["permute"])
|
|
204
162
|
|
|
205
163
|
def _permute_to_kspace(self, data, layouts):
|
|
206
|
-
return np.reshape(data, layouts[
|
|
164
|
+
return np.reshape(data, layouts["k_space"], order="F")
|
|
207
165
|
|
|
208
|
-
def _reorder_fid_lines(self,data, dir=
|
|
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[
|
|
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 ==
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
tmp = data[
|
|
238
|
-
data[
|
|
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=
|
|
216
|
+
data = self._reorder_fid_lines(data, dir="BW")
|
|
261
217
|
|
|
262
|
-
data = np.reshape(data, layouts[
|
|
218
|
+
data = np.reshape(data, layouts["encoding_permuted"], order="F")
|
|
263
219
|
|
|
264
|
-
data = np.transpose(data, layouts[
|
|
220
|
+
data = np.transpose(data, layouts["inverse_permute"])
|
|
265
221
|
|
|
266
|
-
data = np.reshape(data, (layouts[
|
|
222
|
+
data = np.reshape(data, (layouts["acquisition_position"][1] // 2, layouts["storage"][1]), order="F")
|
|
267
223
|
|
|
268
|
-
data_ = np.zeros(layouts[
|
|
224
|
+
data_ = np.zeros(layouts["storage"], dtype=self._dataset.numpy_dtype, order="F")
|
|
269
225
|
|
|
270
|
-
if layouts[
|
|
271
|
-
channels = layouts[
|
|
272
|
-
data = np.reshape(data, (-1,channels, data.shape[-1]),order=
|
|
273
|
-
data_ = np.reshape(data_, (-1,channels, data_.shape[-1]),order=
|
|
274
|
-
data_[layouts[
|
|
275
|
-
data_[layouts[
|
|
276
|
-
data = np.reshape(data, (-1, data.shape[-1]),order=
|
|
277
|
-
data_ = np.reshape(data_, (-1, data_.shape[-1]),order=
|
|
278
|
-
elif layouts[
|
|
279
|
-
data_[0:layouts[
|
|
280
|
-
data_[1:layouts[
|
|
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
|
|
283
|
-
data_[1::2
|
|
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 =
|
|
295
|
-
fp = np.memmap(self._dataset.path, dtype=self.numpy_dtype, mode=
|
|
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[
|
|
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
|
|
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
|
-
|
|
314
|
-
except:
|
|
267
|
+
index_ra_f = self.index_to_data(layouts_ra, (0,) + index_ra)
|
|
268
|
+
except IndexError:
|
|
315
269
|
print(index_ra)
|
|
316
|
-
|
|
317
|
-
|
|
270
|
+
index_ra_f = self.index_to_data(layouts_ra, (0,) + index_ra)
|
|
318
271
|
|
|
319
272
|
try:
|
|
320
|
-
array_ra[
|
|
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[
|
|
325
|
-
layouts_ra[
|
|
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[
|
|
336
|
-
layouts[
|
|
337
|
-
layouts[
|
|
338
|
-
layouts[
|
|
339
|
-
layouts[
|
|
340
|
-
layouts[
|
|
341
|
-
layouts[
|
|
342
|
-
|
|
343
|
-
layouts[
|
|
344
|
-
layouts[
|
|
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[
|
|
351
|
-
layouts_ra[
|
|
352
|
-
layouts_ra[
|
|
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[
|
|
356
|
-
layouts_ra[
|
|
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
|
-
|
|
368
|
-
|
|
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
|
-
|
|
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[
|
|
380
|
-
#permute
|
|
381
|
-
index = tuple(index[i] for i in layout[
|
|
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[
|
|
384
|
-
if layout[
|
|
385
|
-
index = np.unravel_index(index, layout[
|
|
386
|
-
index = (index[0] + layout[
|
|
387
|
-
index = np.ravel_multi_index(index, layout[
|
|
388
|
-
elif layout[
|
|
389
|
-
index = np.unravel_index(index, layout[
|
|
390
|
-
index = np.ravel_multi_index(index, layout[
|
|
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[
|
|
339
|
+
index = np.unravel_index(index, layout["storage"], order="F")
|
|
393
340
|
|
|
394
|
-
index = (slice(index[0], index[0]+layout[
|
|
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[
|
|
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[
|
|
402
|
-
index_full = (0,)+tuple(i + o for i, o in zip(index_ra, layout_ra[
|
|
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[
|
|
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[
|
|
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[
|
|
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,107 +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[
|
|
425
|
-
index_full = np.unravel_index(index_full, layout_full[
|
|
426
|
-
if
|
|
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[
|
|
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[
|
|
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[
|
|
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[
|
|
440
|
-
#permute
|
|
441
|
-
index = tuple(index[i] for i in layout[
|
|
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[
|
|
391
|
+
channel = index[layout["channel_index"]] + 1
|
|
446
392
|
|
|
447
|
-
index = np.ravel_multi_index(index, layout[
|
|
448
|
-
index = np.unravel_index(index, layout[
|
|
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[
|
|
451
|
-
first = index[0] + (layout[
|
|
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[
|
|
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[
|
|
466
|
-
layouts[
|
|
467
|
-
layouts[
|
|
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[
|
|
473
|
-
return np.reshape(data, layouts[
|
|
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[
|
|
477
|
-
return np.reshape(data, layouts[
|
|
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[
|
|
486
|
-
layouts[
|
|
487
|
-
|
|
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
|
|
434
|
+
return data[0::2, ...] + 1j * data[1::2, ...]
|
|
493
435
|
|
|
494
436
|
def serialize(self, data, layouts):
|
|
495
|
-
|
|
496
|
-
data_[
|
|
497
|
-
|
|
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
|
|
443
|
+
|
|
498
444
|
return data_
|
|
499
445
|
|
|
446
|
+
|
|
500
447
|
# Compatibility alias for previous misspelling:
|
|
501
448
|
SchemaRawdata.seralize = SchemaRawdata.serialize
|
|
502
449
|
|
|
503
450
|
|
|
504
451
|
class SchemaSer(Schema):
|
|
505
|
-
|
|
506
452
|
@property
|
|
507
453
|
def layouts(self):
|
|
508
454
|
if self._layouts is not None:
|
|
509
455
|
return self._layouts
|
|
510
456
|
|
|
511
|
-
PVM_SpecMatrix = self._dataset.get_value(
|
|
512
|
-
PVM_Matrix = self._dataset.get_value(
|
|
513
|
-
PVM_EncNReceivers = self._dataset.get_value(
|
|
514
|
-
layouts={}
|
|
515
|
-
layouts[
|
|
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])
|
|
516
462
|
return layouts
|
|
517
463
|
|
|
518
464
|
def deserialize(self, data):
|
|
519
465
|
data = data[0::2] + 1j * data[1::2]
|
|
520
|
-
data = np.reshape(data, self.layouts[
|
|
466
|
+
data = np.reshape(data, self.layouts["raw"], order="F")
|
|
521
467
|
return data
|
|
522
468
|
|
|
523
469
|
def serialize(self, data):
|
|
524
|
-
raise
|
|
470
|
+
raise NotImplementedError
|
|
525
471
|
|
|
526
472
|
|
|
527
473
|
class Schema2dseq(Schema):
|
|
@@ -537,29 +483,28 @@ class Schema2dseq(Schema):
|
|
|
537
483
|
@property
|
|
538
484
|
def layouts(self):
|
|
539
485
|
return {
|
|
540
|
-
"shape_fg"
|
|
541
|
-
"shape_frames"
|
|
542
|
-
"shape_block"
|
|
543
|
-
"shape_storage"
|
|
544
|
-
"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,
|
|
545
491
|
}
|
|
546
492
|
|
|
547
493
|
def get_rel_fg_index(self, fg_type):
|
|
548
494
|
try:
|
|
549
495
|
return self.fg_list.index(fg_type)
|
|
550
|
-
except:
|
|
551
|
-
raise KeyError(
|
|
496
|
+
except MissingProperty:
|
|
497
|
+
raise KeyError(f"Framegroup {fg_type} not found in fg_list") from MissingProperty
|
|
552
498
|
|
|
553
499
|
def scale(self):
|
|
554
|
-
self._dataset.data = np.reshape(self._dataset.data, self._dataset.shape_storage, order=
|
|
555
|
-
self._dataset.data = self._scale_frames(self._dataset.data, self.layouts,
|
|
556
|
-
self._dataset.data = np.reshape(self._dataset.data, self._dataset.shape_final, order=
|
|
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")
|
|
557
503
|
|
|
558
504
|
def deserialize(self, data, layouts):
|
|
559
|
-
|
|
560
505
|
# scale
|
|
561
|
-
if self._dataset._state[
|
|
562
|
-
data = self._scale_frames(data, layouts,
|
|
506
|
+
if self._dataset._state["scale"]:
|
|
507
|
+
data = self._scale_frames(data, layouts, "FW")
|
|
563
508
|
|
|
564
509
|
# frames -> frame_groups
|
|
565
510
|
data = self._frames_to_framegroups(data, layouts)
|
|
@@ -576,24 +521,24 @@ class Schema2dseq(Schema):
|
|
|
576
521
|
"""
|
|
577
522
|
|
|
578
523
|
# dataset is created with scale state set to False
|
|
579
|
-
if self._dataset._state[
|
|
524
|
+
if self._dataset._state["scale"] is False:
|
|
580
525
|
return data
|
|
581
526
|
|
|
582
527
|
# get a float copy of the data array
|
|
583
528
|
data = data.astype(float)
|
|
584
529
|
|
|
585
|
-
slope = self._dataset.slope if not
|
|
586
|
-
offset = self._dataset.offset if not
|
|
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")]
|
|
587
532
|
|
|
588
533
|
for frame in range(data.shape[-1]):
|
|
589
|
-
if dir ==
|
|
534
|
+
if dir == "FW":
|
|
590
535
|
data[..., frame] *= float(slope[frame])
|
|
591
536
|
data[..., frame] += float(offset[frame])
|
|
592
|
-
elif dir ==
|
|
537
|
+
elif dir == "BW":
|
|
593
538
|
data[..., frame] /= float(slope[frame])
|
|
594
539
|
data[..., frame] -= float(offset[frame])
|
|
595
540
|
|
|
596
|
-
if dir ==
|
|
541
|
+
if dir == "BW":
|
|
597
542
|
data = np.round(data)
|
|
598
543
|
|
|
599
544
|
return data
|
|
@@ -607,40 +552,40 @@ class Schema2dseq(Schema):
|
|
|
607
552
|
:return:
|
|
608
553
|
"""
|
|
609
554
|
if mask:
|
|
610
|
-
return np.reshape(data, (-1,) + layouts[
|
|
611
|
-
|
|
612
|
-
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")
|
|
613
557
|
|
|
614
558
|
def serialize(self, data, layout):
|
|
615
559
|
data = self._framegroups_to_frames(data, layout)
|
|
616
|
-
data = self._scale_frames(data, layout,
|
|
560
|
+
data = self._scale_frames(data, layout, "BW")
|
|
617
561
|
return data
|
|
618
562
|
|
|
619
563
|
def _frames_to_vector(self, data):
|
|
620
|
-
return data.flatten(order=
|
|
564
|
+
return data.flatten(order="F")
|
|
621
565
|
|
|
622
566
|
def _framegroups_to_frames(self, data, layouts):
|
|
623
|
-
if layouts.get(
|
|
624
|
-
return np.reshape(data, (-1,) + layouts[
|
|
625
|
-
|
|
626
|
-
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")
|
|
627
570
|
|
|
628
571
|
"""
|
|
629
572
|
Random access
|
|
630
573
|
"""
|
|
574
|
+
|
|
631
575
|
def ra(self, slice_):
|
|
632
576
|
"""
|
|
633
|
-
Random access to the data matrix
|
|
634
|
-
|
|
635
|
-
:
|
|
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
|
|
636
582
|
"""
|
|
637
583
|
|
|
638
584
|
layouts, layouts_ra = self._get_ra_layouts(slice_)
|
|
639
585
|
|
|
640
|
-
array_ra = np.zeros(layouts_ra[
|
|
586
|
+
array_ra = np.zeros(layouts_ra["shape_storage"], dtype=self.numpy_dtype)
|
|
641
587
|
|
|
642
|
-
fp = np.memmap(self._dataset.path, dtype=self.numpy_dtype, mode=
|
|
643
|
-
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")
|
|
644
589
|
|
|
645
590
|
for slice_ra, slice_full in self._generate_ra_indices(layouts_ra, layouts):
|
|
646
591
|
array_ra[slice_ra] = np.array(fp[slice_full])
|
|
@@ -652,48 +597,43 @@ class Schema2dseq(Schema):
|
|
|
652
597
|
return np.squeeze(array_ra, axis=singletons)
|
|
653
598
|
|
|
654
599
|
def _get_ra_layouts(self, slice_full):
|
|
655
|
-
|
|
656
600
|
layouts = deepcopy(self.layouts)
|
|
657
601
|
layouts_ra = deepcopy(layouts)
|
|
658
602
|
|
|
659
|
-
layouts_ra[
|
|
660
|
-
layouts_ra[
|
|
661
|
-
layouts_ra[
|
|
662
|
-
layouts_ra[
|
|
663
|
-
layouts_ra[
|
|
664
|
-
layouts_ra[
|
|
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"]
|
|
665
609
|
|
|
666
610
|
return layouts, layouts_ra
|
|
667
611
|
|
|
668
612
|
def _get_ra_shape(self, mask):
|
|
669
|
-
|
|
670
613
|
axes = []
|
|
671
614
|
for axis in range(mask.ndim):
|
|
672
|
-
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))
|
|
673
616
|
|
|
674
617
|
ra_shape = []
|
|
675
618
|
ra_offset = []
|
|
676
619
|
for axis in axes:
|
|
677
|
-
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)))
|
|
678
621
|
ra_offset.append(np.argmax(np.count_nonzero(mask, axis=axis)))
|
|
679
622
|
|
|
680
623
|
return tuple(ra_shape), np.array(ra_offset)
|
|
681
624
|
|
|
682
625
|
def _generate_ra_indices(self, layouts_ra, layouts):
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
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"])
|
|
686
628
|
index = tuple(0 for i in range(self.encoded_dim)) + index
|
|
687
|
-
|
|
629
|
+
index_ra_f = tuple(0 for i in range(self.encoded_dim)) + index_ra
|
|
688
630
|
|
|
689
|
-
|
|
690
|
-
index = np.ravel_multi_index(index, layouts[
|
|
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")
|
|
691
633
|
|
|
692
|
-
|
|
693
|
-
index = np.unravel_index(index, layouts[
|
|
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")
|
|
694
636
|
|
|
695
|
-
slice_ra = tuple(slice(None) for i in range(self.encoded_dim)) +
|
|
696
|
-
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 :]
|
|
697
639
|
yield slice_ra, slice_full
|
|
698
|
-
|
|
699
|
-
|