LSST Applications g0da5cf3356+25b44625d0,g17e5ecfddb+50a5ac4092,g1c76d35bf8+585f0f68a2,g295839609d+8ef6456700,g2e2c1a68ba+cc1f6f037e,g38293774b4+62d12e78cb,g3b44f30a73+2891c76795,g48ccf36440+885b902d19,g4b2f1765b6+0c565e8f25,g5320a0a9f6+bd4bf1dc76,g56364267ca+403c24672b,g56b687f8c9+585f0f68a2,g5c4744a4d9+78cd207961,g5ffd174ac0+bd4bf1dc76,g6075d09f38+3075de592a,g667d525e37+cacede5508,g6f3e93b5a3+da81c812ee,g71f27ac40c+cacede5508,g7212e027e3+eb621d73aa,g774830318a+18d2b9fa6c,g7985c39107+62d12e78cb,g79ca90bc5c+fa2cc03294,g881bdbfe6c+cacede5508,g91fc1fa0cf+82a115f028,g961520b1fb+2534687f64,g96f01af41f+f2060f23b6,g9ca82378b8+cacede5508,g9d27549199+78cd207961,gb065e2a02a+ad48cbcda4,gb1df4690d6+585f0f68a2,gb35d6563ee+62d12e78cb,gbc3249ced9+bd4bf1dc76,gbec6a3398f+bd4bf1dc76,gd01420fc67+bd4bf1dc76,gd59336e7c4+c7bb92e648,gf46e8334de+81c9a61069,gfed783d017+bd4bf1dc76,v25.0.1.rc3
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Public Attributes | Static Public Attributes | List of all members
lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask Class Reference
Inheritance diagram for lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask:
lsst.ip.diffim.psfMatch.PsfMatchTask lsst.ip.diffim.snapPsfMatch.SnapPsfMatchTask lsst.ip.diffim.zogy.ZogyImagePsfMatchTask

Public Member Functions

def __init__ (self, *args, **kwargs)
 
def getFwhmPix (self, psf, position=None)
 
def matchExposures (self, templateExposure, scienceExposure, templateFwhmPix=None, scienceFwhmPix=None, candidateList=None, doWarping=True, convolveTemplate=True)
 
def matchMaskedImages (self, templateMaskedImage, scienceMaskedImage, candidateList, templateFwhmPix=None, scienceFwhmPix=None)
 
def subtractExposures (self, templateExposure, scienceExposure, templateFwhmPix=None, scienceFwhmPix=None, candidateList=None, doWarping=True, convolveTemplate=True)
 
def subtractMaskedImages (self, templateMaskedImage, scienceMaskedImage, candidateList, templateFwhmPix=None, scienceFwhmPix=None)
 
def getSelectSources (self, exposure, sigma=None, doSmooth=True, idFactory=None)
 
def makeCandidateList (self, templateExposure, scienceExposure, kernelSize, candidateList=None)
 
def makeKernelBasisList (self, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, basisSigmaGauss=None, metadata=None)
 

Public Attributes

 kConfig
 
 background
 
 selectSchema
 
 selectAlgMetadata
 

Static Public Attributes

 ConfigClass = ImagePsfMatchConfig
 

Detailed Description

Psf-match two MaskedImages or Exposures using the sources in the images.

Parameters
----------
args :
    Arguments to be passed to lsst.ip.diffim.PsfMatchTask.__init__
kwargs :
    Keyword arguments to be passed to lsst.ip.diffim.PsfMatchTask.__init__

Notes
-----
Upon initialization, the kernel configuration is defined by self.config.kernel.active.
The task creates an lsst.afw.math.Warper from the subConfig self.config.kernel.active.warpingConfig.
A schema for the selection and measurement of candidate lsst.ip.diffim.KernelCandidates is
defined, and used to initize subTasks selectDetection (for candidate detection) and selectMeasurement
(for candidate measurement).

Description

Build a Psf-matching kernel using two input images, either as MaskedImages (in which case they need
to be astrometrically aligned) or Exposures (in which case astrometric alignment will happen by
default but may be turned off).  This requires a list of input Sources which may be provided
by the calling Task; if not, the Task will perform a coarse source detection
and selection for this purpose. Sources are vetted for signal-to-noise and masked pixels
(in both the template and science image), and substamps around each acceptable
source are extracted and used to create an instance of KernelCandidate.
Each KernelCandidate is then placed within a lsst.afw.math.SpatialCellSet, which is used by an ensemble of
lsst.afw.math.CandidateVisitor instances to build the Psf-matching kernel.   These visitors include, in
the order that they are called: BuildSingleKernelVisitor, KernelSumVisitor, BuildSpatialKernelVisitor,
and AssessSpatialKernelVisitor.

Sigma clipping of KernelCandidates is performed as follows:

- BuildSingleKernelVisitor, using the substamp diffim residuals from the per-source kernel fit,
    if PsfMatchConfig.singleKernelClipping is True
- KernelSumVisitor, using the mean and standard deviation of the kernel sum from all candidates,
    if PsfMatchConfig.kernelSumClipping is True
- AssessSpatialKernelVisitor, using the substamp diffim ressiduals from the spatial kernel fit,
    if PsfMatchConfig.spatialKernelClipping is True

The actual solving for the kernel (and differential background model) happens in
lsst.ip.diffim.PsfMatchTask._solve.  This involves a loop over the SpatialCellSet that first builds the
per-candidate matching kernel for the requested number of KernelCandidates per cell
(PsfMatchConfig.nStarPerCell).  The quality of this initial per-candidate difference image is examined,
using moments of the pixel residuals in the difference image normalized by the square root of the variance
(i.e. sigma); ideally this should follow a normal (0, 1) distribution,
but the rejection thresholds are set
by the config (PsfMatchConfig.candidateResidualMeanMax and PsfMatchConfig.candidateResidualStdMax).
All candidates that pass this initial build are then examined en masse to find the
mean/stdev of the kernel sums across all candidates.
Objects that are significantly above or below the mean,
typically due to variability or sources that are saturated in one image but not the other,
are also rejected.This threshold is defined by PsfMatchConfig.maxKsumSigma.
Finally, a spatial model is built using all currently-acceptable candidates,
and the spatial model used to derive a second set of (spatial) residuals
which are again used to reject bad candidates, using the same thresholds as above.

Invoking the Task

