LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Member Functions | Static Public Attributes | List of all members
lsst.meas.astrom.fitAffineWcs.FitAffineWcsTask Class Reference
Inheritance diagram for lsst.meas.astrom.fitAffineWcs.FitAffineWcsTask:

Public Member Functions

def fitWcs (self, matches, initWcs, bbox=None, refCat=None, sourceCat=None, exposure=None)
 

Static Public Attributes

 ConfigClass = FitAffineWcsConfig
 

Detailed Description

Fit a TAN-SIP WCS given a list of reference object/source matches.

This WCS fitter should be used on top of a cameraGeom distortion model as
the model assumes that only a shift the WCS center position and a small
affine transform are required.

Definition at line 95 of file fitAffineWcs.py.

Member Function Documentation

◆ fitWcs()

def lsst.meas.astrom.fitAffineWcs.FitAffineWcsTask.fitWcs (   self,
  matches,
  initWcs,
  bbox = None,
  refCat = None,
  sourceCat = None,
  exposure = None 
)
Fit a simple Affine transform with a shift to the matches and update
the WCS.

This method assumes that the distortion model of the telescope is
applied correctly and is accurate with only a slight rotation,
rotation, and "squish" required to fit to the reference locations.

Parameters
----------
matches : `list` of `lsst.afw.table.ReferenceMatch`
    The following fields are read:

    - match.first (reference object) coord
    - match.second (source) centroid

    The following fields are written:

    - match.first (reference object) centroid,
    - match.second (source) centroid
    - match.distance (on sky separation, in radians)

initWcs : `lsst.afw.geom.SkyWcs`
    initial WCS
bbox : `lsst.geom.Box2I`
    Ignored; present for consistency with FitSipDistortionTask.
refCat : `lsst.afw.table.SimpleCatalog`
    reference object catalog, or None.
    If provided then all centroids are updated with the new WCS,
    otherwise only the centroids for ref objects in matches are
    updated. Required fields are "centroid_x", "centroid_y",
    "coord_ra", and "coord_dec".
sourceCat : `lsst.afw.table.SourceCatalog`
    source catalog, or None.
    If provided then coords are updated with the new WCS;
    otherwise only the coords for sources in matches are updated.
    Required fields are "slot_Centroid_x", "slot_Centroid_y", and
    "coord_ra", and "coord_dec".
exposure : `lsst.afw.image.Exposure`
    Ignored; present for consistency with FitSipDistortionTask.

Returns
-------
result : `lsst.pipe.base.Struct`
    with the following fields:

    - ``wcs`` :  the fit WCS (`lsst.afw.geom.SkyWcs`)
    - ``scatterOnSky`` :  median on-sky separation between reference
      objects and sources in "matches" (`lsst.afw.geom.Angle`)

Definition at line 106 of file fitAffineWcs.py.

