66 """Fit a simple Affine transform with a shift to the matches and update
69 This method assumes that the distortion model of the telescope is
70 applied correctly and is accurate with only a slight rotation,
71 rotation, and "squish" required to fit to the reference locations.
75 matches : `list` of `lsst.afw.table.ReferenceMatch`
76 The following fields are read:
78 - match.first (reference object) coord
79 - match.second (source) centroid
81 The following fields are written:
83 - match.first (reference object) centroid,
84 - match.second (source) centroid
85 - match.distance (on sky separation, in radians)
87 initWcs : `lsst.afw.geom.SkyWcs`
89 bbox : `lsst.geom.Box2I`
90 Ignored; present for consistency with FitSipDistortionTask.
91 refCat : `lsst.afw.table.SimpleCatalog`
92 reference object catalog, or None.
93 If provided then all centroids are updated with the new WCS,
94 otherwise only the centroids for ref objects in matches are
95 updated. Required fields are "centroid_x", "centroid_y",
96 "coord_ra", and "coord_dec".
97 sourceCat : `lsst.afw.table.SourceCatalog`
98 source catalog, or None.
99 If provided then coords are updated with the new WCS;
100 otherwise only the coords for sources in matches are updated.
101 Required fields are "slot_Centroid_x", "slot_Centroid_y", and
102 "coord_ra", and "coord_dec".
103 exposure : `lsst.afw.image.Exposure`
104 Ignored; present for consistency with FitSipDistortionTask.
108 result : `lsst.pipe.base.Struct`
109 with the following fields:
111 - ``wcs`` : the fit WCS (`lsst.afw.geom.SkyWcs`)
112 - ``scatterOnSky`` : median on-sky separation between reference
113 objects and sources in "matches" (`lsst.afw.geom.Angle`)
121 back = wcsMaker.frameDict.getMapping(wcsMaker.frameMax, wcsMaker.frameMax-1)
122 forward = wcsMaker.lastMapBeforeSky
146 A = np.zeros((len(matches)*2, 6), dtype=float)
147 b = np.empty(len(matches)*2, dtype=float)
154 for i, match
in enumerate(matches):
155 refCoord = match.first.getCoord()
156 b[i*2:i*2+2] = back.applyForward(refCoord)
158 srcCentroid = match.second.getCentroid()
159 val = forward.applyForward(srcCentroid)
166 fit = lstsq(A, b, lapack_driver=
'gelsy')[0]
168 self.log.debug(
"Linear shift in x: %.3f, y: %.3f, "
169 "Affine matrix: [[%.6f, %.6f], [%.6f, %.6f]]...",
171 fit[0], fit[1], fit[2], fit[3])
174 wcs = wcsMaker.makeWcs(fit[4:], fit[:4].reshape((2, 2)))
177 if refCat
is not None:
178 self.log.debug(
"Updating centroids in refCat")
181 self.log.warning(
"Updating reference object centroids in match list; refCat is None")
184 refList=[match.first
for match
in matches])
186 if sourceCat
is not None:
187 self.log.debug(
"Updating coords in sourceCat")
190 self.log.warning(
"Updating source coords in match list; sourceCat is None")
193 sourceList=[match.second
for match
in matches])
194 setMatchDistance(matches)
196 stats = makeMatchStatisticsInRadians(wcs,
198 lsst.afw.math.MEDIAN)
199 scatterOnSky = stats.getValue() * radians
201 self.log.debug(
"In fitter scatter %.4f", scatterOnSky.asArcseconds())
203 return lsst.pipe.base.Struct(
205 scatterOnSky=scatterOnSky,