4
4
5
5
class ActiveOptionsContainer :
6
6
"""
7
- Container for ActiveOptions properties.
7
+ Container for ActiveOptions properties. Only for use within XarrayActive.
8
8
"""
9
9
@property
10
10
def active_options (self ):
@@ -23,28 +23,40 @@ def active_options(self, value):
23
23
24
24
def _set_active_options (self , chunks = {}, chunk_limits = True ):
25
25
26
+ # Auto chunking is not currently supported - 23/08/24
26
27
if chunks == {}:
27
28
raise NotImplementedError (
28
29
'Default chunking is not implemented, please provide a chunk scheme '
29
30
' - active_options = {"chunks": {}}'
30
31
)
32
+
33
+ if 'auto' in chunks .items ():
34
+ raise NotImplementedError (
35
+ 'Auto chunking is not implemented, please provide a chunk scheme '
36
+ ' - active_options = {"chunks": {}}'
37
+ )
31
38
32
39
self ._active_chunks = chunks
33
40
self ._chunk_limits = chunk_limits
34
41
35
- # Holds all Active routines.
36
42
class ActiveChunk :
43
+ """
44
+ Container class for all Active-required methods to perform on each chunk.
45
+ All active-per-chunk content should be found here.
46
+ """
37
47
38
- description = "Container class for Active routines performed on each chunk. All active-per-chunk content can be found here. "
48
+ description = "Container class for Active routines performed on each chunk."
39
49
40
50
def _post_process_data (self , data ):
41
- # Perform any post-processing steps on the data here
51
+ """
52
+ Perform any post-processing steps on the data here.
53
+ """
42
54
return data
43
55
44
56
def _standard_sum (self , axes = None , skipna = None , ** kwargs ):
45
57
"""
46
- Standard Mean routine matches the normal routine for dask, required at this
47
- stage if Active mean not available.
58
+ Standard sum routine matches the normal routine for dask, required at this
59
+ stage if Active mean/sum not available.
48
60
"""
49
61
50
62
arr = np .array (self )
@@ -55,12 +67,31 @@ def _standard_sum(self, axes=None, skipna=None, **kwargs):
55
67
return total
56
68
57
69
def _standard_max (self , axes = None , skipna = None , ** kwargs ):
70
+ """
71
+ Standard max routine if Active not available, warning will be given.
72
+ Kwargs may be necessary to add here.
73
+ """
58
74
return np .max (self , axis = axes )
59
75
60
76
def _standard_min (self , axes = None , skipna = None , ** kwargs ):
77
+ """
78
+ Standard min routine if Active not available, warning will be given.
79
+ Kwargs may be necessary to add here.
80
+ """
61
81
return np .min (self , axis = axes )
62
82
63
83
def _numel (self , method , axes = None ):
84
+ """
85
+ Number of elements remaining after a reduction, to allow
86
+ dask to combine reductions from all different chunks.
87
+ Example:
88
+ (2,3,4) chunk reduced along second dimension. Will
89
+ give a (2,3) array where each value is 4 - for the
90
+ length of the dimension along which a reduction
91
+ took place.
92
+
93
+ """
94
+ # Applied reduction across all axes
64
95
if not axes :
65
96
return self .size
66
97
@@ -91,41 +122,47 @@ def active_method(self, method, axis=None, skipna=None, **kwargs):
91
122
'max' : self ._standard_max ,
92
123
'min' : self ._standard_min
93
124
}
94
- ret = None
125
+ partial = None
95
126
n = self ._numel (method , axes = axis )
96
127
97
128
try :
98
129
from activestorage .active import Active
99
130
except ImportError :
100
131
# Unable to import Active package. Default to using normal mean.
101
132
print ("ActiveWarning: Unable to import active module - defaulting to standard method." )
102
- ret = {
133
+ partial = {
103
134
'n' : n ,
104
135
'total' : standard_methods [method ](axes = axis , skipna = skipna , ** kwargs )
105
136
}
106
137
107
- if not ret :
138
+ if not partial :
108
139
140
+ # Create Active client
109
141
active = Active (self .filename , self .address )
110
142
active .method = method
143
+
144
+ # Fetch extent for this chunk instance.
111
145
extent = tuple (self .get_extent ())
112
146
147
+ # Properly format the 'axis' kwarg.
113
148
if axis == None :
114
149
axis = tuple ([i for i in range (self .ndim )])
115
150
151
+ # Determine reduction parameter for combining chunk results for dask.
116
152
n = self ._numel (method , axes = axis )
117
153
118
154
if len (axis ) == self .ndim :
119
155
data = active [extent ]
120
156
t = self ._post_process_data (data ) * n
121
157
122
- ret = {
158
+ partial = {
123
159
'n' : n ,
124
160
'total' : t
125
161
}
126
162
127
- if not ret :
163
+ if not partial :
128
164
# Experimental Recursive requesting to get each 1D column along the axes being requested.
165
+ # - May be very bad performance due to many requests for (1,1,X) shapes
129
166
range_recursives = []
130
167
for dim in range (self .ndim ):
131
168
if dim not in axis :
@@ -135,17 +172,21 @@ def active_method(self, method, axis=None, skipna=None, **kwargs):
135
172
results = np .array (self ._get_elements (active , range_recursives , hyperslab = []))
136
173
137
174
t = self ._post_process_data (results ) * n
138
- ret = {
175
+ partial = {
139
176
'n' : n ,
140
177
'total' : t
141
178
}
142
179
143
180
if method == 'mean' :
144
- return ret
181
+ return partial
145
182
else :
146
- return ret ['total' ]/ ret ['n' ]
183
+ return partial ['total' ]/ partial ['n' ]
147
184
148
185
def _get_elements (self , active , recursives , hyperslab = []):
186
+ """
187
+ Recursive function to fetch and arrange the appropriate column slices
188
+ from Active.
189
+ """
149
190
dimarray = []
150
191
if not len (recursives ) > 0 :
151
192
0 commit comments