@@ -633,38 +633,77 @@ def dtype(self):
633633 def is_proxy (self ):
634634 return True
635635
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 ):
653637 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 ):
655644 # We can't load direct from REC file, use inefficient slicing
656- return np .asanyarray (self )[slicer ]
645+ return self ._get_unscaled (())[slicer ]
646+
657647 # Slices all sequential from zero, can use fileslice
658648 # This gives more efficient volume by volume loading, for example
659649 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+
662660 # Broadcast scaling to shape of original data
663- slopes , inters = self ._slice_scaling
664661 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+
666668 # 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 )
668707
669708
670709class PARRECHeader (SpatialHeader ):
0 commit comments