Skip to content

Commit 33c3f55

Browse files
committed
NF: implement volume by volume reading for PARREC
Use fileslice when we can to do volume-by-volume reading.
1 parent a2747c7 commit 33c3f55

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

nibabel/parrec.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
from .volumeutils import Recoder, array_from_file, BinOpener
103103
from .affines import from_matvec, dot_reduce, apply_affine
104104
from .nifti1 import unit_codes
105+
from .fileslice import fileslice, strided_scalar
105106

106107
# PSL to RAS affine
107108
PSL_TO_RAS = np.array([[0, 0, -1, 0], # L -> R
@@ -562,7 +563,20 @@ def __array__(self):
562563
mmap=self._mmap)
563564

564565
def __getitem__(self, slicer):
565-
return np.asanyarray(self)[slicer]
566+
indices = self._slice_indices
567+
if indices[0] != 0 or np.any(np.diff(indices) != 1):
568+
# We can't load direct from REC file, use inefficient slicing
569+
return np.asanyarray(self)[slicer]
570+
# Slices all sequential from zero, can use fileslice
571+
# This gives more efficient volume by volume loading, for example
572+
with BinOpener(self.file_like) as fileobj:
573+
raw_data = fileslice(fileobj, slicer, self._shape, self._dtype, 0, 'F')
574+
# Broadcast scaling to shape of original data
575+
slopes, inters = self._slice_scaling
576+
fake_data = strided_scalar(self._shape)
577+
_, slopes, inters = np.broadcast_arrays(fake_data, slopes, inters)
578+
# Slice scaling to give output shape
579+
return raw_data * slopes[slicer] + inters[slicer]
566580

567581

568582
class PARRECHeader(Header):

0 commit comments

Comments
 (0)