Skip to content

Commit

Permalink
Merge pull request #892 from lsst/tickets/DM-41600
Browse files Browse the repository at this point in the history
DM-41600: Write task topic page for CalibrateImageTask
  • Loading branch information
parejkoj committed Feb 23, 2024
2 parents 7be320c + 975ab76 commit e2eec9b
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 93 deletions.
9 changes: 3 additions & 6 deletions doc/lsst.pipe.tasks/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ Configurations
Python API reference
====================

.. automodapi:: lsst.pipe.tasks.assembleCoadd
:no-inheritance-diagram:

.. automodapi:: lsst.pipe.tasks.associationUtils
:no-inheritance-diagram:

Expand All @@ -84,6 +81,9 @@ Python API reference
.. automodapi:: lsst.pipe.tasks.calexpCutout
:no-inheritance-diagram:

.. automodapi:: lsst.pipe.tasks.calibrateImage
:no-inheritance-diagram:

.. automodapi:: lsst.pipe.tasks.calibrate
:no-inheritance-diagram:

Expand All @@ -105,9 +105,6 @@ Python API reference
.. automodapi:: lsst.pipe.tasks.cosmicRayPostDiff
:no-inheritance-diagram:

.. automodapi:: lsst.pipe.tasks.dcrAssembleCoadd
:no-inheritance-diagram:

.. automodapi:: lsst.pipe.tasks.deblendCoaddSourcesPipeline
:no-inheritance-diagram:

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
.. lsst-task-topic:: lsst.pipe.tasks.calibrateImage.CalibrateImageTask

##################
CalibrateImageTask
##################

`~lsst.pipe.tasks.calibrateImage.CalibrateImageTask` performs "single frame processing" on one (single *visit*) or two (two *snap* visit) post- :ref:`Instrument Signature Removal <lsst.ip.isr>` single detector exposure (``postISRCCD``).
This involves merging two *snaps* (if provided) into one *visit* exposure, repairing cosmic rays and defects, detecting and measuring sources on the exposure to make an initial estimation of the point spread function (PSF), re-doing detection and measurement with that fitted PSF to compute the astrometric and photometric calibrations, and computing summary statistics of the exposure and measured catalog.
Its primary outputs are a calibrated exposure (``initial_pvi``, pixel values in nanojansky) and catalog (``initial_stars_detector``) of bright (S/N >= 10) isolated point-like sources that were used as inputs to calibration and that are suitable for downstream use (for example as kernel candidates in difference imaging).
This task replaces the two older tasks `~lsst.pipe.tasks.characterizeImage.CharacterizeImageTask` (roughly repair/estimate PSF/aperture correct) and `~lsst.pipe.tasks.calibrate.CalibrateTask` (roughly detect/measure/astrometry/photometry).

.. _lsst.pipe.tasks.calibrateImage.CalibrateImageTask-summary:

Processing summary
==================

`~lsst.pipe.tasks.calibrateImage.CalibrateImageTask` runs this sequence of operations:

#. If two *snap* exposures are input, :py:class:`combine <lsst.pipe.tasks.snapCombine.SnapCombineTask>` them into one *visit* exposure.

#. Find stars to estimate the PSF, via two passes of repair/detect/measure/estimate PSF:

#. Install a simple Gaussian PSF in the exposure and subtract an initial estimate of the image background.

#. Perform cosmic ray :py:class:`repair <lsst.pipe.tasks.repair.RepairTask>`, source :py:class:`detection <lsst.meas.algorithms.SourceDetectionTask>` to :math:`S/N >= 50`, and a minimal list of :py:class:`measurement plugins <lsst.meas.base.sfm.SingleFrameMeasurementTask>` to compute a first :py:class:`estimate of the PSF <lsst.pipe.tasks.measurePsf.MeasurePsfTask>`.

#. Install an updated Gaussian PSF representation of that first PSF estimate (to reduce noise and help with convergence) and re-run repair/detect/measure/estimate PSF as above.