There is no run() method for this Task.  Instead there are 4 methods that
may be used to invoke the Psf-matching.  These are
`~lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.matchMaskedImages`,
`~lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.subtractMaskedImages`,
`~lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.matchExposures`, and
`~lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.subtractExposures`.

The methods that operate on lsst.afw.image.MaskedImage require that the images already be astrometrically
aligned, and are the same shape.  The methods that operate on lsst.afw.image.Exposure allow for the
input images to be misregistered and potentially be different sizes; by default a
lsst.afw.math.LanczosWarpingKernel is used to perform the astrometric alignment.  The methods
that "match" images return a Psf-matched image, while the methods that "subtract" images
return a Psf-matched and template subtracted image.

See each method's returned lsst.pipe.base.Struct for more details.

Debug variables

The ``pipetask`` command line interface supports a
flag --debug to import @b 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.psfMatch":
            di.display = True                 # enable debug output
            di.maskTransparency = 80          # display mask transparency
            di.displayCandidates = True       # show all the candidates and residuals
            di.displayKernelBasis = False     # show kernel basis functions
            di.displayKernelMosaic = True     # show kernel realized across the image
            di.plotKernelSpatialModel = False # show coefficients of spatial model
            di.showBadCandidates = True       # show the bad candidates (red) along with good (green)
        elif name == "lsst.ip.diffim.imagePsfMatch":
            di.display = True                 # enable debug output
            di.maskTransparency = 30          # display mask transparency
            di.displayTemplate = True         # show full (remapped) template
            di.displaySciIm = True            # show science image to match to
            di.displaySpatialCells = True     # show spatial cells
            di.displayDiffIm = True           # show difference image
            di.showBadCandidates = True       # show the bad candidates (red) along with good (green)
        elif name == "lsst.ip.diffim.diaCatalogSourceSelector":
            di.display = False                # enable debug output
            di.maskTransparency = 30          # display mask transparency
            di.displayExposure = True         # show exposure with candidates indicated
            di.pauseAtEnd = False             # pause when done
        return di
    lsstDebug.Info = DebugInfo
    lsstDebug.frame = 1

Note that if you want addional logging info, you may add to your scripts:

.. code-block:: py

    import lsst.utils.logging as logUtils
    logUtils.trace_set_at("lsst.ip.diffim", 4)

Examples
--------
A complete example of using ImagePsfMatchTask

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

.. code-block:: none

    examples/imagePsfMatchTask.py --debug
    examples/imagePsfMatchTask.py --debug --mode="matchExposures"
    examples/imagePsfMatchTask.py --debug --template /path/to/templateExp.fits
    --science /path/to/scienceExp.fits

Create a subclass of ImagePsfMatchTask that allows us to either match exposures, or subtract exposures:

.. code-block:: none

    class MyImagePsfMatchTask(ImagePsfMatchTask):

        def __init__(self, args, kwargs):
            ImagePsfMatchTask.__init__(self, args, kwargs)

        def run(self, templateExp, scienceExp, mode):
            if mode == "matchExposures":
                return self.matchExposures(templateExp, scienceExp)
            elif mode == "subtractExposures":
                return self.subtractExposures(templateExp, scienceExp)

And allow the user the freedom to either run the script in default mode,
or point to their own images on disk.
Note that these images must be readable as an lsst.afw.image.Exposure.

We have enabled some minor display debugging in this script via the --debug option.  However, if you
have an lsstDebug debug.py in your PYTHONPATH you will get additional debugging displays.  The following
block checks for this script:

.. code-block:: py

    if args.debug:
        try:
            import debug
            # Since I am displaying 2 images here, set the starting frame number for the LSST debug LSST
            debug.lsstDebug.frame = 3
        except ImportError as e:
            print(e, file=sys.stderr)

Finally, we call a run method that we define below.
First set up a Config and modify some of the parameters.
E.g. use an "Alard-Lupton" sum-of-Gaussian basis,
fit for a differential background, and use low order spatial
variation in the kernel and background:

.. code-block:: py

    def run(args):
    #
    # Create the Config and use sum of gaussian basis
    #
    config = ImagePsfMatchTask.ConfigClass()
    config.kernel.name = "AL"
    config.kernel.active.fitForBackground = True
    config.kernel.active.spatialKernelOrder = 1
    config.kernel.active.spatialBgOrder = 0

Make sure the images (if any) that were sent to the script exist on disk and are readable.  If no images
are sent, make some fake data up for the sake of this example script (have a look at the code if you want
more details on generateFakeImages):

.. code-block:: py

    # Run the requested method of the Task
    if args.template is not None and args.science is not None:
        if not os.path.isfile(args.template):
            raise FileNotFoundError("Template image %s does not exist" % (args.template))
        if not os.path.isfile(args.science):
            raise FileNotFoundError("Science image %s does not exist" % (args.science))
        try:
            templateExp = afwImage.ExposureF(args.template)
        except Exception as e:
            raise RuntimeError("Cannot read template image %s" % (args.template))
        try:
            scienceExp = afwImage.ExposureF(args.science)
        except Exception as e:
            raise RuntimeError("Cannot read science image %s" % (args.science))
    else:
        templateExp, scienceExp = generateFakeImages()
        config.kernel.active.sizeCellX = 128
        config.kernel.active.sizeCellY = 128

Create and run the Task:

.. code-block:: py

    # Create the Task
    psfMatchTask = MyImagePsfMatchTask(config=config)
    # Run the Task
    result = psfMatchTask.run(templateExp, scienceExp, args.mode)

And finally provide some optional debugging displays:

.. code-block:: py

    if args.debug:
    # See if the LSST debug has incremented the frame number; if not start with frame 3
    try:
        frame = debug.lsstDebug.frame + 1
    except Exception:
        frame = 3
    afwDisplay.Display(frame=frame).mtv(result.matchedExposure,
                                        title="Example script: Matched Template Image")
    if "subtractedExposure" in result.getDict():
        afwDisplay.Display(frame=frame + 1).mtv(result.subtractedExposure,
                                                title="Example script: Subtracted Image")

Definition at line 82 of file imagePsfMatch.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.__init__ (   self,
args,
**  kwargs 
)
Create the ImagePsfMatchTask.

Reimplemented from lsst.ip.diffim.psfMatch.PsfMatchTask.

Reimplemented in lsst.ip.diffim.zogy.ZogyImagePsfMatchTask.

Definition at line 319 of file imagePsfMatch.py.

