SingleFrameMeasurementTask runs a set of (user-selectable) plugins, implementing particular measurement algorithms, to measure the properties of sources on a single image.

Processing Summary

The set of plugins to run is set in the task configuration. Each plugin defines the values that it measures (which correspond to columns in the output table), and then conducts measurement on each detected source. See SingleFramePlugin for details. This task intializes the set of plugins (thereby defining the catalog schema) from its configuration, then invokes each plugin on each source.

When run after the deblender (see lsst.meas.deblender.SourceDeblendTask), this task also replaces each source’s neighbors with noise before measuring each source, utilizing the heavy Footprints created during deblending (see NoiseReplacer).

Python API summary

from lsst.meas.base.sfm import SingleFrameMeasurementTask
classSingleFrameMeasurementTask(schema, algMetadata=None, **kwds)

A subtask for measuring the properties of sources on a single exposure...


Access configuration fields and retargetable subtasks.

methodrun(measCat, exposure, noiseImage=None, exposureId=None, beginOrder=None, endOrder=None)

Run single frame measurement over an exposure and source catalog...

See also

See the SingleFrameMeasurementTask API reference for complete details.

Configuration fields


Field type

bool Field

When measuring, replace other detected footprints with noise?


Data type


Field type


configuration that sets how to replace neighboring sources with noise


Data type


Field type


Mapping from algorithms to special aliases in Source.


Field type

str Field

Prefix to give undeblended plugins


Refer to examples/ for a complete, executable version of this example: the below presents only the key logic.

First, import the required tasks:

from lsst.meas.algorithms.detection import SourceDetectionTask
from lsst.meas.base import SingleFrameMeasurementTask

We need to create our tasks before processing any data as the task constructors can add extra columns to the schema. The most important argument we pass these to these is an lsst.afw.table.Schema object, which contains information about the fields (i.e. columns) of the measurement catalog we’ll create, including names, types, and additional documentation. Tasks that operate on a catalog are typically passed a schema upon construction, to which they add the fields they’ll fill later when run. We construct a mostly empty schema that contains just the fields required for a lsst.afw.table.SourceCatalog like this:

schema = afwTable.SourceTable.makeMinimalSchema()

Now we can configure and create the lsst.meas.algorithms.detection.SourceDetectionTask:

# Create the detection task
config = SourceDetectionTask.ConfigClass()
config.thresholdPolarity = "both"
config.background.isNanSafe = True
config.thresholdValue = 3
detectionTask = SourceDetectionTask(config=config, schema=schema)

We then move on to configuring the measurement task:

config = SingleFrameMeasurementTask.ConfigClass()

While a reasonable set of plugins is configured by default, we’ll customize the list. We also need to unset one of the slots at the same time, because we’re not running the algorithm that it’s set to by default, and that would cause problems later:

for plugin in ["base_SdssCentroid", "base_SdssShape",
               "base_CircularApertureFlux", "base_GaussianFlux"]:
    config.slots.psfFlux = None

Now, finally, we can construct the measurement task:

measureTask = SingleFrameMeasurementTask(schema, config=config)

After constructing all the tasks, we can inspect the Schema we’ve created:


All of the fields in the schema can be accessed via the get method on a record object. See lsst.afw.table for more information.

We’re now ready to process the data (we could loop over multiple exposures/catalogs using the same task objects). First create the output table and process the image to find sources:

tab = afwTable.SourceTable.make(schema)
sources = result.sources

Then measure them:, exposure)

We then might plot the results (e.g. if you set --doDisplay on the command line)

if display:
    # display image (see also --debug argparse option)
    frame = 1
    disp = afwDisplay.Display(frame=frame)

    with disp.Buffering():
        for s in sources:
            xy = s.getCentroid()
  '+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN)
  , *xy, ctype=afwDisplay.RED)

and end up with something like