#. Use that final fitted PSF to redo repair and measurement (hopefully with all cosmic rays now removed), resulting in the optional ``initial_psf_stars_detector`` and ``initial_psf_stars_footprints_detector`` output catalogs. Note that these catalogs do not have sky coordinates or calibrated fluxes.

#. Compute an :py:class:`aperture correction <lsst.meas.algorithms.MeasureApCorrTask>` for the exposure using the final catalog measured after the PSF fit.

#. Find stars to use as potential calibration sources:

#. Detect sources with a peak :math:`S/N >= 10`.

#. :py:class:`Find potential streaks <lsst.pipe.tasks.maskStreaks.MaskStreaksTask>` on the image from the detection `Mask`_ computed above, and `Mask`_ those streaks on the exposure.

#. For the detected sources, :py:class:`deblend <lsst.meas.deblender.SourceDeblendTask>`, :py:class:`measure <lsst.meas.base.sfm.SingleFrameMeasurementTask>`, aperture correct, and set flags based on blendedness, footprint size, and other properties.

#. Select non-"bad" flagged, unresolved, :math:`S/N >= 10`, isolated sources to pass to the subsequent calibration steps and to be saved as the ``initial_stars_detector`` and ``initial_stars_footprints_detector`` output catalogs. Note that these catalogs do not have sky coordinates or calibrated fluxes: those are computed at a later step.

#. Match the list of stars from the two steps above, to propagate flags (e.g. ``calib_psf_candidate``, ``calib_psf_used``) from the psf stars catalog into the second, primary output catalog.

#. The steps above perform several rounds of background fitting, which together are saved as the ``initial_pvi_background`` output.

#. Fit the :py:class:`astrometry <lsst.meas.astrom.AstrometryTask>` to a reference catalog using an :py:class:`affine WCS fitter <lsst.meas.astrom.FitAffineWcsTask>` that requires a reasonable model of the :ref:`camera geometry <section_CameraGeom_Overview>`, to produce a `SkyWcs`_ for the exposure and compute on-sky coordinates for the catalog of stars. The star/refcat matches used in the astrometric fit is saved as the optional ``initial_astrometry_match_detector`` catalog.

#. Fit the :py:class:`photometry <lsst.pipe.tasks.photoCal.PhotoCalTask>` to a reference catalog, to produce a `PhotoCalib`_ for the exposure and calibrate both the image and catalog of stars to have pixels and fluxes respectively in nanojansky. Note that this results in the output exposure having a `PhotoCalib`_ identically 1; the applied `PhotoCalib`_ is saved as the ``initial_photoCalib_detector`` output. The star/refcat matches used in the photometric fit is saved as the optional ``initial_photometry_match_detector`` catalog.

#. Finally, the measurements and fits performed above are combined into a variety of summary statistics which are attached to the exposure, which is saved as the ``initial_pvi`` output.

.. _lsst.pipe.tasks.calibrateImage.CalibrateImageTask-api:

Python API summary
==================

.. lsst-task-api-summary:: lsst.pipe.tasks.calibrateImage.CalibrateImageTask

.. _lsst.pipe.tasks.calibrateImage.CalibrateImageTask-subtasks:

Retargetable subtasks
=====================

.. lsst-task-config-subtasks:: lsst.pipe.tasks.calibrateImage.CalibrateImageTask

.. _lsst.pipe.tasks.calibrateImage.CalibrateImageTask-configs:

Configuration fields
====================

.. lsst-task-config-fields:: lsst.pipe.tasks.calibrateImage.CalibrateImageTask

.. _Mask: http://doxygen.lsst.codes/stack/doxygen/x_masterDoxyDoc/classlsst_1_1afw_1_1image_1_1_mask.html#details
.. _SkyWcs: http://doxygen.lsst.codes/stack/doxygen/x_masterDoxyDoc/classlsst_1_1afw_1_1geom_1_1_sky_wcs.html#details
.. _PhotoCalib: http://doxygen.lsst.codes/stack/doxygen/x_masterDoxyDoc/classlsst_1_1afw_1_1image_1_1_photo_calib.html#details

This file was deleted.

