Coverage for tests / test_fgcmcal_latiss.py: 31%

81 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-15 00:20 +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. 

36import pyproj # noqa: F401 

37 

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

39import matplotlib 

40matplotlib.use("Agg") 

41 

42import lsst.utils # noqa: E402 

43import lsst.pipe.tasks # noqa: E402 

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

45 

46import fgcmcalTestBase # noqa: E402 

47 

48 

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

50 

51I0STD = [0.0, 0.0, 0.0] 

52I10STD = [0.0, 0.0, 0.0] 

53I0RECON = [0.14882544833566255, 0.1082095952782785, 0.10403867395420009] 

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

55 

56 

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

58 @classmethod 

59 def setUpClass(cls): 

60 try: 

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

62 except LookupError: 

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

64 try: 

65 lsst.utils.getPackageDir('obs_lsst') 

66 except LookupError: 

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

68 

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

70 

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

72 

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

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

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

76 

77 def test_fgcmcalPipeline(self): 

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

79 """ 

80 # Set numpy seed for stability 

81 np.random.seed(seed=1000) 

82 

83 instName = 'LATISS' 

84 testName = 'testfgcmcalpipe' 

85 

86 nBand = 3 

87 i0Std = np.array(I0STD) 

88 i10Std = np.array(I10STD) 

89 i0Recon = np.array(I0RECON) 

90 i10Recon = np.array(I10RECON) 

91 

92 self._testFgcmMakeLut(instName, testName, 

93 nBand, i0Std, i0Recon, i10Std, i10Recon) 

94 

95 visits = [ 

96 2023051100320, 

97 2023051100357, 

98 2023051100390, 

99 2023051100406, 

100 2023051100448, 

101 2023051100454, 

102 2023051100278, 

103 2023051100473, 

104 2023051100263, 

105 2023051100509, 

106 2023051100304, 

107 2023051100431, 

108 2023051100547, 

109 2023051100379, 

110 2023051100495, 

111 2023051100489, 

112 2023051100401, 

113 2023051100280, 

114 2023051100303, 

115 2023051100508, 

116 ] 

117 

118 nStar = 54 

119 nObs = 301 

120 

121 self._testFgcmBuildFromIsolatedStars( 

122 instName, 

123 testName, 

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

125 visits, 

126 nStar, 

127 nObs, 

128 refcatCollection="refcats/DM-33444", 

129 ) 

130 

131 nZp = 20 

132 nGoodZp = 13 

133 nOkZp = 13 

134 nBadZp = 7 

135 nStdStars = 48 

136 nPlots = 52 

137 

138 self._testFgcmFitCycle(instName, testName, 

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

140 self._testFgcmFitCycle(instName, testName, 

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

142 

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

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

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

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

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

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

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

150 

151 self._testFgcmFitCycle(instName, testName, 

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

153 extraConfig=extraConfigFile) 

154 

155 zpOffsets = np.array([0.025642290711402893, 

156 -0.001271035522222519]) 

157 

158 self._testFgcmOutputProducts( 

159 instName, 

160 testName, 

161 zpOffsets, 

162 2023051100320, 

163 0, 

164 'r', 

165 1, 

166 testSrc=False, 

167 ) 

168 

169 self._testFgcmOutputIlluminationCorrection(instName, testName, 0) 

170 

171 def test_fgcmcalMultipleFitPipeline(self): 

172 np.random.seed(seed=1000) 

173 

174 instName = 'LATISS' 

175 testName = 'testfgcmcalmultiple' 

176 

177 nBand = 3 

178 i0Std = np.array(I0STD) 

179 i10Std = np.array(I10STD) 

180 i0Recon = np.array(I0RECON) 

181 i10Recon = np.array(I10RECON) 

182 

183 self._testFgcmMakeLut(instName, testName, 

184 nBand, i0Std, i0Recon, i10Std, i10Recon) 

185 

186 visits = [ 

187 2023051100320, 

188 2023051100357, 

189 2023051100390, 

190 2023051100406, 

191 2023051100448, 

192 2023051100454, 

193 2023051100278, 

194 2023051100473, 

195 2023051100263, 

196 2023051100509, 

197 2023051100304, 

198 2023051100431, 

199 2023051100547, 

200 2023051100379, 

201 2023051100495, 

202 2023051100489, 

203 2023051100401, 

204 2023051100280, 

205 2023051100303, 

206 2023051100508, 

207 ] 

208 

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

210 # mid-way in the separate fits. 

211 zpOffsets = np.array([0.00999188981950283, 

212 -0.009526489302515984]) 

213 

214 self._testFgcmMultiFit( 

215 instName, 

216 testName, 

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

218 visits, 

219 zpOffsets, 

220 58, 

221 50, 

222 refcatCollection="refcats/DM-33444", 

223 ) 

224 

225 

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

227 pass 

228 

229 

230def setup_module(module): 

231 lsst.utils.tests.init() 

232 

233 

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

235 lsst.utils.tests.init() 

236 unittest.main()