Coverage for tests/test_cModelPlugins.py: 29%

58 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-24 10:28 +0000

1# 

2# LSST Data Management System 

3# 

4# Copyright 2008-2016 AURA/LSST. 

5# 

6# This product includes software developed by the 

7# LSST Project (http://www.lsst.org/). 

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 LSST License Statement and 

20# the GNU General Public License along with this program. If not, 

21# see <https://www.lsstcorp.org/LegalNotices/>. 

22# 

23import unittest 

24 

25import lsst.afw.geom 

26import lsst.geom 

27import lsst.afw.table 

28import lsst.utils.tests 

29import lsst.meas.modelfit 

30 

31import lsst.meas.base.tests 

32 

33 

34# n.b. Some tests here depend on the noise realization in the test data 

35# or from the numpy random number generator. 

36# For the current test data and seed value, they pass, but they may not 

37# if the test data is regenerated or the seed value changes. I've marked 

38# these with an "rng dependent" comment. In most cases, they test that 

39# the measured flux lies within 2 sigma of the correct value, which we 

40# should expect to fail sometimes. 

41 

42class CModelTestCase(lsst.meas.base.tests.AlgorithmTestCase, lsst.utils.tests.TestCase): 

43 """Test case for the CModel measurement plugins 

44 """ 

45 

46 def setUp(self): 

47 self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), 

48 lsst.geom.Extent2I(200, 100)) 

49 self.dataset = lsst.meas.base.tests.TestDataset(self.bbox) 

50 # first source is a point 

51 self.dataset.addSource(100000.0, lsst.geom.Point2D(50.1, 49.8)) 

52 # second source is extended 

53 self.dataset.addSource(100000.0, lsst.geom.Point2D(149.9, 50.3), 

54 lsst.afw.geom.ellipses.Quadrupole(8, 9, 3)) 

55 

56 def tearDown(self): 

57 del self.bbox 

58 del self.dataset 

59 

60 def checkOutputs(self, measCat, truthCat=None): 

61 """Test that the outputs of the CModel plugins are reasonable, and that the bookkeeping works. 

62 

63 Science-quality tests either in testCModel.py (where we call the same code via a different interface) 

64 or something we have to do statistically on real data. 

65 """ 

66 if truthCat is None: 

67 truthCat = measCat 

68 for measRecord, truthRecord in zip(measCat, truthCat): 

69 trueFlux = truthRecord.get("truth_instFlux") 

70 self.assertFalse(measRecord.get("modelfit_CModel_initial_flag")) 

71 self.assertFalse(measRecord.get("modelfit_CModel_exp_flag")) 

72 self.assertFalse(measRecord.get("modelfit_CModel_dev_flag")) 

73 self.assertFalse(measRecord.get("modelfit_CModel_flag")) 

74 self.assertFloatsAlmostEqual(measRecord.get("modelfit_CModel_instFlux"), trueFlux, rtol=0.5) 

75 self.assertGreater(measRecord.get("modelfit_CModel_instFluxErr"), 0.0) 

76 self.assertFloatsAlmostEqual(measRecord.get("modelfit_CModel_initial_instFlux"), 

77 trueFlux, rtol=0.5) 

78 self.assertGreater(measRecord.get("modelfit_CModel_initial_instFluxErr"), 0.0) 

79 self.assertFloatsAlmostEqual(measRecord.get("modelfit_CModel_exp_instFlux"), trueFlux, rtol=0.5) 

80 self.assertGreater(measRecord.get("modelfit_CModel_exp_instFluxErr"), 0.0) 

81 self.assertFloatsAlmostEqual(measRecord.get("modelfit_CModel_dev_instFlux"), trueFlux, rtol=0.5) 

82 self.assertGreater(measRecord.get("modelfit_CModel_dev_instFluxErr"), 0.0) 

83 

84 def testPlugins(self): 

85 """Test that the plugin for single-frame measurement works, then use those outputs to test 

86 that the forced measurement plugin works.""" 

87 plugin = "modelfit_CModel" 

88 dependencies = ("modelfit_DoubleShapeletPsfApprox", "base_PsfFlux") 

89 sfmTask = self.makeSingleFrameMeasurementTask(plugin, dependencies=dependencies) 

90 forcedTask = self.makeForcedMeasurementTask(plugin, dependencies=dependencies, 

91 refSchema=sfmTask.schema) 

92 # catalog1 will contain both the SFM outputs and the truth catalog for sources in exposure 1. 

93 # Those SFM outputs will also be used as the references for the forced task. 

94 exposure1, catalog1 = self.dataset.realize(10.0, sfmTask.schema, randomSeed=0) 

95 sfmTask.run(catalog1, exposure1) 

96 self.checkOutputs(catalog1) 

97 if False: # this line should be re-enabled on DM-5405 

98 wcs2 = self.dataset.makePerturbedWcs(self.dataset.exposure.getWcs(), randomSeed=0) 

99 else: 

100 wcs2 = self.dataset.exposure.getWcs() 

101 dataset2 = self.dataset.transform(wcs2) 

102 # catalog2 will contain only the truth catalog for sources in exposure 1; the structure of 

103 # ForcedMeasurementTask means we can't put the outputs in the same catalog. 

104 exposure2, catalog2 = dataset2.realize(10.0, dataset2.makeMinimalSchema(), randomSeed=1) 

105 refWcs = exposure1.getWcs() 

106 refCat = catalog1 

107 measCat = forcedTask.generateMeasCat(exposure2, refCat, refWcs) 

108 forcedTask.attachTransformedFootprints(measCat, refCat, exposure2, refWcs) 

109 forcedTask.run(measCat, exposure2, refCat, refWcs) 

110 self.checkOutputs(measCat, catalog2) 

111 

112 

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

114 pass 

115 

116 

117def setup_module(module): 

118 lsst.utils.tests.init() 

119 

120 

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

122 lsst.utils.tests.init() 

123 unittest.main()