1
|
|
|
# Copyright 2014 Diamond Light Source Ltd. |
2
|
|
|
# |
3
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
4
|
|
|
# you may not use this file except in compliance with the License. |
5
|
|
|
# You may obtain a copy of the License at |
6
|
|
|
# |
7
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0 |
8
|
|
|
# |
9
|
|
|
# Unless required by applicable law or agreed to in writing, software |
10
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, |
11
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12
|
|
|
# See the License for the specific language governing permissions and |
13
|
|
|
# limitations under the License. |
14
|
|
|
|
15
|
|
|
""" |
16
|
|
|
.. module:: slice_lists |
17
|
|
|
:platform: Unix |
18
|
|
|
:synopsis: Contains classes for creating global and local slice lists |
19
|
|
|
|
20
|
|
|
.. moduleauthor:: Nicola Wadeson <[email protected]> |
21
|
|
|
|
22
|
|
|
""" |
23
|
|
|
|
24
|
|
|
import numpy as np |
25
|
|
|
|
26
|
|
|
|
27
|
|
|
class SliceLists(object): |
28
|
|
|
""" |
29
|
|
|
SliceLists class creates global and local slices lists used to transfer |
30
|
|
|
the data |
31
|
|
|
""" |
32
|
|
|
|
33
|
|
|
def __init__(self, name='SliceLists'): |
34
|
|
|
super(SliceLists, self).__init__() |
35
|
|
|
self.pad = False |
36
|
|
|
self.transfer_data = None |
37
|
|
|
|
38
|
|
|
def _get_process_data(self): |
39
|
|
|
return self.process_data |
40
|
|
|
|
41
|
|
|
def _single_slice_list(self, nSlices, nDims, core_slice, core_dirs, |
42
|
|
|
slice_dirs, fix, index): |
43
|
|
|
|
44
|
|
|
fix_dirs, value = fix |
45
|
|
|
slice_list = [] |
46
|
|
|
for i in range(nSlices): |
47
|
|
|
getitem = np.array([slice(None)]*nDims) |
48
|
|
|
getitem[core_dirs] = core_slice[np.arange(len(core_dirs))] |
49
|
|
|
for f in range(len(fix_dirs)): |
50
|
|
|
getitem[fix_dirs[f]] = slice(value[f], value[f] + 1, 1) |
51
|
|
|
for sdir in range(len(slice_dirs)): |
52
|
|
|
getitem[slice_dirs[sdir]] = slice(index[sdir, i], |
53
|
|
|
index[sdir, i] + 1, 1) |
54
|
|
|
slice_list.append(tuple(getitem)) |
55
|
|
|
return slice_list |
56
|
|
|
|
57
|
|
|
def _get_slice_dirs_index(self, slice_dirs, shape, value, extra=None, calc=None): |
58
|
|
|
""" |
59
|
|
|
returns a list of arrays for each slice dimension, where each array |
60
|
|
|
gives the indices for that slice dimension. |
61
|
|
|
""" |
62
|
|
|
# create the indexing array |
63
|
|
|
chunk, length, repeat = self._chunk_length_repeat(slice_dirs, shape) |
64
|
|
|
values = None |
65
|
|
|
idx_list = [] |
66
|
|
|
for i in range(len(slice_dirs)): |
67
|
|
|
c = chunk[i] |
68
|
|
|
r = repeat[i] |
69
|
|
|
values = eval(value) |
70
|
|
|
idx = np.ravel(np.kron(values, np.ones((r, c)))) |
71
|
|
|
idx_list.append(idx.astype(int)) |
72
|
|
|
return np.array(idx_list) |
73
|
|
|
|
74
|
|
|
def _chunk_length_repeat(self, slice_dirs, shape): |
75
|
|
|
""" |
76
|
|
|
For each slice dimension, determine 3 values relevant to the slicing. |
77
|
|
|
|
78
|
|
|
:returns: chunk, length, repeat |
79
|
|
|
chunk: how many repeats of the same index value before an increment |
80
|
|
|
length: the slice dimension length (sequence length) |
81
|
|
|
repeat: how many times does the sequence of chunked numbers repeat |
82
|
|
|
:rtype: [int, int, int] |
83
|
|
|
""" |
84
|
|
|
sshape = self.__get_shape_of_slice_dirs(slice_dirs, shape) |
85
|
|
|
if not slice_dirs: |
86
|
|
|
return [1], [1], [1] |
87
|
|
|
|
88
|
|
|
chunk = [] |
89
|
|
|
length = [] |
90
|
|
|
repeat = [] |
91
|
|
|
for dim in range(len(slice_dirs)): |
92
|
|
|
chunk.append(int(np.prod(sshape[0:dim]))) |
93
|
|
|
length.append(sshape[dim]) |
94
|
|
|
repeat.append(int(np.prod(sshape[dim+1:]))) |
95
|
|
|
return chunk, length, repeat |
96
|
|
|
|
97
|
|
|
def __get_shape_of_slice_dirs(self, slice_dirs, shape): |
98
|
|
|
sshape = [shape[sslice] for sslice in slice_dirs] |
99
|
|
|
if 'var' in sshape: |
100
|
|
|
shape = list(shape) |
101
|
|
|
for index, value in enumerate(shape): |
102
|
|
|
if isinstance(value, str): |
103
|
|
|
shape[index] = \ |
104
|
|
|
len(self.data_info.get('axis_labels')[index]) |
105
|
|
|
shape = tuple(shape) |
106
|
|
|
sshape = [shape[sslice] for sslice in slice_dirs] |
107
|
|
|
return sshape |
108
|
|
|
|
109
|
|
|
def _get_core_slices(self, core_dirs): |
110
|
|
|
core_slice = [] |
111
|
|
|
starts, stops, steps, chunks = \ |
112
|
|
|
self.data.get_preview().get_starts_stops_steps() |
113
|
|
|
|
114
|
|
|
for c in core_dirs: |
115
|
|
|
if (chunks[c]) > 1: |
116
|
|
|
if (stops[c] - starts[c] == 1): |
117
|
|
|
start = starts[c] - int(chunks[c] / 2.0) |
118
|
|
|
if start < 0: |
119
|
|
|
raise Exception('Cannot have a negative value in the ' |
120
|
|
|
'slice list.') |
121
|
|
|
stop = starts[c] + (chunks[c] - int(chunks[c] / 2.0)) |
122
|
|
|
core_slice.append(slice(start, stop, 1)) |
123
|
|
|
else: |
124
|
|
|
raise Exception("The core dimension does not support " |
125
|
|
|
"multiple chunks.") |
126
|
|
|
else: |
127
|
|
|
core_slice.append(slice(starts[c], stops[c], steps[c])) |
128
|
|
|
return np.array(core_slice) |
129
|
|
|
|
130
|
|
|
def _group_dimension(self, sl, dim, step): |
131
|
|
|
start = sl[0][dim].start |
132
|
|
|
stop = sl[-1][dim].stop |
133
|
|
|
working_slice = list(sl[0]) |
134
|
|
|
working_slice[dim] = slice(start, stop, step) |
135
|
|
|
return tuple(working_slice) |
136
|
|
|
|
137
|
|
|
def _split_list(self, the_list, size): |
138
|
|
|
return [the_list[x:x+size] for x in range(0, len(the_list), size)] |
139
|
|
|
|
140
|
|
|
# This method only works if the split dimensions in the slice list contain |
141
|
|
|
# slice objects |
142
|
|
|
def __split_frames(self, slice_list, split_list): |
143
|
|
|
split = [list(map(int, a.split('.'))) for a in split_list] |
144
|
|
|
dims = [s[0] for s in split] |
145
|
|
|
length = [s[1] for s in split] |
146
|
|
|
replace = self.__get_split_frame_entries(slice_list, dims, length) |
147
|
|
|
# now replace each slice list entry with multiple entries |
148
|
|
|
array_list = [] |
149
|
|
|
for sl in slice_list: |
150
|
|
|
new_list = np.array([sl for i in range(len(replace[0]))]) |
151
|
|
|
for d, i in zip(dims, list(range(len(dims)))): |
152
|
|
|
new_list[:, d] = replace[i] |
153
|
|
|
array_list += [tuple(a) for a in new_list] |
154
|
|
|
|
155
|
|
|
return tuple(array_list) |
156
|
|
|
|
157
|
|
|
def __get_split_frame_entries(self, slice_list, dims, length): |
158
|
|
|
shape = self.get_shape |
159
|
|
|
replace = [] |
160
|
|
|
seq_len = [] |
161
|
|
|
|
162
|
|
|
# get the new entries |
163
|
|
|
for d, l in zip(dims, length): |
164
|
|
|
sl = slice_list[0][d] |
165
|
|
|
start = 0 if sl.start is None else sl.start |
166
|
|
|
stop = shape[d] if sl.stop is None else sl.stop |
167
|
|
|
inc = l*sl.step if sl.step else l |
168
|
|
|
temp_list = [slice(a, a+inc) for a in np.arange(start, stop, inc)] |
169
|
|
|
if temp_list[-1].stop > stop: |
170
|
|
|
temp = temp_list[-1] |
171
|
|
|
temp_list[-1] = slice(temp.start, stop, temp.step) |
172
|
|
|
replace.append(temp_list) |
173
|
|
|
seq_len.append(len(temp_list)) |
174
|
|
|
|
175
|
|
|
# calculate the permutations |
176
|
|
|
length = np.array(seq_len) |
177
|
|
|
chunk = [int(np.prod(length[0:dim])) for dim in range(len(dims))] |
178
|
|
|
repeat = [int(np.prod(length[dim+1:])) for dim in range(len(dims))] |
179
|
|
|
full_replace = [] |
180
|
|
|
for d in range(len(dims)): |
181
|
|
|
temp = [[replace[d][i]]*chunk[d] for x in range(repeat[d]) for i |
182
|
|
|
in range(len(replace[d]))] |
183
|
|
|
full_replace.append([t for sub in temp for t in sub]) |
184
|
|
|
return full_replace |
185
|
|
|
|
186
|
|
|
def _get_frames_per_process(self, slice_list): |
187
|
|
|
processes = self.data.exp.meta_data.get("processes") |
188
|
|
|
process = self.data.exp.meta_data.get("process") |
189
|
|
|
frame_idx = np.arange(len(slice_list)) |
190
|
|
|
try: |
191
|
|
|
frames = np.array_split(frame_idx, len(processes))[process] |
192
|
|
|
slice_list = slice_list[frames[0]:frames[-1]+1] |
193
|
|
|
except IndexError: |
194
|
|
|
slice_list = [] |
195
|
|
|
return slice_list, frames |
196
|
|
|
|
197
|
|
|
def _pad_slice_list(self, slice_list, inc_start_str: str, inc_stop_str: str): |
198
|
|
|
""" Amend the slice lists to include padding. Includes variations for |
199
|
|
|
transfer and process slice lists. """ |
200
|
|
|
pData = self.data._get_plugin_data() |
201
|
|
|
if not pData.padding: |
202
|
|
|
return slice_list |
203
|
|
|
|
204
|
|
|
pad_dict = pData.padding._get_padding_directions() |
205
|
|
|
|
206
|
|
|
shape = self.data.get_shape() |
207
|
|
|
for ddir, value in pad_dict.items(): |
208
|
|
|
inc_start = eval(inc_start_str) |
209
|
|
|
inc_stop = eval(inc_stop_str) |
210
|
|
|
for i in range(len(slice_list)): |
211
|
|
|
slice_list[i] = list(slice_list[i]) |
212
|
|
|
sl = slice_list[i][ddir] |
213
|
|
|
if sl.start is None: |
214
|
|
|
sl = slice(0, shape[ddir], 1) |
215
|
|
|
slice_list[i][ddir] = \ |
216
|
|
|
slice(sl.start + inc_start, sl.stop + inc_stop, sl.step) |
217
|
|
|
slice_list[i] = tuple(slice_list[i]) |
218
|
|
|
return slice_list |
219
|
|
|
|
220
|
|
|
def _fix_list_length(self, sl, pad): |
221
|
|
|
sl = list(sl) |
222
|
|
|
steps = self.data.data_info.get("steps") |
223
|
|
|
for i, s in enumerate(sl): |
224
|
|
|
sl[i] = slice(s.start, s.stop + steps[i]*pad[i], s.step) |
225
|
|
|
return tuple(sl) |
226
|
|
|
|
227
|
|
|
def _get_local_single_slice_list(self, shape): |
228
|
|
|
slice_dirs = self.data.get_slice_dimensions() |
229
|
|
|
core_dirs = np.array(self.data.get_core_dimensions()) |
230
|
|
|
fix = [[]]*2 |
231
|
|
|
core_slice = np.array([slice(None)]*len(core_dirs)) |
232
|
|
|
shape = tuple([shape[i] for i in range(len(shape))]) |
233
|
|
|
values = 'np.arange(shape[slice_dirs[i]])' |
234
|
|
|
index = self._get_slice_dirs_index(slice_dirs, shape, values) |
235
|
|
|
# there may be no slice dirs |
236
|
|
|
index = index if index.size else np.array([[0]]) |
237
|
|
|
nSlices = index.shape[1] if index.size else len(fix[0]) |
238
|
|
|
nDims = len(shape) |
239
|
|
|
|
240
|
|
|
ssl = self._single_slice_list( |
241
|
|
|
nSlices, nDims, core_slice, core_dirs, slice_dirs, fix, index) |
242
|
|
|
return ssl |
243
|
|
|
|
244
|
|
|
def _group_slice_list_in_one_dimension(self, slice_list, max_frames, |
245
|
|
|
group_dim, pad=False): |
246
|
|
|
""" Group the slice list in one dimension, stopping at \ |
247
|
|
|
boundaries - prepare a slice list for multi-frame plugin processing. |
248
|
|
|
""" |
249
|
|
|
if group_dim is None: |
250
|
|
|
return slice_list |
251
|
|
|
|
252
|
|
|
banked = self._banked_list(slice_list, max_frames, pad=pad) |
253
|
|
|
grouped = [] |
254
|
|
|
for group in banked: |
255
|
|
|
sub_groups = self._split_list(group, max_frames) |
256
|
|
|
for sub in sub_groups: |
257
|
|
|
grouped.append(self._group_dimension(sub, group_dim, 1)) |
258
|
|
|
return grouped |
259
|
|
|
|
260
|
|
|
def _group_slice_list_in_multiple_dimensions(self, slice_list, max_frames, |
261
|
|
|
group_dim, pad=False): |
262
|
|
|
""" Group the slice list in multiple dimensions - prepare a slice list\ |
263
|
|
|
for file transfer. |
264
|
|
|
""" |
265
|
|
|
if group_dim is None: |
266
|
|
|
return slice_list |
267
|
|
|
|
268
|
|
|
steps = self.data.get_preview().get_starts_stops_steps('steps') |
269
|
|
|
sub_groups = self._banked_list(slice_list, max_frames, pad=pad) |
270
|
|
|
|
271
|
|
|
grouped = [] |
272
|
|
|
for sub in sub_groups: |
273
|
|
|
temp = list(sub[0]) |
274
|
|
|
for dim in group_dim: |
275
|
|
|
temp[dim] = self._group_dimension(sub, dim, steps[dim])[dim] |
276
|
|
|
grouped.append(tuple(temp)) |
277
|
|
|
|
278
|
|
|
return grouped |
279
|
|
|
|
280
|
|
|
|
281
|
|
|
class LocalData(SliceLists): |
282
|
|
|
""" The LocalData class organises the slicing of transferred data to \ |
283
|
|
|
give the shape requested by a plugin for each run of 'process_frames'. |
284
|
|
|
""" |
285
|
|
|
|
286
|
|
|
def __init__(self, dtype, transport_data): |
287
|
|
|
self.dtype = dtype # in or out ProcessData object |
288
|
|
|
self.td = transport_data |
289
|
|
|
self.data = transport_data.data |
290
|
|
|
self.pData = self.data._get_plugin_data() |
291
|
|
|
self.shape = self.data.get_shape() |
292
|
|
|
self.sdir = None |
293
|
|
|
|
294
|
|
|
def _get_dict(self): |
295
|
|
|
return self._get_dict_in() if self.dtype == 'in' else \ |
296
|
|
|
self._get_dict_out() |
297
|
|
|
|
298
|
|
|
def _get_dict_in(self): |
299
|
|
|
sl_dict = {} |
300
|
|
|
sl = self._get_slice_list() |
301
|
|
|
sl = self._pad_slice_list(sl, '0', 'sum(value.values())') |
302
|
|
|
sl_dict['process'] = sl |
303
|
|
|
return sl_dict |
304
|
|
|
|
305
|
|
|
def _get_dict_out(self): |
306
|
|
|
sl_dict = {} |
307
|
|
|
sl_dict['process'] = self._get_slice_list() |
308
|
|
|
sl_dict['unpad'] = self.__get_unpad_slice_list(len(sl_dict['process'])) |
309
|
|
|
return sl_dict |
310
|
|
|
|
311
|
|
|
def _get_slice_list(self): |
312
|
|
|
""" Splits a file transfer slice list into a list of (padded) slices |
313
|
|
|
required for each loop of process_frames. |
314
|
|
|
""" |
315
|
|
|
slice_dirs = self.data.get_slice_dimensions() |
316
|
|
|
self.sdir = slice_dirs[0] if len(slice_dirs) > 0 else None |
317
|
|
|
|
318
|
|
|
pData = self.pData |
319
|
|
|
mf_process = pData.meta_data.get('max_frames_process') |
320
|
|
|
shape = pData.get_shape_transfer() |
321
|
|
|
process_ssl = self._get_local_single_slice_list(shape) |
322
|
|
|
|
323
|
|
|
process_gsl = self._group_slice_list_in_one_dimension( |
324
|
|
|
process_ssl, mf_process, self.sdir) |
325
|
|
|
return process_gsl |
326
|
|
|
|
327
|
|
|
def _banked_list(self, slice_list, max_frames, pad=False): |
328
|
|
|
shape = self.data.get_shape() |
329
|
|
|
slice_dirs = self.data.get_slice_dimensions() |
330
|
|
|
chunk, length, repeat = self._chunk_length_repeat(slice_dirs, shape) |
331
|
|
|
return self._split_list(slice_list, max_frames) |
332
|
|
|
|
333
|
|
|
def __get_unpad_slice_list(self, reps): |
334
|
|
|
# setting process slice list unpad here - not currently working for 4D data |
335
|
|
|
sl = [slice(None)]*len(self.pData.get_shape_transfer()) |
336
|
|
|
if not self.pData.padding: |
337
|
|
|
return tuple([tuple(sl)]*reps) |
338
|
|
|
pad_dict = self.pData.padding._get_padding_directions() |
339
|
|
|
for ddir, value in pad_dict.items(): |
340
|
|
|
sl[ddir] = slice(value['before'], -value['after']) |
341
|
|
|
return tuple([tuple(sl)]*reps) |
342
|
|
|
|
343
|
|
|
|
344
|
|
|
class GlobalData(SliceLists): |
345
|
|
|
""" |
346
|
|
|
The GlobalData class organises the movement and slicing of the data from |
347
|
|
|
file. |
348
|
|
|
""" |
349
|
|
|
|
350
|
|
|
def __init__(self, dtype, transport): |
351
|
|
|
self.dtype = dtype # in or out TransferData object |
352
|
|
|
self.trans = transport |
353
|
|
|
self.data = transport.data |
354
|
|
|
self.pData = self.data._get_plugin_data() |
355
|
|
|
self.shape = self.data.get_shape() |
356
|
|
|
|
357
|
|
|
def _get_dict(self, pad): |
358
|
|
|
temp = self._get_dict_in(pad) if self.dtype == 'in' else \ |
359
|
|
|
self._get_dict_out() |
360
|
|
|
return temp |
361
|
|
|
|
362
|
|
|
def _get_dict_in(self, pad): |
363
|
|
|
sl_dict = {} |
364
|
|
|
sl, current = \ |
365
|
|
|
self._get_slice_list(self.shape, current_sl=True, pad=pad) |
366
|
|
|
|
367
|
|
|
sl_dict['current'], _ = self._get_frames_per_process(current) |
368
|
|
|
sl, sl_dict['frames'] = self._get_frames_per_process(sl) |
369
|
|
|
if self.trans.pad: |
370
|
|
|
sl = self._pad_slice_list( |
371
|
|
|
sl, "-value['before']", "value['after']") |
372
|
|
|
sl_dict['transfer'] = sl |
373
|
|
|
return sl_dict |
374
|
|
|
|
375
|
|
|
def _get_dict_out(self): |
376
|
|
|
sl_dict = {} |
377
|
|
|
sl, _ = self._get_slice_list(self.shape) |
378
|
|
|
sl_dict['transfer'], _ = self._get_frames_per_process(sl) |
379
|
|
|
return sl_dict |
380
|
|
|
|
381
|
|
|
def _banked_list(self, slice_list, max_frames, pad=False): |
382
|
|
|
shape = self.data.get_shape() |
383
|
|
|
slice_dirs = self.data.get_slice_dimensions() |
384
|
|
|
chunk, length, repeat = self._chunk_length_repeat(slice_dirs, shape) |
385
|
|
|
sdir_shape = [shape[i] for i in slice_dirs] |
386
|
|
|
split, split_dim = self._get_split_length(max_frames, sdir_shape) |
387
|
|
|
# split at the boundaries |
388
|
|
|
split_list = self._split_list(slice_list, split) |
389
|
|
|
|
390
|
|
|
banked = [] |
391
|
|
|
for s in split_list: |
392
|
|
|
# split at max_frames |
393
|
|
|
b = self._split_list(s, max_frames) |
394
|
|
|
banked.extend(b) |
395
|
|
|
if pad and any(pad): |
396
|
|
|
b[-1][-1] = self._fix_list_length(b[-1][-1], pad) |
397
|
|
|
|
398
|
|
|
return banked |
399
|
|
|
|
400
|
|
|
def _get_split_length(self, max_frames, sdir_shape): |
401
|
|
|
nDims = 0 |
402
|
|
|
while(nDims < len(sdir_shape)): |
403
|
|
|
nDims += 1 |
404
|
|
|
prod = np.prod([sdir_shape[i] for i in range(nDims)]) |
405
|
|
|
if prod/float(max_frames) >= 1: |
406
|
|
|
break |
407
|
|
|
sdir = self.data.get_slice_dimensions() |
408
|
|
|
return prod, sdir[nDims-1] |
|
|
|
|
409
|
|
|
|
410
|
|
|
def _get_padded_shape(self, orig_shape): |
411
|
|
|
""" |
412
|
|
|
Get the (fake) shape of the data if it was exactly divisible by mft. |
413
|
|
|
""" |
414
|
|
|
trans_shape = self.pData.meta_data.get("transfer_shape") |
415
|
|
|
pad = [] |
416
|
|
|
for i, shape in enumerate(orig_shape): |
417
|
|
|
mod = shape % trans_shape[i] |
418
|
|
|
mod = (trans_shape[i] - mod) % trans_shape[i] |
419
|
|
|
diff = trans_shape[i] - shape |
420
|
|
|
pad.append(max(diff, mod)) |
421
|
|
|
return pad |
422
|
|
|
|
423
|
|
|
def _get_global_single_slice_list(self, shape): |
424
|
|
|
slice_dirs = self.data.get_slice_dimensions() |
425
|
|
|
core_dirs = np.array(self.data.get_core_dimensions()) |
426
|
|
|
fix = self.data._get_plugin_data()._get_fixed_dimensions() |
427
|
|
|
core_slice = self._get_core_slices(core_dirs) |
428
|
|
|
values = 'self._get_slice_dir_index(slice_dirs[i])' |
429
|
|
|
index = self._get_slice_dirs_index(slice_dirs, shape, values) |
430
|
|
|
nSlices = index.shape[1] if index.size else len(fix[0]) |
431
|
|
|
nDims = len(shape) |
432
|
|
|
ssl = self._single_slice_list( |
433
|
|
|
nSlices, nDims, core_slice, core_dirs, slice_dirs, fix, index) |
434
|
|
|
return ssl |
435
|
|
|
|
436
|
|
|
def _get_slice_dir_index(self, dim, boolean=False): |
437
|
|
|
starts, stops, steps, chunks = \ |
438
|
|
|
self.data.get_preview().get_starts_stops_steps() |
439
|
|
|
if chunks[dim] > 1: |
440
|
|
|
dir_idx = np.ravel(np.transpose( |
441
|
|
|
self.trans._get_slice_dir_matrix(dim))) |
442
|
|
|
if boolean: |
443
|
|
|
return self.__get_bool_slice_dir_index(dim, dir_idx) |
444
|
|
|
return dir_idx |
445
|
|
|
else: |
446
|
|
|
fix_dirs, value = \ |
447
|
|
|
self.data._get_plugin_data()._get_fixed_dimensions() |
448
|
|
|
if dim in fix_dirs: |
449
|
|
|
return value[fix_dirs.index(dim)] |
450
|
|
|
else: |
451
|
|
|
return np.arange(starts[dim], stops[dim], steps[dim]) |
452
|
|
|
|
453
|
|
|
def _get_slice_list(self, shape, current_sl=None, pad=False): |
454
|
|
|
mft = self.pData._get_max_frames_transfer() |
455
|
|
|
pad = self._get_padded_shape(shape) if pad else False |
456
|
|
|
transfer_ssl = self._get_global_single_slice_list(shape) |
457
|
|
|
|
458
|
|
|
if transfer_ssl is None: |
459
|
|
|
raise Exception("Data type %s does not support slicing in " |
460
|
|
|
"directions %s" % (self.get_current_pattern_name(), |
461
|
|
|
self.get_slice_directions())) |
462
|
|
|
slice_dims = self.data.get_slice_dimensions() |
463
|
|
|
|
464
|
|
|
transfer_gsl = self._group_slice_list_in_multiple_dimensions( |
465
|
|
|
transfer_ssl, mft, slice_dims, pad=pad) |
466
|
|
|
|
467
|
|
|
if current_sl: |
468
|
|
|
mfp = self.pData._get_max_frames_process() |
469
|
|
|
current_sl = self._group_slice_list_in_multiple_dimensions( |
470
|
|
|
transfer_ssl, mfp, slice_dims, pad=pad) |
471
|
|
|
split_list = self.pData.split |
472
|
|
|
transfer_gsl = self.__split_frames(transfer_gsl, split_list) if \ |
473
|
|
|
split_list else transfer_gsl |
474
|
|
|
|
475
|
|
|
return transfer_gsl, current_sl |
476
|
|
|
|
477
|
|
|
def _get_padded_data(self, slice_list, end=False): |
478
|
|
|
slice_list = list(slice_list) |
479
|
|
|
pData = self.pData |
480
|
|
|
pad_dims = list(set(self.data.get_core_dimensions() + |
481
|
|
|
(self.data.get_slice_dimensions()))) |
482
|
|
|
pad_list = [] |
483
|
|
|
for i in range(len(slice_list)): |
484
|
|
|
pad_list.append([0, 0]) |
485
|
|
|
|
486
|
|
|
data_dict = self.data.data_info.get_dictionary() |
487
|
|
|
shape = data_dict['orig_shape'] if 'orig_shape' in list(data_dict.keys()) \ |
488
|
|
|
else self.data.get_shape() |
489
|
|
|
|
490
|
|
|
for dim in range(len(pad_dims)): |
491
|
|
|
sl = slice_list[dim] |
492
|
|
|
if sl.start < 0: |
493
|
|
|
pad_list[dim][0] = -sl.start |
494
|
|
|
slice_list[dim] = slice(0, sl.stop, sl.step) |
495
|
|
|
diff = sl.stop - shape[dim] |
496
|
|
|
if diff > 0: |
497
|
|
|
pad_list[dim][1] = diff |
498
|
|
|
slice_list[dim] = \ |
499
|
|
|
slice(slice_list[dim].start, sl.stop - diff, sl.step) |
500
|
|
|
|
501
|
|
|
data = self.data.data[tuple(slice_list)] |
502
|
|
|
|
503
|
|
|
if np.sum(pad_list): |
504
|
|
|
mode = pData.padding.mode if pData.padding else 'edge' |
505
|
|
|
temp = np.pad(data, tuple(pad_list), mode=mode) |
506
|
|
|
return temp |
507
|
|
|
return data |
508
|
|
|
|