86 def __init__(self, refObjLoader=None, **kwargs):
87 pipeBase.Task.__init__(self, **kwargs)
93 if self.config.sourceSelector.name ==
'matcher':
94 if self.config.sourceSelector[
'matcher'].sourceFluxType != self.config.sourceFluxType:
95 raise RuntimeError(
"The sourceFluxType in the sourceSelector['matcher'] must match "
96 "the configured sourceFluxType")
98 self.makeSubtask(
"matcher")
99 self.makeSubtask(
"sourceSelector")
100 self.makeSubtask(
"referenceSelector")
114 """Load reference objects overlapping an exposure and match to sources
115 detected on that exposure.
119 exposure : `lsst.afw.image.Exposure`
120 exposure that the sources overlap
121 sourceCat : `lsst.afw.table.SourceCatalog.`
122 catalog of sources detected on the exposure
126 result : `lsst.pipe.base.Struct`
127 Result struct with Components:
129 - ``refCat`` : reference object catalog of objects that overlap the
130 exposure (`lsst.afw.table.SimpleCatalog`)
131 - ``matches`` : Matched sources and references
132 (`list` of `lsst.afw.table.ReferenceMatch`)
133 - ``matchMeta`` : metadata needed to unpersist matches
134 (`lsst.daf.base.PropertyList`)
138 ignores config.matchDistanceSigma
141 raise RuntimeError(
"Running matcher task with no refObjLoader set in __ini__ or setRefObjLoader")
145 epoch = exposure.visitInfo.date.toAstropy()
147 sourceSelection = self.sourceSelector.run(sourceCat)
149 sourceFluxField =
"slot_%sFlux_instFlux" % (self.config.sourceFluxType)
152 bbox=exposure.getBBox(),
154 filterName=exposure.filter.bandLabel,
158 refSelection = self.referenceSelector.run(loadRes.refCat)
161 bbox=exposure.getBBox(),
163 filterName=exposure.filter.bandLabel,
167 matchRes = self.matcher.matchObjectsToSources(
168 refCat=refSelection.sourceCat,
169 sourceCat=sourceSelection.sourceCat,
171 sourceFluxField=sourceFluxField,
172 refFluxField=loadRes.fluxField,
178 "Found %d matches with scatter = %0.3f +- %0.3f arcsec; ",
179 len(matchRes.matches), distStats.distMean.asArcseconds(), distStats.distStdDev.asArcseconds()
183 frame = int(debug.frame)
185 refCat=refSelection.sourceCat,
186 sourceCat=sourceSelection.sourceCat,
187 matches=matchRes.matches,
189 bbox=exposure.getBBox(),
194 return pipeBase.Struct(
195 refCat=loadRes.refCat,
196 refSelection=refSelection,
197 sourceSelection=sourceSelection,
198 matches=matchRes.matches,
203 """Compute on-sky radial distance statistics for a match list
207 matchList : `list` of `lsst.afw.table.ReferenceMatch`
208 list of matches between reference object and sources;
209 the distance field is the only field read and it must be set to distance in radians
213 result : `lsst.pipe.base.Struct`
214 Result struct with components:
216 - ``distMean`` : clipped mean of on-sky radial separation (`float`)
217 - ``distStdDev`` : clipped standard deviation of on-sky radial
219 - ``maxMatchDist`` : distMean + self.config.matchDistanceSigma *
222 distStatsInRadians = makeMatchStatistics(matchList, afwMath.MEANCLIP | afwMath.STDEVCLIP)
223 distMean = distStatsInRadians.getValue(afwMath.MEANCLIP)*lsst.geom.radians
224 distStdDev = distStatsInRadians.getValue(afwMath.STDEVCLIP)*lsst.geom.radians
225 return pipeBase.Struct(
227 distStdDev=distStdDev,
228 maxMatchDist=distMean + self.config.matchDistanceSigma * distStdDev,