Coverage for python/lsst/fgcmcal/sedterms.py: 70%

23 statements  

« prev     ^ index     » next       coverage.py v7.4.2, created at 2024-02-22 13:59 +0000

1# This file is part of fgcmcal. 

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"""Configuration for SED terms in fgcmcal. 

22Analogous to colorterms. 

23""" 

24 

25from lsst.pex.config import Config, Field, ConfigDictField 

26 

27__all__ = ["Sedterm", "SedtermDict", "Sedboundaryterm", "SedboundarytermDict"] 

28 

29 

30class Sedboundaryterm(Config): 

31 """SED boundary term for a pair of bands. 

32 

33 The SED slope (in flux units) at the boundary between two bands is given by: 

34 

35 S = -0.921 * (primary - secondary) / (lambda_primary - lambda_secondary) 

36 

37 To construct a Sedboundaryterm, use keyword arguments: 

38 Sedboundaryterm(primary=primaryBandName, secondary=secondaryBandName) 

39 

40 This is a subclass of Config. This follows the form of 

41 `lsst.pipe.tasks.Colorterm`. 

42 """ 

43 primary = Field(dtype=str, doc="name of primary band") 

44 secondary = Field(dtype=str, doc="name of secondary band") 

45 

46 

47class SedboundarytermDict(Config): 

48 """A mapping of Sedboundaryterm name to Sedterm. 

49 

50 To construct a SedboundarytermDict use keyword arguments: 

51 SedboundarytermDict(data=dataDict) 

52 where dataDict is a Python dict of name: Sedterm 

53 For example:: 

54 

55 SedboundarytermDict(data={ 

56 'gr': Sedboundaryterm(primary="g", secondary="r"), 

57 'ri': Sedboundaryterm(primary="r", secondary="i"), 

58 }) 

59 

60 This is a subclass of Config. This follows the form of 

61 `lsst.pipe.tasks.ColortermDict`. 

62 """ 

63 data = ConfigDictField( 

64 doc="Mapping of Sedboundary term name to Sedboundaryterm", 

65 keytype=str, 

66 itemtype=Sedboundaryterm, 

67 default={}, 

68 ) 

69 

70 

71class Sedterm(Config): 

72 """SED term for a single band. 

73 

74 The SED slope (in flux units) in the middle of a band is computed either 

75 as an "interpolated" or "extrapolated" computation. See Burke et al. 2018 

76 Appendix A (https://ui.adsabs.harvard.edu/abs/2018AJ....155...41B). 

77 

78 For interpolation, with a secondary term:: 

79 

80 F'_nu ~ constant * (primaryTerm + secondaryTerm) / 2.0 

81 

82 For interpolation, without a secondary term:: 

83 

84 F'_nu ~ constant * primaryTerm 

85 

86 For extrapolation:: 

87 

88 F'_nu ~ primaryTerm + constant * (((lambda_primaryBand - lambda_secondaryBand) / 

89 (lambda_primaryBand - lambda_tertiaryBand)) * 

90 (primaryTerm - secondaryTerm)) 

91 

92 where primaryTerm and secondaryTerm are names from a `SedboundarytermDict`, and 

93 primaryBand, secondaryBand, and tertiaryBand are band names. 

94 

95 To construct a Sedterm, use keyword arguments:: 

96 

97 Sedterm(primaryTerm=primaryTermName, secondaryTerm=secondaryTermName, 

98 extrapolated=False, constant=1.0) 

99 

100 or:: 

101 

102 Sedterm(primaryTerm=primaryTermName, secondaryTerm=secondaryTermName, 

103 extrapolated=True, constant=1.0, primaryBand=primaryBandName, 

104 secondaryBand=secondaryBandName, tertiaryBand=tertiaryBandName) 

105 

106 This is a subclass of Config. This follows the form of 

107 `lsst.pipe.tasks.Colorterm`. 

108 """ 

109 primaryTerm = Field(dtype=str, doc="Name of primary Sedboundaryterm") 

110 secondaryTerm = Field(dtype=str, default=None, optional=True, 

111 doc="Name of secondary Sedboundaryterm") 

112 extrapolated = Field(dtype=bool, default=False, doc="Extrapolate to compute SED slope") 

113 constant = Field(dtype=float, default=1.0, doc="Adjustment constant for SED slope") 

114 primaryBand = Field(dtype=str, default=None, optional=True, 

115 doc="Primary band name for extrapolation") 

116 secondaryBand = Field(dtype=str, default=None, optional=True, 

117 doc="Secondary band name for extrapolation") 

118 tertiaryBand = Field(dtype=str, default=None, optional=True, 

119 doc="Tertiary band name for extrapolation") 

120 

121 def validate(self): 

122 Config.validate(self) 

123 if self.extrapolated: 

124 if self.primaryBand is None or \ 

125 self.secondaryBand is None or \ 

126 self.tertiaryBand is None: 

127 raise RuntimeError("extrapolated requires primaryBand, secondaryBand, and " 

128 "tertiaryBand are provided.") 

129 

130 

131class SedtermDict(Config): 

132 """A mapping of bands to Sedterms. 

133 

134 To construct a SedtermDict use keyword arguments:: 

135 

136 SedtermDict(data=dataDict) 

137 

138 where dataDict is a Python dict of band to Sedterm 

139 For example:: 

140 

141 SedtermDict(data={ 

142 'g': Sedterm(primaryTerm='gr', secondaryTerm='ri', extrapolated=True, constant=0.25, 

143 primaryBand='g', secondaryBand='r', tertiaryBand='i'), 

144 'r': Sedterm(primaryTerm='gr', secondaryTerm='ri', extrapolated=False) 

145 }) 

146 

147 This is a subclass of Config. This follows the form of 

148 `lsst.pipe.tasks.ColortermDict`. 

149 """ 

150 data = ConfigDictField( 

151 doc="Mapping of band name to Sedterm", 

152 keytype=str, 

153 itemtype=Sedterm, 

154 default={}, 

155 )