22 import lsst.pex.config
 
   28 from .forcedPhotImage 
import ForcedPhotImageConfig, ForcedPhotImageTask, ForcedPhotImageConnections
 
   31 __all__ = (
"ForcedPhotCoaddConfig", 
"ForcedPhotCoaddTask")
 
   35     footprintDatasetName = lsst.pex.config.Field(
 
   36         doc=
"Dataset (without coadd prefix) that should be used to obtain (Heavy)Footprints for sources. " 
   37             "Must have IDs that match those of the reference catalog." 
   38             "If None, Footprints will be generated by transforming the reference Footprints.",
 
   44     hasFakes = lsst.pex.config.Field(
 
   47         doc=
"Should be set to True if fake sources have been inserted into the input data." 
   51         ForcedPhotImageTask.ConfigClass.setDefaults(self)
 
   55         self.measurement.copyColumns[
"id"] = 
"id" 
   56         self.measurement.copyColumns[
"parent"] = 
"parent" 
   57         self.references.removePatchOverlaps = 
False   
   58         self.measurement.plugins.names |= [
'base_InputCount', 
'base_Variance']
 
   59         self.measurement.plugins[
'base_PixelFlags'].masksFpAnywhere = [
'CLIPPED', 
'SENSOR_EDGE',
 
   60                                                                        'REJECTED', 
'INEXACT_PSF']
 
   61         self.measurement.plugins[
'base_PixelFlags'].masksFpCenter = [
'CLIPPED', 
'SENSOR_EDGE',
 
   62                                                                      'REJECTED', 
'INEXACT_PSF']
 
   65         ForcedPhotImageTask.ConfigClass.validate(self)
 
   67                 and self.references.removePatchOverlaps):
 
   68             raise ValueError(
"Cannot use removePatchOverlaps=True with deblended footprints, as parent " 
   69                              "sources may be rejected while their children are not.")
 
   73     """Get the psfCache setting into ForcedPhotCoaddTask""" 
   76         return lsst.pipe.base.ButlerInitializedTaskRunner.getTargetList(parsedCmd,
 
   77                                                                         psfCache=parsedCmd.psfCache)
 
   81     """A command-line driver for performing forced measurement on coadd images. 
   85     In addition to the run method, `ForcedPhotCcdTask` overrides several 
   86     methods of `ForcedPhotImageTask` to specialize it for coadd processing, 
   87     including `~ForcedPhotImageTask.makeIdFactory` and 
   88     `~ForcedPhotImageTask.fetchReferences`. None of these should be called 
   89     directly by the user, though it may be useful to override them further in 
   93     ConfigClass = ForcedPhotCoaddConfig
 
   95     _DefaultName = 
"forcedPhotCoadd" 
   96     dataPrefix = 
"deepCoadd_" 
  100         if self.config.hasFakes:
 
  101             name = 
"fakes_" + self.config.coaddName + 
"Coadd_calexp" 
  103             name = self.config.coaddName + 
"Coadd_calexp" 
  105         return dataRef.get(name) 
if dataRef.datasetExists(name) 
else None 
  108         """Create an object that generates globally unique source IDs. 
  110         Source IDs are created based on a per-CCD ID and the ID of the CCD 
  115         dataRef : `lsst.daf.persistence.ButlerDataRef` 
  116             Butler data reference. The "CoaddId_bits" and "CoaddId" datasets 
  117             are accessed. The data ID must have tract and patch keys. 
  126         expBits = dataRef.get(self.config.coaddName + 
"CoaddId_bits")
 
  127         expId = int(dataRef.get(self.config.coaddName + 
"CoaddId"))
 
  131         return int(dataRef.get(self.config.coaddName + 
"CoaddId"))
 
  134         """Return an iterable of reference sources which overlap the exposure. 
  138         dataRef : `lsst.daf.persistence.ButlerDataRef` 
  139             Butler data reference corresponding to the image to be measured; 
  140             should have tract, patch, and filter keys. 
  142         exposure : `lsst.afw.image.Exposure` 
  147         All work is delegated to the references subtask; see 
  148         `CoaddSrcReferencesTask` for information about the default behavior. 
  150         skyMap = dataRef.get(self.
dataPrefix + 
"skyMap", immediate=
True)
 
  151         tractInfo = skyMap[dataRef.dataId[
"tract"]]
 
  152         patch = tuple(int(v) 
for v 
in dataRef.dataId[
"patch"].split(
","))
 
  153         patchInfo = tractInfo.getPatchInfo(patch)
 
  155         references.extend(self.references.fetchInPatches(dataRef, patchList=[patchInfo]))
 
  159         r"""Attach Footprints to source records. 
  161         For coadd forced photometry, we use the deblended "heavy" 
  162         `~lsst.afw.detection.Footprint`\ s from the single-band measurements 
  163         of the same band - because we've guaranteed that the peaks (and hence 
  164         child sources) will be consistent across all bands before we get to 
  165         measurement, this should yield reasonable deblending for most sources. 
  166         It's most likely limitation is that it will not provide good flux 
  167         upper limits for sources that were not detected in this band but were 
  168         blended with sources that were. 
  170         if self.config.footprintDatasetName 
is None:
 
  171             return ForcedPhotImageTask.attachFootprints(self, sources, refCat, exposure, refWcs, dataRef)
 
  172         self.log.
info(
"Loading deblended footprints for sources from %s, %s" %
 
  173                       (self.config.footprintDatasetName, dataRef.dataId))
 
  174         fpCat = dataRef.get(
"%sCoadd_%s" % (self.config.coaddName, self.config.footprintDatasetName),
 
  176         for refRecord, srcRecord 
in zip(refCat, sources):
 
  177             fpRecord = fpCat.find(refRecord.getId())
 
  179                 raise LookupError(
"Cannot find Footprint for source %s; please check that %sCoadd_%s " 
  180                                   "IDs are compatible with reference source IDs" %
 
  181                                   (srcRecord.getId(), self.config.coaddName,
 
  182                                    self.config.footprintDatasetName))
 
  183             srcRecord.setFootprint(fpRecord.getFootprint())
 
  186     def _makeArgumentParser(cls):
 
  188         parser.add_id_argument(
"--id", 
"deepCoadd_forced_src", help=
"data ID, with raw CCD keys + tract",
 
  190         parser.add_argument(
"--psfCache", type=int, default=100, help=
"Size of CoaddPsf cache")