190 def run(self, coaddExposures, bbox, wcs, dataIds, physical_filter=None, **kwargs):
191 """Warp coadds from multiple tracts to form a template for image diff.
192
193 Where the tracts overlap, the resulting template image is averaged.
194 The PSF on the template is created by combining the CoaddPsf on each
195 template image into a meta-CoaddPsf.
196
197 Parameters
198 ----------
199 coaddExposures : `list` [`lsst.afw.image.Exposure`]
200 Coadds to be mosaicked.
201 bbox : `lsst.geom.Box2I`
202 Template Bounding box of the detector geometry onto which to
203 resample the ``coaddExposures``.
204 wcs : `lsst.afw.geom.SkyWcs`
205 Template WCS onto which to resample the ``coaddExposures``.
206 dataIds : `list` [`lsst.daf.butler.DataCoordinate`]
207 Record of the tract and patch of each coaddExposure.
208 physical_filter : `str`, optional
209 The physical filter of the science image.
210 **kwargs
211 Any additional keyword parameters.
212
213 Returns
214 -------
215 result : `lsst.pipe.base.Struct`
216 A struct with attributes:
217
218 ``template``
219 A template coadd exposure assembled out of patches
220 (`lsst.afw.image.ExposureF`).
221
222 Raises
223 ------
224 NoWorkFound
225 If no coadds are found with sufficient un-masked pixels.
226 RuntimeError
227 If the PSF of the template can't be calculated.
228 """
229
230 tractsSchema = afwTable.ExposureTable.makeMinimalSchema()
231 tractKey = tractsSchema.addField('tract', type=np.int32, doc='Which tract')
232 patchKey = tractsSchema.addField('patch', type=np.int32, doc='Which patch')
233 weightKey = tractsSchema.addField('weight', type=float, doc='Weight for each tract, should be 1')
235
236 finalWcs = wcs
237 bbox.grow(self.config.templateBorderSize)
238 finalBBox = bbox
239
240 nPatchesFound = 0
241 maskedImageList = []
242 weightList = []
243
244 for coaddExposure, dataId in zip(coaddExposures, dataIds):
245
246
247 warped = self.warper.warpExposure(finalWcs, coaddExposure, maxBBox=finalBBox)
248
249
250 if not np.any(np.isfinite(warped.image.array)):
251 self.log.info("No overlap for warped %s. Skipping" % dataId)
252 continue
253
254 exp = afwImage.ExposureF(finalBBox, finalWcs)
255 exp.maskedImage.set(np.nan, afwImage.Mask.getPlaneBitMask("NO_DATA"), np.nan)
256 exp.maskedImage.assign(warped.maskedImage, warped.getBBox())
257
258 maskedImageList.append(exp.maskedImage)
259 weightList.append(1)
260 record = tractsCatalog.addNew()
261 record.setPsf(coaddExposure.getPsf())
262 record.setWcs(coaddExposure.getWcs())
263 record.setPhotoCalib(coaddExposure.getPhotoCalib())
264 record.setBBox(coaddExposure.getBBox())
266 record.set(tractKey, dataId['tract'])
267 record.set(patchKey, dataId['patch'])
268 record.set(weightKey, 1.)
269 nPatchesFound += 1
270
271 if nPatchesFound == 0:
272 raise pipeBase.NoWorkFound("No patches found to overlap detector")
273
274
277 statsCtrl.setNanSafe(True)
278 statsCtrl.setWeighted(True)
279 statsCtrl.setCalcErrorMosaicMode(True)
280
281 templateExposure = afwImage.ExposureF(finalBBox, finalWcs)
282 templateExposure.maskedImage.set(np.nan, afwImage.Mask.getPlaneBitMask("NO_DATA"), np.nan)
283 xy0 = templateExposure.getXY0()
284
286 weightList, clipped=0, maskMap=[])
287 templateExposure.maskedImage.setXY0(xy0)
288
289
290
291 boolmask = templateExposure.mask.array & templateExposure.mask.getPlaneBitMask('NO_DATA') == 0
293 centerCoord = afwGeom.SpanSet.fromMask(maskx, 1).computeCentroid()
294
295 ctrl = self.config.coaddPsf.makeControl()
296 coaddPsf = CoaddPsf(tractsCatalog, finalWcs, centerCoord, ctrl.warpingKernelName, ctrl.cacheSize)
297 if coaddPsf is None:
298 raise RuntimeError("CoaddPsf could not be constructed")
299
300 templateExposure.setPsf(coaddPsf)
301
302 if physical_filter is None:
303 filterLabel = coaddExposure.getFilter()
304 else:
306 templateExposure.setFilter(filterLabel)
307 templateExposure.setPhotoCalib(coaddExposure.getPhotoCalib())
308 return pipeBase.Struct(template=templateExposure)
309
310
A group of labels for a filter in an exposure or coadd.
Pass parameters to a Statistics object.
Custom catalog class for ExposureRecord/Table.
A floating-point coordinate rectangle geometry.
std::shared_ptr< lsst::afw::image::Image< PixelT > > statisticsStack(std::vector< std::shared_ptr< lsst::afw::image::Image< PixelT > > > &images, Property flags, StatisticsControl const &sctrl=StatisticsControl(), std::vector< lsst::afw::image::VariancePixel > const &wvector=std::vector< lsst::afw::image::VariancePixel >(0))
A function to compute some statistics of a stack of Images.
Property stringToStatisticsProperty(std::string const property)
Conversion function to switch a string to a Property (see Statistics.h)