Skip to content

Commit b19747e

Browse files
authored
Merge pull request #125 from ojustino/bkg-overlap-fix
Found cause of background "overlap" error
2 parents 7623865 + e364baf commit b19747e

File tree

4 files changed

+59
-25
lines changed

4 files changed

+59
-25
lines changed

CHANGES.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
Bug Fixes
55
^^^^^^^^^
66

7-
- Improved errors/warnings when background region extends beyond bounds of image. [#127]
8-
7+
- Improved errors/warnings when background region extends beyond bounds of image [#127]
8+
- Fixed boxcar weighting bug that often resulted in peak pixels having weight
9+
above 1 and erroneously triggered overlapping background errors [#125]
910

1011
1.1.0
1112
-----

specreduce/extract.py

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,46 @@
1919
def _get_boxcar_weights(center, hwidth, npix):
2020
"""
2121
Compute weights given an aperture center, half width,
22-
and number of pixels
22+
and number of pixels.
23+
24+
Based on `get_boxcar_weights()` from a JDAT Notebook by Karl Gordon:
25+
https://github.com/spacetelescope/jdat_notebooks/blob/main/notebooks/MIRI_LRS_spectral_extraction/miri_lrs_spectral_extraction.ipynb
26+
27+
Parameters
28+
----------
29+
center : float, required
30+
The index of the aperture's center pixel on the larger image's
31+
cross-dispersion axis.
32+
33+
hwidth : float, required
34+
Half of the aperture's width in the cross-dispersion direction.
35+
36+
npix : float, required
37+
The number of pixels in the larger image's cross-dispersion
38+
axis.
39+
40+
Returns
41+
-------
42+
weights : `~numpy.ndarray`
43+
A 2D image with weights assigned to pixels that fall within the
44+
defined aperture.
2345
"""
24-
weights = np.zeros((npix))
46+
weights = np.zeros(npix)
47+
48+
# shift center from integer to pixel space, where pixel N is [N-0.5, N+0.5),
49+
# not [N, N+1). a pixel's integer index corresponds to its middle, not edge
50+
center += 0.5
2551

26-
# pixels with full weight
27-
fullpixels = [max(0, int(center - hwidth + 1)),
28-
min(int(center + hwidth), npix)]
29-
weights[fullpixels[0]:fullpixels[1]] = 1.0
52+
# pixels given full weight because they sit entirely within the aperture
53+
fullpixels = [max(0, int(np.ceil(center - hwidth))),
54+
min(int(np.floor(center + hwidth)), npix)]
55+
weights[fullpixels[0]:fullpixels[1]] = 1
3056

31-
# pixels at the edges of the boxcar with partial weight
57+
# pixels at the edges of the boxcar with partial weight, if any
3258
if fullpixels[0] > 0:
33-
w = hwidth - (center - fullpixels[0] + 0.5)
34-
if w >= 0:
35-
weights[fullpixels[0] - 1] = w
36-
else:
37-
weights[fullpixels[0]] = 1. + w
59+
weights[fullpixels[0] - 1] = hwidth - (center - fullpixels[0])
3860
if fullpixels[1] < npix:
39-
weights[fullpixels[1]] = hwidth - (fullpixels[1] - center - 0.5)
61+
weights[fullpixels[1]] = hwidth - (fullpixels[1] - center)
4062

4163
return weights
4264

@@ -46,23 +68,26 @@ def _ap_weight_image(trace, width, disp_axis, crossdisp_axis, image_shape):
4668
"""
4769
Create a weight image that defines the desired extraction aperture.
4870
71+
Based on `ap_weight_images()` from a JDAT Notebook by Karl Gordon:
72+
https://github.com/spacetelescope/jdat_notebooks/blob/main/notebooks/MIRI_LRS_spectral_extraction/miri_lrs_spectral_extraction.ipynb
73+
4974
Parameters
5075
----------
51-
trace : Trace
76+
trace : `~specreduce.tracing.Trace`, required
5277
trace object
53-
width : float
78+
width : float, required
5479
width of extraction aperture in pixels
55-
disp_axis : int
80+
disp_axis : int, required
5681
dispersion axis
57-
crossdisp_axis : int
82+
crossdisp_axis : int, required
5883
cross-dispersion axis
59-
image_shape : tuple with 2 elements
84+
image_shape : tuple with 2 elements, required
6085
size (shape) of image
6186
6287
Returns
6388
-------
64-
wimage : 2D image
65-
weight image defining the aperture
89+
wimage : `~numpy.ndarray`
90+
a 2D weight image defining the aperture
6691
"""
6792
wimage = np.zeros(image_shape)
6893
hwidth = 0.5 * width

specreduce/tests/test_extract.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_boxcar_extraction():
5656

5757
trace.set_position(14.3)
5858
spectrum = boxcar(width=4.7)
59-
assert np.allclose(spectrum.flux.value, np.full_like(spectrum.flux.value, 67.0))
59+
assert np.allclose(spectrum.flux.value, np.full_like(spectrum.flux.value, 67.15))
6060

6161

6262
def test_boxcar_outside_image_condition():

specreduce/tests/test_tracing.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ def test_kosmos_trace():
100100
tg = KosmosTrace(img, peak_method='gaussian')
101101
tc = KosmosTrace(img, peak_method='centroid')
102102
tm = KosmosTrace(img, peak_method='max')
103-
# traces should all be close to 100 (note this passes with the current set values, but if
104-
# changing the seed, noise, etc, then this test might need to be updated)
103+
# traces should all be close to 100
104+
# (values may need to be updated on changes to seed, noise, etc.)
105105
assert np.max(abs(tg.trace-100)) < sigma_pix
106106
assert np.max(abs(tc.trace-100)) < 3 * sigma_pix
107107
assert np.max(abs(tm.trace-100)) < 6 * sigma_pix
@@ -116,6 +116,14 @@ def test_kosmos_trace():
116116
img_win_nans = img.copy()
117117
img_win_nans[guess - window:guess + window] = np.nan
118118

119+
# ensure a low bin number is rejected
120+
with pytest.raises(ValueError, match='bins must be >= 4'):
121+
KosmosTrace(img, bins=3)
122+
123+
# ensure number of bins greater than number of dispersion pixels is rejected
124+
with pytest.raises(ValueError, match=r'bins must be <*'):
125+
KosmosTrace(img, bins=ncols)
126+
119127
# error on trace of otherwise valid image with all-nan window around guess
120128
try:
121129
KosmosTrace(img_win_nans, guess=guess, window=window)

0 commit comments

Comments
 (0)