15 """Overscan configurations applicable to a single amplifier."""
16 doSerialOverscan = pexConfig.Field(
18 doc=
"Do serial overscan subtraction?",
21 serialOverscanConfig = pexConfig.ConfigField(
22 dtype=SerialOverscanCorrectionTaskConfig,
23 doc=
"Serial overscan configuration.",
26 doParallelOverscanCrosstalk = pexConfig.Field(
28 doc=
"Apply crosstalk correction in parallel overscan region?",
30 deprecated=
"This field is no longer used, and will be removed after v29.",
32 doParallelOverscan = pexConfig.Field(
34 doc=
"Do parallel overscan subtraction?",
37 parallelOverscanConfig = pexConfig.ConfigField(
38 dtype=ParallelOverscanCorrectionTaskConfig,
39 doc=
"Parallel overscan configuration.",
41 saturation = pexConfig.Field(
43 doc=
"The saturation level to use to override any detector/calibration product value "
44 "(ignored if NaN). Units are ADU.",
47 suspectLevel = pexConfig.Field(
49 doc=
"The ``suspect`` level to use to override any detector/calibration product value "
50 "(ignored if NaN). Units are ADU.",
53 gain = pexConfig.Field(
55 doc=
"The gain to use to override any calibration product value (ignored if NaN). "
77 """Turn this config into a simple string for hashing.
79 Only essential data for tracking is returned.
85 stringForHash = (f
"doSerial={self.doSerialOverscan} "
86 f
"serialFitType={self.serialOverscanConfig.fitType} "
87 f
"doParallel={self.doParallelOverscan} "
88 f
"parallelFitType={self.parallelOverscanConfig.fitType}")
93 """Overscan configurations applicable to multiple amplifiers in
96 ampRules = pexConfig.ConfigDictField(
97 doc=
"Amplifier level rules for overscan, keyed by amp name.",
99 itemtype=OverscanAmpConfig,
102 defaultAmpConfig = pexConfig.ConfigField(
103 dtype=OverscanAmpConfig,
104 doc=
"Default configuration for amplifiers.",
106 integerDitherMode = pexConfig.ChoiceField(
108 doc=
"Dithering mode to cancel integerization of counts.",
111 "POSITIVE":
"Dithering is done with a uniform random in the range [0, 1).",
112 "NEGATIVE":
"Dithering is done with a uniform random in the range [-1, 0).",
113 "SYMMETRIC":
"Dithering is done with a uniform random in the range [-0.5, 0.5).",
114 "NONE":
"No dithering is performed.",
117 itlDipMinHeight = pexConfig.Field(
119 doc=
"Minimum height for a saturated footprint column to contribute to a dip.",
122 itlDipMinWidth = pexConfig.Field(
124 doc=
"Minimum number of columns in a saturated footprint with idlDipMinHeight "
125 "to contribute to a dip.",
128 itlDipMaxWidth = pexConfig.Field(
130 doc=
"Maximum number of columns to use for a dip mask.",
133 itlDipWidthScale = pexConfig.Field(
135 doc=
"Scaling factor to widen saturated core for dip masking.",
138 itlDipBackgroundFraction = pexConfig.Field(
140 doc=
"Fraction of background (scaled by width) that is in the center of the dip. "
141 "Only dips that are greater than itlDipMinSkyNoiseFraction will be masked. "
142 "If equal to 0.0, dip masking will be skipped.",
145 itlDipMinBackgroundNoiseFraction = pexConfig.Field(
147 doc=
"Only max model dip depth greater than this fraction of the approximate "
148 "background noise will be masked.",
151 itlDipMaxColsPerImage = pexConfig.Field(
153 doc=
"Maximum number of columns detected as ``dip`` columns before dip masking "
154 "is disabled on the image.",
160 """Check if any of the amp configs have doSerialOverscan.
164 doAnySerialOverscan : `bool`
169 for _, ampRule
in self.
ampRules.items():
170 if ampRule.doSerialOverscan:
177 """Check if any of the amp configs have doParallelOverscan.
181 doAnyParallelOverscan : `bool`
186 for _, ampRule
in self.
ampRules.items():
187 if ampRule.doParallelOverscan:
193 """Get the OverscanAmpConfig for a specific amplifier.
197 amplifier : `lsst.afw.cameraGeom.Amplifier`
201 overscanAmpConfig : `lsst.ip.isr.overscanAmpConfig.OverscanAmpConfig`
203 ampKey = amplifier.getName()
206 overscanAmpConfig = self.
ampRules[ampKey]
210 return overscanAmpConfig
214 """Turn this config into a simple string for hashing.
216 Only the default and amps that are different than the
217 default are used in the string representation.
221 stringForHash : `str`
225 stringForHash = f
"default: {defaultString}"
227 ampString = self.
ampRules[ampName]._stringForHash
228 if ampString != defaultString:
229 stringForHash += f
" {ampName}: {ampString}"
235 """Compute the MD5 hash of this config (detector + amps).
237 This can be used to ensure overscan configs are consistent.
243 return hashlib.md5(self.
_stringForHash.encode(
"UTF-8")).hexdigest()
247 """Overscan configurations applicable to multiple detectors in
250 detectorRules = pexConfig.ConfigDictField(
251 doc=
"Detector level rules for overscan",
253 itemtype=OverscanDetectorConfig,
256 defaultDetectorConfig = pexConfig.ConfigField(
257 dtype=OverscanDetectorConfig,
258 doc=
"Default configuration for detectors.",
260 detectorRuleKeyType = pexConfig.ChoiceField(
261 doc=
"Detector rule key type.",
265 "NAME":
"DetectorRules has a key that is the detector name.",
266 "SERIAL":
"DetectorRules has a key that is the detector serial number.",
267 "ID":
"DetectorRules has a key that is the detector id number.",
273 """Check if any of the detector/amp configs have doSerialOverscan.
277 doAnySerialOverscan : `bool`
283 if detectorRule.doAnySerialOverscan:
290 """Check if any of the detector/amp configs have
295 doAnyParallelOverscan : `bool`
302 if detectorRule.doAnyParallelOverscan:
308 """Get the OverscanDetectorConfig for a specific detector.
312 detector : `lsst.afw.cameraGeom.Detector`
316 overscanDetectorConfig : `OverscanDetectorConfig`
320 key = detector.getName()
322 key = detector.getSerial()
324 key = str(detector.getId())
331 return overscanDetectorConfig