23 Subtasks for creating the reference catalogs used in forced measurement.
30 __all__ = (
"BaseReferencesTask",
"CoaddSrcReferencesTask")
34 """Default configuration for reference source selection.
38 doc=
"Only include reference sources for each patch that lie within the patch's inner bbox",
43 doc=
"Bandpass for reference sources; None indicates chi-squared detections.",
50 """Base class for forced photometry subtask that fetches reference sources.
54 schema : `lsst.afw.table.Schema`, optional
55 The schema of the reference catalog.
56 butler : `lsst.daf.persistence.butler.Butler`, optional
57 A butler that will allow the task to load its schema from disk.
61 At least one of the ``schema`` and ``butler`` arguments must be present;
62 if both are, ``schema`` takes precedence.
64 ``BaseReferencesTask`` defines the required API for the references task,
67 - ``getSchema(butler)``
68 - ``fetchInPatches(butler, tract, filter, patchList)``
69 - ``fetchInBox(self, butler, tract, filter, bbox, wcs)``
70 - the ``removePatchOverlaps`` config option
72 It also provides the ``subset`` method, which may be of use to derived
73 classes when reimplementing ``fetchInBox``.
76 ConfigClass = BaseReferencesConfig
77 """Configuration class associated with this task (`lsst.pex.config.Config`).
80 def __init__(self, butler=None, schema=None, **kwargs):
81 lsst.pipe.base.Task.__init__(self, **kwargs)
84 """Return the schema for the reference sources.
88 butler : `lsst.daf.persistence.butler.Butler`
89 Data butler from which the schema will be fetched.
93 Must be available even before any data has been processed.
95 raise NotImplementedError(
"BaseReferencesTask is pure abstract, and cannot be used directly.")
98 """Return the WCS for reference sources.
102 dataRef : `lsst.daf.persistence.ButlerDataRef`
103 The data reference from which the WCS will be fetched. This must
104 include the tract in its dataId.
106 raise NotImplementedError(
"BaseReferencesTask is pure abstract, and cannot be used directly.")
109 """Return reference sources within a given bounding box.
111 Reference sources are selected if they overlap a region defined by a
112 pixel-coordinate bounding box and corresponding WCS.
116 dataRef : `lsst.daf.persistence.ButlerDataRef`
117 Butler data reference. The implied data ID must contain the
119 bbox : `lsst.afw.geom.Box2I` or `lsst.afw.geom.Box2D`
120 Defines the selection region in pixel coordinates.
121 wcs : `lsst.afw.image.SkyWcs`
122 Maps ``bbox`` to sky coordinates.
126 sources : iterable of `~lsst.afw.table.SourceRecord`
127 Reference sources. May be any Python iterable, including a lazy
132 The returned set of sources should be complete and close to minimal.
134 raise NotImplementedError(
"BaseReferencesTask is pure abstract, and cannot be used directly.")
137 """Return reference sources within one or more patches.
141 dataRef : `lsst.daf.persistence.ButlerDataRef`
142 Butler data reference. The implied data ID must contain the
144 patchList : `list` of `lsst.skymap.PatchInfo`
145 Patches for which to fetch reference sources.
149 sources : iterable of `~lsst.afw.table.SourceRecord`
150 Reference sources. May be any Python iterable, including a lazy
155 The returned set of sources should be complete and close to minimal.
157 If ``config.removePatchOverlaps`` is `True`, only sources within each
158 patch's "inner" bounding box should be returned.
160 raise NotImplementedError(
"BaseReferencesTask is pure abstract, and cannot be used directly.")
163 """Filter a list of sources to only those within the bounding box.
167 sources : iterable of `~lsst.afw.table.SourceRecord`
168 Reference sources. May be any Python iterable, including a lazy
170 bbox : `lsst.afw.geom.Box2I` or `lsst.afw.geom.Box2D`
171 Defines the selection region.
172 wcs : `lsst.afw.image.SkyWcs`
173 Maps ``bbox`` to sky coordinates.
177 sources : iterable of `~lsst.afw.table.SourceRecord`
178 Filtered sources. May be any Python iterable, including a lazy
183 Instead of filtering sources directly via their positions, we filter
184 based on the positions of parent objects, then include or discard all
185 children based on their parent's status. This is necessary to support
186 replacement with noise in measurement, which requires all child
187 sources have their parent present.
189 This is not a part of the required `BaseReferencesTask` interface;
190 it's a convenience function used in implementing `fetchInBox` that may
191 be of use to subclasses.
197 catalog.extend(sources)
202 parentSources = catalog.getChildren(0)
203 skyCoordList = [source.getCoord()
for source
in parentSources]
204 pixelPosList = wcs.skyToPixel(skyCoordList)
205 parentList = [parent
for parent, pixel
in zip(parentSources, pixelPosList)
if boxD.contains(pixel)]
206 childrenIter = catalog.getChildren((parent.getId()
for parent
in parentList))
207 for parent, children
in zip(parentList, childrenIter):
213 """Default configuration for coadd reference source selection.
217 doc=
"Coadd name: typically one of deep or goodSeeing.",
222 doc=
"Silently skip patches where the reference catalog does not exist.",
228 if (self.
coaddNamecoaddName ==
"chiSquared") != (self.filter
is None):
230 field=CoaddSrcReferencesConfig.coaddName,
232 msg=
"filter may be None if and only if coaddName is chiSquared"
237 """Select reference sources by loading the “coadd source” dataset directly.
239 The name of the dataset to read is generated by appending the
240 `datasetSuffix` attribute to the string ``Coadd_``. The dataset is then
241 read directly from disk using the Butler.
245 schema : `lsst.afw.table.Schema`, optional
246 The schema of the detection catalogs used as input to this one.
247 butler : `lsst.daf.persistence.butler.Butler`, optional
248 A Butler used to read the input schema from disk. Required if
249 ``schema`` is `None`.
253 The task will set its own ``self.schema`` attribute to the schema of the
254 output merged catalog.
257 ConfigClass = CoaddSrcReferencesConfig
258 """Configuration class associated with this task (`lsst.pex.config.Config`).
261 datasetSuffix =
"src"
262 """Suffix to append to ``Coadd_`` to generate the dataset name (`str`).
265 def __init__(self, butler=None, schema=None, **kwargs):
266 BaseReferencesTask.__init__(self, butler=butler, schema=schema, **kwargs)
268 assert butler
is not None,
"No butler nor schema provided"
269 schema = butler.get(
"{}Coadd_{}_schema".
format(self.config.coaddName, self.
datasetSuffixdatasetSuffix),
274 """Return the WCS for reference sources.
278 dataRef : `lsst.daf.persistence.ButlerDataRef`
279 Butler data reference. Must includ the trac in its dataId.
281 skyMap = dataRef.get(self.config.coaddName +
"Coadd_skyMap", immediate=
True)
282 return skyMap[dataRef.dataId[
"tract"]].
getWcs()
285 """Fetch the source catalog using the Butler.
289 dataRef : `lsst.daf.persistence.ButlerDataRef`
290 Butler data reference. The implied data ID must contain the
292 patchList : `list` of `lsst.skymap.PatchInfo`
293 Patches for which to fetch reference sources.
297 sources : iterable of `~lsst.afw.table.SourceRecord`
298 Reference sources. May be any Python iterable, including a lazy
303 An implementation of `BaseReferencesTask.fetchInPatches` that loads
304 ``Coadd_`` + `datasetSuffix` catalogs using the butler.
307 tract = dataRef.dataId[
"tract"]
308 butler = dataRef.butlerSubset.butler
309 for patch
in patchList:
310 dataId = {
'tract': tract,
'patch':
"%d,%d" % patch.getIndex()}
311 if self.config.filter
is not None:
312 dataId[
'filter'] = self.config.filter
314 if not butler.datasetExists(dataset, dataId):
315 if self.config.skipMissing:
317 raise lsst.pipe.base.TaskError(
"Reference %s doesn't exist" % (dataId,))
318 self.log.
info(
"Getting references in %s", dataId)
319 catalog = butler.get(dataset, dataId, immediate=
True)
320 if self.config.removePatchOverlaps:
322 for source
in catalog:
323 if bbox.contains(source.getCentroid()):
326 for source
in catalog:
330 """Return reference sources within a given bounding box.
332 Reference sources are selected if they overlap a region defined by a
333 pixel-coordinate bounding box and corresponding WCS.
337 dataRef : `lsst.daf.persistence.ButlerDataRef`
338 Butler data reference. The implied data ID must contain the
340 bbox : `lsst.afw.geom.Box2I` or `lsst.afw.geom.Box2D`
341 Defines the selection region in pixel coordinates.
342 wcs : `lsst.afw.image.SkyWcs`
343 Maps ``bbox`` to sky coordinates.
345 a buffer to grow the bounding box by after catalogs have been loaded, but
346 before filtering them to include just the given bounding box.
350 sources : iterable of `~lsst.afw.table.SourceRecord`
351 Reference sources. May be any Python iterable, including a lazy
354 skyMap = dataRef.get(self.config.coaddName +
"Coadd_skyMap", immediate=
True)
355 tract = skyMap[dataRef.dataId[
"tract"]]
356 coordList = [wcs.pixelToSky(corner)
for corner
in lsst.geom.Box2D(bbox).getCorners()]
357 self.log.
info(
"Getting references in region with corners %s [degrees]",
358 ", ".join(
"(%s)" % (coord.getPosition(lsst.geom.degrees),)
for coord
in coordList))
359 patchList = tract.findPatchList(coordList)
368 """Default configuration for multi-band reference source selection.
372 if self.filter
is not None:
374 field=MultiBandReferencesConfig.filter,
376 msg=
"Filter should not be set for the multiband processing scheme")
378 BaseReferencesTask.ConfigClass.validate(self)
382 """Loads references from the multi-band processing scheme.
385 ConfigClass = MultiBandReferencesConfig
386 datasetSuffix =
"ref"
static Key< RecordId > getParentKey()
Key for the parent ID.
A floating-point coordinate rectangle geometry.
def subset(self, sources, bbox, wcs)
def __init__(self, butler=None, schema=None, **kwargs)
def getWcs(self, dataRef)
def fetchInPatches(self, dataRef, patchList)
def fetchInBox(self, dataRef, bbox, wcs)
def getSchema(self, butler)
def __init__(self, butler=None, schema=None, **kwargs)
def getWcs(self, dataRef)
def fetchInBox(self, dataRef, bbox, wcs, pad=0)
def fetchInPatches(self, dataRef, patchList)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)