Skip to content

Commit 0e07910

Browse files
ibuskokecnry
andauthored
Boxcar extraction using Trace class (#82)
* initial implementation of boxcar extract without background subtraction Co-authored-by: Kyle Conroy <kyleconroy@gmail.com>
1 parent 43c3b52 commit 0e07910

File tree

3 files changed

+429
-262
lines changed

3 files changed

+429
-262
lines changed
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Boxcar extraction with specreduce"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"This notebook demonstrates a simplified boxcar extraction scenario, using a rectified spectrum in a 2D spectral image where the dispersion axis is the second (X) axis. \n",
15+
"\n",
16+
"The extraction algorithm in `specreduce` is a plain adaptation of the algorithm presented in the MIRI LRS extraction notebook at https://github.com/spacetelescope/jdat_notebooks/tree/main/notebooks/MIRI_LRS_spectral_extraction This algorithm is demonstrated separately from the `specreduce` package, in the acompanying notebook http://localhost:8888/notebooks/notebook_sandbox/jwst_boxcar/jwst_boxcar_algorithm.ipynb\n",
17+
"\n",
18+
"Note that the extraction algorithm in the MIRI LRS extraction notebook performs simultaneous background subtraction when extracting from the source. Although it can only subtract the average of the two background extraction boxes. The original extraction code in `specreduce`'s `BoxcarExtract` class was capable of modeling the background with a polynomial along the cross-dispersion direction. This feature was lost in the conversion. \n",
19+
"\n",
20+
"Note also that we cannot yet perform offline, after-the-fact background subtractions from spectra extracted with `BoxcarExtract`. The reason is that `BoxcarExtract` delivers its `Spectrum1D` product with `spectral_axis` in units of `pixel`. Subsequent operations with such spectra, such as subtraction, are severely limited due to the `pixel` units."
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": null,
26+
"metadata": {
27+
"slideshow": {
28+
"slide_type": "fragment"
29+
}
30+
},
31+
"outputs": [],
32+
"source": [
33+
"from matplotlib.colors import LogNorm\n",
34+
"%matplotlib inline\n",
35+
"\n",
36+
"from pathlib import Path\n",
37+
"from zipfile import ZipFile\n",
38+
"\n",
39+
"from astropy.io import fits\n",
40+
"from astropy.table import Table\n",
41+
"from astropy.visualization import simple_norm\n",
42+
"from astropy.utils.data import download_file\n",
43+
"\n",
44+
"from jwst import datamodels\n",
45+
"\n",
46+
"from specreduce.extract import BoxcarExtract\n",
47+
"from specreduce.tracing import FlatTrace\n",
48+
"\n",
49+
"import os\n",
50+
"import tempfile\n",
51+
"\n",
52+
"import numpy as np\n",
53+
"import ccdproc\n",
54+
"\n",
55+
"import matplotlib.pyplot as plt\n",
56+
"import matplotlib as mpl"
57+
]
58+
},
59+
{
60+
"cell_type": "markdown",
61+
"metadata": {},
62+
"source": [
63+
"## Ingest s2d data"
64+
]
65+
},
66+
{
67+
"cell_type": "code",
68+
"execution_count": null,
69+
"metadata": {},
70+
"outputs": [],
71+
"source": [
72+
"# data is taken from s2d file. x1d is used for comparison with pipeline extraction.\n",
73+
"zipped_datapath = Path(download_file('https://stsci.box.com/shared/static/qdj79y7rv99wuui2hot0l3kg5ohq0ah9.zip', cache=True))\n",
74+
"\n",
75+
"data_dir = Path(tempfile.gettempdir())\n",
76+
"\n",
77+
"with ZipFile(zipped_datapath, 'r') as sample_data_zip:\n",
78+
" sample_data_zip.extractall(data_dir)\n",
79+
"\n",
80+
"s2dfile = str(data_dir / \"nirspec_fssim_d1_s2d.fits\")\n",
81+
"x1dfile = str(data_dir / \"nirspec_fssim_d1_x1d.fits\")"
82+
]
83+
},
84+
{
85+
"cell_type": "code",
86+
"execution_count": null,
87+
"metadata": {},
88+
"outputs": [],
89+
"source": [
90+
"# use a jwst datamodel to provide a good interface to the data and wcs info\n",
91+
"s2d = datamodels.open(s2dfile)\n",
92+
"image = s2d.slits[0].data"
93+
]
94+
},
95+
{
96+
"cell_type": "code",
97+
"execution_count": null,
98+
"metadata": {},
99+
"outputs": [],
100+
"source": [
101+
"# display s2d image\n",
102+
"norm_data = simple_norm(image, \"sqrt\")\n",
103+
"plt.figure(figsize=(15, 15))\n",
104+
"plt.imshow(image, norm=norm_data, origin=\"lower\")\n",
105+
"plt.title(\"slit[0]\")"
106+
]
107+
},
108+
{
109+
"cell_type": "code",
110+
"execution_count": null,
111+
"metadata": {
112+
"scrolled": false
113+
},
114+
"outputs": [],
115+
"source": [
116+
"# pipeline 1d extraction (for comparison)\n",
117+
"jpipe_x1d = Table.read(x1dfile, hdu=1)\n",
118+
"print(jpipe_x1d.columns)\n",
119+
"# plot\n",
120+
"fig, ax = plt.subplots(figsize=(10, 6))\n",
121+
"ax.plot(jpipe_x1d['WAVELENGTH'], jpipe_x1d['FLUX'], 'k-', label=\"jpipe_x1d\")\n",
122+
"ax.set_title(\"JWST Pipeline x1d extracted spectrum\")\n",
123+
"ax.set_xlabel(\"wavelength\")\n",
124+
"ax.set_ylabel(\"Flux Density [Jy]\")\n",
125+
"ax.set_yscale(\"log\")"
126+
]
127+
},
128+
{
129+
"cell_type": "markdown",
130+
"metadata": {},
131+
"source": [
132+
"## Define region to be extracted"
133+
]
134+
},
135+
{
136+
"cell_type": "markdown",
137+
"metadata": {},
138+
"source": [
139+
"At this point, `specreduce` doesn't provide a tool for finding the trace. Since this is rectified data, we can use the `FlatTrace` class and find the spectrum position and width by eye."
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": null,
145+
"metadata": {},
146+
"outputs": [],
147+
"source": [
148+
"# blow up of the region to be extracted\n",
149+
"plt.figure(figsize=(15, 15))\n",
150+
"plt.imshow(image[::,0:100], norm=norm_data, origin=\"lower\")\n",
151+
"plt.title(\"slit[0] slice\")"
152+
]
153+
},
154+
{
155+
"cell_type": "code",
156+
"execution_count": null,
157+
"metadata": {},
158+
"outputs": [],
159+
"source": [
160+
"# extraction parameters based on image above\n",
161+
"ext_center = 27\n",
162+
"ext_width = 4"
163+
]
164+
},
165+
{
166+
"cell_type": "code",
167+
"execution_count": null,
168+
"metadata": {},
169+
"outputs": [],
170+
"source": [
171+
"# Plot along cross-disperion cut showing the extraction parameters\n",
172+
"fig, ax = plt.subplots(figsize=(10, 6))\n",
173+
"y = np.arange(image.shape[0])\n",
174+
"ax.plot(y, image[:,70], 'k-')\n",
175+
"mm = np.array([ext_center, ext_center])\n",
176+
"mm_y = ax.get_ylim()\n",
177+
"\n",
178+
"ax.plot(mm, mm_y, 'b--')\n",
179+
"ax.plot(mm - ext_width/2., mm_y, 'g:')\n",
180+
"ax.plot(mm + ext_width/2., mm_y, 'g:')\n",
181+
"\n",
182+
"ax.set_title(\"Cross-dispersion Cut at Pixel=70\")"
183+
]
184+
},
185+
{
186+
"cell_type": "markdown",
187+
"metadata": {},
188+
"source": [
189+
"## Extract"
190+
]
191+
},
192+
{
193+
"cell_type": "code",
194+
"execution_count": null,
195+
"metadata": {
196+
"scrolled": false
197+
},
198+
"outputs": [],
199+
"source": [
200+
"# define the Trace\n",
201+
"trace = FlatTrace(image, ext_center)"
202+
]
203+
},
204+
{
205+
"cell_type": "code",
206+
"execution_count": null,
207+
"metadata": {},
208+
"outputs": [],
209+
"source": [
210+
"# extract\n",
211+
"boxcar = BoxcarExtract()\n",
212+
"spectrum = boxcar(image, trace, width=ext_width)"
213+
]
214+
},
215+
{
216+
"cell_type": "code",
217+
"execution_count": null,
218+
"metadata": {},
219+
"outputs": [],
220+
"source": [
221+
"# plot \n",
222+
"f, ax = plt.subplots(figsize=(10, 6))\n",
223+
"ax.plot(spectrum.flux.value, 'k-')\n",
224+
"ax.set_title(\"Boxcar 1D extracted spectrum\")\n",
225+
"ax.set_xlabel(r\"pixel\")\n",
226+
"ax.set_ylabel(\"Flux Density [Jy]\")\n",
227+
"ax.set_yscale(\"log\")"
228+
]
229+
},
230+
{
231+
"cell_type": "markdown",
232+
"metadata": {
233+
"slideshow": {
234+
"slide_type": "slide"
235+
}
236+
},
237+
"source": [
238+
"## About this notebook\n",
239+
"\n",
240+
"**Author:** Ivo Busko, JWST\n",
241+
"**Updated On:** 2022-02-18"
242+
]
243+
},
244+
{
245+
"cell_type": "markdown",
246+
"metadata": {},
247+
"source": [
248+
"***"
249+
]
250+
},
251+
{
252+
"cell_type": "markdown",
253+
"metadata": {},
254+
"source": [
255+
"[Top of Page](#top)\n",
256+
"<img style=\"float: right;\" src=\"https://raw.githubusercontent.com/spacetelescope/notebooks/master/assets/stsci_pri_combo_mark_horizonal_white_bkgd.png\" alt=\"Space Telescope Logo\" width=\"200px\"/> "
257+
]
258+
}
259+
],
260+
"metadata": {
261+
"kernelspec": {
262+
"display_name": "Python 3 (ipykernel)",
263+
"language": "python",
264+
"name": "python3"
265+
},
266+
"language_info": {
267+
"codemirror_mode": {
268+
"name": "ipython",
269+
"version": 3
270+
},
271+
"file_extension": ".py",
272+
"mimetype": "text/x-python",
273+
"name": "python",
274+
"nbconvert_exporter": "python",
275+
"pygments_lexer": "ipython3",
276+
"version": "3.8.12"
277+
}
278+
},
279+
"nbformat": 4,
280+
"nbformat_minor": 2
281+
}

0 commit comments

Comments
 (0)