LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | Static Private Attributes | List of all members
lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask Class Reference

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

Inheritance diagram for lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask:

Public Member Functions

def fitWcs
 Fit a TAN-SIP WCS from a list of reference object/source matches. More...
 
def initialWcs
 
def rejectMatches
 
def plotFit
 

Static Public Member Functions

def updateRefCentroids
 
def updateSourceCoords
 

Static Public Attributes

 ConfigClass = FitTanSipWcsConfig
 

Private Member Functions

def _fitWcs
 

Static Private Attributes

string _DefaultName = "fitWcs"
 

Detailed Description

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

Contents

Description

Fit a TAN-SIP WCS given a list of reference object/source matches. See CreateWithSip.h for information about the fitting algorithm.

Task initialisation

Invoking the Task

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

Parameters
[in,out]matchesa list of reference object/source matches (an lsst::afw::table::ReferenceMatchVector) 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)
[in]initWcsinitial WCS
[in]bboxthe region over which the WCS will be valid (an lsst:afw::geom::Box2I); if None or an empty box then computed from matches
[in,out]refCatreference 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".
[in,out]sourceCatsource 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".
Returns
an lsst.pipe.base.Struct with the following fields:
  • wcs the fit WCS as an lsst.afw.image.Wcs
  • scatterOnSky median on-sky separation between reference objects and sources in "matches", as an lsst.afw.geom.Angle

Configuration parameters

See FitTanSipWcsConfig

A complete example of using FitTanSipWcsTask

FitTanSipWcsTask is a subtask of AstrometryTask, which is called by PhotoCalTask. See meas_photocal_photocal_Example.

Debug variables

FitTanSipWcsTask does not support any debug variables.

Definition at line 57 of file fitTanSipWcs.py.

Member Function Documentation

def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask._fitWcs (   self,
  matches,
  wcs 
)
private
Fit a Wcs based on the matches and a guess Wcs

Definition at line 204 of file fitTanSipWcs.py.

205  def _fitWcs(self, matches, wcs):
206  """Fit a Wcs based on the matches and a guess Wcs"""
207  for i in range(self.config.numIter):
208  sipObject = makeCreateWcsWithSip(matches, wcs, self.config.order)
209  wcs = sipObject.getNewWcs()
210  return sipObject
CreateWcsWithSip< MatchT > makeCreateWcsWithSip(std::vector< MatchT > const &matches, afw::image::Wcs const &linearWcs, int const order, afw::geom::Box2I const &bbox=afw::geom::Box2I(), int const ngrid=0)
Factory function for CreateWcsWithSip.
def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.fitWcs (   self,
  matches,
  initWcs,
  bbox = None,
  refCat = None,
  sourceCat = None 
)

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

Parameters
[in,out]matchesa list of reference object/source matches (an lsst::afw::table::ReferenceMatchVector) 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)
[in]initWcsinitial WCS
[in]bboxthe region over which the WCS will be valid (an lsst:afw::geom::Box2I); if None or an empty box then computed from matches
[in,out]refCatreference 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".
[in,out]sourceCatsource 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".
Returns
an lsst.pipe.base.Struct with the following fields:
  • wcs the fit WCS as an lsst.afw.image.Wcs
  • scatterOnSky median on-sky separation between reference objects and sources in "matches", as an lsst.afw.geom.Angle

Definition at line 102 of file fitTanSipWcs.py.