319 def __init__(self, *args, **kwargs):
320 """Create the ImagePsfMatchTask.
321 """
322 PsfMatchTask.__init__(self, *args, **kwargs)
323 self.kConfig = self.config.kernel.active
324 self._warper = afwMath.Warper.fromConfig(self.kConfig.warpingConfig)
325 # the background subtraction task uses a config from an unusual location,
326 # so cannot easily be constructed with makeSubtask
327 self.background = SubtractBackgroundTask(config=self.kConfig.afwBackgroundConfig, name="background",
328 parentTask=self)
329 self.selectSchema = afwTable.SourceTable.makeMinimalSchema()
330 self.selectAlgMetadata = dafBase.PropertyList()
331 self.makeSubtask("selectDetection", schema=self.selectSchema)
332 self.makeSubtask("selectMeasurement", schema=self.selectSchema, algMetadata=self.selectAlgMetadata)
333
Class for storing ordered metadata with comments.
Definition: PropertyList.h:68

Member Function Documentation

◆ getFwhmPix()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.getFwhmPix (   self,
  psf,
  position = None 
)
Return the FWHM in pixels of a Psf.

Definition at line 334 of file imagePsfMatch.py.

334 def getFwhmPix(self, psf, position=None):
335 """Return the FWHM in pixels of a Psf.
336 """
337 if position is None:
338 position = psf.getAveragePosition()
339 sigPix = psf.computeShape(position).getDeterminantRadius()
340 return sigPix*sigma2fwhm
341

◆ getSelectSources()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.getSelectSources (   self,
  exposure,
  sigma = None,
  doSmooth = True,
  idFactory = None 
)
Get sources to use for Psf-matching.

This method runs detection and measurement on an exposure.
The returned set of sources will be used as candidates for
Psf-matching.

Parameters
----------
exposure : `lsst.afw.image.Exposure`
    Exposure on which to run detection/measurement
sigma : `float`
    Detection threshold
doSmooth : `bool`
    Whether or not to smooth the Exposure with Psf before detection
idFactory :
    Factory for the generation of Source ids

Returns
-------
selectSources :
    source catalog containing candidates for the Psf-matching

Definition at line 762 of file imagePsfMatch.py.

762 def getSelectSources(self, exposure, sigma=None, doSmooth=True, idFactory=None):
763 """Get sources to use for Psf-matching.
764
765 This method runs detection and measurement on an exposure.
766 The returned set of sources will be used as candidates for
767 Psf-matching.
768
769 Parameters
770 ----------
771 exposure : `lsst.afw.image.Exposure`
772 Exposure on which to run detection/measurement
773 sigma : `float`
774 Detection threshold
775 doSmooth : `bool`
776 Whether or not to smooth the Exposure with Psf before detection
777 idFactory :
778 Factory for the generation of Source ids
779
780 Returns
781 -------
782 selectSources :
783 source catalog containing candidates for the Psf-matching
784 """
785 if idFactory:
786 table = afwTable.SourceTable.make(self.selectSchema, idFactory)
787 else:
788 table = afwTable.SourceTable.make(self.selectSchema)
789 mi = exposure.getMaskedImage()
790
791 imArr = mi.getImage().getArray()
792 maskArr = mi.getMask().getArray()
793 miArr = np.ma.masked_array(imArr, mask=maskArr)
794 try:
795 fitBg = self.background.fitBackground(mi)
796 bkgd = fitBg.getImageF(self.background.config.algorithm,
797 self.background.config.undersampleStyle)
798 except Exception:
799 self.log.warning("Failed to get background model. Falling back to median background estimation")
800 bkgd = np.ma.median(miArr)
801
802 # Take off background for detection
803 mi -= bkgd
804 try:
805 table.setMetadata(self.selectAlgMetadata)
806 detRet = self.selectDetection.run(
807 table=table,
808 exposure=exposure,
809 sigma=sigma,
810 doSmooth=doSmooth
811 )
812 selectSources = detRet.sources
813 self.selectMeasurement.run(measCat=selectSources, exposure=exposure)
814 finally:
815 # Put back on the background in case it is needed down stream
816 mi += bkgd
817 del bkgd
818 return selectSources
819
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Definition: Exposure.h:72

◆ makeCandidateList()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.makeCandidateList (   self,
  templateExposure,
  scienceExposure,
  kernelSize,
  candidateList = None 
)
Make a list of acceptable KernelCandidates.

Accept or generate a list of candidate sources for
Psf-matching, and examine the Mask planes in both of the
images for indications of bad pixels

Parameters
----------
templateExposure : `lsst.afw.image.Exposure`
    Exposure that will be convolved
scienceExposure : `lsst.afw.image.Exposure`
    Exposure that will be matched-to
kernelSize : `float`
    Dimensions of the Psf-matching Kernel, used to grow detection footprints
candidateList : `list`, optional
    List of Sources to examine. Elements must be of type afw.table.Source
    or a type that wraps a Source and has a getSource() method, such as
    meas.algorithms.PsfCandidateF.

Returns
-------
candidateList : `list` of `dict`
    A list of dicts having a "source" and "footprint"
    field for the Sources deemed to be appropriate for Psf
    matching

Definition at line 820 of file imagePsfMatch.py.

820 def makeCandidateList(self, templateExposure, scienceExposure, kernelSize, candidateList=None):
821 """Make a list of acceptable KernelCandidates.
822
823 Accept or generate a list of candidate sources for
824 Psf-matching, and examine the Mask planes in both of the
825 images for indications of bad pixels
826
827 Parameters
828 ----------
829 templateExposure : `lsst.afw.image.Exposure`
830 Exposure that will be convolved
831 scienceExposure : `lsst.afw.image.Exposure`
832 Exposure that will be matched-to
833 kernelSize : `float`
834 Dimensions of the Psf-matching Kernel, used to grow detection footprints
835 candidateList : `list`, optional
836 List of Sources to examine. Elements must be of type afw.table.Source
837 or a type that wraps a Source and has a getSource() method, such as
838 meas.algorithms.PsfCandidateF.
839
840 Returns
841 -------
842 candidateList : `list` of `dict`
843 A list of dicts having a "source" and "footprint"
844 field for the Sources deemed to be appropriate for Psf
845 matching
846 """
847 if candidateList is None:
848 candidateList = self.getSelectSources(scienceExposure)
849
850 if len(candidateList) < 1:
851 raise RuntimeError("No candidates in candidateList")
852
853 listTypes = set(type(x) for x in candidateList)
854 if len(listTypes) > 1:
855 raise RuntimeError("Candidate list contains mixed types: %s" % [t for t in listTypes])
856
857 if not isinstance(candidateList[0], afwTable.SourceRecord):
858 try:
859 candidateList[0].getSource()
860 except Exception as e:
861 raise RuntimeError(f"Candidate List is of type: {type(candidateList[0])} "
862 "Can only make candidate list from list of afwTable.SourceRecords, "
863 f"measAlg.PsfCandidateF or other type with a getSource() method: {e}")
864 candidateList = [c.getSource() for c in candidateList]
865
866 candidateList = diffimTools.sourceToFootprintList(candidateList,
867 templateExposure, scienceExposure,
868 kernelSize,
869 self.kConfig.detectionConfig,
870 self.log)
871 if len(candidateList) == 0:
872 raise RuntimeError("Cannot find any objects suitable for KernelCandidacy")
873
874 return candidateList
875
table::Key< int > type
Definition: Detector.cc:163
Record class that contains measurements made on a single exposure.
Definition: Source.h:78
daf::base::PropertySet * set
Definition: fits.cc:927

