LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
LSST Data Management Base Package
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)
 
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
 
 useRegularization
 
 hMat
 

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 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.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.log.utils as logUtils
    logUtils.traceSetAt("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 81 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 318 of file imagePsfMatch.py.

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

Member Function Documentation

◆ getFwhmPix()

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

Definition at line 333 of file imagePsfMatch.py.

333  def getFwhmPix(self, psf):
334  """Return the FWHM in pixels of a Psf.
335  """
336  sigPix = psf.computeShape().getDeterminantRadius()
337  return sigPix*sigma2fwhm
338 

◆ 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 759 of file imagePsfMatch.py.

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

◆ 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 817 of file imagePsfMatch.py.

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

◆ 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 873 of file imagePsfMatch.py.

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

◆ 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 340 of file imagePsfMatch.py.

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

◆ 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 458 of file imagePsfMatch.py.

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

Definition at line 571 of file imagePsfMatch.py.

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

◆ 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

Definition at line 689 of file imagePsfMatch.py.

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

Member Data Documentation

◆ background

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.background

Definition at line 326 of file imagePsfMatch.py.

◆ ConfigClass

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

Definition at line 316 of file imagePsfMatch.py.

◆ hMat

lsst.ip.diffim.psfMatch.PsfMatchTask.hMat
inherited

Definition at line 660 of file psfMatch.py.

◆ kConfig

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.kConfig

Definition at line 322 of file imagePsfMatch.py.

◆ selectAlgMetadata

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.selectAlgMetadata

Definition at line 329 of file imagePsfMatch.py.

◆ selectSchema

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.selectSchema

Definition at line 328 of file imagePsfMatch.py.

◆ useRegularization

lsst.ip.diffim.psfMatch.PsfMatchTask.useRegularization
inherited

Definition at line 655 of file psfMatch.py.


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