116 def fitWcs(self, matches, initWcs, bbox=None, refCat=None, sourceCat=None, exposure=None):
117 """Fit a TAN-SIP WCS from a list of reference object/source matches.
121 matches : `list` of `lsst.afw.table.ReferenceMatch`
122 A sequence of reference object/source matches.
123 The following fields are read:
124 - match.first (reference object) coord
125 - match.second (source) centroid
127 The following fields are written:
128 - match.first (reference object) centroid
129 - match.second (source) centroid
130 - match.distance (on sky separation, in radians)
132 initWcs : `lsst.afw.geom.SkyWcs`
133 An initial WCS whose CD matrix is used as the final CD matrix.
134 bbox : `lsst.geom.Box2I`
135 The region over which the WCS will be valid (PARENT pixel coordinates);
136 if `None` or an empty box then computed from matches
137 refCat : `lsst.afw.table.SimpleCatalog`
138 Reference object catalog, or `None`.
139 If provided then all centroids are updated with the new WCS,
140 otherwise only the centroids for ref objects in matches are updated.
141 Required fields are "centroid_x", "centroid_y", "coord_ra", and "coord_dec".
142 sourceCat : `lsst.afw.table.SourceCatalog`
143 Source catalog, or `None`.
144 If provided then coords are updated with the new WCS;
145 otherwise only the coords for sources in matches are updated.
146 Required input fields are "slot_Centroid_x", "slot_Centroid_y",
147 "slot_Centroid_xErr", "slot_Centroid_yErr", and optionally
148 "slot_Centroid_x_y_Cov". The "coord_ra" and "coord_dec" fields
149 will be updated but are not used as input.
150 exposure : `lsst.afw.image.Exposure`
151 An Exposure or other displayable image on which matches can be
152 overplotted. Ignored (and may be `None`) if display-based debugging
153 is not enabled via lsstDebug.
157 An lsst.pipe.base.Struct with the following fields:
158 - wcs : `lsst.afw.geom.SkyWcs`
160 - scatterOnSky : `lsst.geom.Angle`
161 The median on-sky separation between reference objects and
162 sources in "matches", as an `lsst.geom.Angle`
171 for match
in matches:
172 bbox.include(match.second.getCentroid())
175 wcs = self.makeInitialWcs(matches, initWcs)
184 revFitter = ScaledPolynomialTransformFitter.fromMatches(self.config.order, matches, wcs,
185 self.config.refUncertainty)
187 for nIter
in range(self.config.numRejIter):
188 revFitter.updateModel()
189 intrinsicScatter = revFitter.updateIntrinsicScatter()
190 clippedSigma, nRejected = revFitter.rejectOutliers(self.outlierRejectionCtrl)
192 "Iteration %s: intrinsic scatter is %4.3f pixels, "
193 "rejected %d outliers at %3.2f sigma.",
194 nIter+1, intrinsicScatter, nRejected, clippedSigma
197 displayFrame = self.display(revFitter, exposure=exposure, bbox=bbox,
198 frame=displayFrame, displayPause=displayPause)
200 revScaledPoly = revFitter.getTransform()
204 sipReverse = SipReverseTransform.convert(revScaledPoly, wcs.getPixelOrigin(), cdMatrix)
212 gridBBoxPix.grow(self.config.gridBorder)
218 for point
in gridBBoxPix.getCorners():
220 gridBBoxIwc.include(cdMatrix(point))
221 fwdFitter = ScaledPolynomialTransformFitter.fromGrid(self.config.order, gridBBoxIwc,
222 self.config.nGridX, self.config.nGridY,
226 fwdScaledPoly = fwdFitter.getTransform()
227 sipForward = SipForwardTransform.convert(fwdScaledPoly, wcs.getPixelOrigin(), cdMatrix)
231 wcs =
makeWcs(sipForward, sipReverse, wcs.getSkyOrigin())
233 if refCat
is not None:
234 self.log.
debug(
"Updating centroids in refCat")
237 self.log.
warning(
"Updating reference object centroids in match list; refCat is None")
240 if sourceCat
is not None:
241 self.log.
debug(
"Updating coords in sourceCat")
244 self.log.
warning(
"Updating source coords in match list; sourceCat is None")
247 self.log.
debug(
"Updating distance in match list")
251 scatterOnSky = stats.getValue()*lsst.geom.radians
253 if scatterOnSky.asArcseconds() > self.config.maxScatterArcsec:
254 raise lsst.pipe.base.TaskError(
255 "Fit failed: median scatter on sky = %0.3f arcsec > %0.3f config.maxScatterArcsec" %
256 (scatterOnSky.asArcseconds(), self.config.maxScatterArcsec))
258 return lsst.pipe.base.Struct(
260 scatterOnSky=scatterOnSky,
A floating-point coordinate rectangle geometry.
An integer coordinate rectangle.
void updateRefCentroids(geom::SkyWcs const &wcs, ReferenceCollection &refList)
Update centroids in a collection of reference objects.
void updateSourceCoords(geom::SkyWcs const &wcs, SourceCollection &sourceList)
Update sky coordinates in a collection of source objects.
def setMatchDistance(matches)
afw::math::Statistics makeMatchStatisticsInRadians(afw::geom::SkyWcs const &wcs, std::vector< MatchT > const &matchList, int const flags, afw::math::StatisticsControl const &sctrl=afw::math::StatisticsControl())
Compute statistics of on-sky radial separation for a match list, in radians.
std::shared_ptr< afw::geom::SkyWcs > makeWcs(SipForwardTransform const &sipForward, SipReverseTransform const &sipReverse, geom::SpherePoint const &skyOrigin)
Create a new TAN SIP Wcs from a pair of SIP transforms and the sky origin.