Coverage for python/lsst/obs/fiberspectrograph/data_manager.py: 33%

44 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-04-26 04:24 -0700

1# This file is part of obs_fiberspectrograph 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <https://www.gnu.org/licenses/>. 

21 

22import astropy.io.fits 

23 

24 

25class DataManager: 

26 """A data packager for `Spectrum` objects 

27 that comes from the ts_fiberspectrograph package 

28 """ 

29 

30 wcs_table_name = "WCS-TAB" 

31 """Name of the table containing the wavelength WCS (EXTNAME).""" 

32 wcs_table_ver = 1 

33 """WCS table version (EXTVER).""" 

34 wcs_column_name = "wavelength" 

35 """Name of the table column containing the wavelength information.""" 

36 

37 # The version of the FITS file format produced by this class. 

38 FORMAT_VERSION = 1 

39 

40 def __init__(self, spectrum): 

41 self.spectrum = spectrum 

42 

43 def make_hdulist(self): 

44 """Generate a FITS hdulist built from SpectrographData. 

45 Parameters 

46 ---------- 

47 spec : `SpectrographData` 

48 The data from which to build the FITS hdulist. 

49 Returns 

50 ------- 

51 hdulist : `astropy.io.fits.HDUList` 

52 The FITS hdulist. 

53 """ 

54 hdu1 = self.make_primary_hdu() 

55 hdu2 = self.make_wavelength_hdu() 

56 hdu3, hdu4 = self.make_maskvariance_hdu() 

57 return astropy.io.fits.HDUList([hdu1, hdu2, hdu3, hdu4]) 

58 

59 def make_fits_header(self): 

60 """Return a FITS header built from a Spectrum""" 

61 hdr = astropy.io.fits.Header() 

62 

63 hdr["FORMAT_V"] = self.FORMAT_VERSION 

64 hdr.update(self.spectrum.metadata) 

65 

66 # WCS headers - Use -TAB WCS definition 

67 wcs_cards = [ 

68 "WCSAXES = 1 / Number of WCS axes", 

69 "CRPIX1 = 0.0 / Reference pixel on axis 1", 

70 "CRVAL1 = 0.0 / Value at ref. pixel on axis 1", 

71 "CNAME1 = 'Wavelength' / Axis name for labeling purposes", 

72 "CTYPE1 = 'WAVE-TAB' / Wavelength axis by lookup table", 

73 "CDELT1 = 1.0 / Pixel size on axis 1", 

74 f"CUNIT1 = '{self.spectrum.wavelength.unit.name:8s}' / Units for axis 1", 

75 f"PV1_1 = {self.wcs_table_ver:20d} / EXTVER of bintable extension for -TAB arrays", 

76 f"PS1_0 = '{self.wcs_table_name:8s}' / EXTNAME of bintable extension for -TAB arrays", 

77 f"PS1_1 = '{self.wcs_column_name:8s}' / Wavelength coordinate array", 

78 ] 

79 for c in wcs_cards: 

80 hdr.append(astropy.io.fits.Card.fromstring(c)) 

81 

82 return hdr 

83 

84 def make_primary_hdu(self): 

85 """Return the primary HDU built from a Spectrum.""" 

86 

87 hdu = astropy.io.fits.PrimaryHDU( 

88 data=self.spectrum.flux, header=self.make_fits_header() 

89 ) 

90 return hdu 

91 

92 def make_maskvariance_hdu(self): 

93 """Return the HDU for the mask and variance plane.""" 

94 hdr_mask = astropy.io.fits.Header() 

95 hdr_mask["EXTTYPE"] = 'MASK ' 

96 hdr_mask["EXTNAME"] = 'MASK ' 

97 hdu_mask = astropy.io.fits.ImageHDU( 

98 data=self.spectrum.mask, header=hdr_mask 

99 ) 

100 

101 hdr_variance = astropy.io.fits.Header() 

102 hdr_variance["EXTTYPE"] = 'VARIANCE' 

103 hdr_variance["EXTNAME"] = 'VARIANCE' 

104 hdu_variance = astropy.io.fits.ImageHDU( 

105 data=self.spectrum.variance, header=hdr_variance 

106 ) 

107 return hdu_mask, hdu_variance 

108 

109 def make_wavelength_hdu(self): 

110 """Return the wavelength HDU built from a Spectrum.""" 

111 

112 # The wavelength array must be 2D (N, 1) in numpy but (1, N) in FITS 

113 wavelength = self.spectrum.wavelength.reshape([self.spectrum.wavelength.size, 1]) 

114 

115 # Create a Table. It will be a single element table 

116 table = astropy.table.Table() 

117 

118 # Create the wavelength column 

119 # Create the column explicitly since it is easier to ensure the 

120 # shape this way. 

121 wavecol = astropy.table.Column([wavelength], unit=wavelength.unit.name) 

122 

123 # The column name must match the PS1_1 entry from the primary HDU 

124 table[self.wcs_column_name] = wavecol 

125 

126 # The name MUST match the value of PS1_0 and the version MUST 

127 # match the value of PV1_1 

128 hdu = astropy.io.fits.BinTableHDU(table, name=self.wcs_table_name, ver=1) 

129 return hdu