LSST Applications g0265f82a02+0e5473021a,g02d81e74bb+0dd8ce4237,g1470d8bcf6+3ea6592b6f,g2079a07aa2+86d27d4dc4,g2305ad1205+5ca4c0b359,g295015adf3+d10818ec9d,g2a9a014e59+6f9be1b9cd,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g3ddfee87b4+703ba97ebf,g487adcacf7+4fa16da234,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+ffa42b374e,g5a732f18d5+53520f316c,g64a986408d+0dd8ce4237,g858d7b2824+0dd8ce4237,g8a8a8dda67+585e252eca,g99cad8db69+d39438377f,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+f1d96605c8,gb0e22166c9+60f28cb32d,gb6a65358fc+0e5473021a,gba4ed39666+c2a2e4ac27,gbb8dafda3b+e5339d463f,gc120e1dc64+da31e9920e,gc28159a63d+0e5473021a,gcf0d15dbbd+703ba97ebf,gdaeeff99f8+f9a426f77a,ge6526c86ff+889fc9d533,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gf18bd8381d+7268b93478,gff1a9f87cc+0dd8ce4237,w.2024.16
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | Static Public Attributes | Protected Attributes | Static Protected Attributes | List of all members
lsst.pipe.tasks.characterizeImage.CharacterizeImageTask Class Reference
Inheritance diagram for lsst.pipe.tasks.characterizeImage.CharacterizeImageTask:

Public Member Functions

 __init__ (self, schema=None, **kwargs)
 
 runQuantum (self, butlerQC, inputRefs, outputRefs)
 
 run (self, exposure, background=None, idGenerator=None)
 
 detectMeasureAndEstimatePsf (self, exposure, idGenerator, background)
 
 display (self, itemName, exposure, sourceCat=None)
 

Public Attributes

 schema
 
 algMetadata
 
 outputSchema
 

Static Public Attributes

 ConfigClass = CharacterizeImageConfig
 

Protected Attributes

 _initialFrame
 
 _frame
 

Static Protected Attributes

str _DefaultName = "characterizeImage"
 

Detailed Description

Measure bright sources and use this to estimate background and PSF of
an exposure.

Given an exposure with defects repaired (masked and interpolated over,
e.g. as output by `~lsst.ip.isr.IsrTask`):
- detect and measure bright sources
- repair cosmic rays
- detect and mask streaks
- measure and subtract background
- measure PSF

Parameters
----------
schema : `lsst.afw.table.Schema`, optional
    Initial schema for icSrc catalog.
**kwargs
    Additional keyword arguments.

Notes
-----
Debugging:
CharacterizeImageTask has a debug dictionary with the following keys:

frame
    int: if specified, the frame of first debug image displayed (defaults to 1)
repair_iter
    bool; if True display image after each repair in the measure PSF loop
background_iter
    bool; if True display image after each background subtraction in the measure PSF loop
measure_iter
    bool; if True display image and sources at the end of each iteration of the measure PSF loop
    See `~lsst.meas.astrom.displayAstrometry` for the meaning of the various symbols.
psf
    bool; if True display image and sources after PSF is measured;
    this will be identical to the final image displayed by measure_iter if measure_iter is true
repair
    bool; if True display image and sources after final repair
measure
    bool; if True display image and sources after final measurement

Definition at line 265 of file characterizeImage.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.__init__ ( self,
schema = None,
** kwargs )

Definition at line 310 of file characterizeImage.py.

310 def __init__(self, schema=None, **kwargs):
311 super().__init__(**kwargs)
312
313 if schema is None:
314 schema = SourceTable.makeMinimalSchema()
315 self.schema = schema
316 self.makeSubtask("background")
317 self.makeSubtask("installSimplePsf")
318 self.makeSubtask("repair")
319 if self.config.doMaskStreaks:
320 self.makeSubtask("maskStreaks")
321 self.makeSubtask("measurePsf", schema=self.schema)
322 self.algMetadata = dafBase.PropertyList()
323 self.makeSubtask('detection', schema=self.schema)
324 if self.config.doDeblend:
325 self.makeSubtask("deblend", schema=self.schema)
326 self.makeSubtask('measurement', schema=self.schema, algMetadata=self.algMetadata)
327 if self.config.doApCorr:
328 self.makeSubtask('measureApCorr', schema=self.schema)
329 self.makeSubtask('applyApCorr', schema=self.schema)
330 self.makeSubtask('catalogCalculation', schema=self.schema)
331 self._initialFrame = getDebugFrame(self._display, "frame") or 1
332 self._frame = self._initialFrame
333 self.schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
334 self.outputSchema = afwTable.SourceCatalog(self.schema)
335
Class for storing ordered metadata with comments.

