Coverage for tests / test_fgcmcal_latiss.py: 34%

84 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-17 09:32 +0000

1# See COPYRIGHT file at the top of the source tree. 

2# 

3# This file is part of fgcmcal. 

4# 

5# Developed for the LSST Data Management System. 

6# This product includes software developed by the LSST Project 

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

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

9# for details of code ownership. 

10# 

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

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

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

14# (at your option) any later version. 

15# 

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

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

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

19# GNU General Public License for more details. 

20# 

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

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

23"""Test the fgcmcal code with testdata_jointcal/latiss. 

24 

25Run test suite on fgcmcal using LATISS data from testdata_jointcal. 

26""" 

27import unittest 

28import os 

29import tempfile 

30import numpy as np 

31 

32# Need to import pyproj to prevent file handle leakage since importing 

33# pyproj automatically opens proj.db and never closes it. We can not wait 

34# for some dependent code to import it whilst the test is running since then 

35# the leak checker will think it is a leak. 

36# TODO: Remove import after completing DM-54643. Use DM-54656 

37try: 

38 import pyproj # noqa: F401 

39except ImportError: 

40 pass 

41 

42# Ensure that matplotlib doesn't try to open a display during testing. 

43import matplotlib 

44matplotlib.use("Agg") 

45 

46import lsst.utils # noqa: E402 

47import lsst.pipe.tasks # noqa: E402 

48import lsst.daf.butler.cli.cliLog # noqa: E402 

49 

50import fgcmcalTestBase # noqa: E402 

51 

52 

53ROOT = os.path.abspath(os.path.dirname(__file__)) 

54 

55I0STD = [0.0, 0.0, 0.0] 

56I10STD = [0.0, 0.0, 0.0] 

57I0RECON = [0.14882544833566255, 0.1082095952782785, 0.10403867395420009] 

58I10RECON = [-4.1568350444828335, -1.0020576281832512, -1.2088515357441083] 

59 

60 

61class FgcmcalTestLatiss(fgcmcalTestBase.FgcmcalTestBase, lsst.utils.tests.TestCase): 

62 @classmethod 

63 def setUpClass(cls): 

64 try: 

65 cls.dataDir = lsst.utils.getPackageDir('testdata_jointcal') 

66 except LookupError: 

67 raise unittest.SkipTest("testdata_jointcal not setup") 

68 try: 

69 lsst.utils.getPackageDir('obs_lsst') 

70 except LookupError: 

71 raise unittest.SkipTest("obs_lsst not setup") 

72 

73 lsst.daf.butler.cli.cliLog.CliLog.initLog(longlog=False) 

74 

75 cls.testDir = tempfile.mkdtemp(dir=ROOT, prefix="TestFgcm-") 

76 

77 cls._importRepository('lsst.obs.lsst.Latiss', 

78 os.path.join(cls.dataDir, 'latiss/testdata'), 

79 os.path.join(cls.dataDir, 'latiss', 'exports.yaml')) 

80 

81 def test_fgcmcalPipeline(self): 

82 """Test running the full pipeline, using isolated star association code. 

83 """ 

84 # Set numpy seed for stability 

85 np.random.seed(seed=1000) 

86 

87 instName = 'LATISS' 

88 testName = 'testfgcmcalpipe' 

89 

90 nBand = 3 

91 i0Std = np.array(I0STD) 

92 i10Std = np.array(I10STD) 

93 i0Recon = np.array(I0RECON) 

94 i10Recon = np.array(I10RECON) 

95 

96 self._testFgcmMakeLut(instName, testName, 

97 nBand, i0Std, i0Recon, i10Std, i10Recon) 

98 

99 visits = [ 

100 2023051100320, 

101 2023051100357, 

102 2023051100390, 

103 2023051100406, 

104 2023051100448, 

105 2023051100454, 

106 2023051100278, 

107 2023051100473, 

108 2023051100263, 

109 2023051100509, 

110 2023051100304, 

111 2023051100431, 

112 2023051100547, 

113 2023051100379, 

114 2023051100495, 

115 2023051100489, 

116 2023051100401, 

117 2023051100280, 

118 2023051100303, 

119 2023051100508, 

120 ] 

