@@ -633,38 +633,77 @@ def dtype(self):
633
633
def is_proxy (self ):
634
634
return True
635
635
636
- def get_unscaled (self ):
637
- with ImageOpener (self .file_like ) as fileobj :
638
- return _data_from_rec (fileobj , self ._rec_shape , self ._dtype ,
639
- self ._slice_indices , self ._shape ,
640
- mmap = self ._mmap )
641
-
642
- def __array__ (self ):
643
- with ImageOpener (self .file_like ) as fileobj :
644
- return _data_from_rec (fileobj ,
645
- self ._rec_shape ,
646
- self ._dtype ,
647
- self ._slice_indices ,
648
- self ._shape ,
649
- scalings = self ._slice_scaling ,
650
- mmap = self ._mmap )
651
-
652
- def __getitem__ (self , slicer ):
636
+ def _get_unscaled (self , slicer ):
653
637
indices = self ._slice_indices
654
- if indices [0 ] != 0 or np .any (np .diff (indices ) != 1 ):
638
+ if slicer == ():
639
+ with ImageOpener (self .file_like ) as fileobj :
640
+ rec_data = array_from_file (self ._rec_shape , self ._dtype , fileobj , mmap = self ._mmap )
641
+ rec_data = rec_data [..., indices ]
642
+ return rec_data .reshape (self ._shape , order = 'F' )
643
+ elif indices [0 ] != 0 or np .any (np .diff (indices ) != 1 ):
655
644
# We can't load direct from REC file, use inefficient slicing
656
- return np .asanyarray (self )[slicer ]
645
+ return self ._get_unscaled (())[slicer ]
646
+
657
647
# Slices all sequential from zero, can use fileslice
658
648
# This gives more efficient volume by volume loading, for example
659
649
with ImageOpener (self .file_like ) as fileobj :
660
- raw_data = fileslice (fileobj , slicer , self ._shape , self ._dtype , 0 ,
661
- 'F' )
650
+ return fileslice (fileobj , slicer , self ._shape , self ._dtype , 0 , 'F' )
651
+
652
+ def _get_scaled (self , dtype , slicer ):
653
+ raw_data = self ._get_unscaled (slicer )
654
+ if self ._slice_scaling is None :
655
+ if dtype is None :
656
+ return raw_data
657
+ final_type = np .promote_types (raw_data .dtype , dtype )
658
+ return raw_data .astype (final_type , copy = False )
659
+
662
660
# Broadcast scaling to shape of original data
663
- slopes , inters = self ._slice_scaling
664
661
fake_data = strided_scalar (self ._shape )
665
- _ , slopes , inters = np .broadcast_arrays (fake_data , slopes , inters )
662
+ _ , slopes , inters = np .broadcast_arrays (fake_data , * self ._slice_scaling )
663
+
664
+ final_type = np .result_type (raw_data , slopes , inters )
665
+ if dtype is not None :
666
+ final_type = np .promote_types (final_type , dtype )
667
+
666
668
# Slice scaling to give output shape
667
- return raw_data * slopes [slicer ] + inters [slicer ]
669
+ return raw_data * slopes [slicer ].astype (final_type ) + inters [slicer ].astype (final_type )
670
+
671
+
672
+ def get_unscaled (self ):
673
+ """ Read data from file
674
+
675
+ This is an optional part of the proxy API
676
+ """
677
+ return self ._get_unscaled (slicer = ())
678
+
679
+ def get_scaled (self , dtype = None ):
680
+ """ Read data from file and apply scaling
681
+
682
+ The dtype of the returned array is the narrowest dtype that can
683
+ represent the data without overflow, and is at least as wide as
684
+ the dtype parameter.
685
+
686
+ If dtype is unspecified, it is the wider of the dtypes of the slopes
687
+ or intercepts
688
+
689
+ Parameters
690
+ ----------
691
+ dtype : numpy dtype specifier
692
+ A numpy dtype specifier specifying the narrowest acceptable
693
+ dtype.
694
+
695
+ Returns
696
+ -------
697
+ array
698
+ Scaled of image data of data type `dtype`.
699
+ """
700
+ return self ._get_scaled (dtype = dtype , slicer = ())
701
+
702
+ def __array__ (self ):
703
+ return self ._get_scaled (dtype = None , slicer = ())
704
+
705
+ def __getitem__ (self , slicer ):
706
+ return self ._get_scaled (dtype = None , slicer = slicer )
668
707
669
708
670
709
class PARRECHeader (SpatialHeader ):
0 commit comments