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 | Public Attributes | Static Public Attributes | List of all members
lsst.meas.astrom.astrometry.AstrometryTask Class Reference
Inheritance diagram for lsst.meas.astrom.astrometry.AstrometryTask:
lsst.meas.astrom.ref_match.RefMatchTask

Public Member Functions

def __init__ (self, refObjLoader, schema=None, **kwargs)
 
def run (self, sourceCat, exposure)
 
def solve (self, exposure, sourceCat)
 
def setRefObjLoader (self, refObjLoader)
 
def loadAndMatch (self, exposure, sourceCat)
 

Public Attributes

 usedKey
 
 refObjLoader
 

Static Public Attributes

 ConfigClass = AstrometryConfig
 

Detailed Description

Match an input source catalog with objects from a reference catalog and
solve for the WCS.

This task is broken into two main subasks: matching and WCS fitting which
are very interactive. The matching here can be considered in part a first
pass WCS fitter due to the fitter's sensitivity to outliers.

Parameters
----------
refObjLoader : `lsst.meas.algorithms.ReferenceLoader`
    A reference object loader object
schema : `lsst.afw.table.Schema`
    Used to set "calib_astrometry_used" flag in output source catalog.
**kwargs
    additional keyword arguments for pipe_base
    `lsst.pipe.base.Task.__init__`

Definition at line 100 of file astrometry.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.meas.astrom.astrometry.AstrometryTask.__init__ (   self,
  refObjLoader,
  schema = None,
**  kwargs 
)

Definition at line 121 of file astrometry.py.

121  def __init__(self, refObjLoader, schema=None, **kwargs):
122  RefMatchTask.__init__(self, refObjLoader, **kwargs)
123 
124  if schema is not None:
125  self.usedKey = schema.addField("calib_astrometry_used", type="Flag",
126  doc="set if source was used in astrometric calibration")
127  else:
128  self.usedKey = None
129 
130  self.makeSubtask("wcsFitter")
131 

Member Function Documentation

◆ loadAndMatch()

def lsst.meas.astrom.ref_match.RefMatchTask.loadAndMatch (   self,
  exposure,
  sourceCat 
)
inherited
Load reference objects overlapping an exposure and match to sources
detected on that exposure.

Parameters
----------
exposure : `lsst.afw.image.Exposure`
    exposure that the sources overlap
sourceCat : `lsst.afw.table.SourceCatalog.`
    catalog of sources detected on the exposure

Returns
-------
result : `lsst.pipe.base.Struct`
    Result struct with Components:

    - ``refCat`` : reference object catalog of objects that overlap the
      exposure (`lsst.afw.table.SimpleCatalog`)
    - ``matches`` :  Matched sources and references
      (`list` of `lsst.afw.table.ReferenceMatch`)
    - ``matchMeta`` : metadata needed to unpersist matches
      (`lsst.daf.base.PropertyList`)

Notes
-----
ignores config.matchDistanceSigma

Definition at line 117 of file ref_match.py.

