@@ -52,7 +52,10 @@ If you have questions about it, please contact the [IRSA helpdesk](https://irsa.
5252
5353``` {code-cell} ipython3
5454import urllib
55+
56+ import numpy as np
5557import matplotlib.pyplot as plt
58+ from matplotlib.lines import Line2D
5659
5760from astropy.io import fits
5861from astropy.table import QTable
@@ -62,7 +65,7 @@ from astropy.visualization import quantity_support
6265from astroquery.ipac.irsa import Irsa
6366```
6467
65- ## 1. Search for the spectra of a specific galaxy
68+ ## 1. Search for the spectrum of a specific galaxy
6669
6770First, explore what Euclid catalogs are available. Note that we need to use the object ID for our targets to be able to download their spectrum.
6871
@@ -79,13 +82,13 @@ table_1dspectra = 'euclid.objectid_spectrafile_association_q1'
7982## 2. Search for the spectrum of a specific galaxy in the 1D spectra table
8083
8184``` {code-cell} ipython3
82- obj_id = 2739401293646823742
85+ obj_id = 2689918641685825137
8386```
8487
8588We will use TAP and an ASQL query to find the spectral data for our galaxy. (ADQL is the [ IVOA Astronomical Data Query Language] ( https://www.ivoa.net/documents/latest/ADQL.html ) and is based on SQL.)
8689
8790``` {code-cell} ipython3
88- adql_object = f"SELECT * FROM {table_1dspectra} WHERE objectid = {obj_id} AND uri IS NOT NULL "
91+ adql_object = f"SELECT * FROM {table_1dspectra} WHERE objectid = {obj_id}"
8992
9093# Pull the data on this particular galaxy
9194result = Irsa.query_tap(adql_object).to_table()
@@ -112,6 +115,8 @@ Open the large FITS file without loading it entirely into memory, pulling out ju
112115``` {code-cell} ipython3
113116with fits.open(file_uri) as hdul:
114117 spectra = QTable.read(hdul[result['hdu'][0]], format='fits')
118+
119+ spec_header = hdul[result['hdu'][0]].header
115120```
116121
117122``` {code-cell} ipython3
@@ -128,15 +133,85 @@ As we use astropy.visualization's ``quantity_support``, matplotlib automatically
128133quantity_support()
129134```
130135
136+
137+ ``` {note}
138+ The 1D combined spectra table contains 6 columns, below are a few highlights:
139+
140+ - WAVELENGTH is in Angstroms by default
141+ - SIGNAL is the flux and should be multiplied by the FSCALE factor in the header
142+ - MASK values can be used to determine which flux bins to discard. MASK = odd and MASK >=64 means the flux bins not be used.
143+ ```
144+
145+ +++
146+
147+ We investigate the MASK column to see which flux bins are recommended to keep vs "Do Not Use"
148+
131149``` {code-cell} ipython3
132- plt.plot(spectra['WAVELENGTH'].to(u.micron), spectra['SIGNAL'])
150+ plt.plot(spectra['WAVELENGTH']/10000., spectra['MASK'])
151+ plt.xlabel('Wavelength ($\mu$m)')
152+ plt.ylabel('Mask value')
153+ plt.title('Values of MASK by flux bin')
154+ ```
155+
156+ ``` {code-cell} ipython3
157+ spec_header
158+ ```
159+
160+ ## 4. Plot the image of the extracted spectrum
161+
162+ ``` {tip}
163+ As we use astropy.visualization's ``quantity_support``, matplotlib automatically picks up the axis units from the quantitites we plot.
164+ ```
165+
166+ - Convert the wavelength to microns
167+ - Multiple the signal by FSCALE from the header
168+ - Use the MASK column to discard any values where MASK = odd or >=64
169+ - Use the VAR column (variance) to plot the error on the data
170+
171+ ``` {code-cell} ipython3
172+ signal_scaled = spectra['SIGNAL'] * spec_header['FSCALE']
173+
174+ plt.plot(spectra['WAVELENGTH'].to(u.micron), signal_scaled)
133175plt.title(obj_id)
134176```
135177
178+ ``` {code-cell} ipython3
179+ ## Use the MASK column to create a "good mask", just the flux bins to use
180+ bad_mask = (spectra['MASK'].value % 2 == 1) | (spectra['MASK'].value >= 64)
181+ good_mask = ~bad_mask
182+
183+ ## Plot the spectrum in black for the good flux bins and in red for the masked (do not use) flux bins.
184+ for i in range(1, len(wavelength)):
185+ ## Plot good data (black)
186+ if good_mask[i]:
187+ plt.plot(wavelength[i-1:i+1], signal_scaled[i-1:i+1], color='black')
188+ ## Plot bad data (red)
189+ elif bad_mask[i]:
190+ plt.plot(wavelength[i-1:i+1], signal_scaled[i-1:i+1], color='red')
191+
192+
193+ plt.plot(wavelength, np.sqrt(spectra['VAR']) * spec_header['FSCALE'], color='grey', label='Error')
194+
195+ ## Add the line names to the legend
196+ spectrum_line = Line2D([0], [0], color='black', lw=2, label='Spectrum')
197+ bad_line = Line2D([0], [0], color='red', lw=2, label='Do Not Use')
198+ error_line = Line2D([0], [0], color='grey', lw=2, label='Error')
199+ plt.legend(handles=[spectrum_line, bad_line,error_line], loc='upper right')
200+
201+
202+ plt.xlabel('Wavelength ($\mu$m)')
203+ plt.ylabel('Flux ($\mathrm{erg\,\mu m^{-1}\,s^{-1}\,cm^{-2}}$)')
204+ plt.ylim(-0.15E-16, 0.25E-16)
205+ # plt.xlim(1.25,1.85)
206+ plt.title('Object ID is ' + str(obj_id))
207+
208+ plt.show()
209+ ```
210+
136211## About this Notebook
137212
138- ** Author** : Tiffany Meshkat (IPAC Scientist)
213+ ** Author** : Tiffany Meshkat, Anahita Alavi, Anastasia Laity, Andreas Faisst, Brigitta Sipőcz, Dan Masters, Harry Teplitz, Jaladh Singhal, Shoubaneh Hemmati, Vandana Desai
139214
140- ** Updated** : 2025-03-19
215+ ** Updated** : 2025-03-28
141216
142217** Contact:** [ the IRSA Helpdesk] ( https://irsa.ipac.caltech.edu/docs/help_desk.html ) with questions or reporting problems.
0 commit comments