LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
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 94 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 105 of file fitAffineWcs.py.

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


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