22 """Base command-line driver task for forced measurement. 24 Must be inherited to specialize for a specific dataset to be used (see 25 `ForcedPhotCcdTask`, `ForcedPhotCoaddTask`). 34 from .references
import MultiBandReferencesTask
35 from .forcedMeasurement
import ForcedMeasurementTask
36 from .applyApCorr
import ApplyApCorrTask
37 from .catalogCalculation
import CatalogCalculationTask
39 __all__ = (
"ForcedPhotImageConfig",
"ForcedPhotImageTask")
43 """Config class for forced measurement driver task.""" 45 inputSchema = lsst.pipe.base.InitInputDatasetField(
46 doc=
"Schema for the input measurement catalogs.",
47 nameTemplate=
"{inputCoaddName}Coadd_ref_schema",
48 storageClass=
"SourceCatalog",
50 outputSchema = lsst.pipe.base.InitOutputDatasetField(
51 doc=
"Schema for the output forced measurement catalogs.",
52 nameTemplate=
"{outputCoaddName}Coadd_forced_src_schema",
53 storageClass=
"SourceCatalog",
55 exposure = lsst.pipe.base.InputDatasetField(
56 doc=
"Input exposure to perform photometry on.",
57 nameTemplate=
"{inputCoaddName}Coadd",
59 storageClass=
"ExposureF",
60 dimensions=[
"AbstractFilter",
"SkyMap",
"Tract",
"Patch"],
62 refCat = lsst.pipe.base.InputDatasetField(
63 doc=
"Catalog of shapes and positions at which to force photometry.",
64 nameTemplate=
"{inputCoaddName}Coadd_ref",
66 storageClass=
"SourceCatalog",
67 dimensions=[
"SkyMap",
"Tract",
"Patch"],
69 refWcs = lsst.pipe.base.InputDatasetField(
70 doc=
"Reference world coordinate system.",
71 nameTemplate=
"{inputCoaddName}Coadd.wcs",
73 storageClass=
"TablePersistableWcs",
74 dimensions=[
"AbstractFilter",
"SkyMap",
"Tract",
"Patch"],
76 measCat = lsst.pipe.base.OutputDatasetField(
77 doc=
"Output forced photometry catalog.",
78 nameTemplate=
"{outputCoaddName}Coadd_forced_src",
80 storageClass=
"SourceCatalog",
81 dimensions=[
"AbstractFilter",
"SkyMap",
"Tract",
"Patch"],
85 references = lsst.pex.config.ConfigurableField(
86 target=MultiBandReferencesTask,
87 doc=
"subtask to retrieve reference source catalog" 89 measurement = lsst.pex.config.ConfigurableField(
90 target=ForcedMeasurementTask,
91 doc=
"subtask to do forced measurement" 93 coaddName = lsst.pex.config.Field(
94 doc=
"coadd name: typically one of deep or goodSeeing",
98 doApCorr = lsst.pex.config.Field(
101 doc=
"Run subtask to apply aperture corrections" 103 applyApCorr = lsst.pex.config.ConfigurableField(
104 target=ApplyApCorrTask,
105 doc=
"Subtask to apply aperture corrections" 107 catalogCalculation = lsst.pex.config.ConfigurableField(
108 target=CatalogCalculationTask,
109 doc=
"Subtask to run catalogCalculation plugins on catalog" 119 self.formatTemplateNames({
"inputCoaddName":
"deep",
120 "outputCoaddName":
"deep",
122 self.quantum.dimensions = (
"AbstractFilter",
"SkyMap",
"Tract",
"Patch")
126 """A base class for command-line forced measurement drivers. 130 butler : `lsst.daf.persistence.butler.Butler`, optional 131 A Butler which will be passed to the references subtask to allow it to 132 load its schema from disk. Optional, but must be specified if 133 ``refSchema`` is not; if both are specified, ``refSchema`` takes 135 refSchema : `lsst.afw.table.Schema`, optional 136 The schema of the reference catalog, passed to the constructor of the 137 references subtask. Optional, but must be specified if ``butler`` is 138 not; if both are specified, ``refSchema`` takes precedence. 140 Keyword arguments are passed to the supertask constructor. 144 This is a an abstract class, which is the common ancestor for 145 `ForcedPhotCcdTask` and `ForcedPhotCoaddTask`. It provides the 146 `runDataRef` method that does most of the work, while delegating a few 147 customization tasks to other methods that are overridden by subclasses. 149 This task is not directly usable as a command line task. Subclasses must: 151 - Set the `_DefaultName` class attribute; 152 - Implement `makeIdFactory`; 153 - Implement `fetchReferences`; 154 - Optionally, implement `attachFootprints`. 157 ConfigClass = ForcedPhotImageConfig
158 _DefaultName =
"processImageForcedTask" 160 def __init__(self, butler=None, refSchema=None, initInputs=None, **kwds):
163 if initInputs
is not None:
164 refSchema = initInputs[
'inputSchema'].schema
166 self.makeSubtask(
"references", butler=butler, schema=refSchema)
167 if refSchema
is None:
168 refSchema = self.references.schema
169 self.makeSubtask(
"measurement", refSchema=refSchema)
172 if self.config.doApCorr:
173 self.makeSubtask(
"applyApCorr", schema=self.measurement.schema)
174 self.makeSubtask(
'catalogCalculation', schema=self.measurement.schema)
181 inputData[
'exposure'],
182 inputData[
'refCat'], inputData[
'refWcs'],
183 "TractPatch", butler)
185 return self.
run(**inputData)
187 def generateMeasCat(self, exposureDataId, exposure, refCat, refWcs, idPackerName, butler):
188 """Generate a measurement catalog for Gen3. 192 exposureDataId : `DataId` 193 Butler dataId for this exposure. 194 exposure : `lsst.afw.image.exposure.Exposure` 195 Exposure to generate the catalog for. 196 refCat : `lsst.afw.table.SourceCatalog` 197 Catalog of shapes and positions at which to force photometry. 198 refWcs : `lsst.afw.image.SkyWcs` 199 Reference world coordinate system. 201 Type of ID packer to construct from the registry. 202 butler : `lsst.daf.persistence.butler.Butler` 203 Butler to use to construct id packer. 207 measCat : `lsst.afw.table.SourceCatalog` 208 Catalog of forced sources to measure. 210 packer = butler.registry.makeDataIdPacker(idPackerName, exposureDataId)
211 expId = packer.pack(exposureDataId)
212 expBits = packer.maxBits
220 """Perform forced measurement on a single exposure. 224 dataRef : `lsst.daf.persistence.ButlerDataRef` 225 Passed to the ``references`` subtask to obtain the reference WCS, 226 the ``getExposure`` method (implemented by derived classes) to 227 read the measurment image, and the ``fetchReferences`` method to 228 get the exposure and load the reference catalog (see 229 :lsst-task`lsst.meas.base.references.CoaddSrcReferencesTask`). 230 Refer to derived class documentation for details of the datasets 231 and data ID keys which are used. 232 psfCache : `int`, optional 233 Size of PSF cache, or `None`. The size of the PSF cache can have 234 a significant effect upon the runtime for complicated PSF models. 238 Sources are generated with ``generateMeasCat`` in the ``measurement`` 239 subtask. These are passed to ``measurement``'s ``run`` method, which 240 fills the source catalog with the forced measurement results. The 241 sources are then passed to the ``writeOutputs`` method (implemented by 242 derived classes) which writes the outputs. 244 refWcs = self.references.getWcs(dataRef)
246 if psfCache
is not None:
247 exposure.getPsf().setCacheSize(psfCache)
252 self.log.info(
"Performing forced measurement on %s" % (dataRef.dataId,))
257 forcedPhotResult = self.
run(measCat, exposure, refCat, refWcs, exposureId=exposureId)
259 self.
writeOutput(dataRef, forcedPhotResult.measCat)
261 def run(self, measCat, exposure, refCat, refWcs, exposureId=None):
262 """Perform forced measurement on a single exposure. 266 measCat : `lsst.afw.table.SourceCatalog` 267 The measurement catalog, based on the sources listed in the 269 exposure : `lsst.afw.image.Exposure` 270 The measurement image upon which to perform forced detection. 271 refCat : `lsst.afw.table.SourceCatalog` 272 The reference catalog of sources to measure. 273 refWcs : `lsst.afw.image.SkyWcs` 274 The WCS for the references. 276 Optional unique exposureId used for random seed in measurement 281 result : `lsst.pipe.base.Struct` 282 Structure with fields: 285 Catalog of forced measurement results 286 (`lsst.afw.table.SourceCatalog`). 288 self.measurement.
run(measCat, exposure, refCat, refWcs, exposureId=exposureId)
289 if self.config.doApCorr:
290 self.applyApCorr.
run(
292 apCorrMap=exposure.getInfo().getApCorrMap()
294 self.catalogCalculation.
run(measCat)
296 return lsst.pipe.base.Struct(measCat=measCat)
299 """Hook for derived classes to make an ID factory for forced sources. 303 That this applies to forced *source* IDs, not object IDs, which are 304 usually handled by the ``measurement.copyColumns`` config option. 307 raise NotImplementedError()
310 raise NotImplementedError()
313 """Hook for derived classes to define how to get reference objects. 317 Derived classes should call one of the ``fetch*`` methods on the 318 ``references`` subtask, but which one they call depends on whether the 319 region to get references for is a easy to describe in patches (as it 320 would be when doing forced measurements on a coadd), or is just an 321 arbitrary box (as it would be for CCD forced measurements). 323 raise NotImplementedError()
326 r"""Attach footprints to blank sources prior to measurements. 330 `~lsst.afw.detection.Footprint`\ s for forced photometry must be in the 331 pixel coordinate system of the image being measured, while the actual 332 detections may start out in a different coordinate system. 334 Subclasses of this class must implement this method to define how 335 those `~lsst.afw.detection.Footprint`\ s should be generated. 337 This default implementation transforms the 338 `~lsst.afw.detection.Footprint`\ s from the reference catalog from the 339 reference WCS to the exposure's WcS, which downgrades 340 `lsst.afw.detection.heavyFootprint.HeavyFootprint`\ s into regular 341 `~lsst.afw.detection.Footprint`\ s, destroying deblend information. 343 return self.measurement.attachTransformedFootprints(sources, refCat, exposure, refWcs)
346 """Read input exposure on which measurement will be performed. 350 dataRef : `lsst.daf.persistence.ButlerDataRef` 351 Butler data reference. 353 return dataRef.get(self.dataPrefix +
"calexp", immediate=
True)
356 """Write forced source table 360 dataRef : `lsst.daf.persistence.ButlerDataRef` 361 Butler data reference. The forced_src dataset (with 362 self.dataPrefix prepended) is all that will be modified. 363 sources : `lsst.afw.table.SourceCatalog` 364 Catalog of sources to save. 366 dataRef.put(sources, self.dataPrefix +
"forced_src", flags=lsst.afw.table.SOURCE_IO_NO_FOOTPRINTS)
369 """The schema catalogs that will be used by this task. 373 schemaCatalogs : `dict` 374 Dictionary mapping dataset type to schema catalog. 378 There is only one schema for each type of forced measurement. The 379 dataset type for this measurement is defined in the mapper. 382 catalog.getTable().setMetadata(self.measurement.algMetadata)
383 datasetType = self.dataPrefix +
"forced_src" 384 return {datasetType: catalog}
386 def _getConfigName(self):
388 return self.dataPrefix +
"forced_config" 390 def _getMetadataName(self):
392 return self.dataPrefix +
"forced_metadata"
def getExposure(self, dataRef)
def runDataRef(self, dataRef, psfCache=None)
def adaptArgsAndRun(self, inputData, inputDataIds, outputDataIds, butler)
def fetchReferences(self, dataRef, exposure)
def run(self, measCat, exposure, refCat, refWcs, exposureId=None)
def makeIdFactory(self, dataRef)
def getExposureId(self, dataRef)
static std::shared_ptr< IdFactory > makeSource(RecordId expId, int reserved)
def generateMeasCat(self, exposureDataId, exposure, refCat, refWcs, idPackerName, butler)
def getSchemaCatalogs(self)
def writeOutput(self, dataRef, sources)
def __init__(self, butler=None, refSchema=None, initInputs=None, kwds)
def getInitOutputDatasets(self)
def attachFootprints(self, sources, refCat, exposure, refWcs, dataRef)