115 def fitWcs(self, matches, initWcs, bbox=None, refCat=None, sourceCat=None, exposure=None):
116 """Fit a TAN-SIP WCS from a list of reference object/source matches.
120 matches : `list` of `lsst.afw.table.ReferenceMatch`
121 A sequence of reference object/source matches.
122 The following fields are read:
123 - match.first (reference object) coord
124 - match.second (source) centroid
126 The following fields are written:
127 - match.first (reference object) centroid
128 - match.second (source) centroid
129 - match.distance (on sky separation, in radians)
131 initWcs : `lsst.afw.geom.SkyWcs`
132 An initial WCS whose CD matrix is used as the final CD matrix.
133 bbox : `lsst.geom.Box2I`
134 The region over which the WCS will be valid (PARENT pixel coordinates);
135 if `None` or an empty box then computed from matches
136 refCat : `lsst.afw.table.SimpleCatalog`
137 Reference object catalog, or `None`.
138 If provided then all centroids are updated with the new WCS,
139 otherwise only the centroids for ref objects in matches are updated.
140 Required fields are "centroid_x", "centroid_y", "coord_ra", and "coord_dec".
141 sourceCat : `lsst.afw.table.SourceCatalog`
142 Source catalog, or `None`.
143 If provided then coords are updated with the new WCS;
144 otherwise only the coords for sources in matches are updated.
145 Required input fields are "slot_Centroid_x", "slot_Centroid_y",
146 "slot_Centroid_xErr", "slot_Centroid_yErr", and optionally
147 "slot_Centroid_x_y_Cov". The "coord_ra" and "coord_dec" fields
148 will be updated but are not used as input.
149 exposure : `lsst.afw.image.Exposure`
150 An Exposure or other displayable image on which matches can be
151 overplotted. Ignored (and may be `None`) if display-based debugging
152 is not enabled via lsstDebug.
156 An lsst.pipe.base.Struct with the following fields:
157 - wcs : `lsst.afw.geom.SkyWcs`
159 - scatterOnSky : `lsst.geom.Angle`
160 The median on-sky separation between reference objects and
161 sources in "matches", as an `lsst.geom.Angle`
170 for match
in matches:
171 bbox.include(match.second.getCentroid())
174 wcs = self.makeInitialWcs(matches, initWcs)
183 revFitter = ScaledPolynomialTransformFitter.fromMatches(self.config.order, matches, wcs,
184 self.config.refUncertainty)
186 for nIter
in range(self.config.numRejIter):
187 revFitter.updateModel()
188 intrinsicScatter = revFitter.updateIntrinsicScatter()
189 clippedSigma, nRejected = revFitter.rejectOutliers(self.outlierRejectionCtrl)
191 "Iteration {0}: intrinsic scatter is {1:4.3f} pixels, "
192 "rejected {2} outliers at {3:3.2f} sigma.".
format(
193 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.
warn(
"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.
warn(
"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.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)