22__all__ = [
"MakeKernelConfig",
"MakeKernelTask"]
37from .makeKernelBasisList
import makeKernelBasisList
38from .psfMatch
import PsfMatchConfig, PsfMatchTask, PsfMatchConfigAL, PsfMatchConfigDF
40from .
import diffimLib
41from .
import diffimTools
42from .utils
import evaluateMeanPsfFwhm, getPsfFwhm
55 target=SourceDetectionTask,
56 doc=
"Initial detections used to feed stars to kernel fitting",
59 target=SingleFrameMeasurementTask,
60 doc=
"Initial measurements used to feed stars to kernel fitting",
63 doc=
"Grid size to compute the average PSF FWHM in an exposure",
68 doc=
"Fractional buffer margin to be left out of all sides of the image during construction"
69 "of grid to compute average PSF FWHM in an exposure",
82 self.
selectMeasurement.algorithms.names = (
'base_SdssCentroid',
'base_PsfFlux',
'base_PixelFlags',
83 'base_SdssShape',
'base_GaussianFlux',
'base_SkyCoord')
90 """Construct a kernel for PSF matching two exposures.
93 ConfigClass = MakeKernelConfig
94 _DefaultName = "makeALKernel"
97 PsfMatchTask.__init__(self, *args, **kwargs)
105 self.makeSubtask(
"selectDetection", schema=self.
selectSchema)
108 def run(self, template, science, kernelSources, preconvolved=False):
109 """Solve for the kernel and background model that best match two
110 Exposures evaluated at the given source locations.
115 Exposure that will be convolved.
117 The exposure that will be matched.
118 kernelSources : `list` of `dict`
119 A list of dicts having a "source" and "footprint"
120 field
for the Sources deemed to be appropriate
for Psf
121 matching. Can be the output
from ``selectKernelSources``.
122 preconvolved : `bool`, optional
123 Was the science image convolved
with its own PSF?
127 results : `lsst.pipe.base.Struct`
130 Spatially varying Psf-matching kernel.
131 ``backgroundModel`` : `lsst.afw.math.Function2D`
132 Spatially varying background-matching function.
142 templateFwhmPix = getPsfFwhm(template.psf)
143 scienceFwhmPix = getPsfFwhm(science.psf)
144 except InvalidParameterError:
145 self.
log.debug(
"Unable to evaluate PSF at the average position. "
146 "Evaluting PSF on a grid of points."
148 templateFwhmPix = evaluateMeanPsfFwhm(template,
149 fwhmExposureBuffer=self.config.fwhmExposureBuffer,
150 fwhmExposureGrid=self.config.fwhmExposureGrid
152 scienceFwhmPix = evaluateMeanPsfFwhm(science,
153 fwhmExposureBuffer=self.config.fwhmExposureBuffer,
154 fwhmExposureGrid=self.config.fwhmExposureGrid
158 scienceFwhmPix *= np.sqrt(2)
160 metadata=self.metadata)
161 spatialSolution, psfMatchingKernel, backgroundModel = self.
_solve(kernelCellSet, basisList)
162 return lsst.pipe.base.Struct(
163 psfMatchingKernel=psfMatchingKernel,
164 backgroundModel=backgroundModel,
168 """Select sources from a list of candidates, and extract footprints.
173 Exposure that will be convolved.
175 The exposure that will be matched.
176 candidateList : `list`, optional
177 List of Sources to examine. Elements must be of type afw.table.Source
178 or a type that wraps a Source
and has a getSource() method, such
as
180 preconvolved : `bool`, optional
181 Was the science image convolved
with its own PSF?
185 kernelSources : `list` of `dict`
186 A list of dicts having a
"source" and "footprint"
187 field
for the Sources deemed to be appropriate
for Psf
197 templateFwhmPix = getPsfFwhm(template.psf)
198 scienceFwhmPix = getPsfFwhm(science.psf)
199 except InvalidParameterError:
200 self.
log.debug(
"Unable to evaluate PSF at the average position. "
201 "Evaluting PSF on a grid of points."
203 templateFwhmPix = evaluateMeanPsfFwhm(template,
204 fwhmExposureBuffer=self.config.fwhmExposureBuffer,
205 fwhmExposureGrid=self.config.fwhmExposureGrid
207 scienceFwhmPix = evaluateMeanPsfFwhm(science,
208 fwhmExposureBuffer=self.config.fwhmExposureBuffer,
209 fwhmExposureGrid=self.config.fwhmExposureGrid
212 scienceFwhmPix *= np.sqrt(2)
215 candidateList=candidateList,
216 preconvolved=preconvolved)
220 """Get sources to use for Psf-matching.
222 This method runs detection and measurement on an exposure.
223 The returned set of sources will be used
as candidates
for
229 Exposure on which to run detection/measurement
230 sigma : `float`, optional
231 PSF sigma,
in pixels, used
for smoothing the image
for detection.
232 If `
None`, the PSF width will be used.
234 Whether
or not to smooth the Exposure
with Psf before detection
236 Factory
for the generation of Source ids
241 source catalog containing candidates
for the Psf-matching
247 mi = exposure.getMaskedImage()
249 imArr = mi.image.array
250 maskArr = mi.mask.array
251 miArr = np.ma.masked_array(imArr, mask=maskArr)
254 bkgd = fitBg.getImageF(self.
background.config.algorithm,
257 self.
log.warning(
"Failed to get background model. Falling back to median background estimation")
258 bkgd = np.ma.median(miArr)
264 detRet = self.selectDetection.run(
270 selectSources = detRet.sources
271 self.selectMeasurement.run(measCat=selectSources, exposure=exposure)
279 candidateList=None, preconvolved=False):
280 """Make a list of acceptable KernelCandidates.
282 Accept or generate a list of candidate sources
for
283 Psf-matching,
and examine the Mask planes
in both of the
284 images
for indications of bad pixels
289 Exposure that will be convolved
291 Exposure that will be matched-to
293 Dimensions of the Psf-matching Kernel, used to grow detection footprints
294 candidateList : `list`, optional
295 List of Sources to examine. Elements must be of type afw.table.Source
296 or a type that wraps a Source
and has a getSource() method, such
as
298 preconvolved : `bool`, optional
299 Was the science exposure already convolved
with its PSF?
303 candidateList : `list` of `dict`
304 A list of dicts having a
"source" and "footprint"
305 field
for the Sources deemed to be appropriate
for Psf
311 If ``candidateList``
is empty
or contains incompatible types.
313 if candidateList
is None:
314 candidateList = self.
getSelectSources(scienceExposure, doSmooth=
not preconvolved)
316 if len(candidateList) < 1:
317 raise RuntimeError(
"No candidates in candidateList")
319 listTypes =
set(
type(x)
for x
in candidateList)
320 if len(listTypes) > 1:
321 raise RuntimeError(
"Candidate list contains mixed types: %s" % [t
for t
in listTypes])
325 candidateList[0].getSource()
326 except Exception
as e:
327 raise RuntimeError(f
"Candidate List is of type: {type(candidateList[0])} "
328 "Can only make candidate list from list of afwTable.SourceRecords, "
329 f
"measAlg.PsfCandidateF or other type with a getSource() method: {e}")
330 candidateList = [c.getSource()
for c
in candidateList]
332 candidateList = diffimTools.sourceToFootprintList(candidateList,
333 templateExposure, scienceExposure,
337 if len(candidateList) == 0:
338 raise RuntimeError(
"Cannot find any objects suitable for KernelCandidacy")
342 def makeKernelBasisList(self, targetFwhmPix=None, referenceFwhmPix=None,
343 basisDegGauss=None, basisSigmaGauss=None, metadata=None):
344 """Wrapper to set log messages for
349 targetFwhmPix : `float`, optional
350 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
351 Not used for delta function basis sets.
352 referenceFwhmPix : `float`, optional
353 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
354 Not used
for delta function basis sets.
355 basisDegGauss : `list` of `int`, optional
356 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
357 Not used
for delta function basis sets.
358 basisSigmaGauss : `list` of `int`, optional
359 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
360 Not used
for delta function basis sets.
362 Passed on to `lsst.ip.diffim.generateAlardLuptonBasisList`.
363 Not used
for delta function basis sets.
367 basisList: `list` of `lsst.afw.math.kernel.FixedKernel`
368 List of basis kernels.
371 targetFwhmPix=targetFwhmPix,
372 referenceFwhmPix=referenceFwhmPix,
373 basisDegGauss=basisDegGauss,
374 basisSigmaGauss=basisSigmaGauss,
376 if targetFwhmPix == referenceFwhmPix:
377 self.
log.info(
"Target and reference psf fwhms are equal, falling back to config values")
378 elif referenceFwhmPix > targetFwhmPix:
379 self.
log.info(
"Reference psf fwhm is the greater, normal convolution mode")
381 self.
log.info(
"Target psf fwhm is the greater, deconvolution mode")
385 def _buildCellSet(self, templateMaskedImage, scienceMaskedImage, candidateList):
386 """Build a SpatialCellSet for use with the solve method.
391 MaskedImage to PSF-matched to scienceMaskedImage
393 Reference MaskedImage
394 candidateList : `list`
395 A list of footprints/maskedImages for kernel candidates;
397 - Currently supported: list of Footprints
or measAlg.PsfCandidateF
402 a SpatialCellSet
for use
with self.
_solve
407 If no `candidateList`
is supplied.
409 if not candidateList:
410 raise RuntimeError(
"Candidate list must be populated by makeCandidateList")
414 imageBBox = templateMaskedImage.getBBox()
415 imageBBox.clip(scienceMaskedImage.getBBox())
421 for cand
in candidateList:
423 bbox = cand.getBBox()
425 bbox = cand[
'footprint'].getBBox()
426 tmi = lsst.afw.image.MaskedImageF(templateMaskedImage, bbox)
427 smi = lsst.afw.image.MaskedImageF(scienceMaskedImage, bbox)
431 cand = cand[
'source']
432 xPos = cand.getCentroid()[0]
433 yPos = cand.getCentroid()[1]
434 cand = diffimLib.makeKernelCandidate(xPos, yPos, tmi, smi, ps)
436 self.
log.debug(
"Candidate %d at %f, %f", cand.getId(), cand.getXCenter(), cand.getYCenter())
437 kernelCellSet.insertCandidate(cand)
442 """NOT IMPLEMENTED YET.
446 candidateList : `list`
447 A list of footprints/maskedImages for kernel candidates;
451 sizeCellX, sizeCellY : `int`
452 New dimensions to use
for the kernel.
A class to contain the data, WCS, and other information needed to describe an image of the sky.
A class to manipulate images, masks, and variance as a single object.
A kernel that is a linear combination of fixed basis kernels.
A collection of SpatialCells covering an entire image.
A polymorphic functor base class for generating record IDs for a table.
Record class that contains measurements made on a single exposure.
static std::shared_ptr< SourceTable > make(Schema const &schema, std::shared_ptr< IdFactory > const &idFactory)
Construct a new table.
static Schema makeMinimalSchema()
Return a minimal schema for Source tables and records.
Class for storing ordered metadata with comments.
Class for storing generic metadata.
__init__(self, *args, **kwargs)
_buildCellSet(self, templateMaskedImage, scienceMaskedImage, candidateList)
_adaptCellSize(self, candidateList)
makeKernelBasisList(self, targetFwhmPix=None, referenceFwhmPix=None, basisDegGauss=None, basisSigmaGauss=None, metadata=None)
selectKernelSources(self, template, science, candidateList=None, preconvolved=False)
makeCandidateList(self, templateExposure, scienceExposure, kernelSize, candidateList=None, preconvolved=False)
getSelectSources(self, exposure, sigma=None, doSmooth=True, idFactory=None)
_solve(self, kernelCellSet, basisList, returnOnExcept=False)
_buildCellSet(self, *args)
daf::base::PropertySet * set