Member Function Documentation

◆ detectMeasureAndEstimatePsf()

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.detectMeasureAndEstimatePsf ( self,
exposure,
idGenerator,
background )
Perform one iteration of detect, measure, and estimate PSF.

Performs the following operations:

- if config.doMeasurePsf or not exposure.hasPsf():

    - install a simple PSF model (replacing the existing one, if need be)

- interpolate over cosmic rays with keepCRs=True
- estimate background and subtract it from the exposure
- detect, deblend and measure sources, and subtract a refined background model;
- if config.doMeasurePsf:
    - measure PSF

Parameters
----------
exposure : `lsst.afw.image.ExposureF`
    Exposure to characterize.
idGenerator : `lsst.meas.base.IdGenerator`
    Object that generates source IDs and provides RNG seeds.
background : `lsst.afw.math.BackgroundList`, optional
    Initial model of background already subtracted from exposure.

Returns
-------
result : `lsst.pipe.base.Struct`
    Results as a struct with attributes:

    ``exposure``
       Characterized exposure (`lsst.afw.image.ExposureF`).
    ``sourceCat``
       Detected sources (`lsst.afw.table.SourceCatalog`).
    ``background``
       Model of subtracted background (`lsst.afw.math.BackgroundList`).
    ``psfCellSet``
       Spatial cells of PSF candidates (`lsst.afw.math.SpatialCellSet`).

Raises
------
LengthError
    Raised if there are too many CR pixels.

Definition at line 460 of file characterizeImage.py.

460 def detectMeasureAndEstimatePsf(self, exposure, idGenerator, background):
461 """Perform one iteration of detect, measure, and estimate PSF.
462
463 Performs the following operations:
464
465 - if config.doMeasurePsf or not exposure.hasPsf():
466
467 - install a simple PSF model (replacing the existing one, if need be)
468
469 - interpolate over cosmic rays with keepCRs=True
470 - estimate background and subtract it from the exposure
471 - detect, deblend and measure sources, and subtract a refined background model;
472 - if config.doMeasurePsf:
473 - measure PSF
474
475 Parameters
476 ----------
477 exposure : `lsst.afw.image.ExposureF`
478 Exposure to characterize.
479 idGenerator : `lsst.meas.base.IdGenerator`
480 Object that generates source IDs and provides RNG seeds.
481 background : `lsst.afw.math.BackgroundList`, optional
482 Initial model of background already subtracted from exposure.
483
484 Returns
485 -------
486 result : `lsst.pipe.base.Struct`
487 Results as a struct with attributes:
488
489 ``exposure``
490 Characterized exposure (`lsst.afw.image.ExposureF`).
491 ``sourceCat``
492 Detected sources (`lsst.afw.table.SourceCatalog`).
493 ``background``
494 Model of subtracted background (`lsst.afw.math.BackgroundList`).
495 ``psfCellSet``
496 Spatial cells of PSF candidates (`lsst.afw.math.SpatialCellSet`).
497
498 Raises
499 ------
500 LengthError
501 Raised if there are too many CR pixels.
502 """
503 # install a simple PSF model, if needed or wanted
504 if not exposure.hasPsf() or (self.config.doMeasurePsf and self.config.useSimplePsf):
505 self.log.info("PSF estimation initialized with 'simple' PSF")
506 self.installSimplePsf.run(exposure=exposure)
507
508 # run repair, but do not interpolate over cosmic rays (do that elsewhere, with the final PSF model)
509 if self.config.requireCrForPsf:
510 self.repair.run(exposure=exposure, keepCRs=True)
511 else:
512 try:
513 self.repair.run(exposure=exposure, keepCRs=True)
514 except LengthError:
515 self.log.warning("Skipping cosmic ray detection: Too many CR pixels (max %0.f)",
516 self.config.repair.cosmicray.nCrPixelMax)
517
518 self.display("repair_iter", exposure=exposure)
519
520 if background is None:
521 background = BackgroundList()
522
523 sourceIdFactory = idGenerator.make_table_id_factory()
524 table = SourceTable.make(self.schema, sourceIdFactory)
525 table.setMetadata(self.algMetadata)
526
527 detRes = self.detection.run(table=table, exposure=exposure, doSmooth=True)
528 sourceCat = detRes.sources
529 if detRes.background:
530 for bg in detRes.background:
531 background.append(bg)
532
533 if self.config.doDeblend:
534 self.deblend.run(exposure=exposure, sources=sourceCat)
535 # We need the output catalog to be contiguous for further processing.
536 if not sourceCat.isContiguous():
537 sourceCat = sourceCat.copy(deep=True)
538
539 self.measurement.run(measCat=sourceCat, exposure=exposure, exposureId=idGenerator.catalog_id)
540
541 measPsfRes = pipeBase.Struct(cellSet=None)
542 if self.config.doMeasurePsf:
543 measPsfRes = self.measurePsf.run(exposure=exposure, sources=sourceCat,
544 expId=idGenerator.catalog_id)
545 self.display("measure_iter", exposure=exposure, sourceCat=sourceCat)
546
547 return pipeBase.Struct(
548 exposure=exposure,
549 sourceCat=sourceCat,
550 background=background,
551 psfCellSet=measPsfRes.cellSet,
552 )
553