3 changes: 2 additions & 1 deletion python/lsst/pipe/tasks/calibrateImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ class CalibrateImageConfig(pipeBase.PipelineTaskConfig, pipelineConnections=Cali
)
star_deblend = pexConfig.ConfigurableField(
target=lsst.meas.deblender.SourceDeblendTask,
doc="Split blended sources into their components"
doc="Split blended sources into their components."
)
star_measurement = pexConfig.ConfigurableField(
target=lsst.meas.base.SingleFrameMeasurementTask,
Expand Down Expand Up @@ -496,6 +496,7 @@ def run(self, *, exposures, id_generator=None):
self._measure_aperture_correction(exposure, psf_stars)

stars = self._find_stars(exposure, background, id_generator)
self._match_psf_stars(psf_stars, stars)

astrometry_matches, astrometry_meta = self._fit_astrometry(exposure, stars)
stars, photometry_matches, photometry_meta, photo_calib = self._fit_photometry(exposure, stars)
Expand Down
18 changes: 12 additions & 6 deletions tests/test_calibrateImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def setUp(self):
# Something about this test dataset prefers the older fluxRatio here.
self.config.star_catalog_calculation.plugins['base_ClassificationExtendedness'].fluxRatio = 0.925

def _check_run(self, calibrate, result, *, photo_calib):
def _check_run(self, calibrate, result):
"""Test the result of CalibrateImage.run().
Parameters
Expand All @@ -128,8 +128,6 @@ def _check_run(self, calibrate, result, *, photo_calib):
Configured task that had `run` called on it.
result : `lsst.pipe.base.Struct`
Result of calling calibrate.run().
photo_calib : `float`
Expected value of the PhotoCalib mean.
"""
# Background should have 4 elements: 3 from compute_psf and one from
# re-estimation during source detection.
Expand All @@ -143,13 +141,18 @@ def _check_run(self, calibrate, result, *, photo_calib):

# Returned photoCalib should be the applied value, not the ==1 one on the exposure.
self.assertFloatsAlmostEqual(result.applied_photo_calib.getCalibrationMean(),
photo_calib, rtol=2e-3)
self.photo_calib, rtol=2e-3)
# Should have flux/magnitudes in the afw and astropy catalogs
self.assertIn("slot_PsfFlux_flux", result.stars_footprints.schema)
self.assertIn("slot_PsfFlux_mag", result.stars_footprints.schema)
self.assertEqual(result.stars["slot_PsfFlux_flux"].unit, u.nJy)
self.assertEqual(result.stars["slot_PsfFlux_mag"].unit, u.ABmag)

# Should have detected all S/N >= 10 sources plus 2 sky sources, whether 1 or 2 snaps.
self.assertEqual(len(result.stars), 7)
# Did the psf flags get propagated from the psf_stars catalog?
self.assertEqual(result.stars["calib_psf_used"].sum(), 3)

# Check that all necessary fields are in the output.
lsst.pipe.base.testUtils.assertValidOutput(calibrate, result)

Expand All @@ -161,7 +164,7 @@ def test_run(self):
calibrate.photometry.match.setRefObjLoader(self.ref_loader)
result = calibrate.run(exposures=self.exposure)

self._check_run(calibrate, result, photo_calib=self.photo_calib)
self._check_run(calibrate, result)

def test_run_2_snaps(self):
"""Test that run() returns reasonable values to be butler put, when
Expand All @@ -170,9 +173,12 @@ def test_run_2_snaps(self):
calibrate = CalibrateImageTask(config=self.config)
calibrate.astrometry.setRefObjLoader(self.ref_loader)
calibrate.photometry.match.setRefObjLoader(self.ref_loader)
# Halve the flux in each exposure to get the expected visit sum.
self.exposure.image /= 2
self.exposure.variance /= 2
result = calibrate.run(exposures=[self.exposure, self.exposure])

self._check_run(calibrate, result, photo_calib=self.photo_calib/2)
self._check_run(calibrate, result)

def test_handle_snaps(self):
calibrate = CalibrateImageTask(config=self.config)
Expand Down

0 comments on commit e2eec9b

Please sign in to comment.