@@ -87,15 +87,15 @@ def init_from_netcdf(cls, nc_var, shape=None, fill=None):
87
87
nc_var .flag_meanings ,
88
88
nc_var .flag_values ,
89
89
getattr (nc_var , "flag_masks" , None ),
90
- name = nc_var .name
90
+ name = nc_var .name ,
91
91
)
92
92
else :
93
93
instance = cls (
94
94
nc_var [:],
95
95
nc_var .flag_meanings ,
96
96
nc_var .flag_values ,
97
97
getattr (nc_var , "flag_masks" , None ),
98
- name = nc_var .name
98
+ name = nc_var .name ,
99
99
)
100
100
101
101
instance ._nc_var = nc_var
@@ -127,26 +127,31 @@ def write_to_netcdf(self, nc_var=None):
127
127
# only write masks if they aren't the default all bits 1 or somethign existed before
128
128
nc_var .flag_masks = self ._flag_masks
129
129
130
- def get_flag (self , flag_meaning ):
130
+ def get_flag (self , flag_meaning , ignore_missing = False ):
131
131
"""
132
132
Get an array of booleans, same length as flags, at each index indicating if flag_meaning was set.
133
133
134
134
:type flag_meaning: str | list[str] | tuple[str]
135
- :param flag_meaning: flag meaning(s) to be looked up
135
+ :param flag_meaning: flag meaning(s) to be looked up, bitwise_or reduced across first axis if multiple
136
+ :type ignore_missing: bool
137
+ :param ignore_missing: if False, raises exception for missing flags, if True assumes missing
138
+ flags are not set.
136
139
:rtype: np.array
137
140
:return: array of booleans where flag_meaning(s) is(are) set
138
141
"""
139
142
140
143
def get (meaning ):
141
- """ Get the meaning of an individual flag_meaning. """
144
+ """Get the meaning of an individual flag_meaning."""
145
+ if ignore_missing and meaning not in self .flag_meanings :
146
+ return np .full_like (self .flags , False , dtype = bool )
142
147
index = self .flag_meanings .index (meaning )
143
148
144
149
# start by default assuming there are no flags set.
145
150
# Do not return a masked array! All value should be either True or False.
146
151
# A flag is either set or not set. There is no inbetween.
147
- default = np .full (self .flags .shape , False , dtype = np . bool )
152
+ default = np .full (self .flags .shape , False , dtype = bool )
148
153
if not np .ma .is_masked (self .flags ):
149
- mask = np .full_like (self .flags , True , np . bool )
154
+ mask = np .full_like (self .flags , True , dtype = bool )
150
155
else :
151
156
mask = ~ np .ma .getmask (self .flags )
152
157
@@ -156,15 +161,15 @@ def get(meaning):
156
161
) == self ._flag_values [index ]
157
162
return default
158
163
164
+ any_set = np .zeros (self .flags .shape , dtype = bool )
159
165
if isinstance (flag_meaning , (list , tuple )):
160
166
# if receive a sequence, or them together.
161
- any_set = np .zeros (self .flags .shape , dtype = np .bool )
162
167
for each in flag_meaning :
163
168
any_set |= get (each )
164
- return any_set
165
169
else :
166
170
# otherwise just get the one.
167
- return get (flag_meaning )
171
+ any_set |= get (flag_meaning )
172
+ return any_set
168
173
169
174
def reduce (self , exclude_mask = 0 , axis = - 1 ):
170
175
"""
@@ -183,7 +188,9 @@ def reduce(self, exclude_mask=0, axis=-1):
183
188
if exclude_mask != 0 :
184
189
exclude_mask = self .flags .dtype .type (exclude_mask )
185
190
excluded_flags_not_set = (self .flags & exclude_mask ) == 0
186
- new_flags = np .ma .bitwise_or .reduce (self .flags * excluded_flags_not_set , axis = axis )
191
+ new_flags = np .ma .bitwise_or .reduce (
192
+ self .flags * excluded_flags_not_set , axis = axis
193
+ )
187
194
else :
188
195
new_flags = np .ma .bitwise_or .reduce (self .flags , axis = axis )
189
196
@@ -197,7 +204,7 @@ def reduce(self, exclude_mask=0, axis=-1):
197
204
def get_flag_at_index (self , flag_meaning , i ):
198
205
"""
199
206
Returns True or False if flag_meaning set at index i?
200
-
207
+
201
208
:type flag_meaning: str
202
209
:param flag_meaning: flag meaning intended to be set
203
210
:type i: int
@@ -215,7 +222,7 @@ def get_flag_at_index(self, flag_meaning, i):
215
222
def get_flags_set_at_index (self , i , exit_on_good = False ):
216
223
"""
217
224
Get a list of the flag_meanings set at a particular index.
218
-
225
+
219
226
:type i: int
220
227
:param i: the index to examine
221
228
:type exit_on_good: bool
@@ -279,7 +286,7 @@ def set_flag(self, flag_meaning, should_be_set, zero_if_unset=False):
279
286
:return: None
280
287
"""
281
288
index = self .flag_meanings .index (flag_meaning )
282
- bool_flags = np .array (should_be_set ).astype (np . bool )
289
+ bool_flags = np .array (should_be_set ).astype (bool )
283
290
if np .ma .is_masked (self .flags ):
284
291
# if it's masked, set initial flag to 0 where going to set flags (from bool_flags)
285
292
masked_modify = bool_flags & np .ma .getmaskarray (self .flags ) | zero_if_unset
@@ -300,7 +307,7 @@ def set_flag_at_index(self, flag_meaning, i):
300
307
AND the original flag with the NOT mask, to 0 out any bits impacting the target location
301
308
of the flag_meaning within the bit vec while leaving the rest set or unset as they were.
302
309
Then, OR the flag value onto the target, preserves all other independent flags set.
303
-
310
+
304
311
:type flag_meaning: str
305
312
:param flag_meaning: flag meaning intended to be set
306
313
:type i: int
@@ -325,7 +332,7 @@ def get_value_for_meaning(self, flag_meaning):
325
332
eg:
326
333
>>> f = FlagWrap([], "good bad", [0, 1])
327
334
>>> f.flags = np.full(10, f.get_value_for_meaning("bad"), dtype=np.uint)
328
-
335
+
329
336
Note: Raises ValueError if flag_meaning is not found.
330
337
331
338
:type flag_meaning: str
@@ -347,7 +354,7 @@ def get_mask_for_meaning(self, flag_meaning):
347
354
masks together in order to test if *any* of those flags are set.
348
355
349
356
Note: Raises ValueError if flag_meaning not found.
350
-
357
+
351
358
:type flag_meaning: str
352
359
:param flag_meaning: string flag name to return corrsponding mask of
353
360
:rtype: int
@@ -369,4 +376,3 @@ def is_valid_meaning(self, flag_meaning):
369
376
:return: if flag_meaning is a valid meaning for the flag.
370
377
"""
371
378
return flag_meaning in self .flag_meanings
372
-
0 commit comments