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# This file is part of ip_isr. 

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/>. 

21from abc import ABC, abstractmethod 

22from typing import Optional 

23 

24from lsst.pex.config import Config, Field, ListField 

25from lsst.pipe.base import Task 

26from lsst.geom import Angle 

27 

28 

29class StrayLightConfig(Config): 

30 doRotatorAngleCorrection = Field( 

31 dtype=bool, 

32 doc="", 

33 default=False, 

34 ) 

35 # TODO DM-28093: change the doc to specify that these are physical labels 

36 filters = ListField( 

37 dtype=str, 

38 doc="Filters that need straylight correction.", 

39 default=[], 

40 ) 

41 

42 

43class StrayLightTask(Task): 

44 """Remove stray light from instruments. 

45 

46 This is a dummy task to be retargeted with an camera-specific version. 

47 """ 

48 ConfigClass = StrayLightConfig 

49 _DefaultName = "isrStrayLight" 

50 

51 def readIsrData(self, dataRef, rawExposure): 

52 """Read and return calibration products relevant for correcting 

53 stray light in the given exposure. 

54 

55 Parameters 

56 ---------- 

57 dataRef : `daf.persistence.butlerSubset.ButlerDataRef` 

58 Butler reference of the detector data to be processed 

59 rawExposure : `afw.image.Exposure` 

60 The raw exposure that will later be corrected with the 

61 retrieved calibration data; should not be modified in this 

62 method. 

63 

64 Returns 

65 ------- 

66 straylightData : `object`, optional 

67 An opaque object that should be passed as the second argument to 

68 the `run` method. If `None`, no stray light correction will be 

69 performed for the given image. Any other object (e.g. `True`) 

70 may be used to signal that stray light correction should be 

71 performed even if there is nothing to read. 

72 

73 Notes 

74 ----- 

75 This method will be called only when `IsrTask` is run by the Gen2 

76 Middleware (i.e. CmdLineTask). 

77 """ 

78 return None 

79 

80 def check(self, exposure): 

81 """Check if stray light correction should be run. 

82 

83 Parameters 

84 ---------- 

85 exposure : `lsst.afw.image.Exposure` 

86 Exposure to correct. 

87 """ 

88 return False 

89 

90 def run(self, exposure, strayLightData): 

91 """Correct stray light. 

92 

93 Parameters 

94 ---------- 

95 exposure : `lsst.afw.image.Exposure` 

96 Exposure to correct. 

97 strayLightData : `object`, optional 

98 An opaque object that contains any calibration data used to 

99 correct for stray light. 

100 """ 

101 raise NotImplementedError("Must be implemented by subclasses.") 

102 

103 def checkFilter(self, exposure): 

104 """Check whether we should fringe-subtract the science exposure. 

105 

106 Parameters 

107 ---------- 

108 exposure : `lsst.afw.image.Exposure` 

109 Exposure to check the filter of. 

110 

111 Returns 

112 ------- 

113 needsFringe : `bool` 

114 If True, then the exposure has a filter listed in the 

115 configuration, and should have the fringe applied. 

116 """ 

117 return exposure.getFilter().getName() in self.config.filters 

118 

119 

120class StrayLightData(ABC): 

121 """An abstract base class for rotator-dependent stray light information. 

122 """ 

123 

124 @abstractmethod 

125 def evaluate(self, angle_start: Angle, angle_end: Optional[Angle] = None): 

126 """Get a stray light array for a range of rotator angles. 

127 

128 Parameters 

129 ---------- 

130 angle_begin : `float` 

131 Instrument rotation angle at the start of the exposure. 

132 angle_end : `float`, optional 

133 Instrument rotation angle at the end of the exposure. 

134 If not provided, the returned array will reflect a snapshot at 

135 `angle_start`. 

136 

137 Returns 

138 ------- 

139 array : `numpy.ndarray` 

140 A stray-light background image for this exposure. 

141 """ 

142 raise NotImplementedError("Must be implemented by subclasses.")