117  def loadAndMatch(self, exposure, sourceCat):
118  """Load reference objects overlapping an exposure and match to sources
119  detected on that exposure.
120 
121  Parameters
122  ----------
123  exposure : `lsst.afw.image.Exposure`
124  exposure that the sources overlap
125  sourceCat : `lsst.afw.table.SourceCatalog.`
126  catalog of sources detected on the exposure
127 
128  Returns
129  -------
130  result : `lsst.pipe.base.Struct`
131  Result struct with Components:
132 
133  - ``refCat`` : reference object catalog of objects that overlap the
134  exposure (`lsst.afw.table.SimpleCatalog`)
135  - ``matches`` : Matched sources and references
136  (`list` of `lsst.afw.table.ReferenceMatch`)
137  - ``matchMeta`` : metadata needed to unpersist matches
138  (`lsst.daf.base.PropertyList`)
139 
140  Notes
141  -----
142  ignores config.matchDistanceSigma
143  """
144  if self.refObjLoader is None:
145  raise RuntimeError("Running matcher task with no refObjLoader set in __ini__ or setRefObjLoader")
146  import lsstDebug
147  debug = lsstDebug.Info(__name__)
148 
149  expMd = self._getExposureMetadata(exposure)
150 
151  sourceSelection = self.sourceSelector.run(sourceCat)
152 
153  sourceFluxField = "slot_%sFlux_instFlux" % (self.config.sourceFluxType)
154 
155  loadRes = self.refObjLoader.loadPixelBox(
156  bbox=expMd.bbox,
157  wcs=expMd.wcs,
158  filterName=expMd.filterName,
159  photoCalib=expMd.photoCalib,
160  epoch=expMd.epoch,
161  )
162 
163  refSelection = self.referenceSelector.run(loadRes.refCat)
164 
165  matchMeta = self.refObjLoader.getMetadataBox(
166  bbox=expMd.bbox,
167  wcs=expMd.wcs,
168  filterName=expMd.filterName,
169  photoCalib=expMd.photoCalib,
170  epoch=expMd.epoch,
171  )
172 
173  matchRes = self.matcher.matchObjectsToSources(
174  refCat=refSelection.sourceCat,
175  sourceCat=sourceSelection.sourceCat,
176  wcs=expMd.wcs,
177  sourceFluxField=sourceFluxField,
178  refFluxField=loadRes.fluxField,
179  match_tolerance=None,
180  )
181 
182  distStats = self._computeMatchStatsOnSky(matchRes.matches)
183  self.log.info(
184  "Found %d matches with scatter = %0.3f +- %0.3f arcsec; ",
185  len(matchRes.matches), distStats.distMean.asArcseconds(), distStats.distStdDev.asArcseconds()
186  )
187 
188  if debug.display:
189  frame = int(debug.frame)
191  refCat=refSelection.sourceCat,
192  sourceCat=sourceSelection.sourceCat,
193  matches=matchRes.matches,
194  exposure=exposure,
195  bbox=expMd.bbox,
196  frame=frame,
197  title="Matches",
198  )
199 
200  return pipeBase.Struct(
201  refCat=loadRes.refCat,
202  refSelection=refSelection,
203  sourceSelection=sourceSelection,
204  matches=matchRes.matches,
205  matchMeta=matchMeta,
206  )
207 
def run(self, coaddExposures, bbox, wcs)
Definition: getTemplate.py:603
def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None, matches=None, frame=1, title="", pause=True)
Definition: display.py:34

◆ run()

def lsst.meas.astrom.astrometry.AstrometryTask.run (   self,
  sourceCat,
  exposure 
)
Load reference objects, match sources and optionally fit a WCS.

This is a thin layer around solve or loadAndMatch, depending on
config.forceKnownWcs.

Parameters
----------
exposure : `lsst.afw.image.Exposure`
    exposure whose WCS is to be fit
    The following are read only:

    - bbox
    - photoCalib (may be absent)
    - filter (may be unset)
    - detector (if wcs is pure tangent; may be absent)

    The following are updated:

    - wcs (the initial value is used as an initial guess, and is
      required)

sourceCat : `lsst.afw.table.SourceCatalog`
    catalog of sources detected on the exposure

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

    - ``refCat`` : reference object catalog of objects that overlap the
      exposure (with some margin) (`lsst.afw.table.SimpleCatalog`).
    - ``matches`` : astrometric matches
      (`list` of `lsst.afw.table.ReferenceMatch`).
    - ``scatterOnSky`` :  median on-sky separation between reference
      objects and sources in "matches"
      (`lsst.afw.geom.Angle`) or `None` if config.forceKnownWcs True
    - ``matchMeta`` :  metadata needed to unpersist matches
      (`lsst.daf.base.PropertyList`)

Definition at line 133 of file astrometry.py.

133  def run(self, sourceCat, exposure):
134  """Load reference objects, match sources and optionally fit a WCS.
135 
136  This is a thin layer around solve or loadAndMatch, depending on
137  config.forceKnownWcs.
138 
139  Parameters
140  ----------
141  exposure : `lsst.afw.image.Exposure`
142  exposure whose WCS is to be fit
143  The following are read only:
144 
145  - bbox
146  - photoCalib (may be absent)
147  - filter (may be unset)
148  - detector (if wcs is pure tangent; may be absent)
149 
150  The following are updated:
151 
152  - wcs (the initial value is used as an initial guess, and is
153  required)
154 
155  sourceCat : `lsst.afw.table.SourceCatalog`
156  catalog of sources detected on the exposure
157 
158  Returns
159  -------
160  result : `lsst.pipe.base.Struct`
161  with these fields:
162 
163  - ``refCat`` : reference object catalog of objects that overlap the
164  exposure (with some margin) (`lsst.afw.table.SimpleCatalog`).
165  - ``matches`` : astrometric matches
166  (`list` of `lsst.afw.table.ReferenceMatch`).
167  - ``scatterOnSky`` : median on-sky separation between reference
168  objects and sources in "matches"
169  (`lsst.afw.geom.Angle`) or `None` if config.forceKnownWcs True
170  - ``matchMeta`` : metadata needed to unpersist matches
171  (`lsst.daf.base.PropertyList`)
172  """
173  if self.refObjLoader is None:
174  raise RuntimeError("Running matcher task with no refObjLoader set in __init__ or setRefObjLoader")
175  if self.config.forceKnownWcs:
176  res = self.loadAndMatch(exposure=exposure, sourceCat=sourceCat)
177  res.scatterOnSky = None
178  else:
179  res = self.solve(exposure=exposure, sourceCat=sourceCat)
180  return res
181 

