lsst.ip.diffim gaa63f70f4e+5e034ae04a
Loading...
Searching...
No Matches
Static Public Attributes | Static Protected Attributes | List of all members
lsst.ip.diffim.dipoleMeasurement.DipoleMeasurementTask Class Reference
Inheritance diagram for lsst.ip.diffim.dipoleMeasurement.DipoleMeasurementTask:

Static Public Attributes

DipoleMeasurementConfig ConfigClass = DipoleMeasurementConfig
 

Static Protected Attributes

str _DefaultName = "dipoleMeasurement"
 

Detailed Description

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

Parameters
----------
sources : 'lsst.afw.table.SourceCatalog'
    Sources that will be measured
badFlags : `list` of `dict`
    A list of flags that will be used to determine if there was a measurement problem

Notes
-----
The list of badFlags will be used to make a list of keys to check for measurement flags on.  By
default the centroid keys are added to this list

Description

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

.. code-block:: py

    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.instFlux = 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 SingleFrameMeasurementTask, the same result may be acheived by
manually editing the config and running SingleFrameMeasurementTask. For example:

.. code-block:: py

    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.instFlux = None
    config.slots.shape = None
    config.slots.centroid = "ip_diffim_NaiveDipoleCentroid"
    config.doReplaceWithNoise = False

    schema = afwTable.SourceTable.makeMinimalSchema()
    task = SingleFrameMeasurementTask(schema, config=config)-

Debug variables

The ``lsst.pipe.base.cmdLineTask.CmdLineTask`` 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:

.. code-block:: py

    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          # display mask transparency
            di.displayDiaSources = True       # show exposure with dipole results
        return di
    lsstDebug.Info = DebugInfo
    lsstDebug.frame = 1

    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

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

.. code-block:: none

    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).

.. code-block:: py

    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:

.. code-block:: py

    def run(args):
        exposure = loadData(args.image)
        if args.debug:
            afwDisplay.Display(frame=1).mtv(exposure)

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

.. code-block:: py

    schema = afwTable.SourceTable.makeMinimalSchema()

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

.. code-block:: py

        # 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:

.. code-block:: py

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

Run detection:

.. code-block:: py

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

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

.. code-block:: py

    # 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:

.. code-block:: py

    measureTask.run(diaSources, exposure)

Optionally display debugging information:

.. code-block:: py

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

Definition at line 123 of file dipoleMeasurement.py.

Member Data Documentation

◆ _DefaultName

str lsst.ip.diffim.dipoleMeasurement.DipoleMeasurementTask._DefaultName = "dipoleMeasurement"
staticprotected

Definition at line 344 of file dipoleMeasurement.py.

◆ ConfigClass

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

Definition at line 343 of file dipoleMeasurement.py.


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