33 from .forcedPhotImage
import ForcedPhotImageTask, ForcedPhotImageConfig
36 from lsst.meas.mosaic
import applyMosaicResults
38 applyMosaicResults =
None
40 __all__ = (
"PerTractCcdDataIdContainer",
"ForcedPhotCcdConfig",
"ForcedPhotCcdTask")
44 """A version of lsst.pipe.base.DataIdContainer that combines raw data IDs with a tract.
46 Required because we need to add "tract" to the raw data ID keys (defined as whatever we
47 use for 'src') when no tract is provided (so that the user is not required to know
48 which tracts are spanned by the raw data ID).
50 This IdContainer assumes that a calexp is being measured using the detection information,
51 a set of reference catalogs, from the set of coadds which intersect with the calexp.
52 It needs the calexp id (e.g. visit, raft, sensor), but is also uses the tract to decide
53 what set of coadds to use. The references from the tract whose patches intersect with
58 """Construct a dataRef based on dataId, but with an added tract key"""
59 forcedDataId = dataId.copy()
60 forcedDataId[
'tract'] = tract
61 dataRef = namespace.butler.dataRef(datasetType=self.datasetType, dataId=forcedDataId)
62 self.refList.append(dataRef)
65 """Make self.refList from self.idList
67 if self.datasetType
is None:
68 raise RuntimeError(
"Must call setDatasetType first")
69 log = Log.getLogger(
"meas.base.forcedPhotCcd.PerTractCcdDataIdContainer")
71 visitTract = collections.defaultdict(set)
72 visitRefs = collections.defaultdict(list)
73 for dataId
in self.idList:
74 if "tract" not in dataId:
76 log.info(
"Reading WCS for components of dataId=%s to determine tracts", dict(dataId))
78 skymap = namespace.butler.get(namespace.config.coaddName +
"Coadd_skyMap")
80 for ref
in namespace.butler.subset(
"calexp", dataId=dataId):
81 if not ref.datasetExists(
"calexp"):
84 visit = ref.dataId[
"visit"]
85 visitRefs[visit].append(ref)
87 md = ref.get(
"calexp_md", immediate=
True)
93 tract = skymap.findTract(wcs.pixelToSky(box.getCenter()))
95 visitTract[visit].add(tract.getId())
97 tract = dataId.pop(
"tract")
99 for ref
in namespace.butler.subset(
"src", dataId=dataId):
103 for visit, tractSet
in visitTract.items():
104 for ref
in visitRefs[visit]:
105 for tract
in tractSet:
108 tractCounter = collections.Counter()
109 for tractSet
in visitTract.values():
110 tractCounter.update(tractSet)
111 log.info(
"Number of visits for each tract: %s", dict(tractCounter))
115 """Return whether the image (specified by Wcs and bounding box) overlaps the tract
117 @param tract: TractInfo specifying a tract
118 @param imageWcs: Wcs for image
119 @param imageBox: Bounding box for image
122 tractWcs = tract.getWcs()
124 coord
in tract.getBBox().getCorners()]
129 except lsst.pex.exceptions.LsstCppException
as e:
131 if (
not isinstance(e.message, lsst.pex.exceptions.DomainErrorException)
and
132 not isinstance(e.message, lsst.pex.exceptions.RuntimeErrorException)):
136 imagePoly =
convexHull([coord.getVector()
for coord
in imageCorners])
137 if imagePoly
is None:
139 return tractPoly.intersects(imagePoly)
143 doApplyUberCal = lsst.pex.config.Field(
145 doc=
"Apply meas_mosaic ubercal results to input calexps?",
158 """!A command-line driver for performing forced measurement on CCD images
160 This task is a subclass of ForcedPhotImageTask which is specifically for doing forced
161 measurement on a single CCD exposure, using as a reference catalog the detections which
162 were made on overlapping coadds.
164 The run method (inherited from ForcedPhotImageTask) takes a lsst.daf.persistence.ButlerDataRef
165 argument that corresponds to a single CCD. This should contain the data ID keys that correspond to
166 the "forced_src" dataset (the output dataset for ForcedPhotCcdTask), which are typically all those
167 used to specify the "calexp" dataset (e.g. visit, raft, sensor for LSST data) as well as a coadd
168 tract. The tract is used to look up the appropriate coadd measurement catalogs to use as references
169 (e.g. deepCoadd_src; see CoaddSrcReferencesTask for more information). While the tract must be given
170 as part of the dataRef, the patches are determined automatically from the bounding box and WCS of the
171 calexp to be measured, and the filter used to fetch references is set via config
172 (BaseReferencesConfig.filter).
174 In addition to the run method, ForcedPhotCcdTask overrides several methods of ForcedPhotImageTask
175 to specialize it for single-CCD processing, including makeIdFactory(), fetchReferences(), and
176 getExposure(). None of these should be called directly by the user, though it may be useful
177 to override them further in subclasses.
180 ConfigClass = ForcedPhotCcdConfig
181 RunnerClass = lsst.pipe.base.ButlerInitializedTaskRunner
182 _DefaultName =
"forcedPhotCcd"
186 """Create an object that generates globally unique source IDs from per-CCD IDs and the CCD ID.
188 @param dataRef Data reference from butler. The "ccdExposureId_bits" and "ccdExposureId"
189 datasets are accessed. The data ID must have the keys that correspond
190 to ccdExposureId, which is generally the same that correspond to "calexp"
191 (e.g. visit, raft, sensor for LSST data).
193 expBits = dataRef.get(
"ccdExposureId_bits")
194 expId = int(dataRef.get(
"ccdExposureId"))
198 return int(dataRef.get(
"ccdExposureId", immediate=
True))
201 """Return a SourceCatalog of sources which overlap the exposure.
203 The returned catalog is sorted by ID and guarantees that all included children have their
204 parent included and that all Footprints are valid.
206 @param dataRef Data reference from butler corresponding to the image to be measured;
207 should have tract, patch, and filter keys.
208 @param exposure lsst.afw.image.Exposure to be measured (used only to obtain a Wcs and
211 All work is delegated to the references subtask; see CoaddSrcReferencesTask for information
212 about the default behavior.
216 unfiltered = self.references.fetchInBox(dataRef, exposure.getBBox(), exposure.getWcs())
217 for record
in unfiltered:
218 if record.getFootprint()
is None or record.getFootprint().getArea() == 0:
219 if record.getParent() != 0:
220 self.log.warn(
"Skipping reference %s (child of %s) with bad Footprint",
221 record.getId(), record.getParent())
223 self.log.warn(
"Skipping reference parent %s with bad Footprint", record.getId())
224 badParents.add(record.getId())
225 elif record.getParent()
not in badParents:
226 references.append(record)
232 """Read input exposure to measure
234 @param dataRef Data reference from butler. Only the 'calexp' dataset is used,
235 unless config.doApplyUberCal is true, in which case the corresponding
236 meas_mosaic outputs are used as well.
238 exposure = ForcedPhotImageTask.getExposure(self, dataRef)
239 if not self.config.doApplyUberCal:
241 if applyMosaicResults
is None:
243 "Cannot use improved calibrations for %s because meas_mosaic could not be imported."
250 """!Return the name of the config dataset. Forces config comparison from run-to-run
252 return self.
dataPrefix +
"forcedPhotCcd_config"
255 """!Return the name of the metadata dataset. Forced metadata to be saved
257 return self.
dataPrefix +
"forcedPhotCcd_metadata"
261 parser = lsst.pipe.base.ArgumentParser(name=cls._DefaultName)
262 parser.add_id_argument(
"--id",
"forced_src", help=
"data ID with raw CCD keys [+ tract optionally], "
263 "e.g. --id visit=12345 ccd=1,2 [tract=0]",
264 ContainerClass=PerTractCcdDataIdContainer)
static boost::shared_ptr< IdFactory > makeSource(RecordId expId, int reserved)
Return an IdFactory that includes another, fixed ID in the higher-order bits.
A command-line driver for performing forced measurement on CCD images.
def _getConfigName
Return the name of the config dataset.
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
boost::shared_ptr< Wcs > makeWcs(coord::Coord const &crval, geom::Point2D const &crpix, double CD11, double CD12, double CD21, double CD22)
Create a Wcs object from crval, crpix, CD, using CD elements (useful from python) ...
def _getMetadataName
Return the name of the metadata dataset.
static Key< RecordId > getParentKey()
Key for the parent ID.
A floating-point coordinate rectangle geometry.