@@ -24,13 +24,13 @@ def test_background(mk_test_img_raw, mk_test_spec_no_spectral_axis,
24
24
25
25
# all the following should be equivalent, whether image's spectral axis
26
26
# is in pixels or physical units:
27
- bg1 = Background (image , [trace - bkg_sep , trace + bkg_sep ], width = bkg_width )
27
+ bg1 = Background (image , [trace - bkg_sep , trace + bkg_sep ], width = bkg_width )
28
28
bg2 = Background .two_sided (image , trace , bkg_sep , width = bkg_width )
29
29
bg3 = Background .two_sided (image , trace_pos , bkg_sep , width = bkg_width )
30
30
assert np .allclose (bg1 .bkg_image ().flux , bg2 .bkg_image ().flux )
31
31
assert np .allclose (bg1 .bkg_image ().flux , bg3 .bkg_image ().flux )
32
32
33
- bg4 = Background (image_um , [trace - bkg_sep , trace + bkg_sep ], width = bkg_width )
33
+ bg4 = Background (image_um , [trace - bkg_sep , trace + bkg_sep ], width = bkg_width )
34
34
bg5 = Background .two_sided (image_um , trace , bkg_sep , width = bkg_width )
35
35
bg6 = Background .two_sided (image_um , trace_pos , bkg_sep , width = bkg_width )
36
36
assert np .allclose (bg1 .bkg_image ().flux , bg4 .bkg_image ().flux )
@@ -74,7 +74,7 @@ def test_background(mk_test_img_raw, mk_test_spec_no_spectral_axis,
74
74
stats = ['average' , 'median' ]
75
75
76
76
for st in stats :
77
- bg = Background (img , trace - bkg_sep , width = bkg_width , statistic = st )
77
+ bg = Background (img , trace - bkg_sep , width = bkg_width , statistic = st )
78
78
assert np .isnan (bg .image .flux ).sum () == 2
79
79
assert np .isnan (bg ._bkg_array ).sum () == 0
80
80
assert np .isnan (bg .bkg_spectrum ().flux ).sum () == 0
@@ -101,7 +101,7 @@ def test_warnings_errors(mk_test_spec_no_spectral_axis):
101
101
with pytest .warns (match = "background window extends beyond image boundaries" ):
102
102
Background .two_sided (image , 7 , 5 , width = 6 )
103
103
104
- trace = ArrayTrace (image , trace = np .arange (10 )+ 20 ) # from 20 to 29
104
+ trace = ArrayTrace (image , trace = np .arange (10 ) + 20 ) # from 20 to 29
105
105
with pytest .warns (match = "background window extends beyond image boundaries" ):
106
106
with pytest .raises (ValueError ,
107
107
match = "background window does not remain in bounds across entire dispersion axis" ): # noqa
@@ -112,8 +112,8 @@ def test_warnings_errors(mk_test_spec_no_spectral_axis):
112
112
with pytest .raises (ValueError , match = "width must be positive" ):
113
113
Background .two_sided (image , 25 , 2 , width = - 1 )
114
114
115
- def test_trace_inputs (mk_test_img_raw ):
116
115
116
+ def test_trace_inputs (mk_test_img_raw ):
117
117
"""
118
118
Tests for the input argument 'traces' to `Background`. This should accept
119
119
a list of or a single Trace object, or a list of or a single (positive)
@@ -143,78 +143,84 @@ def test_trace_inputs(mk_test_img_raw):
143
143
with pytest .raises (ValueError , match = match_str ):
144
144
Background (image , 'non_valid_trace_pos' )
145
145
146
+
146
147
class TestMasksBackground ():
147
148
148
149
"""
149
150
Various test functions to test how masked and non-finite data is handled
150
- in `Background.
151
+ in `Background. There are three currently implemented options for masking
152
+ in Background: filter, omit, and zero-fill.
151
153
"""
152
154
153
155
def mk_img (self , nrows = 4 , ncols = 5 , nan_slices = None ):
154
156
"""
155
- Make a simpleimage to test masking in Background.
156
- Optionally add NaNs to data. Returned array is in u.DN.
157
+ Make a simple gradient image to test masking in Background.
158
+ Optionally add NaNs to data with `nan_slices`. Returned array is in
159
+ u.DN.
157
160
"""
158
161
159
- img = np .tile ((np .arange (1. , ncols + 1 )), (nrows , 1 ))
162
+ img = np .tile ((np .arange (1. , ncols + 1 )), (nrows , 1 ))
160
163
161
164
if nan_slices : # add nans in data
162
165
for s in nan_slices :
163
166
img [s ] = np .nan
164
167
165
168
return img * u .DN
166
169
167
- def test_fully_masked_column (self ):
170
+ @pytest .mark .parametrize ("mask" , ["filter" , "omit" , "zero-fill" ])
171
+ def test_fully_masked_column (self , mask ):
168
172
"""
169
- Test what happens when a full column is masked, not the entire
170
- image. In this case, the background value for that fully-masked
171
- column should be 0.0, with no error or warning raised.
173
+ Test background with some fully-masked columns (not fully masked image).
174
+ In this case, the background value for that fully-masked column should
175
+ be 0.0, with no error or warning raised. This is the case for
176
+ mask_treatment=filter, omit, or zero-fill.
172
177
"""
173
178
174
- img = np . ones (( 12 , 12 ) )
179
+ img = self . mk_img ( nrows = 10 , ncols = 10 )
175
180
img [:, 0 :1 ] = np .nan
176
181
177
- bkg = Background (img , traces = FlatTrace (img , 6 ))
178
-
182
+ bkg = Background (img , traces = FlatTrace (img , 6 ), mask_treatment = mask )
179
183
assert np .all (bkg .bkg_image ().data [:, 0 :1 ] == 0.0 )
180
184
181
-
182
- def test_fully_masked (self ):
185
+ @ pytest . mark . parametrize ( "mask" , [ "filter" , "omit" , "zero-fill" ])
186
+ def test_fully_masked_image (self , mask ):
183
187
"""
184
188
Test that the appropriate error is raised by `Background` when image
185
189
is fully masked/NaN.
186
190
"""
187
191
188
192
with pytest .raises (ValueError , match = 'Image is fully masked.' ):
189
193
# fully NaN image
190
- img = np . zeros (( 4 , 5 ) ) * np .nan
191
- Background (img , traces = FlatTrace (self .mk_img (), 2 ))
194
+ img = self . mk_img ( ) * np .nan
195
+ Background (img , traces = FlatTrace (self .mk_img (), 2 ), mask_treatment = mask )
192
196
193
197
with pytest .raises (ValueError , match = 'Image is fully masked.' ):
194
- # fully masked image (should be equivilant )
198
+ # fully masked image (should be equivalent )
195
199
img = NDData (np .ones ((4 , 5 )), mask = np .ones ((4 , 5 )))
196
- Background (img , traces = FlatTrace (self .mk_img (), 2 ))
200
+ Background (img , traces = FlatTrace (self .mk_img (), 2 ), mask_treatment = mask )
197
201
198
202
# Now test that an image that isn't fully masked, but is fully masked
199
- # within the window determined by `width`, produces the correct result
203
+ # within the window determined by `width`, produces the correct result.
204
+ # only applicable for mask_treatment=filter, because this is the only
205
+ # option that allows a slice of masked values that don't span all rows.
200
206
msg = 'Image is fully masked within background window determined by `width`.'
201
207
with pytest .raises (ValueError , match = msg ):
202
208
img = self .mk_img (nrows = 12 , ncols = 12 , nan_slices = [np .s_ [3 :10 , :]])
203
209
Background (img , traces = FlatTrace (img , 6 ), width = 7 )
204
210
205
211
@pytest .mark .filterwarnings ("ignore:background window extends beyond image boundaries" )
206
212
@pytest .mark .parametrize ("method,expected" ,
207
- [("filter" , np .array ([1. , 2. , 3. , 4. , 5. , 6. , 7. ,
213
+ [("filter" , np .array ([1. , 2. , 3. , 4. , 5. , 6. , 7. ,
208
214
8. , 9. , 10. , 11. , 12. ])),
209
- ("omit" , np .array ([0. , 2. , 3. , 0. , 5. , 6. ,
210
- 7. , 0. , 9. , 10. , 11. , 12. ])),
211
- ("zero-fill" , np .array ([ 0.58333333 , 2. , 3. ,
212
- 2.33333333 , 5. , 6. , 7. ,
213
- 7.33333333 , 9. , 10. , 11. ,
214
- 12. ]))])
215
+ ("omit" , np .array ([0. , 2. , 3. , 0. , 5. , 6. ,
216
+ 7. , 0. , 9. , 10. , 11. , 12. ])),
217
+ ("zero-fill" , np .array ([0.58333333 , 2. , 3. ,
218
+ 2.33333333 , 5. , 6. , 7. ,
219
+ 7.33333333 , 9. , 10. , 11. ,
220
+ 12. ]))])
215
221
def test_mask_treatment_bkg_img_spectrum (self , method , expected ):
216
- """
217
- This test function tests `Backgroud.bkg_image` and
222
+ """
223
+ This test function tests `Backgroud.bkg_image` and
218
224
`Background.bkg_spectrum` when there is masked data. It also tests
219
225
background subtracting the image, and returning the spectrum of the
220
226
background subtracted image. This test is parameterized over all
@@ -227,8 +233,8 @@ def test_mask_treatment_bkg_img_spectrum(self, method, expected):
227
233
228
234
# make image, set some value to nan, which will be masked in the function
229
235
image1 = self .mk_img (nrows = img_size , ncols = img_size ,
230
- nan_slices = [np .s_ [5 :10 , 0 ], np .s_ [7 :12 , 3 ],
231
- np .s_ [2 , 7 ]])
236
+ nan_slices = [np .s_ [5 :10 , 0 ], np .s_ [7 :12 , 3 ],
237
+ np .s_ [2 , 7 ]])
232
238
233
239
# also make an image that doesn't have nonf data values, but has
234
240
# masked values at the same locations, to make sure they give the same
@@ -240,13 +246,13 @@ def test_mask_treatment_bkg_img_spectrum(self, method, expected):
240
246
for image in [image1 , image2 ]:
241
247
242
248
# construct a flat trace in center of image
243
- trace = FlatTrace (image , img_size / 2 )
249
+ trace = FlatTrace (image , img_size / 2 )
244
250
245
251
# create 'Background' object with `mask_treatment` set
246
252
# 'width' should be > size of image to use all pix (but warning will
247
253
# be raised, which we ignore.)
248
254
background = Background (image , mask_treatment = method ,
249
- traces = trace , width = img_size + 1 )
255
+ traces = trace , width = img_size + 1 )
250
256
251
257
# test background image matches 'expected'
252
258
bk_img = background .bkg_image ()
@@ -265,7 +271,7 @@ def test_sub_bkg_image(self):
265
271
"""
266
272
Test that masked and nonfinite data is handled correctly when subtracting
267
273
background from image, for all currently implemented masking
268
- options ('filter', 'omit', and 'zero-fill').
274
+ options ('filter', 'omit', and 'zero-fill').
269
275
"""
270
276
271
277
# make image, set some value to nan, which will be masked in the function
@@ -288,7 +294,7 @@ def test_sub_bkg_image(self):
288
294
# 2d mask is reduced to a 1d mask to mask out full columns in the
289
295
# presence of any nans - this means that (as tested above in
290
296
# `test_mask_treatment_bkg_img_spectrum`) those columns will have 0.0
291
- # background. In this case, image.mask is expanded to mask full
297
+ # background. In this case, image.mask is expanded to mask full
292
298
# columns - the image itself will not have full columns set to np.nan,
293
299
# so there are still valid background subtracted data values in this
294
300
# case, but the corresponding mask for that entire column will be masked.
@@ -314,4 +320,3 @@ def test_sub_bkg_image(self):
314
320
315
321
assert np .all (np .isfinite (subtracted_img_zero_fill .data ))
316
322
assert np .all (subtracted_img_zero_fill .mask == 0 )
317
-
0 commit comments