32 from lsst.geom
import convexHull
34 from .forcedPhotImage
import ForcedPhotImageTask, ForcedPhotImageConfig
37 from lsst.meas.mosaic
import applyMosaicResults
39 applyMosaicResults =
None 41 __all__ = (
"PerTractCcdDataIdContainer",
"ForcedPhotCcdConfig",
"ForcedPhotCcdTask")
45 """A version of lsst.pipe.base.DataIdContainer that combines raw data IDs with a tract. 47 Required because we need to add "tract" to the raw data ID keys (defined as whatever we 48 use for 'src') when no tract is provided (so that the user is not required to know 49 which tracts are spanned by the raw data ID). 51 This IdContainer assumes that a calexp is being measured using the detection information, 52 a set of reference catalogs, from the set of coadds which intersect with the calexp. 53 It needs the calexp id (e.g. visit, raft, sensor), but is also uses the tract to decide 54 what set of coadds to use. The references from the tract whose patches intersect with 59 """Make self.refList from self.idList 61 if self.datasetType
is None:
62 raise RuntimeError(
"Must call setDatasetType first")
63 log = Log.getLogger(
"meas.base.forcedPhotCcd.PerTractCcdDataIdContainer")
65 visitTract = collections.defaultdict(set)
66 visitRefs = collections.defaultdict(list)
67 for dataId
in self.idList:
68 if "tract" not in dataId:
70 log.info(
"Reading WCS for components of dataId=%s to determine tracts", dict(dataId))
72 skymap = namespace.butler.get(namespace.config.coaddName +
"Coadd_skyMap")
74 for ref
in namespace.butler.subset(
"calexp", dataId=dataId):
75 if not ref.datasetExists(
"calexp"):
78 visit = ref.dataId[
"visit"]
79 visitRefs[visit].append(ref)
81 md = ref.get(
"calexp_md", immediate=
True)
86 tract = skymap.findTract(wcs.pixelToSky(box.getCenter()))
88 visitTract[visit].add(tract.getId())
90 self.refList.extend(ref
for ref
in namespace.butler.subset(self.datasetType, dataId=dataId))
93 for visit, tractSet
in visitTract.items():
94 for ref
in visitRefs[visit]:
95 for tract
in tractSet:
96 self.refList.append(namespace.butler.dataRef(datasetType=self.datasetType,
97 dataId=ref.dataId, tract=tract))
99 tractCounter = collections.Counter()
100 for tractSet
in visitTract.values():
101 tractCounter.update(tractSet)
102 log.info(
"Number of visits for each tract: %s", dict(tractCounter))
106 """Return whether the image (specified by Wcs and bounding box) overlaps the tract 108 @param tract: TractInfo specifying a tract 109 @param imageWcs: Wcs for image 110 @param imageBox: Bounding box for image 113 tractWcs = tract.getWcs()
115 coord
in tract.getBBox().getCorners()]
116 tractPoly = convexHull(tractCorners)
120 except lsst.pex.exceptions.LsstCppException
as e:
122 if (
not isinstance(e.message, lsst.pex.exceptions.DomainErrorException)
and 123 not isinstance(e.message, lsst.pex.exceptions.RuntimeErrorException)):
127 imagePoly = convexHull([coord.getVector()
for coord
in imageCorners])
128 if imagePoly
is None:
130 return tractPoly.intersects(imagePoly)
134 doApplyUberCal = lsst.pex.config.Field(
136 doc=
"Apply meas_mosaic ubercal results to input calexps?",
149 """!A command-line driver for performing forced measurement on CCD images 151 This task is a subclass of ForcedPhotImageTask which is specifically for doing forced 152 measurement on a single CCD exposure, using as a reference catalog the detections which 153 were made on overlapping coadds. 155 The run method (inherited from ForcedPhotImageTask) takes a lsst.daf.persistence.ButlerDataRef 156 argument that corresponds to a single CCD. This should contain the data ID keys that correspond to 157 the "forced_src" dataset (the output dataset for ForcedPhotCcdTask), which are typically all those 158 used to specify the "calexp" dataset (e.g. visit, raft, sensor for LSST data) as well as a coadd 159 tract. The tract is used to look up the appropriate coadd measurement catalogs to use as references 160 (e.g. deepCoadd_src; see CoaddSrcReferencesTask for more information). While the tract must be given 161 as part of the dataRef, the patches are determined automatically from the bounding box and WCS of the 162 calexp to be measured, and the filter used to fetch references is set via config 163 (BaseReferencesConfig.filter). 165 In addition to the run method, ForcedPhotCcdTask overrides several methods of ForcedPhotImageTask 166 to specialize it for single-CCD processing, including makeIdFactory(), fetchReferences(), and 167 getExposure(). None of these should be called directly by the user, though it may be useful 168 to override them further in subclasses. 171 ConfigClass = ForcedPhotCcdConfig
172 RunnerClass = lsst.pipe.base.ButlerInitializedTaskRunner
173 _DefaultName =
"forcedPhotCcd" 177 """Create an object that generates globally unique source IDs from per-CCD IDs and the CCD ID. 179 @param dataRef Data reference from butler. The "ccdExposureId_bits" and "ccdExposureId" 180 datasets are accessed. The data ID must have the keys that correspond 181 to ccdExposureId, which is generally the same that correspond to "calexp" 182 (e.g. visit, raft, sensor for LSST data). 184 expBits = dataRef.get(
"ccdExposureId_bits")
185 expId = int(dataRef.get(
"ccdExposureId"))
189 return int(dataRef.get(
"ccdExposureId", immediate=
True))
192 """Return a SourceCatalog of sources which overlap the exposure. 194 The returned catalog is sorted by ID and guarantees that all included children have their 195 parent included and that all Footprints are valid. 197 @param dataRef Data reference from butler corresponding to the image to be measured; 198 should have tract, patch, and filter keys. 199 @param exposure lsst.afw.image.Exposure to be measured (used only to obtain a Wcs and 202 All work is delegated to the references subtask; see CoaddSrcReferencesTask for information 203 about the default behavior. 207 unfiltered = self.references.fetchInBox(dataRef, exposure.getBBox(), exposure.getWcs())
208 for record
in unfiltered:
209 if record.getFootprint()
is None or record.getFootprint().getArea() == 0:
210 if record.getParent() != 0:
211 self.log.warn(
"Skipping reference %s (child of %s) with bad Footprint",
212 record.getId(), record.getParent())
214 self.log.warn(
"Skipping reference parent %s with bad Footprint", record.getId())
215 badParents.add(record.getId())
216 elif record.getParent()
not in badParents:
217 references.append(record)
223 """Read input exposure to measure 225 @param dataRef Data reference from butler. Only the 'calexp' dataset is used, 226 unless config.doApplyUberCal is true, in which case the corresponding 227 meas_mosaic outputs are used as well. 229 exposure = ForcedPhotImageTask.getExposure(self, dataRef)
230 if not self.config.doApplyUberCal:
232 if applyMosaicResults
is None:
234 "Cannot use improved calibrations for %s because meas_mosaic could not be imported." 240 def _getConfigName(self):
241 """!Return the name of the config dataset. Forces config comparison from run-to-run 243 return self.
dataPrefix +
"forcedPhotCcd_config" 245 def _getMetadataName(self):
246 """!Return the name of the metadata dataset. Forced metadata to be saved 248 return self.
dataPrefix +
"forcedPhotCcd_metadata" 251 def _makeArgumentParser(cls):
252 parser = lsst.pipe.base.ArgumentParser(name=cls.
_DefaultName)
253 parser.add_id_argument(
"--id",
"forced_src", help=
"data ID with raw CCD keys [+ tract optionally], " 254 "e.g. --id visit=12345 ccd=1,2 [tract=0]",
255 ContainerClass=PerTractCcdDataIdContainer)
def getExposure(self, dataRef)
A base class for command-line forced measurement drivers.
def makeDataRefList(self, namespace)
A command-line driver for performing forced measurement on CCD images.
def makeIdFactory(self, dataRef)
static std::shared_ptr< IdFactory > makeSource(RecordId expId, int reserved)
geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
std::shared_ptr< SkyWcs > makeSkyWcs(Point2D const &crpix, SpherePoint const &crval, Eigen::Matrix2d const &cdMatrix, std::string const &projection="TAN")
def getExposureId(self, dataRef)
def overlapsTract(tract, imageWcs, imageBox)
static Key< RecordId > getParentKey()
def fetchReferences(self, dataRef, exposure)
Config class for forced measurement driver task.