Coverage for python/lsst/ip/isr/gainCorrection.py: 88%

60 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-15 03:24 +0000

1# This file is part of ip_isr. 

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""" 

22Gain correction storage class. 

23""" 

24 

25__all__ = ["GainCorrection"] 

26 

27from astropy.table import Table 

28import numpy as np 

29 

30from lsst.ip.isr import IsrCalib 

31 

32 

33class GainCorrection(IsrCalib): 

34 """Gain correction parameters. 

35 

36 Parameters 

37 ---------- 

38 ampNames : `list` [`str`] 

39 List of amplifier names. 

40 gainAdjustments : `list` [`float`] 

41 List of gain adjustment parameters. 

42 **kwargs : 

43 Additional parameters. 

44 """ 

45 

46 _OBSTYPE = "gainCorrection" 

47 _SCHEMA = "GainCorrection" 

48 _VERSION = 1.0 

49 

50 def __init__(self, ampNames=[], gainAdjustments=[], **kwargs): 

51 if len(ampNames) != len(gainAdjustments): 51 ↛ 52line 51 didn't jump to line 52 because the condition on line 51 was never true

52 raise ValueError("Number of ampNames must be the same as number of gainAdjustments.") 

53 

54 self.ampNames = ampNames 

55 self.gainAdjustments = np.asarray(gainAdjustments) 

56 

57 super().__init__(**kwargs) 

58 self.requiredAttributes.update(["ampNames", "gainAdjustments"]) 

59 

60 self.updateMetadata(setCalibInfo=True, setCalibId=True, **kwargs) 

61 

62 def setParameters( 

63 self, 

64 *, 

65 ampNames=[], 

66 gainAdjustments=[], 

67 ): 

68 """Set the parameters for the gain correction model. 

69 

70 Parameters 

71 ---------- 

72 ampNames : `list` [`str`] 

73 List of amplifier names. 

74 gainAdjustments : `list` [`float`] 

75 List of gain adjustment parameters. 

76 """ 

77 if len(ampNames) != len(gainAdjustments): 

78 raise ValueError("Number of ampNames must be the same as number of gainAdjustments.") 

79 

80 self.ampNames = ampNames 

81 self.gainAdjustments = gainAdjustments 

82 

83 @classmethod 

84 def fromDict(cls, dictionary): 

85 """Construct a GainCorrection from a dictionary of properties. 

86 

87 Parameters 

88 ---------- 

89 dictionary : `dict` 

90 Dictionary of properties. 

91 

92 Returns 

93 ------- 

94 calib : `lsst.ip.isr.GainCorrection` 

95 Constructed calibration. 

96 """ 

97 calib = cls() 

98 

99 calib.setMetadata(dictionary["metadata"]) 

100 

101 calib.ampNames = dictionary["ampNames"] 

102 calib.gainAdjustments = np.asarray(dictionary["gainAdjustments"]) 

103 

104 calib.updateMetadata() 

105 return calib 

106 

107 def toDict(self): 

108 """Return a dictionary containing the calibration properties. 

109 

110 Returns 

111 ------- 

112 dictionary : `dict` 

113 Dictionary of properties. 

114 """ 

115 self.updateMetadata() 

116 

117 outDict = dict() 

118 metadata = self.getMetadata() 

119 outDict["metadata"] = metadata 

120 

121 outDict["ampNames"] = self.ampNames 

122 outDict["gainAdjustments"] = self.gainAdjustments.tolist() 

123 

124 return outDict 

125 

126 @classmethod 

127 def fromTable(cls, tableList): 

128 """Construct a calibration from a list of tables. 

129 

130 Parameters 

131 ---------- 

132 tableList : `list` [`astropy.table.Table`] 

133 List of table(s) to use to construct the GainCorrection. 

134 

135 Returns 

136 ------- 

137 calib : `lsst.ip.isr.GainCorrection` 

138 The calibration defined in the table(s). 

139 """ 

140 gainCorrectionTable = tableList[0] 

141 

142 inDict = dict() 

143 

144 inDict["metadata"] = gainCorrectionTable.meta 

145 inDict["ampNames"] = list(gainCorrectionTable["AMP_NAME"]) 

146 inDict["gainAdjustments"] = np.asarray(gainCorrectionTable["GAIN_ADJUSTMENT"], dtype=np.float64) 

147 

148 return cls().fromDict(inDict) 

149 

150 def toTable(self): 

151 """Construct a list of table(s) containing the GainCorrection data. 

152 

153 Returns 

154 ------- 

155 tableList : `list` [`astropy.table.Table`] 

156 List of tables containing the GainCorrection information. 

157 """ 

158 tableList = [] 

159 self.updateMetadata() 

160 

161 catalog = Table() 

162 catalog["AMP_NAME"] = self.ampNames 

163 catalog["GAIN_ADJUSTMENT"] = self.gainAdjustments 

164 

165 inMeta = self.getMetadata().toDict() 

166 outMeta = {k: v for k, v in inMeta.items() if v is not None} 

167 outMeta.update({k: "" for k, v in inMeta.items() if v is None}) 

168 catalog.meta = outMeta 

169 tableList.append(catalog) 

170 

171 return tableList 

172 

173 def correctGains(self, gains, exposure=None): 

174 """Correct a dictionary of gains (in place). 

175 

176 Parameters 

177 ---------- 

178 gains : `dict` [`str`, `float`] 

179 Array of gains to correct. 

180 exposure : `lsst.afw.image.Exposure`, optional 

181 Exposure with additional metadata for correction. 

182 """ 

183 for i, ampName in enumerate(self.ampNames): 

184 gains[ampName] *= self.gainAdjustments[i]