103  def fitWcs(self, matches, initWcs, bbox=None, refCat=None, sourceCat=None):
104  """!Fit a TAN-SIP WCS from a list of reference object/source matches
105 
106  @param[in,out] matches a list of reference object/source matches
107  (an lsst::afw::table::ReferenceMatchVector)
108  The following fields are read:
109  - match.first (reference object) coord
110  - match.second (source) centroid
111  The following fields are written:
112  - match.first (reference object) centroid,
113  - match.second (source) centroid
114  - match.distance (on sky separation, in radians)
115  @param[in] initWcs initial WCS
116  @param[in] bbox the region over which the WCS will be valid (an lsst:afw::geom::Box2I);
117  if None or an empty box then computed from matches
118  @param[in,out] refCat reference object catalog, or None.
119  If provided then all centroids are updated with the new WCS,
120  otherwise only the centroids for ref objects in matches are updated.
121  Required fields are "centroid_x", "centroid_y", "coord_ra", and "coord_dec".
122  @param[in,out] sourceCat source catalog, or None.
123  If provided then coords are updated with the new WCS;
124  otherwise only the coords for sources in matches are updated.
125  Required fields are "slot_Centroid_x", "slot_Centroid_y", and "coord_ra", and "coord_dec".
126 
127  @return an lsst.pipe.base.Struct with the following fields:
128  - wcs the fit WCS as an lsst.afw.image.Wcs
129  - scatterOnSky median on-sky separation between reference objects and sources in "matches",
130  as an lsst.afw.geom.Angle
131  """
132  if bbox is None:
133  bbox = afwGeom.Box2I()
134 
135  import lsstDebug
136  debug = lsstDebug.Info(__name__)
137 
138  wcs = self.initialWcs(matches, initWcs)
139  rejected = numpy.zeros(len(matches), dtype=bool)
140  for rej in range(self.config.numRejIter):
141  sipObject = self._fitWcs([mm for i, mm in enumerate(matches) if not rejected[i]], wcs)
142  wcs = sipObject.getNewWcs()
143  rejected = self.rejectMatches(matches, wcs, rejected)
144  if rejected.sum() == len(rejected):
145  raise RuntimeError("All matches rejected in iteration %d" % (rej + 1,))
146  if debug.plot:
147  print("Plotting fit after rejection iteration %d/%d" % (rej + 1, self.config.numRejIter))
148  self.plotFit(matches, wcs, rejected)
149  # Final fit after rejection
150  sipObject = self._fitWcs([mm for i, mm in enumerate(matches) if not rejected[i]], wcs)
151  wcs = sipObject.getNewWcs()
152  if debug.plot:
153  print("Plotting final fit")
154  self.plotFit(matches, wcs, rejected)
155 
156  if refCat is not None:
157  self.log.info("Updating centroids in refCat")
158  self.updateRefCentroids(wcs, refList=refCat)
159  else:
160  self.log.warning("Updating reference object centroids in match list; refCat is None")
161  self.updateRefCentroids(wcs, refList=[match.first for match in matches])
162 
163  if sourceCat is not None:
164  self.log.info("Updating coords in sourceCat")
165  self.updateSourceCoords(wcs, sourceList=sourceCat)
166  else:
167  self.log.warning("Updating source coords in match list; sourceCat is None")
168  self.updateSourceCoords(wcs, sourceList=[match.second for match in matches])
169 
170  self.log.info("Updating distance in match list")
171  setMatchDistance(matches)
172 
173  scatterOnSky = sipObject.getScatterOnSky()
174 
175  if scatterOnSky.asArcseconds() > self.config.maxScatterArcsec:
176  raise pipeBase.TaskError(
177  "Fit failed: median scatter on sky = %0.3f arcsec > %0.3f config.maxScatterArcsec" %
178  (scatterOnSky.asArcseconds(), self.config.maxScatterArcsec))
179 
180  return pipeBase.Struct(
181  wcs = wcs,
182  scatterOnSky = scatterOnSky,
183  )
def fitWcs
Fit a TAN-SIP WCS from a list of reference object/source matches.
An integer coordinate rectangle.
Definition: Box.h:53
def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.initialWcs (   self,
  matches,
  wcs 
)
Generate a guess Wcs from the astrometric matches

We create a Wcs anchored at the center of the matches, with the scale
of the input Wcs.  This is necessary because matching returns only
matches with no estimated Wcs, and the input Wcs is a wild guess.
We're using the best of each: positions from the matches, and scale
from the input Wcs.

Definition at line 184 of file fitTanSipWcs.py.

185  def initialWcs(self, matches, wcs):
186  """Generate a guess Wcs from the astrometric matches
187 
188  We create a Wcs anchored at the center of the matches, with the scale
189  of the input Wcs. This is necessary because matching returns only
190  matches with no estimated Wcs, and the input Wcs is a wild guess.
191  We're using the best of each: positions from the matches, and scale
192  from the input Wcs.
193  """
194  crpix = afwGeom.Extent2D(0, 0)
195  crval = afwGeom.Extent3D(0, 0, 0)
196  for mm in matches:
197  crpix += afwGeom.Extent2D(mm.second.getCentroid())
198  crval += afwGeom.Extent3D(mm.first.getCoord().toIcrs().getVector())
199  crpix /= len(matches)
200  crval /= len(matches)
201  newWcs = afwImage.Wcs(afwCoord.IcrsCoord(afwGeom.Point3D(crval)).getPosition(),
202  afwGeom.Point2D(crpix), wcs.getCDMatrix())
203  return newWcs
Implementation of the WCS standard for a any projection.
Definition: Wcs.h:107
A coordinate class intended to represent absolute positions.
A class to handle Icrs coordinates (inherits from Coord)
Definition: Coord.h:157
def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.plotFit (   self,
  matches,
  wcs,
  rejected 
)
Plot the fit

We create four plots, for all combinations of (dx, dy) against
(x, y).  Good points are black, while rejected points are red.

Definition at line 247 of file fitTanSipWcs.py.

