lsst.ip.diffim  16.0-12-g1dc09ba+6
Static Public Attributes | List of all members
lsst.ip.diffim.dipoleMeasurement.DipoleMeasurementTask Class Reference

Measurement of Sources, specifically ones from difference images, for characterization as dipoles. More...

Inheritance diagram for lsst.ip.diffim.dipoleMeasurement.DipoleMeasurementTask:

Static Public Attributes

 ConfigClass = DipoleMeasurementConfig
 

Detailed Description

Measurement of Sources, specifically ones from difference images, for characterization as dipoles.

Contents

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Description

This class provides a default configuration for running Source measurement on image differences.

These default plugins include:

class DipoleMeasurementConfig(SingleFrameMeasurementConfig):
"""!Measurement of detected diaSources as dipoles"""
def setDefaults(self):
SingleFrameMeasurementConfig.setDefaults(self)
self.plugins = ["base_CircularApertureFlux",
"base_PixelFlags",
"base_SkyCoord",
"base_PsfFlux",
"ip_diffim_NaiveDipoleCentroid",
"ip_diffim_NaiveDipoleFlux",
"ip_diffim_PsfDipoleFlux",
"ip_diffim_ClassificationDipole",
]
self.slots.calibFlux = None
self.slots.modelFlux = None
self.slots.gaussianFlux = None
self.slots.shape = None
self.slots.centroid = "ip_diffim_NaiveDipoleCentroid"
self.doReplaceWithNoise = False

These plugins enabled by default allow the user to test the hypothesis that the Source is a dipole. This includes a set of measurements derived from intermediate base classes DipoleCentroidAlgorithm and DipoleFluxAlgorithm. Their respective algorithm control classes are defined in DipoleCentroidControl and DipoleFluxControl. Each centroid and flux measurement will have _neg (negative) and _pos (positive lobe) fields.

The first set of measurements uses a "naive" alrogithm for centroid and flux measurements, implemented in NaiveDipoleCentroidControl and NaiveDipoleFluxControl. The algorithm uses a naive 3x3 weighted moment around the nominal centroids of each peak in the Source Footprint. These algorithms fill the table fields ip_diffim_NaiveDipoleCentroid* and ip_diffim_NaiveDipoleFlux*

The second set of measurements undertakes a joint-Psf model on the negative and positive lobe simultaneously. This fit simultaneously solves for the negative and positive lobe centroids and fluxes using non-linear least squares minimization. The fields are stored in table elements ip_diffim_PsfDipoleFlux*.

Because this Task is just a config for SourceMeasurementTask, the same result may be acheived by manually editing the config and running SourceMeasurementTask. For example:

config = SingleFrameMeasurementConfig()
config.plugins.names = ["base_PsfFlux",
"ip_diffim_PsfDipoleFlux",
"ip_diffim_NaiveDipoleFlux",
"ip_diffim_NaiveDipoleCentroid",
"ip_diffim_ClassificationDipole",
"base_CircularApertureFlux",
"base_SkyCoord"]
config.slots.calibFlux = None
config.slots.modelFlux = None
config.slots.gaussianFlux = None
config.slots.shape = None
config.slots.centroid = "ip_diffim_NaiveDipoleCentroid"
config.doReplaceWithNoise = False
schema = afwTable.SourceTable.makeMinimalSchema()
task = SingleFrameMeasurementTask(schema, config=config)
task.run(sources, exposure)

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Task initialization

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Invoking the Task

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Configuration parameters

See DipoleMeasurementConfig

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Quantities set in Metadata

No specific values are set in the Task metadata. However, the Source schema are modified to store the results of the dipole-specific measurements.

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Debug variables

The command line task interface supports a flag -d/–debug to import debug.py from your PYTHONPATH. The relevant contents of debug.py for this Task include:

import sys
import lsstDebug
def DebugInfo(name):
di = lsstDebug.getInfo(name)
if name == "lsst.ip.diffim.dipoleMeasurement":
di.display = True # enable debug output
di.maskTransparency = 90 # ds9 mask transparency
di.displayDiaSources = True # show exposure with dipole results
return di
lsstDebug.Info = DebugInfo
lsstDebug.frame = 1

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

A complete example of using DipoleMeasurementTask

This code is dipoleMeasTask.py in the examples directory, and can be run as e.g.

examples/dipoleMeasTask.py
examples/dipoleMeasTask.py --debug
examples/dipoleMeasTask.py --debug --image /path/to/image.fits
Start the processing by parsing the command line, where the user has the option of enabling debugging output and/or sending their own image for demonstration (in case they have not downloaded the afwdata package).
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="Demonstrate the use of SourceDetectionTask and DipoleMeasurementTask")
parser.add_argument('--debug', '-d', action="store_true", help="Load debug.py?", default=False)
parser.add_argument("--image", "-i", help="User defined image", default=None)
args = parser.parse_args()
if args.debug:
try:
import debug
debug.lsstDebug.frame = 2
except ImportError as e:
print(e, file=sys.stderr)
run(args)

The processing occurs in the run function. We first extract an exposure from disk or afwdata, displaying it if requested:
def run(args):
exposure = loadData(args.image)
if args.debug:
ds9.mtv(exposure, frame=1)

Create a default source schema that we will append fields to as we add more algorithms:

schema = afwTable.SourceTable.makeMinimalSchema()

Create the detection and measurement Tasks, with some minor tweaking of their configs:

# Create the detection task
config = SourceDetectionTask.ConfigClass()
config.thresholdPolarity = "both"
config.background.isNanSafe = True
config.thresholdValue = 3
detectionTask = SourceDetectionTask(config=config, schema=schema)
# And the measurement Task
config = DipoleMeasurementTask.ConfigClass()
config.plugins.names.remove('base_SkyCoord')
algMetadata = dafBase.PropertyList()
measureTask = DipoleMeasurementTask(schema, algMetadata, config=config)

Having fully initialied the schema, we create a Source table from it:

# Create the output table
tab = afwTable.SourceTable.make(schema)

Run detection:

# Process the data
results = detectionTask.run(tab, exposure)

Because we are looking for dipoles, we need to merge the positive and negative detections:

# Merge the positve and negative sources
fpSet = results.fpSets.positive
growFootprint = 2
fpSet.merge(results.fpSets.negative, growFootprint, growFootprint, False)
diaSources = afwTable.SourceCatalog(tab)
fpSet.makeSources(diaSources)
print("Merged %s Sources into %d diaSources (from %d +ve, %d -ve)" % (len(results.sources),
len(diaSources),
results.fpSets.numPos,
results.fpSets.numNeg))

Finally, perform measurement (both standard and dipole-specialized) on the merged sources:

measureTask.run(diaSources, exposure)

Optionally display debugging information:

# Display dipoles if debug enabled
if args.debug:
dpa = DipoleAnalysis()
dpa.displayDipoles(exposure, diaSources)
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Definition at line 127 of file dipoleMeasurement.py.

Member Data Documentation

◆ ConfigClass

lsst.ip.diffim.dipoleMeasurement.DipoleMeasurementTask.ConfigClass = DipoleMeasurementConfig
static

Definition at line 297 of file dipoleMeasurement.py.


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