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 | Public Attributes | Static Public Attributes | Static Private Attributes | List of all members
lsst.pipe.tasks.measurePsf.MeasurePsfTask Class Reference

Measure the PSF. More...

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

Public Member Functions

def __init__
 Create the detection task. More...
 
def run
 Measure the PSF. More...
 

Public Attributes

 candidateKey
 
 usedKey
 
 starSelector
 
 psfDeterminer
 

Static Public Attributes

 ConfigClass = MeasurePsfConfig
 

Static Private Attributes

string _DefaultName = "measurePsf"
 

Detailed Description

Measure the PSF.

Contents

Description

A task that wraps two algorithms set via a pair of registries specified in the task's Configuration parameters. Both algorithms are classes with a constructor taking a pex.config.Config object (e.g. lsst.meas.algorithms.objectSizeStarSelector.ObjectSizeStarSelector.__init__).

The algorithms are:

See also lsst.meas.algorithms.starSelectorRegistry.starSelectorRegistry and lsst.meas.algorithms.psfDeterminerRegistry.psfDeterminerRegistry.

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.

Parameters
schemaAn lsst::afw::table::Schema used to create the output lsst.afw.table.SourceCatalog
**kwargsKeyword 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.

Parameters
[in,out]exposureExposure to process; measured PSF will be added.
[in,out]sourcesMeasured 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.
[in]matchesa list of lsst.afw.table.ReferenceMatch objects (i.e. of lsst.afw.table.Match with first being of type lsst.afw.table.SimpleRecord and second type lsst.afw.table.SourceRecord — the reference object and detected object respectively) as returned by e.g. the AstrometryTask. Used by star selectors that choose to refer to an external catalog.
Returns
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.

Warning
The star selector and psf determiner registries should be modified to return a class which has a ConfigClass attribute and can be instantiated with a config. Until then, there's no obvious way to get a registry algorithm's Config from another Config.

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 measurePsfTask.py in the examples directory, and can be run as e.g.

1 examples/measurePsfTask.py --ds9

The example also runs SourceDetectionTask and SourceMeasurementTask; see meas_algorithms_measurement_Example for more explanation.

Import the tasks (there are some other standard imports; read the file to see them all):

1 from lsst.meas.algorithms.detection import SourceDetectionTask
2 from lsst.meas.base import SingleFrameMeasurementTask
3 from lsst.pipe.tasks.measurePsf import 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:

1  schema = afwTable.SourceTable.makeMinimalSchema()

We can now call the constructors for the tasks we need to find and characterize candidate PSF stars:

1  config = SourceDetectionTask.ConfigClass()
2  config.reEstimateBackground = False
3  detectionTask = SourceDetectionTask(config=config, schema=schema)
4 
5  config = SingleFrameMeasurementTask.ConfigClass()
6  # Use the minimum set of plugins required.
7  config.plugins.names.clear()
8  for plugin in ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_PixelFlags"]:
9  config.plugins.names.add(plugin)
10  config.plugins["base_CircularApertureFlux"].radii = [7.0]
11  config.slots.psfFlux = "base_CircularApertureFlux_7_0" # Use of the PSF flux is hardcoded in secondMomentStarSelector
12  measureTask = SingleFrameMeasurementTask(schema, config=config)

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:

1  config = MeasurePsfTask.ConfigClass()
2 
3  psfDeterminer = config.psfDeterminer.apply()
4  psfDeterminer.config.sizeCellX = 128
5  psfDeterminer.config.sizeCellY = 128
6  psfDeterminer.config.spatialOrder = 1
7  psfDeterminer.config.nEigenComponents = 3
8 
9  measurePsfTask = MeasurePsfTask(config=config, schema=schema)

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:

1  tab = afwTable.SourceTable.make(schema)

And process the image:

1  sources = detectionTask.run(tab, exposure, sigma=2).sources
2  measureTask.measure(exposure, sources)
3 
4  result = measurePsfTask.run(exposure, sources)

We can then unpack and use the results:

1  psf = result.psf
2  cellSet = result.cellSet

If you specified –ds9 you can see the PSF candidates:

1  if display: # display on ds9 (see also --debug argparse option)
2  frame = 1
3  ds9.mtv(exposure, frame=frame)
4 
5  with ds9.Buffering():
6  for s in sources:
7  xy = s.getCentroid()
8  ds9.dot('+', *xy, frame=frame)
9  if s.get("calib.psf.candidate"):
10  ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame)
11  if s.get("calib.psf.used"):
12  ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame)


To investigate the Debug variables, put something like

1 import lsstDebug
2 def DebugInfo(name):
3  di = lsstDebug.getInfo(name) # N.b. lsstDebug.Info(name) would call us recursively
4 
5  if name == "lsst.pipe.tasks.measurePsf" :
6  di.display = True
7  di.displayExposure = False # display the Exposure + spatialCells
8  di.displayPsfCandidates = True # show mosaic of candidates
9  di.displayPsfMosaic = True # show mosaic of reconstructed PSF(xy)
10  di.displayResiduals = True # show residuals
11  di.showBadCandidates = True # Include bad candidates
12  di.normalizeResiduals = False # Normalise residuals by object amplitude
13 
14  return di
15 
16 lsstDebug.Info = DebugInfo

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

Definition at line 41 of file measurePsf.py.

Constructor & Destructor Documentation

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

Create the detection task.

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

Parameters
schemaAn lsst::afw::table::Schema used to create the output lsst.afw.table.SourceCatalog
**kwargsKeyword 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 212 of file measurePsf.py.

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

Member Function Documentation

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

Measure the PSF.

Parameters
[in,out]exposureExposure to process; measured PSF will be added.
[in,out]sourcesMeasured 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.
[in]matchesa list of lsst.afw.table.ReferenceMatch objects (i.e. of lsst.afw.table.Match with first being of type lsst.afw.table.SimpleRecord and second type lsst.afw.table.SourceRecord — the reference object and detected object respectively) as returned by e.g. the AstrometryTask. Used by star selectors that choose to refer to an external catalog.
Returns
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 244 of file measurePsf.py.

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

Member Data Documentation

string lsst.pipe.tasks.measurePsf.MeasurePsfTask._DefaultName = "measurePsf"
staticprivate

Definition at line 210 of file measurePsf.py.

lsst.pipe.tasks.measurePsf.MeasurePsfTask.candidateKey

Definition at line 227 of file measurePsf.py.

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

Definition at line 209 of file measurePsf.py.

lsst.pipe.tasks.measurePsf.MeasurePsfTask.psfDeterminer

Definition at line 241 of file measurePsf.py.

lsst.pipe.tasks.measurePsf.MeasurePsfTask.starSelector

Definition at line 240 of file measurePsf.py.

lsst.pipe.tasks.measurePsf.MeasurePsfTask.usedKey

Definition at line 232 of file measurePsf.py.


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