112  exposure=None):
113  """Fit a simple Affine transform with a shift to the matches and update
114  the WCS.
115 
116  This method assumes that the distortion model of the telescope is
117  applied correctly and is accurate with only a slight rotation,
118  rotation, and "squish" required to fit to the reference locations.
119 
120  Parameters
121  ----------
122  matches : `list` of `lsst.afw.table.ReferenceMatch`
123  The following fields are read:
124 
125  - match.first (reference object) coord
126  - match.second (source) centroid
127 
128  The following fields are written:
129 
130  - match.first (reference object) centroid,
131  - match.second (source) centroid
132  - match.distance (on sky separation, in radians)
133 
134  initWcs : `lsst.afw.geom.SkyWcs`
135  initial WCS
136  bbox : `lsst.geom.Box2I`
137  Ignored; present for consistency with FitSipDistortionTask.
138  refCat : `lsst.afw.table.SimpleCatalog`
139  reference object catalog, or None.
140  If provided then all centroids are updated with the new WCS,
141  otherwise only the centroids for ref objects in matches are
142  updated. Required fields are "centroid_x", "centroid_y",
143  "coord_ra", and "coord_dec".
144  sourceCat : `lsst.afw.table.SourceCatalog`
145  source catalog, or None.
146  If provided then coords are updated with the new WCS;
147  otherwise only the coords for sources in matches are updated.
148  Required fields are "slot_Centroid_x", "slot_Centroid_y", and
149  "coord_ra", and "coord_dec".
150  exposure : `lsst.afw.image.Exposure`
151  Ignored; present for consistency with FitSipDistortionTask.
152 
153  Returns
154  -------
155  result : `lsst.pipe.base.Struct`
156  with the following fields:
157 
158  - ``wcs`` : the fit WCS (`lsst.afw.geom.SkyWcs`)
159  - ``scatterOnSky`` : median on-sky separation between reference
160  objects and sources in "matches" (`lsst.afw.geom.Angle`)
161  """
162  # Create a data-structure that decomposes the input Wcs frames and
163  # appends the new transform.
164  wcsMaker = TransformedSkyWcsMaker(initWcs)
165 
166  refPoints = []
167  srcPixels = []
168  offsetLong = 0
169  offsetLat = 0
170  # Grab reference coordinates and source centroids. Compute the average
171  # direction and separation between the reference and the sources.
172  for match in matches:
173  refCoord = match.first.getCoord()
174  refPoints.append(refCoord)
175  srcCentroid = match.second.getCentroid()
176  srcPixels.append(srcCentroid)
177  srcCoord = initWcs.pixelToSky(srcCentroid)
178  deltaLong, deltaLat = srcCoord.getTangentPlaneOffset(refCoord)
179  offsetLong += deltaLong.asArcseconds()
180  offsetLat += deltaLat.asArcseconds()
181  offsetLong /= len(srcPixels)
182  offsetLat /= len(srcPixels)
183  offsetDist = np.sqrt(offsetLong ** 2 + offsetLat ** 2)
184  if offsetDist > 0.:
185  offsetDir = np.degrees(np.arccos(offsetLong / offsetDist))
186  else:
187  offsetDir = 0.
188  offsetDir *= np.sign(offsetLat)
189  self.log.debug("Initial shift guess: Direction: %.3f, Dist %.3f...",
190  offsetDir, offsetDist)
191 
192  # Best performing fitter in scipy tried so far (vs. default settings in
193  # minimize). Exits early because of the xTol value which cannot be
194  # disabled in scipy1.2.1. Matrix starting values are non-zero as this
195  # results in better fit off-diagonal terms.
196  fit = least_squares(
197  _chiFunc,
198  x0=[offsetDir, offsetDist, 1., 1e-8, 1e-8, 1.],
199  args=(refPoints, srcPixels, wcsMaker),
200  method='dogbox',
201  bounds=[[-360, -np.inf, -np.inf, -np.inf, -np.inf, -np.inf],
202  [360, np.inf, np.inf, np.inf, np.inf, np.inf]],
203  ftol=2.3e-16,
204  gtol=2.31e-16,
205  xtol=2.3e-16)
206  self.log.debug("Best fit: Direction: %.3f, Dist: %.3f, "
207  "Affine matrix: [[%.6f, %.6f], [%.6f, %.6f]]...",
208  fit.x[0], fit.x[1],
209  fit.x[2], fit.x[3], fit.x[4], fit.x[5])
210 
211  wcs = wcsMaker.makeWcs(fit.x[:2], fit.x[2:].reshape((2, 2)))
212 
213  # Copied from other fit*WcsTasks.
214  if refCat is not None:
215  self.log.debug("Updating centroids in refCat")
216  lsst.afw.table.updateRefCentroids(wcs, refList=refCat)
217  else:
218  self.log.warning("Updating reference object centroids in match list; refCat is None")
220  wcs,
221  refList=[match.first for match in matches])
222 
223  if sourceCat is not None:
224  self.log.debug("Updating coords in sourceCat")
225  lsst.afw.table.updateSourceCoords(wcs, sourceList=sourceCat)
226  else:
227  self.log.warning("Updating source coords in match list; sourceCat is None")
229  wcs,
230  sourceList=[match.second for match in matches])
231  setMatchDistance(matches)
232 
233  stats = makeMatchStatisticsInRadians(wcs,
234  matches,
235  lsst.afw.math.MEDIAN)
236  scatterOnSky = stats.getValue() * radians
237 
238  self.log.debug("In fitter scatter %.4f", scatterOnSky.asArcseconds())
239 
240  return lsst.pipe.base.Struct(
241  wcs=wcs,
242  scatterOnSky=scatterOnSky,
243  )
244 
245 
void updateRefCentroids(geom::SkyWcs const &wcs, ReferenceCollection &refList)
Update centroids in a collection of reference objects.
Definition: wcsUtils.cc:72
void updateSourceCoords(geom::SkyWcs const &wcs, SourceCollection &sourceList)
Update sky coordinates in a collection of source objects.
Definition: wcsUtils.cc:95
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.

Member Data Documentation

◆ ConfigClass

lsst.meas.astrom.fitAffineWcs.FitAffineWcsTask.ConfigClass = FitAffineWcsConfig
static

Definition at line 102 of file fitAffineWcs.py.


The documentation for this class was generated from the following file: