35 from .forcedPhotImage
import ForcedPhotImageTask, ForcedPhotImageConfig
38 from lsst.meas.mosaic
import applyMosaicResults
40 applyMosaicResults =
None 42 __all__ = (
"PerTractCcdDataIdContainer",
"ForcedPhotCcdConfig",
"ForcedPhotCcdTask",
"imageOverlapsTract")
46 """A version of lsst.pipe.base.DataIdContainer that combines raw data IDs with a tract. 48 Required because we need to add "tract" to the raw data ID keys (defined as whatever we 49 use for 'src') when no tract is provided (so that the user is not required to know 50 which tracts are spanned by the raw data ID). 52 This IdContainer assumes that a calexp is being measured using the detection information, 53 a set of reference catalogs, from the set of coadds which intersect with the calexp. 54 It needs the calexp id (e.g. visit, raft, sensor), but is also uses the tract to decide 55 what set of coadds to use. The references from the tract whose patches intersect with 60 """Make self.refList from self.idList 62 if self.datasetType
is None:
63 raise RuntimeError(
"Must call setDatasetType first")
64 log = Log.getLogger(
"meas.base.forcedPhotCcd.PerTractCcdDataIdContainer")
66 visitTract = collections.defaultdict(set)
67 visitRefs = collections.defaultdict(list)
68 for dataId
in self.idList:
69 if "tract" not in dataId:
71 log.info(
"Reading WCS for components of dataId=%s to determine tracts", dict(dataId))
73 skymap = namespace.butler.get(namespace.config.coaddName +
"Coadd_skyMap")
75 for ref
in namespace.butler.subset(
"calexp", dataId=dataId):
76 if not ref.datasetExists(
"calexp"):
79 visit = ref.dataId[
"visit"]
80 visitRefs[visit].append(ref)
82 md = ref.get(
"calexp_md", immediate=
True)
87 tract = skymap.findTract(wcs.pixelToSky(box.getCenter()))
89 visitTract[visit].add(tract.getId())
91 self.refList.extend(ref
for ref
in namespace.butler.subset(self.datasetType, dataId=dataId))
94 for visit, tractSet
in visitTract.items():
95 for ref
in visitRefs[visit]:
96 for tract
in tractSet:
97 self.refList.append(namespace.butler.dataRef(datasetType=self.datasetType,
98 dataId=ref.dataId, tract=tract))
100 tractCounter = collections.Counter()
101 for tractSet
in visitTract.values():
102 tractCounter.update(tractSet)
103 log.info(
"Number of visits for each tract: %s", dict(tractCounter))
107 """Return whether the image (specified by Wcs and bounding box) overlaps the tract 109 @param tract: TractInfo specifying a tract 110 @param imageWcs: Wcs for image 111 @param imageBox: Bounding box for image 114 tractPoly = tract.getOuterSkyPolygon()
118 imageSkyCorners = imageWcs.pixelToSky(imagePixelCorners)
119 except lsst.pex.exceptions.LsstCppException
as e:
121 if (
not isinstance(e.message, lsst.pex.exceptions.DomainErrorException)
and 122 not isinstance(e.message, lsst.pex.exceptions.RuntimeErrorException)):
127 return tractPoly.intersects(imagePoly)
131 doApplyUberCal = lsst.pex.config.Field(
133 doc=
"Apply meas_mosaic ubercal results to input calexps?",
146 """!A command-line driver for performing forced measurement on CCD images 148 This task is a subclass of ForcedPhotImageTask which is specifically for doing forced 149 measurement on a single CCD exposure, using as a reference catalog the detections which 150 were made on overlapping coadds. 152 The run method (inherited from ForcedPhotImageTask) takes a lsst.daf.persistence.ButlerDataRef 153 argument that corresponds to a single CCD. This should contain the data ID keys that correspond to 154 the "forced_src" dataset (the output dataset for ForcedPhotCcdTask), which are typically all those 155 used to specify the "calexp" dataset (e.g. visit, raft, sensor for LSST data) as well as a coadd 156 tract. The tract is used to look up the appropriate coadd measurement catalogs to use as references 157 (e.g. deepCoadd_src; see CoaddSrcReferencesTask for more information). While the tract must be given 158 as part of the dataRef, the patches are determined automatically from the bounding box and WCS of the 159 calexp to be measured, and the filter used to fetch references is set via config 160 (BaseReferencesConfig.filter). 162 In addition to the run method, ForcedPhotCcdTask overrides several methods of ForcedPhotImageTask 163 to specialize it for single-CCD processing, including makeIdFactory(), fetchReferences(), and 164 getExposure(). None of these should be called directly by the user, though it may be useful 165 to override them further in subclasses. 168 ConfigClass = ForcedPhotCcdConfig
169 RunnerClass = lsst.pipe.base.ButlerInitializedTaskRunner
170 _DefaultName =
"forcedPhotCcd" 174 """Create an object that generates globally unique source IDs from per-CCD IDs and the CCD ID. 176 @param dataRef Data reference from butler. The "ccdExposureId_bits" and "ccdExposureId" 177 datasets are accessed. The data ID must have the keys that correspond 178 to ccdExposureId, which is generally the same that correspond to "calexp" 179 (e.g. visit, raft, sensor for LSST data). 181 expBits = dataRef.get(
"ccdExposureId_bits")
182 expId = int(dataRef.get(
"ccdExposureId"))
186 return int(dataRef.get(
"ccdExposureId", immediate=
True))
189 """Return a SourceCatalog of sources which overlap the exposure. 191 The returned catalog is sorted by ID and guarantees that all included children have their 192 parent included and that all Footprints are valid. 194 @param dataRef Data reference from butler corresponding to the image to be measured; 195 should have tract, patch, and filter keys. 196 @param exposure lsst.afw.image.Exposure to be measured (used only to obtain a Wcs and 199 All work is delegated to the references subtask; see CoaddSrcReferencesTask for information 200 about the default behavior. 204 unfiltered = self.references.fetchInBox(dataRef, exposure.getBBox(), exposure.getWcs())
205 for record
in unfiltered:
206 if record.getFootprint()
is None or record.getFootprint().getArea() == 0:
207 if record.getParent() != 0:
208 self.log.warn(
"Skipping reference %s (child of %s) with bad Footprint",
209 record.getId(), record.getParent())
211 self.log.warn(
"Skipping reference parent %s with bad Footprint", record.getId())
212 badParents.add(record.getId())
213 elif record.getParent()
not in badParents:
214 references.append(record)
220 """Read input exposure to measure 222 @param dataRef Data reference from butler. Only the 'calexp' dataset is used, 223 unless config.doApplyUberCal is true, in which case the corresponding 224 meas_mosaic outputs are used as well. 226 exposure = ForcedPhotImageTask.getExposure(self, dataRef)
227 if not self.config.doApplyUberCal:
229 if applyMosaicResults
is None:
231 "Cannot use improved calibrations for %s because meas_mosaic could not be imported." 237 def _getConfigName(self):
238 """!Return the name of the config dataset. Forces config comparison from run-to-run 240 return self.
dataPrefix +
"forcedPhotCcd_config" 242 def _getMetadataName(self):
243 """!Return the name of the metadata dataset. Forced metadata to be saved 245 return self.
dataPrefix +
"forcedPhotCcd_metadata" 248 def _makeArgumentParser(cls):
249 parser = lsst.pipe.base.ArgumentParser(name=cls.
_DefaultName)
250 parser.add_id_argument(
"--id",
"forced_src", help=
"data ID with raw CCD keys [+ tract optionally], " 251 "e.g. --id visit=12345 ccd=1,2 [tract=0]",
252 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)
static ConvexPolygon convexHull(std::vector< UnitVector3d > const &points)
def imageOverlapsTract(tract, imageWcs, imageBox)
def getExposureId(self, dataRef)
std::shared_ptr< SkyWcs > makeSkyWcs(TransformPoint2ToPoint2 const &pixelsToFieldAngle, lsst::geom::Angle const &orientation, bool flipX, lsst::geom::SpherePoint const &boresight, std::string const &projection="TAN")
static Key< RecordId > getParentKey()
def fetchReferences(self, dataRef, exposure)
lsst::geom::Box2I bboxFromMetadata(daf::base::PropertySet &metadata)
Config class for forced measurement driver task.