Coverage for python/lsst/obs/cfht/cfhtIsrTask.py: 23%
46 statements
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-18 03:22 -0700
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-18 03:22 -0700
2__all__ = ["CfhtIsrTaskConfig", "CfhtIsrTask"]
4import numpy as np
6import lsst.pex.config as pexConfig
7from lsst.ip.isr import IsrTask
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 )
17 def setDefaults(self):
18 IsrTask.ConfigClass.setDefaults(self)
21class CfhtIsrTask(IsrTask):
22 ConfigClass = CfhtIsrTaskConfig
24 def run(self, ccdExposure, bias=None, linearizer=None, dark=None, flat=None, defects=None,
25 fringes=None, bfKernel=None, **kwds):
26 """Perform instrument signature removal on an exposure
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
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 `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 **kwds : `dict`
54 additional kwargs forwarded to IsrTask.run.
56 Returns
57 -------
58 struct : `lsst.pipe.base.Struct` with fields:
59 - exposure: the exposure after application of ISR
60 """
61 if bfKernel is not None:
62 raise ValueError("CFHT ISR does not currently support brighter-fatter correction.")
64 ccd = ccdExposure.getDetector()
65 floatExposure = self.convertIntToFloat(ccdExposure)
66 metadata = floatExposure.getMetadata()
68 # Detect saturation
69 # Saturation values recorded in the fits hader is not reliable, try to
70 # estimate it from the pixel values.
71 # Find the peak location in the high end part the pixel values'
72 # histogram and set the saturation level at safe * (peak location)
73 # where safe is a configurable parameter (typically 0.95)
74 image = floatExposure.getMaskedImage().getImage()
75 imageArray = image.getArray()
76 maxValue = np.max(imageArray)
77 if maxValue > 60000.0:
78 hist, bin_edges = np.histogram(imageArray.ravel(), bins=100, range=(60000.0, maxValue+1.0))
79 saturate = int(self.config.safe*bin_edges[np.argmax(hist)])
80 else:
81 saturate = metadata.getScalar("SATURATE")
82 self.log.info("Saturation set to %d", saturate)
84 tempCcd = ccd.rebuild()
85 tempCcd.clear()
86 for amp in ccd:
87 tempAmp = amp.rebuild()
88 tempAmp.setSaturation(saturate)
89 if tempAmp.getName() == "A":
90 tempAmp.setGain(metadata.getScalar("GAINA"))
91 rdnA = metadata.getScalar("RDNOISEA")
92 # Check if the noise value is making sense for this amp. If
93 # not, replace with value stored in RDNOISE slot. This change
94 # is necessary to process some old CFHT images
95 # (visit : 7xxxxx) where RDNOISEA/B = 65535
96 if rdnA > 60000.0:
97 rdnA = metadata.getScalar("RDNOISE")
98 tempAmp.setReadNoise(rdnA)
99 elif tempAmp.getName() == "B":
100 tempAmp.setGain(metadata.getScalar("GAINB"))
101 rdnB = metadata.getScalar("RDNOISEB")
102 # Check if the noise value is making sense for this amp.
103 # If not, replace with value
104 # stored in RDNOISE slot. This change is necessary to process
105 # some old CFHT images
106 # (visit : 7xxxxx) where RDNOISEA/B = 65535
107 if rdnB > 60000.0:
108 rdnB = metadata.getScalar("RDNOISE")
109 tempAmp.setReadNoise(rdnB)
110 else:
111 raise ValueError("Unexpected amplifier name : %s"%(amp.getName()))
112 tempCcd.append(tempAmp)
114 ccd = tempCcd.finish()
115 ccdExposure.setDetector(ccd)
116 return IsrTask.run(self,
117 ccdExposure=ccdExposure,
118 bias=bias,
119 linearizer=linearizer,
120 dark=dark,
121 flat=flat,
122 defects=defects,
123 fringes=fringes,
124 **kwds
125 )