◆ setRefObjLoader()

def lsst.meas.astrom.ref_match.RefMatchTask.setRefObjLoader (   self,
  refObjLoader 
)
inherited
Sets the reference object loader for the task

Parameters
----------
refObjLoader
    An instance of a reference object loader task or class

Definition at line 106 of file ref_match.py.

106  def setRefObjLoader(self, refObjLoader):
107  """Sets the reference object loader for the task
108 
109  Parameters
110  ----------
111  refObjLoader
112  An instance of a reference object loader task or class
113  """
114  self.refObjLoader = refObjLoader
115 

◆ solve()

def lsst.meas.astrom.astrometry.AstrometryTask.solve (   self,
  exposure,
  sourceCat 
)
Load reference objects overlapping an exposure, match to sources and
fit a WCS

Returns
-------
result : `lsst.pipe.base.Struct`
    Result struct with components:

    - ``refCat`` : reference object catalog of objects that overlap the
      exposure (with some margin) (`lsst::afw::table::SimpleCatalog`).
    - ``matches`` :  astrometric matches
      (`list` of `lsst.afw.table.ReferenceMatch`).
    - ``scatterOnSky`` :  median on-sky separation between reference
      objects and sources in "matches" (`lsst.geom.Angle`)
    - ``matchMeta`` :  metadata needed to unpersist matches
      (`lsst.daf.base.PropertyList`)

Raises
------
TaskError
    If the measured mean on-sky distance between the matched source and
    reference objects is greater than
    ``self.config.maxMeanDistanceArcsec``.

Notes
-----
ignores config.forceKnownWcs

Definition at line 183 of file astrometry.py.

183  def solve(self, exposure, sourceCat):
184  """Load reference objects overlapping an exposure, match to sources and
185  fit a WCS
186 
187  Returns
188  -------
189  result : `lsst.pipe.base.Struct`
190  Result struct with components:
191 
192  - ``refCat`` : reference object catalog of objects that overlap the
193  exposure (with some margin) (`lsst::afw::table::SimpleCatalog`).
194  - ``matches`` : astrometric matches
195  (`list` of `lsst.afw.table.ReferenceMatch`).
196  - ``scatterOnSky`` : median on-sky separation between reference
197  objects and sources in "matches" (`lsst.geom.Angle`)
198  - ``matchMeta`` : metadata needed to unpersist matches
199  (`lsst.daf.base.PropertyList`)
200 
201  Raises
202  ------
203  TaskError
204  If the measured mean on-sky distance between the matched source and
205  reference objects is greater than
206  ``self.config.maxMeanDistanceArcsec``.
207 
208  Notes
209  -----
210  ignores config.forceKnownWcs
211  """
212  if self.refObjLoader is None:
213  raise RuntimeError("Running matcher task with no refObjLoader set in __init__ or setRefObjLoader")
214  import lsstDebug
215  debug = lsstDebug.Info(__name__)
216 
217  expMd = self._getExposureMetadata(exposure)
218 
219  sourceSelection = self.sourceSelector.run(sourceCat)
220 
221  self.log.info("Purged %d sources, leaving %d good sources",
222  len(sourceCat) - len(sourceSelection.sourceCat),
223  len(sourceSelection.sourceCat))
224 
225  loadRes = self.refObjLoader.loadPixelBox(
226  bbox=expMd.bbox,
227  wcs=expMd.wcs,
228  filterName=expMd.filterName,
229  photoCalib=expMd.photoCalib,
230  epoch=expMd.epoch,
231  )
232 
233  refSelection = self.referenceSelector.run(loadRes.refCat)
234 
235  matchMeta = self.refObjLoader.getMetadataBox(
236  bbox=expMd.bbox,
237  wcs=expMd.wcs,
238  filterName=expMd.filterName,
239  photoCalib=expMd.photoCalib,
240  epoch=expMd.epoch,
241  )
242 
243  if debug.display:
244  frame = int(debug.frame)
246  refCat=refSelection.sourceCat,
247  sourceCat=sourceSelection.sourceCat,
248  exposure=exposure,
249  bbox=expMd.bbox,
250  frame=frame,
251  title="Reference catalog",
252  )
253 
254  res = None
255  wcs = expMd.wcs
256  match_tolerance = None
257  for i in range(self.config.maxIter):
258  iterNum = i + 1
259  try:
260  tryRes = self._matchAndFitWcs(
261  refCat=refSelection.sourceCat,
262  sourceCat=sourceCat,
263  goodSourceCat=sourceSelection.sourceCat,
264  refFluxField=loadRes.fluxField,
265  bbox=expMd.bbox,
266  wcs=wcs,
267  exposure=exposure,
268  match_tolerance=match_tolerance,
269  )
270  except Exception as e:
271  # if we have had a succeessful iteration then use that; otherwise fail
272  if i > 0:
273  self.log.info("Fit WCS iter %d failed; using previous iteration: %s", iterNum, e)
274  iterNum -= 1
275  break
276  else:
277  raise
278 
279  match_tolerance = tryRes.match_tolerance
280  tryMatchDist = self._computeMatchStatsOnSky(tryRes.matches)
281  self.log.debug(
282  "Match and fit WCS iteration %d: found %d matches with on-sky distance mean "
283  "= %0.3f +- %0.3f arcsec; max match distance = %0.3f arcsec",
284  iterNum, len(tryRes.matches), tryMatchDist.distMean.asArcseconds(),
285  tryMatchDist.distStdDev.asArcseconds(), tryMatchDist.maxMatchDist.asArcseconds())
286 
287  maxMatchDist = tryMatchDist.maxMatchDist
288  res = tryRes
289  wcs = res.wcs
290  if maxMatchDist.asArcseconds() < self.config.minMatchDistanceArcSec:
291  self.log.debug(
292  "Max match distance = %0.3f arcsec < %0.3f = config.minMatchDistanceArcSec; "
293  "that's good enough",
294  maxMatchDist.asArcseconds(), self.config.minMatchDistanceArcSec)
295  break
296  match_tolerance.maxMatchDist = maxMatchDist
297 
298  self.log.info(
299  "Matched and fit WCS in %d iterations; "
300  "found %d matches with on-sky distance mean and scatter = %0.3f +- %0.3f arcsec",
301  iterNum, len(tryRes.matches), tryMatchDist.distMean.asArcseconds(),
302  tryMatchDist.distStdDev.asArcseconds())
303  if tryMatchDist.distMean.asArcseconds() > self.config.maxMeanDistanceArcsec:
304  raise pipeBase.TaskError(
305  "Fatal astrometry failure detected: mean on-sky distance = %0.3f arcsec > %0.3f "
306  "(maxMeanDistanceArcsec)" %
307  (tryMatchDist.distMean.asArcseconds(), self.config.maxMeanDistanceArcsec))
308  for m in res.matches:
309  if self.usedKey:
310  m.second.set(self.usedKey, True)
311  exposure.setWcs(res.wcs)
312 
313  # Record the scatter in the exposure metadata
314  md = exposure.getMetadata()
315  md['SFM_ASTROM_OFFSET_MEAN'] = tryMatchDist.distMean.asArcseconds()
316  md['SFM_ASTROM_OFFSET_STD'] = tryMatchDist.distStdDev.asArcseconds()
317 
318  return pipeBase.Struct(
319  refCat=refSelection.sourceCat,
320  matches=res.matches,
321  scatterOnSky=res.scatterOnSky,
322  matchMeta=matchMeta,
323  )
324 

Member Data Documentation

◆ ConfigClass

lsst.meas.astrom.astrometry.AstrometryTask.ConfigClass = AstrometryConfig
static

Definition at line 118 of file astrometry.py.

◆ refObjLoader

lsst.meas.astrom.ref_match.RefMatchTask.refObjLoader
inherited

Definition at line 93 of file ref_match.py.

◆ usedKey

lsst.meas.astrom.astrometry.AstrometryTask.usedKey

Definition at line 125 of file astrometry.py.


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