248  def plotFit(self, matches, wcs, rejected):
249  """Plot the fit
250 
251  We create four plots, for all combinations of (dx, dy) against
252  (x, y). Good points are black, while rejected points are red.
253  """
254  import matplotlib.pyplot as plt
255 
256  fit = [wcs.skyToPixel(m.first.getCoord()) for m in matches]
257  x1 = numpy.array([ff.getX() for ff in fit])
258  y1 = numpy.array([ff.getY() for ff in fit])
259  x2 = numpy.array([m.second.getCentroid().getX() for m in matches])
260  y2 = numpy.array([m.second.getCentroid().getY() for m in matches])
261 
262  dx = x1 - x2
263  dy = y1 - y2
264 
265  good = numpy.logical_not(rejected)
266 
267  figure = plt.figure()
268  axes = figure.add_subplot(2, 2, 1)
269  axes.plot(x2[good], dx[good], 'ko')
270  axes.plot(x2[rejected], dx[rejected], 'ro')
271  axes.set_xlabel("x")
272  axes.set_ylabel("dx")
273 
274  axes = figure.add_subplot(2, 2, 2)
275  axes.plot(x2[good], dy[good], 'ko')
276  axes.plot(x2[rejected], dy[rejected], 'ro')
277  axes.set_xlabel("x")
278  axes.set_ylabel("dy")
279 
280  axes = figure.add_subplot(2, 2, 3)
281  axes.plot(y2[good], dx[good], 'ko')
282  axes.plot(y2[rejected], dx[rejected], 'ro')
283  axes.set_xlabel("y")
284  axes.set_ylabel("dx")
285 
286  axes = figure.add_subplot(2, 2, 4)
287  axes.plot(y2[good], dy[good], 'ko')
288  axes.plot(y2[rejected], dy[rejected], 'ro')
289  axes.set_xlabel("y")
290  axes.set_ylabel("dy")
291 
292  plt.show()
def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.rejectMatches (   self,
  matches,
  wcs,
  rejected 
)
Flag deviant matches

We return a boolean numpy array indicating whether the corresponding
match should be rejected.  The previous list of rejections is used
so we can calculate uncontaminated statistics.

Definition at line 211 of file fitTanSipWcs.py.

212  def rejectMatches(self, matches, wcs, rejected):
213  """Flag deviant matches
214 
215  We return a boolean numpy array indicating whether the corresponding
216  match should be rejected. The previous list of rejections is used
217  so we can calculate uncontaminated statistics.
218  """
219  fit = [wcs.skyToPixel(m.first.getCoord()) for m in matches]
220  dx = numpy.array([ff.getX() - mm.second.getCentroid().getX() for ff, mm in zip(fit, matches)])
221  dy = numpy.array([ff.getY() - mm.second.getCentroid().getY() for ff, mm in zip(fit, matches)])
222  good = numpy.logical_not(rejected)
223  return (dx > self.config.rejSigma*dx[good].std()) | (dy > self.config.rejSigma*dy[good].std())
STL namespace.
def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.updateRefCentroids (   wcs,
  refList 
)
static
Update centroids in a collection of reference objects, given a WCS

Definition at line 225 of file fitTanSipWcs.py.

226  def updateRefCentroids(wcs, refList):
227  """Update centroids in a collection of reference objects, given a WCS
228  """
229  if len(refList) < 1:
230  return
231  schema = refList[0].schema
232  coordKey = afwTable.CoordKey(schema["coord"])
233  centroidKey = afwTable.Point2DKey(schema["centroid"])
234  for refObj in refList:
235  refObj.set(centroidKey, wcs.skyToPixel(refObj.get(coordKey)))
A FunctorKey used to get or set celestial coordiantes from a pair of Angle keys.
Definition: aggregates.h:119
def lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.updateSourceCoords (   wcs,
  sourceList 
)
static
Update coords in a collection of sources, given a WCS

Definition at line 237 of file fitTanSipWcs.py.

238  def updateSourceCoords(wcs, sourceList):
239  """Update coords in a collection of sources, given a WCS
240  """
241  if len(sourceList) < 1:
242  return
243  schema = sourceList[1].schema
244  srcCoordKey = afwTable.CoordKey(schema["coord"])
245  for src in sourceList:
246  src.set(srcCoordKey, wcs.pixelToSky(src.getCentroid()))
A FunctorKey used to get or set celestial coordiantes from a pair of Angle keys.
Definition: aggregates.h:119

Member Data Documentation

string lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask._DefaultName = "fitWcs"
staticprivate

Definition at line 99 of file fitTanSipWcs.py.

lsst.meas.astrom.fitTanSipWcs.FitTanSipWcsTask.ConfigClass = FitTanSipWcsConfig
static

Definition at line 98 of file fitTanSipWcs.py.


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