◆ makeKernelBasisList()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.makeKernelBasisList (   self,
  targetFwhmPix = None,
  referenceFwhmPix = None,
  basisDegGauss = None,
  basisSigmaGauss = None,
  metadata = None 
)
Wrapper to set log messages for
`lsst.ip.diffim.makeKernelBasisList`.

Parameters
----------
targetFwhmPix : `float`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
referenceFwhmPix : `float`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
basisDegGauss : `list` of `int`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
basisSigmaGauss : `list` of `int`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.
metadata : `lsst.daf.base.PropertySet`, optional
    Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
    Not used for delta function basis sets.

Returns
-------
basisList: `list` of `lsst.afw.math.kernel.FixedKernel`
    List of basis kernels.

Definition at line 876 of file imagePsfMatch.py.

877 basisDegGauss=None, basisSigmaGauss=None, metadata=None):
878 """Wrapper to set log messages for
880
881 Parameters
882 ----------
883 targetFwhmPix : `float`, optional
884 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
885 Not used for delta function basis sets.
886 referenceFwhmPix : `float`, optional
887 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
888 Not used for delta function basis sets.
889 basisDegGauss : `list` of `int`, optional
890 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
891 Not used for delta function basis sets.
892 basisSigmaGauss : `list` of `int`, optional
893 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
894 Not used for delta function basis sets.
895 metadata : `lsst.daf.base.PropertySet`, optional
896 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
897 Not used for delta function basis sets.
898
899 Returns
900 -------
901 basisList: `list` of `lsst.afw.math.kernel.FixedKernel`
902 List of basis kernels.
903 """
904 basisList = makeKernelBasisList(self.kConfig,
905 targetFwhmPix=targetFwhmPix,
906 referenceFwhmPix=referenceFwhmPix,
907 basisDegGauss=basisDegGauss,
908 basisSigmaGauss=basisSigmaGauss,
909 metadata=metadata)
910 if targetFwhmPix == referenceFwhmPix:
911 self.log.info("Target and reference psf fwhms are equal, falling back to config values")
912 elif referenceFwhmPix > targetFwhmPix:
913 self.log.info("Reference psf fwhm is the greater, normal convolution mode")
914 else:
915 self.log.info("Target psf fwhm is the greater, deconvolution mode")
916
917 return basisList
918
Class for storing generic metadata.
Definition: PropertySet.h:66

◆ matchExposures()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.matchExposures (   self,
  templateExposure,
  scienceExposure,
  templateFwhmPix = None,
  scienceFwhmPix = None,
  candidateList = None,
  doWarping = True,
  convolveTemplate = True 
)
Warp and PSF-match an exposure to the reference.

Do the following, in order:

- Warp templateExposure to match scienceExposure,
    if doWarping True and their WCSs do not already match
- Determine a PSF matching kernel and differential background model
    that matches templateExposure to scienceExposure
- Convolve templateExposure by PSF matching kernel

Parameters
----------
templateExposure : `lsst.afw.image.Exposure`
    Exposure to warp and PSF-match to the reference masked image
scienceExposure : `lsst.afw.image.Exposure`
    Exposure whose WCS and PSF are to be matched to
templateFwhmPix :`float`
    FWHM (in pixels) of the Psf in the template image (image to convolve)
scienceFwhmPix : `float`
    FWHM (in pixels) of the Psf in the science image
candidateList : `list`, optional
    a list of footprints/maskedImages for kernel candidates;
    if `None` then source detection is run.

    - Currently supported: list of Footprints or measAlg.PsfCandidateF

doWarping : `bool`
    what to do if ``templateExposure`` and ``scienceExposure`` WCSs do not match:

    - if `True` then warp ``templateExposure`` to match ``scienceExposure``
    - if `False` then raise an Exception

convolveTemplate : `bool`
    Whether to convolve the template image or the science image:

    - if `True`, ``templateExposure`` is warped if doWarping,
      ``templateExposure`` is convolved
    - if `False`, ``templateExposure`` is warped if doWarping,
      ``scienceExposure`` is convolved

Returns
-------
results : `lsst.pipe.base.Struct`
    An `lsst.pipe.base.Struct` containing these fields:

    - ``matchedImage`` : the PSF-matched exposure =
        Warped ``templateExposure`` convolved by psfMatchingKernel. This has:

        - the same parent bbox, Wcs and PhotoCalib as scienceExposure
        - the same filter as templateExposure
        - no Psf (because the PSF-matching process does not compute one)

    - ``psfMatchingKernel`` : the PSF matching kernel
    - ``backgroundModel`` : differential background model
    - ``kernelCellSet`` : SpatialCellSet used to solve for the PSF matching kernel

Raises
------
RuntimeError
   Raised if doWarping is False and ``templateExposure`` and
   ``scienceExposure`` WCSs do not match

Definition at line 343 of file imagePsfMatch.py.