121 

122 nStar = 54 

123 nObs = 301 

124 

125 self._testFgcmBuildFromIsolatedStars( 

126 instName, 

127 testName, 

128 "band IN ('g', 'r', 'i')", 

129 visits, 

130 nStar, 

131 nObs, 

132 refcatCollection="refcats/DM-33444", 

133 ) 

134 

135 nZp = 20 

136 nGoodZp = 13 

137 nOkZp = 13 

138 nBadZp = 7 

139 nStdStars = 48 

140 nPlots = 52 

141 

142 self._testFgcmFitCycle(instName, testName, 

143 0, nZp, nGoodZp, nOkZp, nBadZp, nStdStars, nPlots, skipChecks=True) 

144 self._testFgcmFitCycle(instName, testName, 

145 1, nZp, nGoodZp, nOkZp, nBadZp, nStdStars, nPlots, skipChecks=True) 

146 

147 # We need to create an extra config file to turn on "sub-ccd gray" for testing. 

148 # We also want to exercise the code path setting useExposureReferenceOffset = False. 

149 extraConfigFile = os.path.join(self.testDir, "cycle03_patch_config.py") 

150 with open(extraConfigFile, "w") as f: 

151 f.write("config.isFinalCycle = True\n") 

152 f.write("config.ccdGraySubCcdDict = {'g': True, 'r': True, 'i': True}\n") 

153 f.write("config.useExposureReferenceOffset = False") 

154 

155 self._testFgcmFitCycle(instName, testName, 

156 2, nZp, nGoodZp, nOkZp, nBadZp, nStdStars, nPlots, 

157 extraConfig=extraConfigFile) 

158 

159 zpOffsets = np.array([0.025642290711402893, 

160 -0.001271035522222519]) 

161 

162 self._testFgcmOutputProducts( 

163 instName, 

164 testName, 

165 zpOffsets, 

166 2023051100320, 

167 0, 

168 'r', 

169 1, 

170 testSrc=False, 

171 ) 

172 

173 self._testFgcmOutputIlluminationCorrection(instName, testName, 0) 

174 

175 def test_fgcmcalMultipleFitPipeline(self): 

176 np.random.seed(seed=1000) 

177 

178 instName = 'LATISS' 

179 testName = 'testfgcmcalmultiple' 

180 

181 nBand = 3 

182 i0Std = np.array(I0STD) 

183 i10Std = np.array(I10STD) 

184 i0Recon = np.array(I0RECON) 

185 i10Recon = np.array(I10RECON) 

186 

187 self._testFgcmMakeLut(instName, testName, 

188 nBand, i0Std, i0Recon, i10Std, i10Recon) 

189 

190 visits = [ 

191 2023051100320, 

192 2023051100357, 

193 2023051100390, 

194 2023051100406, 

195 2023051100448, 

196 2023051100454, 

197 2023051100278, 

198 2023051100473, 

199 2023051100263, 

200 2023051100509, 

201 2023051100304, 

202 2023051100431, 

203 2023051100547, 

204 2023051100379, 

205 2023051100495, 

206 2023051100489, 

207 2023051100401, 

208 2023051100280, 

209 2023051100303, 

210 2023051100508, 

211 ] 

212 

213 # These are slightly different from above due to the configuration change 

214 # mid-way in the separate fits. 

215 zpOffsets = np.array([0.00999188981950283, 

216 -0.009526489302515984]) 

217 

218 self._testFgcmMultiFit( 

219 instName, 

220 testName, 

221 "band IN ('g', 'r', 'i')", 

222 visits, 

223 zpOffsets, 

224 58, 

225 50, 

226 refcatCollection="refcats/DM-33444", 

227 ) 

228 

229 

230class TestMemory(lsst.utils.tests.MemoryTestCase): 

231 pass 

232 

233 

234def setup_module(module): 

235 lsst.utils.tests.init() 

236 

237 

238if __name__ == "__main__": 238 ↛ 239line 238 didn't jump to line 239 because the condition on line 238 was never true

239 lsst.utils.tests.init() 

240 unittest.main()