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.zogy.ZogyImagePsfMatchTask Class Reference
Inheritance diagram for lsst.ip.diffim.zogy.ZogyImagePsfMatchTask:
lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask lsst.ip.diffim.psfMatch.PsfMatchTask

Public Member Functions

def __init__ (self, *args, **kwargs)
 
def run (self, scienceExposure, templateExposure, doWarping=True)
 
def subtractExposures (self, templateExposure, scienceExposure, *args)
 
def subtractMaskedImages (self, templateExposure, scienceExposure, *args)
 
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 = ZogyImagePsfMatchConfig
 

Detailed Description

Task to perform Zogy PSF matching and image subtraction.

This class inherits from ImagePsfMatchTask to contain the _warper
subtask and related methods.

Definition at line 1269 of file zogy.py.

Constructor & Destructor Documentation

◆ __init__()

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

Reimplemented from lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.

Definition at line 1278 of file zogy.py.

1278  def __init__(self, *args, **kwargs):
1279  ImagePsfMatchTask.__init__(self, *args, **kwargs)
1280 

Member Function Documentation

◆ getFwhmPix()

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.getFwhmPix (   self,
  psf 
)
inherited
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 
)
inherited
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 
)
inherited
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 
)
inherited
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 
)
inherited
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 
)
inherited
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.

◆ run()

def lsst.ip.diffim.zogy.ZogyImagePsfMatchTask.run (   self,
  scienceExposure,
  templateExposure,
  doWarping = True 
)
Register, PSF-match, and subtract two Exposures, ``scienceExposure - templateExposure``
using the ZOGY algorithm.

Parameters
----------
templateExposure : `lsst.afw.image.Exposure`
    exposure to be warped to scienceExposure.
scienceExposure : `lsst.afw.image.Exposure`
    reference Exposure.
doWarping : `bool`
    what to do if templateExposure's and scienceExposure's WCSs do not match:
    - if True then warp templateExposure to match scienceExposure
    - if False then raise an Exception

Notes
-----
Do the following, in order:
    - Warp templateExposure to match scienceExposure, if their WCSs do not already match
    - Compute subtracted exposure ZOGY image subtraction algorithm on the two exposures

This is the new entry point of the task as of DM-25115.

Returns
-------
results : `lsst.pipe.base.Struct` containing these fields:
    - subtractedExposure: `lsst.afw.image.Exposure`
        The subtraction result.
    - warpedExposure: `lsst.afw.image.Exposure` or `None`
        templateExposure after warping to match scienceExposure

Definition at line 1281 of file zogy.py.

1281  def run(self, scienceExposure, templateExposure, doWarping=True):
1282  """Register, PSF-match, and subtract two Exposures, ``scienceExposure - templateExposure``
1283  using the ZOGY algorithm.
1284 
1285  Parameters
1286  ----------
1287  templateExposure : `lsst.afw.image.Exposure`
1288  exposure to be warped to scienceExposure.
1289  scienceExposure : `lsst.afw.image.Exposure`
1290  reference Exposure.
1291  doWarping : `bool`
1292  what to do if templateExposure's and scienceExposure's WCSs do not match:
1293  - if True then warp templateExposure to match scienceExposure
1294  - if False then raise an Exception
1295 
1296  Notes
1297  -----
1298  Do the following, in order:
1299  - Warp templateExposure to match scienceExposure, if their WCSs do not already match
1300  - Compute subtracted exposure ZOGY image subtraction algorithm on the two exposures
1301 
1302  This is the new entry point of the task as of DM-25115.
1303 
1304  Returns
1305  -------
1306  results : `lsst.pipe.base.Struct` containing these fields:
1307  - subtractedExposure: `lsst.afw.image.Exposure`
1308  The subtraction result.
1309  - warpedExposure: `lsst.afw.image.Exposure` or `None`
1310  templateExposure after warping to match scienceExposure
1311  """
1312 
1313  if not self._validateWcs(scienceExposure, templateExposure):
1314  if doWarping:
1315  self.log.info("Warping templateExposure to scienceExposure")
1316  xyTransform = afwGeom.makeWcsPairTransform(templateExposure.getWcs(),
1317  scienceExposure.getWcs())
1318  psfWarped = measAlg.WarpedPsf(templateExposure.getPsf(), xyTransform)
1319  templateExposure = self._warper.warpExposure(
1320  scienceExposure.getWcs(), templateExposure, destBBox=scienceExposure.getBBox())
1321  templateExposure.setPsf(psfWarped)
1322  else:
1323  raise RuntimeError("Input images are not registered. Consider setting doWarping=True.")
1324 
1325  config = self.config.zogyConfig
1326  task = ZogyTask(config=config)
1327  results = task.run(scienceExposure, templateExposure)
1328  results.warpedExposure = templateExposure
1329  return results
1330 

◆ subtractExposures() [1/2]

def lsst.ip.diffim.zogy.ZogyImagePsfMatchTask.subtractExposures (   self,
  templateExposure,
  scienceExposure,
args 
)

Definition at line 1331 of file zogy.py.

1331  def subtractExposures(self, templateExposure, scienceExposure, *args):
1332  raise NotImplementedError
1333 

◆ subtractExposures() [2/2]

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.subtractExposures (   self,
  templateExposure,
  scienceExposure,
  templateFwhmPix = None,
  scienceFwhmPix = None,
  candidateList = None,
  doWarping = True,
  convolveTemplate = True 
)
inherited
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() [1/2]

def lsst.ip.diffim.zogy.ZogyImagePsfMatchTask.subtractMaskedImages (   self,
  templateExposure,
  scienceExposure,
args 
)

Definition at line 1334 of file zogy.py.

1334  def subtractMaskedImages(self, templateExposure, scienceExposure, *args):
1335  raise NotImplementedError
1336 
1337 
1338 subtractAlgorithmRegistry.register('zogy', ZogyImagePsfMatchTask)

◆ subtractMaskedImages() [2/2]

def lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.subtractMaskedImages (   self,
  templateMaskedImage,
  scienceMaskedImage,
  candidateList,
  templateFwhmPix = None,
  scienceFwhmPix = None 
)
inherited
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
inherited

Definition at line 326 of file imagePsfMatch.py.

◆ ConfigClass

lsst.ip.diffim.zogy.ZogyImagePsfMatchTask.ConfigClass = ZogyImagePsfMatchConfig
static

Definition at line 1276 of file zogy.py.

◆ hMat

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

Definition at line 660 of file psfMatch.py.

◆ kConfig

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.kConfig
inherited

Definition at line 322 of file imagePsfMatch.py.

◆ selectAlgMetadata

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.selectAlgMetadata
inherited

Definition at line 329 of file imagePsfMatch.py.

◆ selectSchema

lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask.selectSchema
inherited

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: