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.pipe.tasks.measurePsf.MeasurePsfTask Class Reference

More...

Inheritance diagram for lsst.pipe.tasks.measurePsf.MeasurePsfTask:

Public Member Functions

def __init__ (self, schema=None, **kwargs)
 Create the detection task. More...
 
def run (self, exposure, sources, expId=0, matches=None)
 Measure the PSF. More...
 
def usesMatches (self)
 

Public Attributes

 candidateKey
 
 usedKey
 

Static Public Attributes

 ConfigClass = MeasurePsfConfig
 

Detailed Description

Measure the PSF

Contents

Description

A task that selects stars from a catalog of sources and uses those to measure the PSF.

The star selector is a subclass of lsst.meas.algorithms.BaseStarSelectorTask and the PSF determiner is a sublcass of lsst.meas.algorithms.BasePsfDeterminerTask

Warning
There is no establised set of configuration parameters for these algorithms, so once you start modifying parameters (as we do in A complete example of using MeasurePsfTask) your code is no longer portable.

Task initialisation

Create the detection task. Most arguments are simply passed onto pipe.base.Task.

    @param schema An lsst::afw::table::Schema used to create the output lsst.afw.table.SourceCatalog
    @param **kwargs Keyword arguments passed to lsst.pipe.base.task.Task.__init__.

    If schema is not None, 'calib_psf_candidate' and 'calib_psf_used' fields will be added to
    identify which stars were employed in the PSF estimation.

    @note This task can add fields to the schema, so any code calling this task must ensure that
    these fields are indeed present in the input table.

Invoking the Task

Measure the PSF.

    @param[in,out]   exposure   Exposure to process; measured PSF will be added.
    @param[in,out]   sources    Measured sources on exposure; flag fields will be set marking
                                stars chosen by the star selector and the PSF determiner if a schema
                                was passed to the task constructor.
    @param[in]       expId      Exposure id used for generating random seed.
    @param[in]  matches         A list of lsst.afw.table.ReferenceMatch objects
                                (@em i.e. of lsst.afw.table.Match
                                with @c first being of type lsst.afw.table.SimpleRecord and @c second
                                type lsst.afw.table.SourceRecord --- the reference object and detected
                                object respectively) as returned by @em e.g. the AstrometryTask.
                                Used by star selectors that choose to refer to an external catalog.

    @return a pipe.base.Struct with fields:
     - psf: The measured PSF (also set in the input exposure)
     - cellSet: an lsst.afw.math.SpatialCellSet containing the PSF candidates
        as returned by the psf determiner.

Configuration parameters

See MeasurePsfConfig.

Debug variables

The command line task interface supports a flag -d to import debug.py from your PYTHONPATH; see Using lsstDebug to control debugging output for more about debug.py files.

display
If True, display debugging plots
displayExposure
display the Exposure + spatialCells
displayPsfCandidates
show mosaic of candidates
showBadCandidates
Include bad candidates
displayPsfMosaic
show mosaic of reconstructed PSF(xy)
displayResiduals
show residuals
normalizeResiduals
Normalise residuals by object amplitude

Additionally you can enable any debug outputs that your chosen star selector and psf determiner support.

A complete example of using MeasurePsfTask

This code is in in the examples directory, and can be run as e.g examples/measurePsfTask.py --doDisplay measurePsfTask.py The example also runs SourceDetectionTask and SingleFrameMeasurementTask; see meas_algorithms_measurement_Example for more explanation. Import the tasks (there are some other standard imports; read the file to see them all): SourceDetectionTask MeasurePsfTask We need to create the tasks before processing any data as the task constructor can add an extra column to the schema, but first we need an almost-empty Schema: makeMinimalSchema We can now call the constructors for the tasks we need to find and characterize candidate PSF stars: SourceDetectionTask.ConfigClass measureTask Note that we've chosen a minimal set of measurement plugins: we need the outputs of base_SdssCentroid base_SdssShape and base_CircularApertureFlux as inputs to the PSF measurement algorithm, while base_PixelFlags identifies and flags bad sources (e.g. with pixels too close to the edge) so they can be removed later. Now we can create and configure the task that we're interested in: MeasurePsfTask measurePsfTask We're now ready to process the data (we could loop over multiple exposures/catalogues using the same task objects). First create the output table: afwTable And process the image: sources = result We can then unpack and use the results: psf cellSet If you specified –doDisplay you can see the PSF candidates: display RED

To investigate the Debug variables, put something like

import lsstDebug
def DebugInfo(name):
di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively
if name == "lsst.pipe.tasks.measurePsf" :
di.display = True
di.displayExposure = False # display the Exposure + spatialCells
di.displayPsfCandidates = True # show mosaic of candidates
di.displayPsfMosaic = True # show mosaic of reconstructed PSF(xy)
di.displayResiduals = True # show residuals
di.showBadCandidates = True # Include bad candidates
di.normalizeResiduals = False # Normalise residuals by object amplitude
return di
lsstDebug.Info = DebugInfo

into your debug.py file and run measurePsfTask.py with the –debug flag.

Definition at line 58 of file measurePsf.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.pipe.tasks.measurePsf.MeasurePsfTask.__init__ (   self,
  schema = None,
**  kwargs 
)

Create the detection task.

Most arguments are simply passed onto pipe.base.Task.

    @param schema An lsst::afw::table::Schema used to create the output lsst.afw.table.SourceCatalog
    @param **kwargs Keyword arguments passed to lsst.pipe.base.task.Task.__init__.

    If schema is not None, 'calib_psf_candidate' and 'calib_psf_used' fields will be added to
    identify which stars were employed in the PSF estimation.

    @note This task can add fields to the schema, so any code calling this task must ensure that
    these fields are indeed present in the input table.

Definition at line 207 of file measurePsf.py.

207  def __init__(self, schema=None, **kwargs):
208  """!Create the detection task. Most arguments are simply passed onto pipe.base.Task.
209 
210  @param schema An lsst::afw::table::Schema used to create the output lsst.afw.table.SourceCatalog
211  @param **kwargs Keyword arguments passed to lsst.pipe.base.task.Task.__init__.
212 
213  If schema is not None, 'calib_psf_candidate' and 'calib_psf_used' fields will be added to
214  identify which stars were employed in the PSF estimation.
215 
216  @note This task can add fields to the schema, so any code calling this task must ensure that
217  these fields are indeed present in the input table.
218  """
219 
220  pipeBase.Task.__init__(self, **kwargs)
221  if schema is not None:
222  self.candidateKey = schema.addField(
223  "calib_psf_candidate", type="Flag",
224  doc=("Flag set if the source was a candidate for PSF determination, "
225  "as determined by the star selector.")
226  )
227  self.usedKey = schema.addField(
228  "calib_psf_used", type="Flag",
229  doc=("Flag set if the source was actually used for PSF determination, "
230  "as determined by the '%s' PSF determiner.") % self.config.psfDeterminer.name
231  )
232  else:
233  self.candidateKey = None
234  self.usedKey = None
235  self.makeSubtask("starSelector")
236  self.makeSubtask("makePsfCandidates")
237  self.makeSubtask("psfDeterminer", schema=schema)
238  self.makeSubtask("reserve", columnName="calib_psf", schema=schema,
239  doc="set if source was reserved from PSF determination")
240 

Member Function Documentation

◆ run()

def lsst.pipe.tasks.measurePsf.MeasurePsfTask.run (   self,
  exposure,
  sources,
  expId = 0,
  matches = None 
)

Measure the PSF.

    @param[in,out]   exposure   Exposure to process; measured PSF will be added.
    @param[in,out]   sources    Measured sources on exposure; flag fields will be set marking
                                stars chosen by the star selector and the PSF determiner if a schema
                                was passed to the task constructor.
    @param[in]       expId      Exposure id used for generating random seed.
    @param[in]  matches         A list of lsst.afw.table.ReferenceMatch objects
                                (@em i.e. of lsst.afw.table.Match
                                with @c first being of type lsst.afw.table.SimpleRecord and @c second
                                type lsst.afw.table.SourceRecord --- the reference object and detected
                                object respectively) as returned by @em e.g. the AstrometryTask.
                                Used by star selectors that choose to refer to an external catalog.

    @return a pipe.base.Struct with fields:
     - psf: The measured PSF (also set in the input exposure)
     - cellSet: an lsst.afw.math.SpatialCellSet containing the PSF candidates
        as returned by the psf determiner.

Definition at line 242 of file measurePsf.py.

242  def run(self, exposure, sources, expId=0, matches=None):
243  """!Measure the PSF
244 
245  @param[in,out] exposure Exposure to process; measured PSF will be added.
246  @param[in,out] sources Measured sources on exposure; flag fields will be set marking
247  stars chosen by the star selector and the PSF determiner if a schema
248  was passed to the task constructor.
249  @param[in] expId Exposure id used for generating random seed.
250  @param[in] matches A list of lsst.afw.table.ReferenceMatch objects
251  (@em i.e. of lsst.afw.table.Match
252  with @c first being of type lsst.afw.table.SimpleRecord and @c second
253  type lsst.afw.table.SourceRecord --- the reference object and detected
254  object respectively) as returned by @em e.g. the AstrometryTask.
255  Used by star selectors that choose to refer to an external catalog.
256 
257  @return a pipe.base.Struct with fields:
258  - psf: The measured PSF (also set in the input exposure)
259  - cellSet: an lsst.afw.math.SpatialCellSet containing the PSF candidates
260  as returned by the psf determiner.
261  """
262  self.log.info("Measuring PSF")
263 
264  import lsstDebug
265  display = lsstDebug.Info(__name__).display
266  displayExposure = lsstDebug.Info(__name__).displayExposure # display the Exposure + spatialCells
267  displayPsfMosaic = lsstDebug.Info(__name__).displayPsfMosaic # show mosaic of reconstructed PSF(x,y)
268  displayPsfCandidates = lsstDebug.Info(__name__).displayPsfCandidates # show mosaic of candidates
269  displayResiduals = lsstDebug.Info(__name__).displayResiduals # show residuals
270  showBadCandidates = lsstDebug.Info(__name__).showBadCandidates # include bad candidates
271  normalizeResiduals = lsstDebug.Info(__name__).normalizeResiduals # normalise residuals by object peak
272 
273  #
274  # Run star selector
275  #
276  stars = self.starSelector.run(sourceCat=sources, matches=matches, exposure=exposure)
277  selectionResult = self.makePsfCandidates.run(stars.sourceCat, exposure=exposure)
278  self.log.info("PSF star selector found %d candidates", len(selectionResult.psfCandidates))
279  reserveResult = self.reserve.run(selectionResult.goodStarCat, expId=expId)
280  # Make list of psf candidates to send to the determiner (omitting those marked as reserved)
281  psfDeterminerList = [cand for cand, use
282  in zip(selectionResult.psfCandidates, reserveResult.use) if use]
283 
284  if selectionResult.psfCandidates and self.candidateKey is not None:
285  for cand in selectionResult.psfCandidates:
286  source = cand.getSource()
287  source.set(self.candidateKey, True)
288 
289  self.log.info("Sending %d candidates to PSF determiner", len(psfDeterminerList))
290 
291  if display:
292  frame = 1
293  if displayExposure:
294  disp = afwDisplay.Display(frame=frame)
295  disp.mtv(exposure, title="psf determination")
296  frame += 1
297  #
298  # Determine PSF
299  #
300  psf, cellSet = self.psfDeterminer.determinePsf(exposure, psfDeterminerList, self.metadata,
301  flagKey=self.usedKey)
302  self.log.info("PSF determination using %d/%d stars.",
303  self.metadata.getScalar("numGoodStars"), self.metadata.getScalar("numAvailStars"))
304 
305  exposure.setPsf(psf)
306 
307  if display:
308  frame = display
309  if displayExposure:
310  disp = afwDisplay.Display(frame=frame)
311  showPsfSpatialCells(exposure, cellSet, showBadCandidates, frame=frame)
312  frame += 1
313 
314  if displayPsfCandidates: # Show a mosaic of PSF candidates
315  plotPsfCandidates(cellSet, showBadCandidates=showBadCandidates, frame=frame)
316  frame += 1
317 
318  if displayResiduals:
319  frame = plotResiduals(exposure, cellSet,
320  showBadCandidates=showBadCandidates,
321  normalizeResiduals=normalizeResiduals,
322  frame=frame)
323  if displayPsfMosaic:
324  disp = afwDisplay.Display(frame=frame)
325  maUtils.showPsfMosaic(exposure, psf, display=disp, showFwhm=True)
326  disp.scale("linear", 0, 1)
327  frame += 1
328 
329  return pipeBase.Struct(
330  psf=psf,
331  cellSet=cellSet,
332  )
333 
def run(self, coaddExposures, bbox, wcs)
Definition: getTemplate.py:603
def plotPsfCandidates(cellSet, showBadCandidates=False, frame=1)
Definition: measurePsf.py:357
def plotResiduals(exposure, cellSet, showBadCandidates=False, normalizeResiduals=True, frame=2)
Definition: measurePsf.py:393
def showPsfSpatialCells(exposure, cellSet, showBadCandidates, frame=1)
Definition: measurePsf.py:344

◆ usesMatches()

def lsst.pipe.tasks.measurePsf.MeasurePsfTask.usesMatches (   self)
Return True if this task makes use of the "matches" argument to the run method

Definition at line 335 of file measurePsf.py.

335  def usesMatches(self):
336  """Return True if this task makes use of the "matches" argument to the run method"""
337  return self.starSelector.usesMatches
338 
339 #
340 # Debug code
341 #
342 
343 

Member Data Documentation

◆ candidateKey

lsst.pipe.tasks.measurePsf.MeasurePsfTask.candidateKey

Definition at line 222 of file measurePsf.py.

◆ ConfigClass

lsst.pipe.tasks.measurePsf.MeasurePsfTask.ConfigClass = MeasurePsfConfig
static

Definition at line 204 of file measurePsf.py.

◆ usedKey

lsst.pipe.tasks.measurePsf.MeasurePsfTask.usedKey

Definition at line 227 of file measurePsf.py.


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