345 candidateList=None, doWarping=True, convolveTemplate=True):
346 """Warp and PSF-match an exposure to the reference.
347
348 Do the following, in order:
349
350 - Warp templateExposure to match scienceExposure,
351 if doWarping True and their WCSs do not already match
352 - Determine a PSF matching kernel and differential background model
353 that matches templateExposure to scienceExposure
354 - Convolve templateExposure by PSF matching kernel
355
356 Parameters
357 ----------
358 templateExposure : `lsst.afw.image.Exposure`
359 Exposure to warp and PSF-match to the reference masked image
360 scienceExposure : `lsst.afw.image.Exposure`
361 Exposure whose WCS and PSF are to be matched to
362 templateFwhmPix :`float`
363 FWHM (in pixels) of the Psf in the template image (image to convolve)
364 scienceFwhmPix : `float`
365 FWHM (in pixels) of the Psf in the science image
366 candidateList : `list`, optional
367 a list of footprints/maskedImages for kernel candidates;
368 if `None` then source detection is run.
369
370 - Currently supported: list of Footprints or measAlg.PsfCandidateF
371
372 doWarping : `bool`
373 what to do if ``templateExposure`` and ``scienceExposure`` WCSs do not match:
374
375 - if `True` then warp ``templateExposure`` to match ``scienceExposure``
376 - if `False` then raise an Exception
377
378 convolveTemplate : `bool`
379 Whether to convolve the template image or the science image:
380
381 - if `True`, ``templateExposure`` is warped if doWarping,
382 ``templateExposure`` is convolved
383 - if `False`, ``templateExposure`` is warped if doWarping,
384 ``scienceExposure`` is convolved
385
386 Returns
387 -------
388 results : `lsst.pipe.base.Struct`
389 An `lsst.pipe.base.Struct` containing these fields:
390
391 - ``matchedImage`` : the PSF-matched exposure =
392 Warped ``templateExposure`` convolved by psfMatchingKernel. This has:
393
394 - the same parent bbox, Wcs and PhotoCalib as scienceExposure
395 - the same filter as templateExposure
396 - no Psf (because the PSF-matching process does not compute one)
397
398 - ``psfMatchingKernel`` : the PSF matching kernel
399 - ``backgroundModel`` : differential background model
400 - ``kernelCellSet`` : SpatialCellSet used to solve for the PSF matching kernel
401
402 Raises
403 ------
404 RuntimeError
405 Raised if doWarping is False and ``templateExposure`` and
406 ``scienceExposure`` WCSs do not match
407 """
408 if not self._validateWcs(templateExposure, scienceExposure):
409 if doWarping:
410 self.log.info("Astrometrically registering template to science image")
411 templatePsf = templateExposure.getPsf()
412 # Warp PSF before overwriting exposure
413 xyTransform = afwGeom.makeWcsPairTransform(templateExposure.getWcs(),
414 scienceExposure.getWcs())
415 psfWarped = WarpedPsf(templatePsf, xyTransform)
416 templateExposure = self._warper.warpExposure(scienceExposure.getWcs(),
417 templateExposure,
418 destBBox=scienceExposure.getBBox())
419 templateExposure.setPsf(psfWarped)
420 else:
421 self.log.error("ERROR: Input images not registered")
422 raise RuntimeError("Input images not registered")
423
424 if templateFwhmPix is None:
425 if not templateExposure.hasPsf():
426 self.log.warning("No estimate of Psf FWHM for template image")
427 else:
428 templateFwhmPix = self.getFwhmPix(templateExposure.getPsf())
429 self.log.info("templateFwhmPix: %s", templateFwhmPix)
430
431 if scienceFwhmPix is None:
432 if not scienceExposure.hasPsf():
433 self.log.warning("No estimate of Psf FWHM for science image")
434 else:
435 scienceFwhmPix = self.getFwhmPix(scienceExposure.getPsf())
436 self.log.info("scienceFwhmPix: %s", scienceFwhmPix)
437
438 if convolveTemplate:
439 kernelSize = self.makeKernelBasisList(templateFwhmPix, scienceFwhmPix)[0].getWidth()
440 candidateList = self.makeCandidateList(
441 templateExposure, scienceExposure, kernelSize, candidateList)
442 results = self.matchMaskedImages(
443 templateExposure.getMaskedImage(), scienceExposure.getMaskedImage(), candidateList,
444 templateFwhmPix=templateFwhmPix, scienceFwhmPix=scienceFwhmPix)
445 else:
446 kernelSize = self.makeKernelBasisList(scienceFwhmPix, templateFwhmPix)[0].getWidth()
447 candidateList = self.makeCandidateList(
448 templateExposure, scienceExposure, kernelSize, candidateList)
449 results = self.matchMaskedImages(
450 scienceExposure.getMaskedImage(), templateExposure.getMaskedImage(), candidateList,
451 templateFwhmPix=scienceFwhmPix, scienceFwhmPix=templateFwhmPix)
452
453 psfMatchedExposure = afwImage.makeExposure(results.matchedImage, scienceExposure.getWcs())
454 psfMatchedExposure.setFilter(templateExposure.getFilter())
455 psfMatchedExposure.setPhotoCalib(scienceExposure.getPhotoCalib())
456 results.warpedExposure = templateExposure
457 results.matchedExposure = psfMatchedExposure
458 return results
459
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
A Transform obtained by putting two SkyWcs objects "back to back".
Definition: SkyWcs.cc:146
std::shared_ptr< Exposure< ImagePixelT, MaskPixelT, VariancePixelT > > makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, std::shared_ptr< geom::SkyWcs const > wcs=std::shared_ptr< geom::SkyWcs const >())
A function to return an Exposure of the correct type (cf.
Definition: Exposure.h:445

◆ matchMaskedImages()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.matchMaskedImages (   self,
  templateMaskedImage,
  scienceMaskedImage,
  candidateList,
  templateFwhmPix = None,
  scienceFwhmPix = None 
)
PSF-match a MaskedImage (templateMaskedImage) to a reference MaskedImage (scienceMaskedImage).

Do the following, in order:

- Determine a PSF matching kernel and differential background model
    that matches templateMaskedImage to scienceMaskedImage
- Convolve templateMaskedImage by the PSF matching kernel

Parameters
----------
templateMaskedImage : `lsst.afw.image.MaskedImage`
    masked image to PSF-match to the reference masked image;
    must be warped to match the reference masked image
scienceMaskedImage : `lsst.afw.image.MaskedImage`
    maskedImage whose PSF is to be matched to
templateFwhmPix : `float`
    FWHM (in pixels) of the Psf in the template image (image to convolve)
scienceFwhmPix : `float`
    FWHM (in pixels) of the Psf in the science image
candidateList : `list`, optional
    A list of footprints/maskedImages for kernel candidates;
    if `None` then source detection is run.

    - Currently supported: list of Footprints or measAlg.PsfCandidateF

Returns
-------
result : `callable`
An `lsst.pipe.base.Struct` containing these fields:

- psfMatchedMaskedImage: the PSF-matched masked image =
    ``templateMaskedImage`` convolved with psfMatchingKernel.
    This has the same xy0, dimensions and wcs as ``scienceMaskedImage``.
- psfMatchingKernel: the PSF matching kernel
- backgroundModel: differential background model
- kernelCellSet: SpatialCellSet used to solve for the PSF matching kernel

Raises
------
RuntimeError
    Raised if input images have different dimensions

Definition at line 461 of file imagePsfMatch.py.

462 templateFwhmPix=None, scienceFwhmPix=None):
463 """PSF-match a MaskedImage (templateMaskedImage) to a reference MaskedImage (scienceMaskedImage).
464
465 Do the following, in order:
466
467 - Determine a PSF matching kernel and differential background model
468 that matches templateMaskedImage to scienceMaskedImage
469 - Convolve templateMaskedImage by the PSF matching kernel
470
471 Parameters
472 ----------
473 templateMaskedImage : `lsst.afw.image.MaskedImage`
474 masked image to PSF-match to the reference masked image;
475 must be warped to match the reference masked image
476 scienceMaskedImage : `lsst.afw.image.MaskedImage`
477 maskedImage whose PSF is to be matched to
478 templateFwhmPix : `float`
479 FWHM (in pixels) of the Psf in the template image (image to convolve)
480 scienceFwhmPix : `float`
481 FWHM (in pixels) of the Psf in the science image
482 candidateList : `list`, optional
483 A list of footprints/maskedImages for kernel candidates;
484 if `None` then source detection is run.
485
486 - Currently supported: list of Footprints or measAlg.PsfCandidateF
487
488 Returns
489 -------
490 result : `callable`
491 An `lsst.pipe.base.Struct` containing these fields:
492
493 - psfMatchedMaskedImage: the PSF-matched masked image =
494 ``templateMaskedImage`` convolved with psfMatchingKernel.
495 This has the same xy0, dimensions and wcs as ``scienceMaskedImage``.
496 - psfMatchingKernel: the PSF matching kernel
497 - backgroundModel: differential background model
498 - kernelCellSet: SpatialCellSet used to solve for the PSF matching kernel
499
500 Raises
501 ------
502 RuntimeError
503 Raised if input images have different dimensions
504 """
505 import lsstDebug
506 display = lsstDebug.Info(__name__).display
507 displayTemplate = lsstDebug.Info(__name__).displayTemplate
508 displaySciIm = lsstDebug.Info(__name__).displaySciIm
509 displaySpatialCells = lsstDebug.Info(__name__).displaySpatialCells
510 maskTransparency = lsstDebug.Info(__name__).maskTransparency
511 if not maskTransparency:
512 maskTransparency = 0
513 if display:
514 afwDisplay.setDefaultMaskTransparency(maskTransparency)
515
516 if not candidateList:
517 raise RuntimeError("Candidate list must be populated by makeCandidateList")
518
519 if not self._validateSize(templateMaskedImage, scienceMaskedImage):
520 self.log.error("ERROR: Input images different size")
521 raise RuntimeError("Input images different size")
522
523 if display and displayTemplate:
524 disp = afwDisplay.Display(frame=lsstDebug.frame)
525 disp.mtv(templateMaskedImage, title="Image to convolve")
526 lsstDebug.frame += 1
527
528 if display and displaySciIm:
529 disp = afwDisplay.Display(frame=lsstDebug.frame)
530 disp.mtv(scienceMaskedImage, title="Image to not convolve")
531 lsstDebug.frame += 1
532
533 kernelCellSet = self._buildCellSet(templateMaskedImage,
534 scienceMaskedImage,
535 candidateList)
536
537 if display and displaySpatialCells:
538 diffimUtils.showKernelSpatialCells(scienceMaskedImage, kernelCellSet,
539 symb="o", ctype=afwDisplay.CYAN, ctypeUnused=afwDisplay.YELLOW,
540 ctypeBad=afwDisplay.RED, size=4, frame=lsstDebug.frame,
541 title="Image to not convolve")
542 lsstDebug.frame += 1
543
544 if templateFwhmPix and scienceFwhmPix:
545 self.log.info("Matching Psf FWHM %.2f -> %.2f pix", templateFwhmPix, scienceFwhmPix)
546
547 if self.kConfig.useBicForKernelBasis:
548 tmpKernelCellSet = self._buildCellSet(templateMaskedImage,
549 scienceMaskedImage,
550 candidateList)
551 nbe = diffimTools.NbasisEvaluator(self.kConfig, templateFwhmPix, scienceFwhmPix)
552 bicDegrees = nbe(tmpKernelCellSet, self.log)
553 basisList = self.makeKernelBasisList(templateFwhmPix, scienceFwhmPix,
554 basisDegGauss=bicDegrees[0], metadata=self.metadata)
555 del tmpKernelCellSet
556 else:
557 basisList = self.makeKernelBasisList(templateFwhmPix, scienceFwhmPix,
558 metadata=self.metadata)
559
560 spatialSolution, psfMatchingKernel, backgroundModel = self._solve(kernelCellSet, basisList)
561
562 psfMatchedMaskedImage = afwImage.MaskedImageF(templateMaskedImage.getBBox())
563 convolutionControl = afwMath.ConvolutionControl()
564 convolutionControl.setDoNormalize(False)
565 afwMath.convolve(psfMatchedMaskedImage, templateMaskedImage, psfMatchingKernel, convolutionControl)
566 return pipeBase.Struct(
567 matchedImage=psfMatchedMaskedImage,
568 psfMatchingKernel=psfMatchingKernel,
569 backgroundModel=backgroundModel,
570 kernelCellSet=kernelCellSet,
571 )
572
A class to manipulate images, masks, and variance as a single object.
Definition: MaskedImage.h:74
Parameters to control convolution.
Definition: ConvolveImage.h:50
void convolve(OutImageT &convolvedImage, InImageT const &inImage, KernelT const &kernel, ConvolutionControl const &convolutionControl=ConvolutionControl())
Convolve an Image or MaskedImage with a Kernel, setting pixels of an existing output image.

