@@ -45,14 +45,17 @@ class ArrayProxy(object):
45
45
of the numpy dtypes, starting at a given file position ``offset`` with
46
46
single ``slope`` and ``intercept`` scaling to produce output values.
47
47
48
- The class ``__init__`` requires a ``header`` object with methods:
48
+ The class ``__init__`` requires a spec which defines how the data will be
49
+ read and rescaled. The spec may be a tuple of length 2 - 5, containing the
50
+ shape, storage dtype, offset, slope and intercept, or a ``header`` object
51
+ with methods:
49
52
50
53
* get_data_shape
51
54
* get_data_dtype
52
55
* get_data_offset
53
56
* get_slope_inter
54
57
55
- The header should also have a 'copy' method. This requirement will go away
58
+ A header should also have a 'copy' method. This requirement will go away
56
59
when the deprecated 'header' propoerty goes away.
57
60
58
61
This implementation allows us to deal with Analyze and its variants,
@@ -64,17 +67,32 @@ class ArrayProxy(object):
64
67
"""
65
68
# Assume Fortran array memory layout
66
69
order = 'F'
70
+ _header = None
67
71
68
72
@kw_only_meth (2 )
69
- def __init__ (self , file_like , header , mmap = True ):
73
+ def __init__ (self , file_like , spec , mmap = True ):
70
74
""" Initialize array proxy instance
71
75
72
76
Parameters
73
77
----------
74
78
file_like : object
75
79
File-like object or filename. If file-like object, should implement
76
80
at least ``read`` and ``seek``.
77
- header : object
81
+ spec : object or tuple
82
+ Tuple must have length 2-5, with the following fields:
83
+ - shape : tuple
84
+ tuple of ints describing shape of data
85
+ - storage_dtype : dtype specifier
86
+ dtype of array inside proxied file, or input to ``numpy.dtype``
87
+ to specify array dtype
88
+ - offset : int
89
+ Offset, in bytes, of data array from start of file
90
+ (default: 0)
91
+ - slope : float
92
+ Scaling factor for resulting data (default: 1.0)
93
+ - inter : float
94
+ Intercept for rescaled dadta (default: 0.0)
95
+ OR
78
96
Header object implementing ``get_data_shape``, ``get_data_dtype``,
79
97
``get_data_offset``, ``get_slope_inter``
80
98
mmap : {True, False, 'c', 'r'}, optional, keyword only
@@ -90,16 +108,26 @@ def __init__(self, file_like, header, mmap=True):
90
108
if mmap not in (True , False , 'c' , 'r' ):
91
109
raise ValueError ("mmap should be one of {True, False, 'c', 'r'}" )
92
110
self .file_like = file_like
111
+ if hasattr (spec , 'get_data_shape' ):
112
+ slope , inter = spec .get_slope_inter ()
113
+ par = (spec .get_data_shape (),
114
+ spec .get_data_dtype (),
115
+ spec .get_data_offset (),
116
+ 1. if slope is None else slope ,
117
+ 0. if inter is None else inter )
118
+ # Reference to original header; we will remove this soon
119
+ self ._header = spec .copy ()
120
+ elif 2 <= len (spec ) <= 5 :
121
+ optional = (0 , 1. , 0. )
122
+ par = spec + optional [len (spec ) - 2 :]
123
+ else :
124
+ raise TypeError ('spec must be tuple of length 2-5 or header object' )
125
+
93
126
# Copies of values needed to read array
94
- self ._shape = header .get_data_shape ()
95
- self ._dtype = header .get_data_dtype ()
96
- self ._offset = header .get_data_offset ()
97
- self ._slope , self ._inter = header .get_slope_inter ()
98
- self ._slope = 1.0 if self ._slope is None else self ._slope
99
- self ._inter = 0.0 if self ._inter is None else self ._inter
127
+ self ._shape , self ._dtype , self ._offset , self ._slope , self ._inter = par
128
+ # Permit any specifier that can be interpreted as a numpy dtype
129
+ self ._dtype = np .dtype (self ._dtype )
100
130
self ._mmap = mmap
101
- # Reference to original header; we will remove this soon
102
- self ._header = header .copy ()
103
131
104
132
@property
105
133
def header (self ):
0 commit comments