211 sensorRef=None, visitInfo=None):
212 """Determination of exposure dimensions and copying of pixels from
213 overlapping patch regions.
214
215 Parameters
216 ----------
218 SkyMap object that corresponds to the template coadd.
220 The selected tract.
222 Patches to consider for making the template exposure.
224 Sky corner coordinates to be covered by the template exposure.
225 availableCoaddRefs : `dict` [`int`]
226 Dictionary of spatially relevant retrieved coadd patches,
227 indexed by their sequential patch number. Values are
228 `lsst.daf.butler.DeferredDatasetHandle` and ``.get()`` is called.
229 sensorRef : `None`
230 Must always be `None`. Gen2 parameters are no longer used.
232 VisitInfo to make dcr model.
233
234 Returns
235 -------
236 templateExposure : `lsst.afw.image.ExposureF`
237 The created template exposure.
238 """
239 if sensorRef is not None:
240 raise ValueError("sensorRef parameter is a Gen2 parameter that is no longer usable."
241 " Please move to Gen3 middleware.")
242 coaddWcs = tractInfo.getWcs()
243
244
246 for skyPos in skyCorners:
247 coaddBBox.include(coaddWcs.skyToPixel(skyPos))
249 self.log.info("coadd dimensions=%s", coaddBBox.getDimensions())
250
251 coaddExposure = afwImage.ExposureF(coaddBBox, coaddWcs)
252 coaddExposure.maskedImage.set(np.nan, afwImage.Mask.getPlaneBitMask("NO_DATA"), np.nan)
253 nPatchesFound = 0
254 coaddFilterLabel = None
255 coaddPsf = None
256 coaddPhotoCalib = None
257 for patchInfo in patchList:
258 patchNumber = tractInfo.getSequentialPatchIndex(patchInfo)
259 patchSubBBox = patchInfo.getOuterBBox()
260 patchSubBBox.clip(coaddBBox)
261 if patchNumber not in availableCoaddRefs:
262 self.log.warning("skip patch=%d; patch does not exist for this coadd", patchNumber)
263 continue
264 if patchSubBBox.isEmpty():
265 if isinstance(availableCoaddRefs[patchNumber], DeferredDatasetHandle):
266 tract = availableCoaddRefs[patchNumber].dataId['tract']
267 else:
268 tract = availableCoaddRefs[patchNumber]['tract']
269 self.log.info("skip tract=%d patch=%d; no overlapping pixels", tract, patchNumber)
270 continue
271
272 if self.config.coaddName == 'dcr':
273 patchInnerBBox = patchInfo.getInnerBBox()
274 patchInnerBBox.clip(coaddBBox)
275 if np.min(patchInnerBBox.getDimensions()) <= 2*self.config.templateBorderSize:
276 self.log.info("skip tract=%(tract)s, patch=%(patch)s; too few pixels.",
277 availableCoaddRefs[patchNumber])
278 continue
279 self.log.info("Constructing DCR-matched template for patch %s",
280 availableCoaddRefs[patchNumber])
281
282 dcrModel = DcrModel.fromQuantum(availableCoaddRefs[patchNumber],
283 self.config.effectiveWavelength,
284 self.config.bandwidth)
285
286
287
288
289
290
292 dcrBBox.grow(-self.config.templateBorderSize)
293 dcrBBox.include(patchInnerBBox)
294 coaddPatch = dcrModel.buildMatchedExposure(bbox=dcrBBox,
295 visitInfo=visitInfo)
296 else:
297 coaddPatch = availableCoaddRefs[patchNumber].get()
298
299 nPatchesFound += 1
300
301
302
303 overlapBox = coaddPatch.getBBox()
304 overlapBox.clip(coaddBBox)
305 coaddExposure.maskedImage.assign(coaddPatch.maskedImage[overlapBox], overlapBox)
306
307 if coaddFilterLabel is None:
308 coaddFilterLabel = coaddPatch.getFilter()
309
310
311 if coaddPsf is None and coaddPatch.hasPsf():
312 coaddPsf = coaddPatch.getPsf()
313
314
315
316 if coaddPhotoCalib is None:
317 coaddPhotoCalib = coaddPatch.getPhotoCalib()
318
319 if coaddPhotoCalib is None:
320 raise RuntimeError("No coadd PhotoCalib found!")
321 if nPatchesFound == 0:
322 raise RuntimeError("No patches found!")
323 if coaddPsf is None:
324 raise RuntimeError("No coadd Psf found!")
325
326 coaddExposure.setPhotoCalib(coaddPhotoCalib)
327 coaddExposure.setPsf(coaddPsf)
328 coaddExposure.setFilter(coaddFilterLabel)
329 return coaddExposure
330
Information about a single exposure of an imaging camera.
An integer coordinate rectangle.