Coverage for tests/test_computeExposureSummaryStats.py: 22%

74 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-19 05:10 -0700

1# This file is part of pipe_tasks. 

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 

22"""Test ComputeExposureSummaryStatsTask. 

23""" 

24import unittest 

25 

26import numpy as np 

27 

28import lsst.utils.tests 

29from lsst.afw.detection import GaussianPsf 

30import lsst.afw.image as afwImage 

31import lsst.afw.math as afwMath 

32from lsst.daf.base import DateTime 

33from lsst.afw.coord import Observatory 

34from lsst.afw.geom import makeCdMatrix, makeSkyWcs 

35from lsst.pipe.tasks.computeExposureSummaryStats import ComputeExposureSummaryStatsTask 

36 

37 

38class ComputeExposureSummaryTestCase(lsst.utils.tests.TestCase): 

39 

40 def testComputeExposureSummary(self): 

41 """Make a fake exposure and background and compute summary. 

42 """ 

43 np.random.seed(12345) 

44 

45 # Make an exposure with a noise image 

46 band = "i" 

47 physical_filter = "test-i" 

48 exposure = afwImage.ExposureF(100, 100) 

49 exposure.setFilter(afwImage.FilterLabel(band=band, physical=physical_filter)) 

50 

51 skyMean = 100.0 

52 skySigma = 10.0 

53 exposure.getImage().getArray()[:, :] = np.random.normal(skyMean, skySigma, size=(100, 100)) 

54 exposure.getVariance().getArray()[:, :] = skySigma**2. 

55 

56 # Set the visitInfo 

57 date = DateTime(date=59234.7083333334, system=DateTime.DateSystem.MJD) 

58 observatory = Observatory(-70.7366*lsst.geom.degrees, -30.2407*lsst.geom.degrees, 

59 2650.) 

60 visitInfo = afwImage.VisitInfo(exposureTime=10.0, 

61 date=date, 

62 observatory=observatory) 

63 exposure.getInfo().setVisitInfo(visitInfo) 

64 

65 # Install a Gaussian PSF 

66 psfSize = 2.0 

67 psf = GaussianPsf(5, 5, psfSize) 

68 exposure.setPsf(psf) 

69 

70 # Install a simple WCS 

71 scale = 0.2*lsst.geom.arcseconds 

72 raCenter = 300.0*lsst.geom.degrees 

73 decCenter = 0.0*lsst.geom.degrees 

74 cdMatrix = makeCdMatrix(scale=scale) 

75 skyWcs = makeSkyWcs(crpix=exposure.getBBox().getCenter(), 

76 crval=lsst.geom.SpherePoint(raCenter, decCenter), 

77 cdMatrix=cdMatrix) 

78 exposure.setWcs(skyWcs) 

79 

80 # Install a simple photoCalib 

81 photoCalib = afwImage.PhotoCalib(calibrationMean=0.3) 

82 zp = 2.5*np.log10(photoCalib.getInstFluxAtZeroMagnitude()) 

83 exposure.setPhotoCalib(photoCalib) 

84 

85 # Compute the background image 

86 bgGridSize = 10 

87 bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE) 

88 bctrl.setNxSample(int(exposure.getMaskedImage().getWidth()/bgGridSize) + 1) 

89 bctrl.setNySample(int(exposure.getMaskedImage().getHeight()/bgGridSize) + 1) 

90 backobj = afwMath.makeBackground(exposure.getMaskedImage().getImage(), bctrl) 

91 background = afwMath.BackgroundList() 

92 background.append(backobj) 

93 

94 # Configure and run the task 

95 expSummaryTask = ComputeExposureSummaryStatsTask() 

96 # Configure nominal values for effective time calculation 

97 expSummaryTask.config.fiducialZeroPoint = {band: float(zp)} 

98 expSummaryTask.config.fiducialPsfSigma = {band: float(psfSize)} 

99 expSummaryTask.config.fiducialSkyBackground = {band: float(skyMean)} 

100 # Run the task 

101 summary = expSummaryTask.run(exposure, None, background) 

102 

103 # Test the outputs 

104 self.assertFloatsAlmostEqual(summary.psfSigma, psfSize) 

105 self.assertFloatsAlmostEqual(summary.psfIxx, psfSize**2.) 

106 self.assertFloatsAlmostEqual(summary.psfIyy, psfSize**2.) 

107 self.assertFloatsAlmostEqual(summary.psfIxy, 0.0) 

108 self.assertFloatsAlmostEqual(summary.psfArea, 23.088975164455444) 

109 

110 delta = (scale*50).asDegrees() 

111 for a, b in zip(summary.raCorners, 

112 [raCenter.asDegrees() + delta, raCenter.asDegrees() - delta, 

113 raCenter.asDegrees() - delta, raCenter.asDegrees() + delta]): 

114 self.assertFloatsAlmostEqual(a, b, atol=1e-10) 

115 for a, b in zip(summary.decCorners, 

116 [decCenter.asDegrees() - delta, decCenter.asDegrees() - delta, 

117 decCenter.asDegrees() + delta, decCenter.asDegrees() + delta]): 

118 self.assertFloatsAlmostEqual(a, b, atol=1e-10) 

119 

120 self.assertFloatsAlmostEqual(summary.ra, raCenter.asDegrees(), atol=1e-10) 

121 self.assertFloatsAlmostEqual(summary.dec, decCenter.asDegrees(), atol=1e-10) 

122 

123 self.assertFloatsAlmostEqual(summary.zeroPoint, zp) 

124 

125 # Need to compare background level and noise 

126 # These are only approximately 0+/-10 because of the small image 

127 self.assertFloatsAlmostEqual(summary.skyBg, skyMean, rtol=1e-3) 

128 self.assertFloatsAlmostEqual(summary.meanVar, skySigma**2.) 

129 

130 self.assertFloatsAlmostEqual(summary.zenithDistance, 30.57112, atol=1e-5) 

131 

132 # Effective exposure time 

133 self.assertFloatsAlmostEqual(summary.effTime, 1.0, rtol=1e-3) 

134 

135 

136class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase): 

137 pass 

138 

139 

140def setup_module(module): 

141 lsst.utils.tests.init() 

142 

143 

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

145 lsst.utils.tests.init() 

146 unittest.main()