LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
LSSTDataManagementBasePackage
forcedPhotCoadd.py
Go to the documentation of this file.
1 # This file is part of meas_base.
2 #
3 # Developed for the LSST Data Management System.
4 # This product includes software developed by the LSST Project
5 # (https://www.lsst.org).
6 # See the COPYRIGHT file at the top-level directory of this distribution
7 # for details of code ownership.
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 
22 import lsst.pex.config
23 import lsst.pipe.base
24 import lsst.coadd.utils
25 import lsst.afw.table
26 
27 from .forcedPhotImage import ForcedPhotImageConfig, ForcedPhotImageTask
28 
29 __all__ = ("ForcedPhotCoaddConfig", "ForcedPhotCoaddTask")
30 
31 
33  footprintDatasetName = lsst.pex.config.Field(
34  doc="Dataset (without coadd prefix) that should be used to obtain (Heavy)Footprints for sources. "
35  "Must have IDs that match those of the reference catalog."
36  "If None, Footprints will be generated by transforming the reference Footprints.",
37  dtype=str,
38  default="meas",
39  optional=True
40  )
41 
42  def setDefaults(self):
43  ForcedPhotImageTask.ConfigClass.setDefaults(self)
44  # Copy 'id' and 'parent' columns without renaming them; since these are
45  # the only IDs we have in coadd processing, there's no need to qualify
46  # them with 'object'.
47  self.measurement.copyColumns["id"] = "id"
48  self.measurement.copyColumns["parent"] = "parent"
49  self.references.removePatchOverlaps = False # see validate() for why
50  self.measurement.plugins.names |= ['base_InputCount', 'base_Variance']
51  self.measurement.plugins['base_PixelFlags'].masksFpAnywhere = ['CLIPPED', 'SENSOR_EDGE',
52  'REJECTED', 'INEXACT_PSF']
53  self.measurement.plugins['base_PixelFlags'].masksFpCenter = ['CLIPPED', 'SENSOR_EDGE',
54  'REJECTED', 'INEXACT_PSF']
55 
56  def validate(self):
57  ForcedPhotImageTask.ConfigClass.validate(self)
58  if (self.measurement.doReplaceWithNoise and self.footprintDatasetName is not None and
59  self.references.removePatchOverlaps):
60  raise ValueError("Cannot use removePatchOverlaps=True with deblended footprints, as parent "
61  "sources may be rejected while their children are not.")
62 
63 
65  """Get the psfCache setting into ForcedPhotCoaddTask"""
66  @staticmethod
67  def getTargetList(parsedCmd, **kwargs):
68  return lsst.pipe.base.ButlerInitializedTaskRunner.getTargetList(parsedCmd,
69  psfCache=parsedCmd.psfCache)
70 
71 
73  """A command-line driver for performing forced measurement on coadd images.
74 
75  Notes
76  -----
77  In addition to the run method, `ForcedPhotCcdTask` overrides several
78  methods of `ForcedPhotImageTask` to specialize it for coadd processing,
79  including `~ForcedPhotImageTask.makeIdFactory` and
80  `~ForcedPhotImageTask.fetchReferences`. None of these should be called
81  directly by the user, though it may be useful to override them further in
82  subclasses.
83  """
84 
85  ConfigClass = ForcedPhotCoaddConfig
87  _DefaultName = "forcedPhotCoadd"
88  dataPrefix = "deepCoadd_"
89 
90  def getExposure(self, dataRef):
91  name = self.config.coaddName + "Coadd_calexp"
92  return dataRef.get(name) if dataRef.datasetExists(name) else None
93 
94  def makeIdFactory(self, dataRef):
95  """Create an object that generates globally unique source IDs.
96 
97  Source IDs are created based on a per-CCD ID and the ID of the CCD
98  itself.
99 
100  Parameters
101  ----------
102  dataRef : `lsst.daf.persistence.ButlerDataRef`
103  Butler data reference. The "CoaddId_bits" and "CoaddId" datasets
104  are accessed. The data ID must have tract and patch keys.
105  """
106  # With the default configuration, this IdFactory doesn't do anything,
107  # because the IDs it generates are immediately overwritten by the ID
108  # from the reference catalog (since that's in
109  # config.measurement.copyColumns). But we create one here anyway, to
110  # allow us to revert back to the old behavior of generating new forced
111  # source IDs, just by renaming the ID in config.copyColumns to
112  # "object_id".
113  expBits = dataRef.get(self.config.coaddName + "CoaddId_bits")
114  expId = int(dataRef.get(self.config.coaddName + "CoaddId"))
115  return lsst.afw.table.IdFactory.makeSource(expId, 64 - expBits)
116 
117  def getExposureId(self, dataRef):
118  return int(dataRef.get(self.config.coaddName + "CoaddId"))
119 
120  def fetchReferences(self, dataRef, exposure):
121  """Return an iterable of reference sources which overlap the exposure.
122 
123  Parameters
124  ----------
125  dataRef : `lsst.daf.persistence.ButlerDataRef`
126  Butler data reference corresponding to the image to be measured;
127  should have tract, patch, and filter keys.
128 
129  exposure : `lsst.afw.image.Exposure`
130  Unused.
131 
132  Notes
133  -----
134  All work is delegated to the references subtask; see
135  `CoaddSrcReferencesTask` for information about the default behavior.
136  """
137  skyMap = dataRef.get(self.dataPrefix + "skyMap", immediate=True)
138  tractInfo = skyMap[dataRef.dataId["tract"]]
139  patch = tuple(int(v) for v in dataRef.dataId["patch"].split(","))
140  patchInfo = tractInfo.getPatchInfo(patch)
141  references = lsst.afw.table.SourceCatalog(self.references.schema)
142  references.extend(self.references.fetchInPatches(dataRef, patchList=[patchInfo]))
143  return references
144 
145  def attachFootprints(self, sources, refCat, exposure, refWcs, dataRef):
146  r"""Attach Footprints to source records.
147 
148  For coadd forced photometry, we use the deblended "heavy"
149  `~lsst.afw.detection.Footprint`\ s from the single-band measurements
150  of the same band - because we've guaranteed that the peaks (and hence
151  child sources) will be consistent across all bands before we get to
152  measurement, this should yield reasonable deblending for most sources.
153  It's most likely limitation is that it will not provide good flux
154  upper limits for sources that were not detected in this band but were
155  blended with sources that were.
156  """
157  if self.config.footprintDatasetName is None:
158  return ForcedPhotImageTask.attachFootprints(self, sources, refCat, exposure, refWcs, dataRef)
159  self.log.info("Loading deblended footprints for sources from %s, %s" %
160  (self.config.footprintDatasetName, dataRef.dataId))
161  fpCat = dataRef.get("%sCoadd_%s" % (self.config.coaddName, self.config.footprintDatasetName),
162  immediate=True)
163  for refRecord, srcRecord in zip(refCat, sources):
164  fpRecord = fpCat.find(refRecord.getId())
165  if fpRecord is None:
166  raise LookupError("Cannot find Footprint for source %s; please check that %sCoadd_%s "
167  "IDs are compatible with reference source IDs" %
168  (srcRecord.getId(), self.config.coaddName,
169  self.config.footprintDatasetName))
170  srcRecord.setFootprint(fpRecord.getFootprint())
171 
172  @classmethod
173  def _makeArgumentParser(cls):
175  parser.add_id_argument("--id", "deepCoadd_forced_src", help="data ID, with raw CCD keys + tract",
177  parser.add_argument("--psfCache", type=int, default=100, help="Size of CoaddPsf cache")
178  return parser
static std::shared_ptr< IdFactory > makeSource(RecordId expId, int reserved)
Return an IdFactory that includes another, fixed ID in the higher-order bits.
Definition: IdFactory.cc:72
def attachFootprints(self, sources, refCat, exposure, refWcs, dataRef)