1216 ):
1217
1218 detector = ccdExposure.getDetector()
1219
1220 overscanDetectorConfig = self.config.overscanCamera.getOverscanDetectorConfig(detector)
1221
1222 gains = ptc.gain
1223
1224 if self.config.doHeaderProvenance:
1225
1226
1227 exposureMetadata = ccdExposure.getMetadata()
1228 exposureMetadata["LSST CALIB OVERSCAN HASH"] = overscanDetectorConfig.md5
1229 exposureMetadata["LSST CALIB DATE PTC"] = self.extractCalibDate(ptc)
1230 if self.config.doDiffNonLinearCorrection:
1231 exposureMetadata["LSST CALIB DATE DNL"] = self.extractCalibDate(dnlLUT)
1232 if self.config.doBias:
1233 exposureMetadata["LSST CALIB DATE BIAS"] = self.extractCalibDate(bias)
1234 if self.config.doDeferredCharge:
1235 exposureMetadata["LSST CALIB DATE CTI"] = self.extractCalibDate(deferredChargeCalib)
1236 if self.doLinearize(detector):
1237 exposureMetadata["LSST CALIB DATE LINEARIZER"] = self.extractCalibDate(linearizer)
1238 if self.config.doCrosstalk or overscanDetectorConfig.doAnyParallelOverscanCrosstalk:
1239 exposureMetadata["LSST CALIB DATE CROSSTALK"] = self.extractCalibDate(crosstalk)
1240 if self.config.doDefect:
1241 exposureMetadata["LSST CALIB DATE DEFECTS"] = self.extractCalibDate(defects)
1242 if self.config.doBrighterFatter:
1243 exposureMetadata["LSST CALIB DATE BFK"] = self.extractCalibDate(bfKernel)
1244 if self.config.doDark:
1245 exposureMetadata["LSST CALIB DATE DARK"] = self.extractCalibDate(dark)
1246 if self.config.doFlat:
1247 exposureMetadata["LSST CALIB DATE FLAT"] = self.extractCalibDate(flat)
1248
1249
1250 badAmpDict = self.maskFullDefectAmplifiers(ccdExposure, detector, defects)
1251
1252 if self.config.doDiffNonLinearCorrection:
1253 self.diffNonLinearCorrection(ccdExposure, dnlLUT)
1254
1255 if overscanDetectorConfig.doAnySerialOverscan:
1256
1257 serialOverscans = self.overscanCorrection(
1258 "SERIAL",
1259 overscanDetectorConfig,
1260 detector,
1261 badAmpDict,
1262 ccdExposure,
1263 )
1264 else:
1265 serialOverscans = [None]*len(detector)
1266
1267 if overscanDetectorConfig.doAnyParallelOverscanCrosstalk:
1268
1269
1270
1271 self.crosstalk.run(
1272 ccdExposure,
1273 crosstalk=crosstalk,
1274 camera=camera,
1275 parallelOverscanRegion=True,
1276 detectorConfig=overscanDetectorConfig,
1277 )
1278
1279
1280
1281
1282 badAmpDict = self.maskSaturatedPixels(badAmpDict, ccdExposure, detector)
1283
1284 if overscanDetectorConfig.doAnyParallelOverscan:
1285
1286
1287 _ = self.overscanCorrection(
1288 "PARALLEL",
1289 overscanDetectorConfig,
1290 detector,
1291 badAmpDict,
1292 ccdExposure,
1293 )
1294
1295 if self.config.doAssembleCcd:
1296
1297 self.log.info("Assembling CCD from amplifiers.")
1298 ccdExposure = self.assembleCcd.assembleCcd(ccdExposure)
1299
1300 if self.config.expectWcs and not ccdExposure.getWcs():
1301 self.log.warning("No WCS found in input exposure.")
1302
1303 if self.config.doLinearize:
1304
1305 self.log.info("Applying linearizer.")
1306 linearizer = self.getLinearizer(detector=detector)
1307 linearizer.applyLinearity(image=ccdExposure.getMaskedImage().getImage(),
1308 detector=detector, log=self.log)
1309
1310 if self.config.doCrosstalk:
1311
1312 self.log.info("Applying crosstalk correction.")
1313 self.crosstalk.run(ccdExposure, crosstalk=crosstalk)
1314
1315 if self.config.doBias:
1316
1317 self.log.info("Applying bias correction.")
1318 isrFunctions.biasCorrection(ccdExposure.getMaskedImage(), bias.getMaskedImage())
1319
1320 if self.config.doGainsCorrection:
1321
1322 self.log.info("Apply temperature dependence to the gains.")
1323 gains, readNoise = self.gainsCorrection(**kwargs)
1324
1325 if self.config.doApplyGains:
1326
1327
1328 self.log.info("Apply PTC gains (temperature corrected or not) to the image.")
1329 isrFunctions.applyGains(ccdExposure, normalizeGains=False, ptcGains=gains)
1330
1331 if self.config.doDeferredCharge:
1332
1333 self.log.info("Applying deferred charge/CTI correction.")
1334 self.deferredChargeCorrection.run(ccdExposure, deferredChargeCalib)
1335
1336 if self.config.doVariance:
1337
1338 self.variancePlane(ccdExposure, detector, ptc)
1339
1340
1341
1342 if self.config.doDefect:
1343
1344 self.log.info("Applying defects masking.")
1345 self.maskDefect(ccdExposure, defects)
1346
1347 if self.config.doNanMasking:
1348 self.log.info("Masking non-finite (NAN, inf) value pixels.")
1349 self.maskNan(ccdExposure)
1350
1351 if self.config.doWidenSaturationTrails:
1352 self.log.info("Widening saturation trails.")
1353 isrFunctions.widenSaturationTrails(ccdExposure.getMaskedImage().getMask())
1354
1355 preInterpExp = None
1356 if self.config.doSaveInterpPixels:
1357 preInterpExp = ccdExposure.clone()
1358
1359 if self.config.doSetBadRegions:
1360 self.log.info('Counting pixels in BAD regions.')
1361 self.countBadPixels(ccdExposure)
1362
1363 if self.config.doInterpolate:
1364 self.log.info("Interpolating masked pixels.")
1365 isrFunctions.interpolateFromMask(
1366 maskedImage=ccdExposure.getMaskedImage(),
1367 fwhm=self.config.brighterFatterFwhmForInterpolation,
1368 growSaturatedFootprints=self.config.growSaturationFootprintSize,
1369 maskNameList=list(self.config.maskListToInterpolate)
1370 )
1371
1372 if self.config.doDark:
1373
1374 self.log.info("Applying dark subtraction.")
1375 self.darkCorrection(ccdExposure, dark)
1376
1377 if self.config.doBrighterFatter:
1378
1379 self.log.info("Applying Bright-Fatter kernels.")
1380 bfKernelOut, bfGains = self.getBrighterFatterKernel(detector, bfKernel)
1381 ccdExposure = self.applyBrighterFatterCorrection(ccdExposure, flat, dark, bfKernelOut, bfGains)
1382
1383 if self.config.doFlat:
1384
1385 self.log.info("Applying flat correction.")
1386
1387
1388 self.flatCorrection(ccdExposure, flat)
1389
1390
1391 if self.config.doStandardStatistics:
1392 metadata = ccdExposure.getMetadata()
1393 for amp in detector:
1394 ampExposure = ccdExposure.Factory(ccdExposure, amp.getBBox())
1395 ampName = amp.getName()
1396 metadata[f"LSST ISR MASK SAT {ampName}"] = isrFunctions.countMaskedPixels(
1397 ampExposure.getMaskedImage(),
1398 [self.config.saturatedMaskName]
1399 )
1400 metadata[f"LSST ISR MASK BAD {ampName}"] = isrFunctions.countMaskedPixels(
1401 ampExposure.getMaskedImage(),
1402 ["BAD"]
1403 )
1405 afwMath.MEAN | afwMath.MEDIAN | afwMath.STDEVCLIP)
1406
1407 metadata[f"LSST ISR FINAL MEAN {ampName}"] = qaStats.getValue(afwMath.MEAN)
1408 metadata[f"LSST ISR FINAL MEDIAN {ampName}"] = qaStats.getValue(afwMath.MEDIAN)
1409 metadata[f"LSST ISR FINAL STDEV {ampName}"] = qaStats.getValue(afwMath.STDEVCLIP)
1410
1411 k1 = f"LSST ISR FINAL MEDIAN {ampName}"
1412 k2 = f"LSST ISR OVERSCAN SERIAL MEDIAN {ampName}"
1413 if overscanDetectorConfig.doAnySerialOverscan and k1 in metadata and k2 in metadata:
1414 metadata[f"LSST ISR LEVEL {ampName}"] = metadata[k1] - metadata[k2]
1415 else:
1416 metadata[f"LSST ISR LEVEL {ampName}"] = numpy.nan
1417
1418
1419 outputStatistics = None
1420 if self.config.doCalculateStatistics:
1421 outputStatistics = self.isrStats.run(ccdExposure, overscanResults=serialOverscans,
1422 ptc=ptc).results
1423
1424
1425 outputBin1Exposure = None
1426 outputBin2Exposure = None
1427 if self.config.doBinnedExposures:
1428 outputBin1Exposure, outputBin2Exposure = self.makeBinnedImages(ccdExposure)
1429
1430 return pipeBase.Struct(
1431 exposure=ccdExposure,
1432
1433 outputBin1Exposure=outputBin1Exposure,
1434 outputBin2Exposure=outputBin2Exposure,
1435
1436 preInterpExposure=preInterpExp,
1437 outputExposure=ccdExposure,
1438 outputStatistics=outputStatistics,
1439 )
Statistics makeStatistics(lsst::afw::image::Image< Pixel > const &img, lsst::afw::image::Mask< image::MaskPixel > const &msk, int const flags, StatisticsControl const &sctrl=StatisticsControl())
Handle a watered-down front-end to the constructor (no variance)