22 from __future__
import absolute_import, division, print_function
24 __all__ = [
'RefMatchConfig',
'RefMatchTask']
30 import lsst.pipe.base
as pipeBase
31 from lsst.meas.algorithms
import ScienceSourceSelectorTask, ReferenceSourceSelectorTask
32 from .matchOptimisticB
import MatchOptimisticBTask
33 from .display
import displayAstrometry
34 from .
import makeMatchStatistics
38 matcher = pexConfig.ConfigurableField(
39 target=MatchOptimisticBTask,
40 doc=
"reference object/source matcher",
42 matchDistanceSigma = pexConfig.RangeField(
43 doc=
"the maximum match distance is set to " 44 " mean_match_distance + matchDistanceSigma*std_dev_match_distance; " +
45 "ignored if not fitting a WCS",
50 sourceSelection = pexConfig.ConfigurableField(target=ScienceSourceSelectorTask,
51 doc=
"Selection of science sources")
52 referenceSelection = pexConfig.ConfigurableField(target=ReferenceSourceSelectorTask,
53 doc=
"Selection of reference sources")
65 """!Match an input source catalog with objects from a reference catalog 69 ConfigClass = RefMatchConfig
70 _DefaultName =
"calibrationBaseClass" 72 def __init__(self, refObjLoader, schema=None, **kwargs):
73 """!Construct a RefMatchTask 75 @param[in] refObjLoader A reference object loader object 76 @param[in] schema ignored; available for compatibility with an older astrometry task 77 @param[in] kwargs additional keyword arguments for pipe_base Task.\_\_init\_\_ 79 pipeBase.Task.__init__(self, **kwargs)
81 self.makeSubtask(
"matcher")
82 self.makeSubtask(
"sourceSelection")
83 self.makeSubtask(
"referenceSelection")
87 """!Load reference objects overlapping an exposure and match to sources detected on that exposure 89 @param[in] exposure exposure that the sources overlap 90 @param[in] sourceCat catalog of sources detected on the exposure (an lsst.afw.table.SourceCatalog) 92 @return an lsst.pipe.base.Struct with these fields: 93 - refCat reference object catalog of objects that overlap the exposure (with some margin) 94 (an lsst::afw::table::SimpleCatalog) 95 - matches a list of lsst.afw.table.ReferenceMatch 96 - matchMeta metadata needed to unpersist matches (an lsst.daf.base.PropertyList) 98 @note ignores config.matchDistanceSigma 105 sourceSelection = self.sourceSelection.selectSources(sourceCat)
110 filterName=expMd.filterName,
114 refSelection = self.referenceSelection.selectSources(loadRes.refCat)
119 filterName=expMd.filterName,
123 matchRes = self.matcher.matchObjectsToSources(
124 refCat=refSelection.sourceCat,
125 sourceCat=sourceSelection.sourceCat,
127 refFluxField=loadRes.fluxField,
128 match_tolerance=
None,
133 "Found %d matches with scatter = %0.3f +- %0.3f arcsec; " %
134 (len(matchRes.matches), distStats.distMean.asArcseconds(), distStats.distStdDev.asArcseconds())
138 frame = int(debug.frame)
140 refCat=refSelection.sourceCat,
141 sourceCat=sourceSelection.sourceCat,
142 matches=matchRes.matches,
149 return pipeBase.Struct(
150 refCat=loadRes.refCat,
151 refSelection=refSelection,
152 sourceSelection=sourceSelection,
153 matches=matchRes.matches,
157 def _computeMatchStatsOnSky(self, matchList):
158 """Compute on-sky radial distance statistics for a match list 160 @param[in] matchList list of matches between reference object and sources; 161 the distance field is the only field read and it must be set to distance in radians 163 @return a pipe_base Struct containing these fields: 164 - distMean clipped mean of on-sky radial separation 165 - distStdDev clipped standard deviation of on-sky radial separation 166 - maxMatchDist distMean + self.config.matchDistanceSigma*distStdDev 169 distMean = distStatsInRadians.getValue(afwMath.MEANCLIP)*afwGeom.radians
170 distStdDev = distStatsInRadians.getValue(afwMath.STDEVCLIP)*afwGeom.radians
171 return pipeBase.Struct(
173 distStdDev=distStdDev,
174 maxMatchDist=distMean + self.config.matchDistanceSigma*distStdDev,
177 def _getExposureMetadata(self, exposure):
178 """!Extract metadata from an exposure 180 @return an lsst.pipe.base.Struct containing the following exposure metadata: 181 - bbox: parent bounding box 182 - wcs: WCS (an lsst.afw.image.Wcs) 183 - calib calibration (an lsst.afw.image.Calib), or None if unknown 184 - filterName: name of filter, or None if unknown 186 exposureInfo = exposure.getInfo()
187 filterName = exposureInfo.getFilter().getName()
or None 188 if filterName ==
"_unknown_":
190 return pipeBase.Struct(
191 bbox=exposure.getBBox(),
192 wcs=getDistortedWcs(exposureInfo, log=self.log),
193 calib=exposureInfo.getCalib()
if exposureInfo.hasCalib()
else None,
194 filterName=filterName,
def _computeMatchStatsOnSky(self, matchList)
def __init__(self, refObjLoader, schema=None, kwargs)
Construct a RefMatchTask.
def _getExposureMetadata(self, exposure)
Extract metadata from an exposure.
Match an input source catalog with objects from a reference catalog.
def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None, matches=None, frame=1, title="", pause=True)
def loadAndMatch(self, exposure, sourceCat)
Load reference objects overlapping an exposure and match to sources detected on that exposure...