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__all__ = ["CfhtIsrTaskConfig", "CfhtIsrTask"] 

3 

4import numpy as np 

5 

6import lsst.pex.config as pexConfig 

7from lsst.ip.isr import IsrTask 

8 

9 

10class CfhtIsrTaskConfig(IsrTask.ConfigClass): 

11 safe = pexConfig.Field( 

12 dtype=float, 

13 doc="Safety margin for CFHT sensors gain determination", 

14 default=0.95, 

15 ) 

16 

17 def setDefaults(self): 

18 IsrTask.ConfigClass.setDefaults(self) 

19 

20 

21class CfhtIsrTask(IsrTask): 

22 ConfigClass = CfhtIsrTaskConfig 

23 

24 def run(self, ccdExposure, bias=None, linearizer=None, dark=None, flat=None, defects=None, 

25 fringes=None, bfKernel=None, camera=None, **kwds): 

26 """Perform instrument signature removal on an exposure 

27 

28 Steps include: 

29 - Detect saturation, apply overscan correction, bias, dark and flat 

30 - Perform CCD assembly 

31 - Interpolate over defects, saturated pixels and all NaNs 

32 - Persist the ISR-corrected exposure as "postISRCCD" if 

33 config.doWrite is True 

34 

35 Parameters 

36 ---------- 

37 ccdExposure : `lsst.afw.image.Exposure` 

38 Detector data. 

39 bias : `lsst.afw.image.exposure` 

40 Exposure of bias frame. 

41 linearizer : `lsst.ip.isr.LinearizeBase` callable 

42 Linearizing functor; a subclass of lsst.ip.isr.LinearizeBase. 

43 dark : `lsst.afw.image.exposure` 

44 Exposure of dark frame. 

45 flat : `lsst.afw.image.exposure` 

46 Exposure of flatfield. 

47 defects : `list` 

48 list of detects 

49 fringes : `lsst.afw.image.exposure` or `list` of `lsst.afw.image.exposure` 

50 exposure of fringe frame or list of fringe exposure 

51 bfKernel : None 

52 kernel used for brighter-fatter correction; currently unsupported 

53 camera : `lsst.afw.cameraGeom.Camera` 

54 Camera geometry, used by addDistortionModel. 

55 **kwds : `dict` 

56 additional kwargs forwarded to IsrTask.run. 

57 

58 Returns 

59 ------- 

60 struct : `lsst.pipe.base.Struct` with fields: 

61 - exposure: the exposure after application of ISR 

62 """ 

63 if bfKernel is not None: 

64 raise ValueError("CFHT ISR does not currently support brighter-fatter correction.") 

65 

66 ccd = ccdExposure.getDetector() 

67 floatExposure = self.convertIntToFloat(ccdExposure) 

68 metadata = floatExposure.getMetadata() 

69 

70 # Detect saturation 

71 # Saturation values recorded in the fits hader is not reliable, try to 

72 # estimate it from the pixel values. 

73 # Find the peak location in the high end part the pixel values' 

74 # histogram and set the saturation level at safe * (peak location) 

75 # where safe is a configurable parameter (typically 0.95) 

76 image = floatExposure.getMaskedImage().getImage() 

77 imageArray = image.getArray() 

78 maxValue = np.max(imageArray) 

79 if maxValue > 60000.0: 

80 hist, bin_edges = np.histogram(imageArray.ravel(), bins=100, range=(60000.0, maxValue+1.0)) 

81 saturate = int(self.config.safe*bin_edges[np.argmax(hist)]) 

82 else: 

83 saturate = metadata.getScalar("SATURATE") 

84 self.log.info("Saturation set to %d" % saturate) 

85 

86 tempCcd = ccd.rebuild() 

87 tempCcd.clear() 

88 for amp in ccd: 

89 tempAmp = amp.rebuild() 

90 tempAmp.setSaturation(saturate) 

91 if tempAmp.getName() == "A": 

92 tempAmp.setGain(metadata.getScalar("GAINA")) 

93 rdnA = metadata.getScalar("RDNOISEA") 

94 # Check if the noise value is making sense for this amp. If 

95 # not, replace with value stored in RDNOISE slot. This change 

96 # is necessary to process some old CFHT images 

97 # (visit : 7xxxxx) where RDNOISEA/B = 65535 

98 if rdnA > 60000.0: 

99 rdnA = metadata.getScalar("RDNOISE") 

100 tempAmp.setReadNoise(rdnA) 

101 elif tempAmp.getName() == "B": 

102 tempAmp.setGain(metadata.getScalar("GAINB")) 

103 rdnB = metadata.getScalar("RDNOISEB") 

104 # Check if the noise value is making sense for this amp. 

105 # If not, replace with value 

106 # stored in RDNOISE slot. This change is necessary to process 

107 # some old CFHT images 

108 # (visit : 7xxxxx) where RDNOISEA/B = 65535 

109 if rdnB > 60000.0: 

110 rdnB = metadata.getScalar("RDNOISE") 

111 tempAmp.setReadNoise(rdnB) 

112 else: 

113 raise ValueError("Unexpected amplifier name : %s"%(amp.getName())) 

114 tempCcd.append(tempAmp) 

115 

116 ccd = tempCcd.finish() 

117 ccdExposure.setDetector(ccd) 

118 return IsrTask.run(self, 

119 ccdExposure=ccdExposure, 

120 bias=bias, 

121 linearizer=linearizer, 

122 dark=dark, 

123 flat=flat, 

124 defects=defects, 

125 fringes=fringes, 

126 camera=camera, 

127 **kwds 

128 )