◆ subtractExposures()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.subtractExposures (   self,
  templateExposure,
  scienceExposure,
  templateFwhmPix = None,
  scienceFwhmPix = None,
  candidateList = None,
  doWarping = True,
  convolveTemplate = True 
)
Register, Psf-match and subtract two Exposures.

Do the following, in order:

- Warp templateExposure to match scienceExposure, if their WCSs do not already match
- Determine a PSF matching kernel and differential background model
    that matches templateExposure to scienceExposure
- PSF-match templateExposure to scienceExposure
- Compute subtracted exposure (see return values for equation).

Parameters
----------
templateExposure : `lsst.afw.image.ExposureF`
    Exposure to PSF-match to scienceExposure
scienceExposure : `lsst.afw.image.ExposureF`
    Reference Exposure
templateFwhmPix : `float`
    FWHM (in pixels) of the Psf in the template image (image to convolve)
scienceFwhmPix : `float`
    FWHM (in pixels) of the Psf in the science image
candidateList : `list`, optional
    A list of footprints/maskedImages for kernel candidates;
    if `None` then source detection is run.

    - Currently supported: list of Footprints or measAlg.PsfCandidateF

doWarping : `bool`
    What to do if ``templateExposure``` and ``scienceExposure`` WCSs do
    not match:

    - if `True` then warp ``templateExposure`` to match ``scienceExposure``
    - if `False` then raise an Exception

convolveTemplate : `bool`
    Convolve the template image or the science image

    - if `True`, ``templateExposure`` is warped if doWarping,
      ``templateExposure`` is convolved
    - if `False`, ``templateExposure`` is warped if doWarping,
      ``scienceExposure is`` convolved

Returns
-------
result : `lsst.pipe.base.Struct`
    An `lsst.pipe.base.Struct` containing these fields:

    - ``subtractedExposure`` : subtracted Exposure
        scienceExposure - (matchedImage + backgroundModel)
    - ``matchedImage`` : ``templateExposure`` after warping to match
                         ``templateExposure`` (if doWarping true),
                         and convolving with psfMatchingKernel
    - ``psfMatchingKernel`` : PSF matching kernel
    - ``backgroundModel`` : differential background model
    - ``kernelCellSet`` : SpatialCellSet used to determine PSF matching kernel

Reimplemented in lsst.ip.diffim.zogy.ZogyImagePsfMatchTask, and lsst.ip.diffim.snapPsfMatch.SnapPsfMatchTask.

Definition at line 574 of file imagePsfMatch.py.

576 candidateList=None, doWarping=True, convolveTemplate=True):
577 """Register, Psf-match and subtract two Exposures.
578
579 Do the following, in order:
580
581 - Warp templateExposure to match scienceExposure, if their WCSs do not already match
582 - Determine a PSF matching kernel and differential background model
583 that matches templateExposure to scienceExposure
584 - PSF-match templateExposure to scienceExposure
585 - Compute subtracted exposure (see return values for equation).
586
587 Parameters
588 ----------
589 templateExposure : `lsst.afw.image.ExposureF`
590 Exposure to PSF-match to scienceExposure
591 scienceExposure : `lsst.afw.image.ExposureF`
592 Reference Exposure
593 templateFwhmPix : `float`
594 FWHM (in pixels) of the Psf in the template image (image to convolve)
595 scienceFwhmPix : `float`
596 FWHM (in pixels) of the Psf in the science image
597 candidateList : `list`, optional
598 A list of footprints/maskedImages for kernel candidates;
599 if `None` then source detection is run.
600
601 - Currently supported: list of Footprints or measAlg.PsfCandidateF
602
603 doWarping : `bool`
604 What to do if ``templateExposure``` and ``scienceExposure`` WCSs do
605 not match:
606
607 - if `True` then warp ``templateExposure`` to match ``scienceExposure``
608 - if `False` then raise an Exception
609
610 convolveTemplate : `bool`
611 Convolve the template image or the science image
612
613 - if `True`, ``templateExposure`` is warped if doWarping,
614 ``templateExposure`` is convolved
615 - if `False`, ``templateExposure`` is warped if doWarping,
616 ``scienceExposure is`` convolved
617
618 Returns
619 -------
620 result : `lsst.pipe.base.Struct`
621 An `lsst.pipe.base.Struct` containing these fields:
622
623 - ``subtractedExposure`` : subtracted Exposure
624 scienceExposure - (matchedImage + backgroundModel)
625 - ``matchedImage`` : ``templateExposure`` after warping to match
626 ``templateExposure`` (if doWarping true),
627 and convolving with psfMatchingKernel
628 - ``psfMatchingKernel`` : PSF matching kernel
629 - ``backgroundModel`` : differential background model
630 - ``kernelCellSet`` : SpatialCellSet used to determine PSF matching kernel
631 """
632 results = self.matchExposures(
633 templateExposure=templateExposure,
634 scienceExposure=scienceExposure,
635 templateFwhmPix=templateFwhmPix,
636 scienceFwhmPix=scienceFwhmPix,
637 candidateList=candidateList,
638 doWarping=doWarping,
639 convolveTemplate=convolveTemplate
640 )
641 # Always inherit WCS and photocalib from science exposure
642 subtractedExposure = afwImage.ExposureF(scienceExposure, deep=True)
643 # Note, the decorrelation afterburner re-calculates the variance plane
644 # from the variance planes of the original exposures.
645 # That recalculation code must be in accordance with the
646 # photometric level set here in ``subtractedMaskedImage``.
647 if convolveTemplate:
648 subtractedMaskedImage = subtractedExposure.maskedImage
649 subtractedMaskedImage -= results.matchedExposure.maskedImage
650 subtractedMaskedImage -= results.backgroundModel
651 else:
652 subtractedMaskedImage = subtractedExposure.maskedImage
653 subtractedMaskedImage[:, :] = results.warpedExposure.maskedImage
654 subtractedMaskedImage -= results.matchedExposure.maskedImage
655 subtractedMaskedImage -= results.backgroundModel
656
657 # Preserve polarity of differences
658 subtractedMaskedImage *= -1
659
660 # Place back on native photometric scale
661 subtractedMaskedImage /= results.psfMatchingKernel.computeImage(
662 afwImage.ImageD(results.psfMatchingKernel.getDimensions()), False)
663 # We matched to the warped template
664 subtractedExposure.setPsf(results.warpedExposure.getPsf())
665
666 import lsstDebug
667 display = lsstDebug.Info(__name__).display
668 displayDiffIm = lsstDebug.Info(__name__).displayDiffIm
669 maskTransparency = lsstDebug.Info(__name__).maskTransparency
670 if not maskTransparency:
671 maskTransparency = 0
672 if display:
673 afwDisplay.setDefaultMaskTransparency(maskTransparency)
674 if display and displayDiffIm:
675 disp = afwDisplay.Display(frame=lsstDebug.frame)
676 disp.mtv(templateExposure, title="Template")
677 lsstDebug.frame += 1
678 disp = afwDisplay.Display(frame=lsstDebug.frame)
679 disp.mtv(results.matchedExposure, title="Matched template")
680 lsstDebug.frame += 1
681 disp = afwDisplay.Display(frame=lsstDebug.frame)
682 disp.mtv(scienceExposure, title="Science Image")
683 lsstDebug.frame += 1
684 disp = afwDisplay.Display(frame=lsstDebug.frame)
685 disp.mtv(subtractedExposure, title="Difference Image")
686 lsstDebug.frame += 1
687
688 results.subtractedExposure = subtractedExposure
689 return results
690

◆ subtractMaskedImages()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.subtractMaskedImages (   self,
  templateMaskedImage,
  scienceMaskedImage,
  candidateList,
  templateFwhmPix = None,
  scienceFwhmPix = None 
)
Psf-match and subtract two MaskedImages.

Do the following, in order:

- PSF-match templateMaskedImage to scienceMaskedImage
- Determine the differential background
- Return the difference: scienceMaskedImage
    ((warped templateMaskedImage convolved with psfMatchingKernel) + backgroundModel)

Parameters
----------
templateMaskedImage : `lsst.afw.image.MaskedImage`
    MaskedImage to PSF-match to ``scienceMaskedImage``
scienceMaskedImage : `lsst.afw.image.MaskedImage`
    Reference MaskedImage
templateFwhmPix : `float`
    FWHM (in pixels) of the Psf in the template image (image to convolve)
scienceFwhmPix : `float`
    FWHM (in pixels) of the Psf in the science image
candidateList : `list`, optional
    A list of footprints/maskedImages for kernel candidates;
    if `None` then source detection is run.

    - Currently supported: list of Footprints or measAlg.PsfCandidateF

Returns
-------
results : `lsst.pipe.base.Struct`
    An `lsst.pipe.base.Struct` containing these fields:

    - ``subtractedMaskedImage`` : ``scienceMaskedImage`` - (matchedImage + backgroundModel)
    - ``matchedImage`` : templateMaskedImage convolved with psfMatchingKernel
    - `psfMatchingKernel`` : PSF matching kernel
    - ``backgroundModel`` : differential background model
    - ``kernelCellSet`` : SpatialCellSet used to determine PSF matching kernel

Reimplemented in lsst.ip.diffim.zogy.ZogyImagePsfMatchTask.

Definition at line 692 of file imagePsfMatch.py.

693 templateFwhmPix=None, scienceFwhmPix=None):
694 """Psf-match and subtract two MaskedImages.
695
696 Do the following, in order:
697
698 - PSF-match templateMaskedImage to scienceMaskedImage
699 - Determine the differential background
700 - Return the difference: scienceMaskedImage
701 ((warped templateMaskedImage convolved with psfMatchingKernel) + backgroundModel)
702
703 Parameters
704 ----------
705 templateMaskedImage : `lsst.afw.image.MaskedImage`
706 MaskedImage to PSF-match to ``scienceMaskedImage``
707 scienceMaskedImage : `lsst.afw.image.MaskedImage`
708 Reference MaskedImage
709 templateFwhmPix : `float`
710 FWHM (in pixels) of the Psf in the template image (image to convolve)
711 scienceFwhmPix : `float`
712 FWHM (in pixels) of the Psf in the science image
713 candidateList : `list`, optional
714 A list of footprints/maskedImages for kernel candidates;
715 if `None` then source detection is run.
716
717 - Currently supported: list of Footprints or measAlg.PsfCandidateF
718
719 Returns
720 -------
721 results : `lsst.pipe.base.Struct`
722 An `lsst.pipe.base.Struct` containing these fields:
723
724 - ``subtractedMaskedImage`` : ``scienceMaskedImage`` - (matchedImage + backgroundModel)
725 - ``matchedImage`` : templateMaskedImage convolved with psfMatchingKernel
726 - `psfMatchingKernel`` : PSF matching kernel
727 - ``backgroundModel`` : differential background model
728 - ``kernelCellSet`` : SpatialCellSet used to determine PSF matching kernel
729
730 """
731 if not candidateList:
732 raise RuntimeError("Candidate list must be populated by makeCandidateList")
733
734 results = self.matchMaskedImages(
735 templateMaskedImage=templateMaskedImage,
736 scienceMaskedImage=scienceMaskedImage,
737 candidateList=candidateList,
738 templateFwhmPix=templateFwhmPix,
739 scienceFwhmPix=scienceFwhmPix,
740 )
741
742 subtractedMaskedImage = afwImage.MaskedImageF(scienceMaskedImage, True)
743 subtractedMaskedImage -= results.matchedImage
744 subtractedMaskedImage -= results.backgroundModel
745 results.subtractedMaskedImage = subtractedMaskedImage
746
747 import lsstDebug
748 display = lsstDebug.Info(__name__).display
749 displayDiffIm = lsstDebug.Info(__name__).displayDiffIm
750 maskTransparency = lsstDebug.Info(__name__).maskTransparency
751 if not maskTransparency:
752 maskTransparency = 0
753 if display:
754 afwDisplay.setDefaultMaskTransparency(maskTransparency)
755 if display and displayDiffIm:
756 disp = afwDisplay.Display(frame=lsstDebug.frame)
757 disp.mtv(subtractedMaskedImage, title="Subtracted masked image")
758 lsstDebug.frame += 1
759
760 return results
761

Member Data Documentation

◆ background

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.background

Definition at line 327 of file imagePsfMatch.py.

◆ ConfigClass

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.ConfigClass = ImagePsfMatchConfig
static

Definition at line 317 of file imagePsfMatch.py.

◆ kConfig

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.kConfig

Definition at line 323 of file imagePsfMatch.py.

◆ selectAlgMetadata

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.selectAlgMetadata

Definition at line 330 of file imagePsfMatch.py.

◆ selectSchema

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.selectSchema

Definition at line 329 of file imagePsfMatch.py.


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