def deimos_spectrum1D_reader(file_name): """ Data loader for Keck/DEIMOS 1D spectra. This loads the 'Bxspf-B' (extension 1) and 'Bxspf-R' (extension 2) and appends them together to proudce the combined Red/Blue Spectrum along with their Wavelength and Inverse Variance arrays. """ with fits.open(file_name) as hdulist: data = Data(label='1D Spectrum') hdulist[1].header['CTYPE1'] = 'WAVE' hdulist[1].header['CUNIT1'] = 'Angstrom' data.header = hdulist[1].header wcs = WCS(hdulist[1].header) data.coords = coordinates_from_wcs(wcs) full_wl = np.append(hdulist[1].data['LAMBDA'][0], hdulist[2].data['LAMBDA'][0]) full_spec = np.append(hdulist[1].data['SPEC'][0], hdulist[2].data['SPEC'][0]) full_ivar = np.append(hdulist[1].data['IVAR'][0], hdulist[2].data['IVAR'][0]) data.add_component(full_wl, 'Wavelength') data.add_component(full_spec, 'Flux') data.add_component(1 / np.sqrt(full_ivar), 'Uncertainty') return data
def nirspec_spectrum1d_reader(file_name): """ Data loader for MOSViz 1D spectrum. This function extracts the DATA, QUALITY, and VAR extensions and returns them as a glue Data object. It then uses the header keywords of the DATA extension to detemine the wavelengths. """ hdulist = fits.open(file_name) # make wavelength a seperate component in addition to coordinate # so you can plot it on the x axis wavelength = np.linspace(hdulist['DATA'].header['CRVAL1'], hdulist['DATA'].header['CRVAL1']*hdulist['DATA'].header['CDELT1'], hdulist['DATA'].header['NAXIS1'])[::-1] data = Data(label='1D Spectrum') data.header = hdulist['DATA'].header data.add_component(wavelength, 'Wavelength') data.add_component(hdulist['DATA'].data, 'Flux') data.add_component(hdulist['VAR'].data, 'Uncertainty') return data
def pre_nirspec_spectrum1d_reader(file_name): """ Data loader for MOSViz 1D spectrum. This function extracts the DATA, QUALITY, and VAR extensions and returns them as a glue Data object. It then uses the header keywords of the DATA extension to detemine the wavelengths. """ hdulist = fits.open(file_name) # make wavelength a seperate component in addition to coordinate # so you can plot it on the x axis wavelength = np.linspace( hdulist['DATA'].header['CRVAL1'], hdulist['DATA'].header['CRVAL1'] * hdulist['DATA'].header['CDELT1'], hdulist['DATA'].header['NAXIS1'])[::-1] data = Data(label='1D Spectrum') data.header = hdulist['DATA'].header data.add_component(wavelength, 'Wavelength') data.add_component(hdulist['DATA'].data, 'Flux') data.add_component(np.sqrt(hdulist['VAR'].data), 'Uncertainty') hdulist.close() return data
def deimos_spectrum1D_reader(file_name): """ Data loader for Keck/DEIMOS 1D spectra. This loads the 'Bxspf-B' (extension 1) and 'Bxspf-R' (extension 2) and appends them together to proudce the combined Red/Blue Spectrum along with their Wavelength and Inverse Variance arrays. """ with fits.open(file_name) as hdulist: data = Data(label='1D Spectrum') hdulist[1].header['CTYPE1'] = 'WAVE' hdulist[1].header['CUNIT1'] = 'Angstrom' data.header = hdulist[1].header wcs = WCS(hdulist[1].header) data.coords = coordinates_from_wcs(wcs) full_wl = np.append(hdulist[1].data['LAMBDA'][0], hdulist[2].data['LAMBDA'][0]) full_spec = np.append(hdulist[1].data['SPEC'][0], hdulist[2].data['SPEC'][0]) full_ivar = np.append(hdulist[1].data['IVAR'][0], hdulist[2].data['IVAR'][0]) data.add_component(full_wl, 'Wavelength') data.add_component(full_spec, 'Flux') data.add_component(1 / np.sqrt(full_ivar), 'Uncertainty') return data
def deimos_spectrum1D_reader(file_name): """ Data loader for Keck/DEIMOS 1D spectra. This loads the 'Bxspf-B' (extension 1) and 'Bxspf-R' (extension 2) and appends them together to proudce the combined Red/Blue Spectrum along with their Wavelength and Inverse Variance arrays. """ hdulist = fits.open(file_name) data = Data(label='1D Spectrum') data.header = hdulist[1].header full_wl = np.append(hdulist[1].data['LAMBDA'][0], hdulist[2].data['LAMBDA'][0]) full_spec = np.append(hdulist[1].data['SPEC'][0], hdulist[2].data['SPEC'][0]) full_ivar = np.append(hdulist[1].data['IVAR'][0], hdulist[2].data['IVAR'][0]) data.add_component(full_wl, 'Wavelength') data.add_component(full_spec, 'Flux') data.add_component(1 / np.sqrt(full_ivar), 'Uncertainty') return data
def nirspec_spectrum1d_reader(file_name): with fits.open(file_name) as hdulist: header = hdulist['PRIMARY'].header tab = Table.read(file_name) data = Data(label="1D Spectrum") data.header = header data.add_component(tab['WAVELENGTH'], "Wavelength") data.add_component(tab['FLUX'], "Flux") data.add_component(tab['ERROR'], "Uncertainty") return data
def pre_nirspec_level2_reader(file_name): """ THIS IS A TEST! """ #TODO The level 2 file has multiple exposures. #TODO the level 2 test file has SCI extensions with different shapes. #TODO hdulist = fits.open(file_name) data = Data(label='2D Spectra') hdulist[1].header['CTYPE2'] = 'Spatial Y' data.header = hdulist[1].header # This is a stop gap fix to let fake data be ingested as # level 2 apectra. The level 2 file we have for testing # right now has SCI extensions with different sized arrays # among them. It remains to be seen if this is a expected # feature of level 2 spectra, or just a temporary glitch. # In case it's actually what lvel 2 spectral files look # like, proper handling must be put in place to allow # glue Data objects with different sized components. Or, # if that is not feasible, to properly cut the arrays so # as to make them all of the same size. The solution below # is a naive interpretation of this concept. x_min = 10000 y_min = 10000 for k in range(1, len(hdulist)): if 'SCI' in hdulist[k].header['EXTNAME']: x_min = min(x_min, hdulist[k].data.shape[0]) y_min = min(y_min, hdulist[k].data.shape[1]) # hdulist[k].header['CTYPE2'] = 'Spatial Y' # wcs = WCS(hdulist[1].header) # original WCS has both axes named "LAMBDA", glue requires unique component names # data.coords = coordinates_from_wcs(wcs) # data.header = hdulist[k].header # data.add_component(hdulist[1].data['FLUX'][0], 'Flux') count = 1 for k in range(1, len(hdulist)): if 'SCI' in hdulist[k].header['EXTNAME']: data.add_component(hdulist[k].data[0:x_min, 0:y_min], 'Flux_' + '{:03d}'.format(count)) count += 1 # data.add_component(1 / np.sqrt(hdulist[1].data['IVAR'][0]), 'Uncertainty') return data
def acs_cutout_image_reader(file_name): """ Data loader for the ACS cut-outs for the DEIMOS spectra. The cutouts contain only the image. """ hdulist = fits.open(file_name) data = Data(label='ACS Cutout Image') data.coords = coordinates_from_header(hdulist[0].header) data.header = hdulist[0].header data.add_component(hdulist[0].data, 'Flux') return data
def pre_nirspec_level2_reader(file_name): """ THIS IS A TEST! """ #TODO The level 2 file has multiple exposures. #TODO the level 2 test file has SCI extensions with different shapes. #TODO hdulist = fits.open(file_name) data = Data(label='2D Spectra') hdulist[1].header['CTYPE2'] = 'Spatial Y' data.header = hdulist[1].header # This is a stop gap fix to let fake data be ingested as # level 2 apectra. The level 2 file we have for testing # right now has SCI extensions with different sized arrays # among them. It remains to be seen if this is a expected # feature of level 2 spectra, or just a temporary glitch. # In case it's actually what lvel 2 spectral files look # like, proper handling must be put in place to allow # glue Data objects with different sized components. Or, # if that is not feasible, to properly cut the arrays so # as to make them all of the same size. The solution below # is a naive interpretation of this concept. x_min = 10000 y_min = 10000 for k in range(1, len(hdulist)): if 'SCI' in hdulist[k].header['EXTNAME']: x_min = min(x_min, hdulist[k].data.shape[0]) y_min = min(y_min, hdulist[k].data.shape[1]) # hdulist[k].header['CTYPE2'] = 'Spatial Y' # wcs = WCS(hdulist[1].header) # original WCS has both axes named "LAMBDA", glue requires unique component names # data.coords = coordinates_from_wcs(wcs) # data.header = hdulist[k].header # data.add_component(hdulist[1].data['FLUX'][0], 'Flux') count = 1 for k in range(1, len(hdulist)): if 'SCI' in hdulist[k].header['EXTNAME']: data.add_component(hdulist[k].data[0:x_min, 0:y_min], 'Flux_' + '{:03d}'.format(count)) count += 1 # data.add_component(1 / np.sqrt(hdulist[1].data['IVAR'][0]), 'Uncertainty') return data
def acs_cutout_image_reader(file_name): """ Data loader for the ACS cut-outs for the DEIMOS spectra. The cutouts contain only the image. """ hdulist = fits.open(file_name) data = Data(label='ACS Cutout Image') data.coords = coordinates_from_header(hdulist[0].header) data.header = hdulist[0].header data.add_component(hdulist[0].data, 'Flux') return data
def nirspec_spectrum1d_reader(file_name): with fits.open(file_name) as hdulist: header = hdulist['PRIMARY'].header tab = Table.read(file_name, hdu=1) data = Data(label="1D Spectrum") data.header = header # This assumes the wavelength is in microns data.coords = SpectralCoordinates(tab['WAVELENGTH'] * u.micron) data.add_component(tab['WAVELENGTH'], "Wavelength") data.add_component(tab['FLUX'], "Flux") data.add_component(tab['ERROR'], "Uncertainty") return data
def nirspec_spectrum2d_reader(file_name): """ Data loader for simulated NIRSpec 2D spectrum. This function extracts the DATA, QUALITY, and VAR extensions and returns them as a glue Data object. It then uses the header keywords of the DATA extension to detemine the wavelengths. """ hdulist = fits.open(file_name) data = Data(label='2D Spectrum') data.header = hdulist['DATA'].header data.coords = coordinates_from_header(hdulist[1].header) data.add_component(hdulist['DATA'].data, 'Flux') data.add_component(np.sqrt(hdulist['VAR'].data), 'Uncertainty') return data
def deimos_spectrum2D_reader(file_name): """ Data loader for Keck/DEIMOS 2D spectra. This loads only the Flux and Inverse variance. Wavelength information comes from the WCS. """ hdulist = fits.open(file_name) data = Data(label='2D Spectrum') hdulist[1].header['CTYPE2'] = 'Spatial Y' wcs = WCS(hdulist[1].header) # original WCS has both axes named "LAMBDA", glue requires unique component names data.coords = coordinates_from_wcs(wcs) data.header = hdulist[1].header data.add_component(hdulist[1].data['FLUX'][0], 'Flux') data.add_component(hdulist[1].data['IVAR'][0], 'Uncertainty') return data
def nirspec_spectrum1d_reader(file_name): file_name, ext = split_file_name(file_name, default_ext=1) with fits.open(file_name) as hdulist: header = hdulist['PRIMARY'].header tab = Table.read(file_name, hdu=ext) data = Data(label="1D Spectrum") data.header = header # This assumes the wavelength is in microns data.coords = SpectralCoordinates(np.array(tab['WAVELENGTH']) * u.micron) data.add_component(tab['WAVELENGTH'], "Wavelength") data.add_component(tab['FLUX'], "Flux") data.add_component(tab['ERROR'], "Uncertainty") return data
def nirspec_spectrum2d_reader(file_name): """ Data loader for simulated NIRSpec 2D spectrum. This function extracts the DATA, QUALITY, and VAR extensions and returns them as a glue Data object. It then uses the header keywords of the DATA extension to detemine the wavelengths. """ hdulist = fits.open(file_name) data = Data(label='2D Spectrum') data.header = hdulist['DATA'].header data.coords = coordinates_from_header(hdulist[1].header) data.add_component(hdulist['DATA'].data, 'Flux') data.add_component(hdulist['VAR'].data, 'Uncertainty') return data
def deimos_spectrum2D_reader(file_name): """ Data loader for Keck/DEIMOS 2D spectra. This loads only the Flux and Inverse variance. Wavelength information comes from the WCS. """ hdulist = fits.open(file_name) data = Data(label='2D Spectrum') hdulist[1].header['CTYPE2'] = 'Spatial Y' wcs = WCS(hdulist[1].header) # original WCS has both axes named "LAMBDA", glue requires unique component names data.coords = coordinates_from_wcs(wcs) data.header = hdulist[1].header data.add_component(hdulist[1].data['FLUX'][0], 'Flux') data.add_component(1 / np.sqrt(hdulist[1].data['IVAR'][0]), 'Uncertainty') return data
def pre_nircam_image_reader(file_name): """ Data loader for simulated NIRCam image. This is for the full image, where cut-outs will be created on the fly. From the header: If ISWFS is T, structure is: - Plane 1: Signal [frame3 - frame1] in ADU - Plane 2: Signal uncertainty [sqrt(2*RN/g + \|frame3\|)] If ISWFS is F, structure is: - Plane 1: Signal from linear fit to ramp [ADU/sec] - Plane 2: Signal uncertainty [ADU/sec] Note that in the later case, the uncertainty is simply the formal uncertainty in the fit parameter (eg. uncorrelated, WRONG!). Noise model to be implemented at a later date. In the case of WFS, error is computed as SQRT(2*sigma_read + \|frame3\|) which should be a bit more correct - ~Fowler sampling. The FITS file has a single extension with a data cube. The data is the first slice of the cube and the uncertainty is the second slice. """ hdulist = fits.open(file_name) data = Data(label='NIRCam Image') data.header = hdulist[0].header wcs = WCS(hdulist[0].header) # drop the last axis since the cube will be split data.coords = coordinates_from_wcs(wcs) data.add_component(hdulist[0].data, 'Flux') data.add_component(hdulist[0].data / 100, 'Uncertainty') hdulist.close() return data
def pre_nircam_image_reader(file_name): """ Data loader for simulated NIRCam image. This is for the full image, where cut-outs will be created on the fly. From the header: If ISWFS is T, structure is: - Plane 1: Signal [frame3 - frame1] in ADU - Plane 2: Signal uncertainty [sqrt(2*RN/g + \|frame3\|)] If ISWFS is F, structure is: - Plane 1: Signal from linear fit to ramp [ADU/sec] - Plane 2: Signal uncertainty [ADU/sec] Note that in the later case, the uncertainty is simply the formal uncertainty in the fit parameter (eg. uncorrelated, WRONG!). Noise model to be implemented at a later date. In the case of WFS, error is computed as SQRT(2*sigma_read + \|frame3\|) which should be a bit more correct - ~Fowler sampling. The FITS file has a single extension with a data cube. The data is the first slice of the cube and the uncertainty is the second slice. """ hdulist = fits.open(file_name) data = Data(label='NIRCam Image') data.header = hdulist[0].header wcs = WCS(hdulist[0].header) # drop the last axis since the cube will be split data.coords = coordinates_from_wcs(wcs) data.add_component(hdulist[0].data, 'Flux') data.add_component(hdulist[0].data / 100, 'Uncertainty') hdulist.close() return data
def nirspec_level2_reader(file_name): """ Data Loader for level2 products. Uses extension information to index fits hdu list. The ext info is included in the file_name as follows: <file_path>[<ext>] """ file_name, ext = split_file_name(file_name, default_ext=1) hdulist = fits.open(file_name) data = Data(label="2D Spectra") data.header = hdulist[ext].header data.coords = coordinates_from_header(hdulist[ext].header) data.add_component(hdulist[ext].data, 'Level2 Flux') # TODO: update uncertainty once data model becomes clear data.add_component(np.sqrt(hdulist[ext + 2].data), 'Level2 Uncertainty') hdulist.close() return data
def nirspec_level2_reader(file_name): """ Data Loader for level2 products. Uses extension information to index fits hdu list. The ext info is included in the file_name as follows: <file_path>[<ext>] """ file_name, ext = split_file_name(file_name) hdulist = fits.open(file_name) data = Data(label="2D Spectra") data.header = hdulist[ext].header data.coords = coordinates_from_header(hdulist[ext].header) data.add_component(hdulist[ext].data, 'Level2 Flux') # TODO: update uncertainty once data model becomes clear data.add_component(np.sqrt(hdulist[ext + 2].data), 'Level2 Uncertainty') hdulist.close() return data
def nirspec_spectrum2d_reader(file_name): """ Data loader for simulated NIRSpec 2D spectrum. This function extracts the DATA, QUALITY, and VAR extensions and returns them as a glue Data object. It then uses the header keywords of the DATA extension to detemine the wavelengths. """ file_name, ext = split_file_name(file_name, default_ext=1) hdulist = fits.open(file_name) data = Data(label="2D Spectrum") data.header = hdulist['PRIMARY'].header data.coords = coordinates_from_header(hdulist[ext].header) data.add_component(hdulist[ext].data, 'Flux') data.add_component(np.sqrt(hdulist[ext + 2].data), 'Uncertainty') hdulist.close() return data
def nirspec_spectrum2d_reader(file_name): """ Data loader for simulated NIRSpec 2D spectrum. This function extracts the DATA, QUALITY, and VAR extensions and returns them as a glue Data object. It then uses the header keywords of the DATA extension to detemine the wavelengths. """ file_name, ext = split_file_name(file_name, default_ext=1) hdulist = fits.open(file_name) data = Data(label="2D Spectrum") data.header = hdulist['PRIMARY'].header data.coords = coordinates_from_header(hdulist[ext].header) data.add_component(hdulist[ext].data, 'Flux') data.add_component(np.sqrt(hdulist[ext + 2].data), 'Uncertainty') hdulist.close() return data
def deimos_spectrum1D_reader(file_name): """ Data loader for Keck/DEIMOS 1D spectra. This loads the 'Bxspf-B' (extension 1) and 'Bxspf-R' (extension 2) and appends them together to proudce the combined Red/Blue Spectrum along with their Wavelength and Inverse Variance arrays. """ hdulist = fits.open(file_name) data = Data(label='1D Spectrum') data.header = hdulist[1].header full_wl = np.append(hdulist[1].data['LAMBDA'][0], hdulist[2].data['LAMBDA'][0]) full_spec = np.append(hdulist[1].data['SPEC'][0], hdulist[2].data['SPEC'][0]) full_ivar = np.append(hdulist[1].data['IVAR'][0], hdulist[2].data['IVAR'][0]) data.add_component(full_wl, 'Wavelength') data.add_component(full_spec, 'Flux') data.add_component(full_ivar, 'Uncertainty') return data