◆ display()

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.display ( self,
itemName,
exposure,
sourceCat = None )
Display exposure and sources on next frame (for debugging).

Parameters
----------
itemName : `str`
    Name of item in ``debugInfo``.
exposure : `lsst.afw.image.ExposureF`
    Exposure to display.
sourceCat : `lsst.afw.table.SourceCatalog`, optional
    Catalog of sources detected on the exposure.

Definition at line 554 of file characterizeImage.py.

554 def display(self, itemName, exposure, sourceCat=None):
555 """Display exposure and sources on next frame (for debugging).
556
557 Parameters
558 ----------
559 itemName : `str`
560 Name of item in ``debugInfo``.
561 exposure : `lsst.afw.image.ExposureF`
562 Exposure to display.
563 sourceCat : `lsst.afw.table.SourceCatalog`, optional
564 Catalog of sources detected on the exposure.
565 """
566 val = getDebugFrame(self._display, itemName)
567 if not val:
568 return
569
570 displayAstrometry(exposure=exposure, sourceCat=sourceCat, frame=self._frame, pause=False)
571 self._frame += 1

◆ run()

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.run ( self,
exposure,
background = None,
idGenerator = None )
Characterize a science image.

Peforms the following operations:
- Iterate the following config.psfIterations times, or once if config.doMeasurePsf false:
    - detect and measure sources and estimate PSF (see detectMeasureAndEstimatePsf for details)
- interpolate over cosmic rays
- perform final measurement

Parameters
----------
exposure : `lsst.afw.image.ExposureF`
    Exposure to characterize.
background : `lsst.afw.math.BackgroundList`, optional
    Initial model of background already subtracted from exposure.
idGenerator : `lsst.meas.base.IdGenerator`, optional
    Object that generates source IDs and provides RNG seeds.

Returns
-------
result : `lsst.pipe.base.Struct`
    Results as a struct with attributes:

    ``exposure``
       Characterized exposure (`lsst.afw.image.ExposureF`).
    ``sourceCat``
       Detected sources (`lsst.afw.table.SourceCatalog`).
    ``background``
       Model of subtracted background (`lsst.afw.math.BackgroundList`).
    ``psfCellSet``
       Spatial cells of PSF candidates (`lsst.afw.math.SpatialCellSet`).
    ``characterized``
       Another reference to ``exposure`` for compatibility.
    ``backgroundModel``
       Another reference to ``background`` for compatibility.

Raises
------
RuntimeError
    Raised if PSF sigma is NaN.

Definition at line 344 of file characterizeImage.py.

