Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# 

2# LSST Data Management System 

3# 

4# Copyright 2008-2017 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# 

23__all__ = ["InstallGaussianPsfConfig", "InstallGaussianPsfTask"] 

24 

25import math 

26 

27import lsst.pex.config as pexConfig 

28import lsst.pipe.base as pipeBase 

29from lsst.meas.algorithms import SingleGaussianPsf 

30 

31FwhmPerSigma = 2.0*math.sqrt(2.0*math.log(2.0)) 

32 

33 

34class InstallGaussianPsfConfig(pexConfig.Config): 

35 """!Config for InstallGaussianPsfTask""" 

36 fwhm = pexConfig.Field( 

37 dtype=float, 

38 default=1.5 * FwhmPerSigma, 

39 doc="Estimated FWHM of simple Gaussian PSF model, in pixels. " 

40 "Ignored if input exposure has a PSF model." 

41 ) 

42 width = pexConfig.RangeField( 

43 dtype=int, 

44 doc="Width and height of PSF model, in pixels. Must be odd.", 

45 default=11, 

46 min=1, 

47 ) 

48 

49 def validate(self): 

50 if self.width % 2 == 0: 50 ↛ exitline 50 didn't return from function 'validate', because the condition on line 50 was never false

51 raise RuntimeError("width=%s must be odd" % (self.width,)) 

52 

53 

54## @addtogroup LSST_task_documentation 

55## @{ 

56## @page InstallGaussianPsfTask 

57## @ref InstallGaussianPsfTask_ "InstallGaussianPsfTask" 

58## @copybrief InstallGaussianPsfTask 

59## @} 

60 

61class InstallGaussianPsfTask(pipeBase.Task): 

62 r"""!Install a Gaussian PSF model in an exposure 

63 

64 @anchor InstallGaussianPsfTask_ 

65 

66 @section pipe_tasks_installGaussianPsf_Contents Contents 

67 

68 - @ref pipe_tasks_installGaussianPsf_Purpose 

69 - @ref pipe_tasks_installGaussianPsf_Initialize 

70 - @ref pipe_tasks_installGaussianPsf_IO 

71 - @ref pipe_tasks_installGaussianPsf_Config 

72 - @ref pipe_tasks_installGaussianPsf_Metadata 

73 - @ref pipe_tasks_installGaussianPsf_Debug 

74 - @ref pipe_tasks_installGaussianPsf_Example 

75 

76 @section pipe_tasks_installGaussianPsf_Purpose Description 

77 

78 Install a Gaussian PSF model in an exposure. 

79 If the exposure already has a PSF model then the new model 

80 has the same sigma and size (width and height in pixels) of the existing model. 

81 If the exposure does not have a PSF model then the PSF sigma and size 

82 are taken from the config. 

83 

84 At present the produced model is always circularly symmetric, but it is planned 

85 to change this to an elliptical PSF model (only for the case that the exposure 

86 already has a PSF model), once the necessary PSF object is available. 

87 

88 A variant of this task may someday exist to estimate the PSF 

89 from the pixel data if no PSF model is present. 

90 

91 @section pipe_tasks_installGaussianPsf_Initialize Task initialisation 

92 

93 @copydoc \_\_init\_\_ 

94 

95 @section pipe_tasks_installGaussianPsf_IO Invoking the Task 

96 

97 The main method is `run`. 

98 

99 @section pipe_tasks_installGaussianPsf_Config Configuration parameters 

100 

101 See @ref InstallGaussianPsfConfig 

102 

103 @section pipe_tasks_installGaussianPsf_Debug Debug variables 

104 

105 This task has no debug display 

106 

107 @section pipe_tasks_installGaussianPsf_Example A complete example of using InstallGaussianPsfTask 

108 

109 from lsst.afw.image import ExposureF 

110 from lsst.meas.algorithms.installGaussianPsf import InstallGaussianPsfTask, FwhmPerSigma 

111 

112 exposure = ExposureF(100, 100) 

113 task = InstallGaussianPsfTask() 

114 task.run(exposure=exposure) 

115 

116 # This particular exposure had no PSF model to begin with, so the new PSF model 

117 # uses the config's FWHM. However, measured FWHM is based on the truncated 

118 # PSF image, so it does not exactly match the input 

119 measFwhm = exposure.getPsf().computeShape().getDeterminantRadius() * FwhmPerSigma 

120 assert abs(measFwhm - task.config.fwhm) < 1e-3 

121 """ 

122 ConfigClass = InstallGaussianPsfConfig 

123 _DefaultName = "installSimplePsfModel" 

124 

125 def run(self, exposure): 

126 """!Set exposure's PSF to a simple PSF model 

127 

128 The sigma and width of the new simple PSF model matches the sigma and width of the current model, 

129 if any, else the config parameters are used. 

130 

131 @param[in,out] exposure exposure to which to replace or add the PSF model 

132 """ 

133 if exposure.hasPsf(): 

134 psfModel = exposure.getPsf() 

135 psfSigma = psfModel.computeShape().getDeterminantRadius() 

136 width, height = psfModel.computeImage().getDimensions() 

137 else: 

138 psfSigma = self.config.fwhm / FwhmPerSigma 

139 width = height = self.config.width 

140 

141 if psfSigma <= 0: 141 ↛ 142line 141 didn't jump to line 142, because the condition on line 141 was never true

142 raise RuntimeError("psfSigma = %s <= 0" % (psfSigma,)) 

143 

144 self.log.debug("installing a simple Gaussian PSF model with width=%s, height=%s, FWHM=%0.3f", 

145 width, height, psfSigma*FwhmPerSigma) 

146 psfModel = SingleGaussianPsf(width, height, psfSigma) 

147 exposure.setPsf(psfModel)