344 def run(self, exposure, background=None, idGenerator=None):
345 """Characterize a science image.
346
347 Peforms the following operations:
348 - Iterate the following config.psfIterations times, or once if config.doMeasurePsf false:
349 - detect and measure sources and estimate PSF (see detectMeasureAndEstimatePsf for details)
350 - interpolate over cosmic rays
351 - perform final measurement
352
353 Parameters
354 ----------
355 exposure : `lsst.afw.image.ExposureF`
356 Exposure to characterize.
357 background : `lsst.afw.math.BackgroundList`, optional
358 Initial model of background already subtracted from exposure.
359 idGenerator : `lsst.meas.base.IdGenerator`, optional
360 Object that generates source IDs and provides RNG seeds.
361
362 Returns
363 -------
364 result : `lsst.pipe.base.Struct`
365 Results as a struct with attributes:
366
367 ``exposure``
368 Characterized exposure (`lsst.afw.image.ExposureF`).
369 ``sourceCat``
370 Detected sources (`lsst.afw.table.SourceCatalog`).
371 ``background``
372 Model of subtracted background (`lsst.afw.math.BackgroundList`).
373 ``psfCellSet``
374 Spatial cells of PSF candidates (`lsst.afw.math.SpatialCellSet`).
375 ``characterized``
376 Another reference to ``exposure`` for compatibility.
377 ``backgroundModel``
378 Another reference to ``background`` for compatibility.
379
380 Raises
381 ------
382 RuntimeError
383 Raised if PSF sigma is NaN.
384 """
385 self._frame = self._initialFrame # reset debug display frame
386
387 if not self.config.doMeasurePsf and not exposure.hasPsf():
388 self.log.info("CharacterizeImageTask initialized with 'simple' PSF.")
389 self.installSimplePsf.run(exposure=exposure)
390
391 if idGenerator is None:
392 idGenerator = IdGenerator()
393
394 # subtract an initial estimate of background level
395 background = self.background.run(exposure).background
396
397 psfIterations = self.config.psfIterations if self.config.doMeasurePsf else 1
398 for i in range(psfIterations):
399 dmeRes = self.detectMeasureAndEstimatePsf(
400 exposure=exposure,
401 idGenerator=idGenerator,
402 background=background,
403 )
404
405 psf = dmeRes.exposure.getPsf()
406 # Just need a rough estimate; average positions are fine
407 psfAvgPos = psf.getAveragePosition()
408 psfSigma = psf.computeShape(psfAvgPos).getDeterminantRadius()
409 psfDimensions = psf.computeImage(psfAvgPos).getDimensions()
410 medBackground = np.median(dmeRes.background.getImage().getArray())
411 self.log.info("iter %s; PSF sigma=%0.4f, dimensions=%s; median background=%0.2f",
412 i + 1, psfSigma, psfDimensions, medBackground)
413 if np.isnan(psfSigma):
414 raise RuntimeError("PSF sigma is NaN, cannot continue PSF determination.")
415
416 self.display("psf", exposure=dmeRes.exposure, sourceCat=dmeRes.sourceCat)
417
418 # perform final repair with final PSF
419 self.repair.run(exposure=dmeRes.exposure)
420 self.display("repair", exposure=dmeRes.exposure, sourceCat=dmeRes.sourceCat)
421
422 # mask streaks
423 if self.config.doMaskStreaks:
424 _ = self.maskStreaks.run(dmeRes.exposure)
425
426 # perform final measurement with final PSF, including measuring and applying aperture correction,
427 # if wanted
428 self.measurement.run(measCat=dmeRes.sourceCat, exposure=dmeRes.exposure,
429 exposureId=idGenerator.catalog_id)
430 if self.config.doApCorr:
431 try:
432 apCorrMap = self.measureApCorr.run(
433 exposure=dmeRes.exposure,
434 catalog=dmeRes.sourceCat,
435 ).apCorrMap
436 except MeasureApCorrError:
437 # We have failed to get a valid aperture correction map.
438 # Proceed with processing, and image will be filtered
439 # downstream.
440 dmeRes.exposure.info.setApCorrMap(None)
441 else:
442 dmeRes.exposure.info.setApCorrMap(apCorrMap)
443 self.applyApCorr.run(catalog=dmeRes.sourceCat, apCorrMap=exposure.getInfo().getApCorrMap())
444
445 self.catalogCalculation.run(dmeRes.sourceCat)
446
447 self.display("measure", exposure=dmeRes.exposure, sourceCat=dmeRes.sourceCat)
448
449 return pipeBase.Struct(
450 exposure=dmeRes.exposure,
451 sourceCat=dmeRes.sourceCat,
452 background=dmeRes.background,
453 psfCellSet=dmeRes.psfCellSet,
454
455 characterized=dmeRes.exposure,
456 backgroundModel=dmeRes.background
457 )
458

◆ runQuantum()

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.runQuantum ( self,
butlerQC,
inputRefs,
outputRefs )

Definition at line 336 of file characterizeImage.py.

336 def runQuantum(self, butlerQC, inputRefs, outputRefs):
337 inputs = butlerQC.get(inputRefs)
338 if 'idGenerator' not in inputs.keys():
339 inputs['idGenerator'] = self.config.idGenerator.apply(butlerQC.quantum.dataId)
340 outputs = self.run(**inputs)
341 butlerQC.put(outputs, outputRefs)
342

Member Data Documentation

◆ _DefaultName

str lsst.pipe.tasks.characterizeImage.CharacterizeImageTask._DefaultName = "characterizeImage"
staticprotected

Definition at line 308 of file characterizeImage.py.

◆ _frame

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask._frame
protected

Definition at line 332 of file characterizeImage.py.

◆ _initialFrame

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask._initialFrame
protected

Definition at line 331 of file characterizeImage.py.

◆ algMetadata

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.algMetadata

Definition at line 322 of file characterizeImage.py.

◆ ConfigClass

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.ConfigClass = CharacterizeImageConfig
static

Definition at line 307 of file characterizeImage.py.

◆ outputSchema

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.outputSchema

Definition at line 334 of file characterizeImage.py.

◆ schema

lsst.pipe.tasks.characterizeImage.CharacterizeImageTask.schema

Definition at line 315 of file characterizeImage.py.


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