Coverage for python/lsst/ip/diffim/psfMatch.py : 82%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# # LSST Data Management System # Copyright 2008-2016 LSST Corporation. # # This product includes software developed by the # LSST Project (http://www.lsst.org/). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the LSST License Statement and # the GNU General Public License along with this program. If not, # see <http://www.lsstcorp.org/LegalNotices/>. #
"""!Configuration for detecting sources on images for building a PSF-matching kernel
Configuration for turning detected lsst.afw.detection.FootPrints into an acceptable (unmasked, high signal-to-noise, not too large or not too small) list of lsst.ip.diffim.KernelSources that are used to build the Psf-matching kernel"""
dtype=float, doc="Value of footprint detection threshold", default=10.0, check=lambda x: x >= 3.0 ) dtype=str, doc="Type of detection threshold", default="pixel_stdev", allowed={ "value": "Use counts as the detection threshold type", "stdev": "Use standard deviation of image plane", "variance": "Use variance of image plane", "pixel_stdev": "Use stdev derived from variance plane" } ) dtype=bool, doc="""If true run detection on the template (image to convolve); if false run detection on the science image""", default=True ) dtype=str, doc="""Mask planes that lead to an invalid detection. Options: NO_DATA EDGE SAT BAD CR INTRP""", default=("NO_DATA", "EDGE", "SAT") ) dtype=int, doc="Minimum number of pixels in an acceptable Footprint", default=5, check=lambda x: x >= 5 ) dtype=int, doc="""Maximum number of pixels in an acceptable Footprint; too big and the subsequent convolutions become unwieldy""", default=500, check=lambda x: x <= 500 ) dtype=float, doc="""If config.scaleByFwhm, grow the footprint based on the final kernelSize. Each footprint will be 2*fpGrowKernelScaling*kernelSize x 2*fpGrowKernelScaling*kernelSize. With the value of 1.0, the remaining pixels in each KernelCandiate after convolution by the basis functions will be equal to the kernel size itself.""", default=1.0, check=lambda x: x >= 1.0 ) dtype=int, doc="""Growing radius (in pixels) for each raw detection footprint. The smaller the faster; however the kernel sum does not converge if the stamp is too small; and the kernel is not constrained at all if the stamp is the size of the kernel. The grown stamp is 2 * fpGrowPix pixels larger in each dimension. This is overridden by fpGrowKernelScaling if scaleByFwhm""", default=30, check=lambda x: x >= 10 ) dtype=bool, doc="Scale fpGrowPix by input Fwhm?", default=True, )
"""!Base configuration for Psf-matching
The base configuration of the Psf-matching kernel, and of the warping, detection, and background modeling subTasks."""
afwMath.warper.WarperConfig) DetectionConfig) SubtractBackgroundConfig)
dtype=bool, doc="Use afw background subtraction instead of ip_diffim", default=False, ) dtype=bool, doc="Include terms (including kernel cross terms) for background in ip_diffim", default=False, ) dtype=str, doc="Type of basis set for PSF matching kernel.", default="alard-lupton", allowed={ "alard-lupton": """Alard-Lupton sum-of-gaussians basis set, * The first term has no spatial variation * The kernel sum is conserved * You may want to turn off 'usePcaForSpatialKernel'""", "delta-function": """Delta-function kernel basis set, * You may enable the option useRegularization * You should seriously consider usePcaForSpatialKernel, which will also enable kernel sum conservation for the delta function kernels""" } ) dtype=int, doc="""Number of rows/columns in the convolution kernel; should be odd-valued. Modified by kernelSizeFwhmScaling if scaleByFwhm = true""", default=21, ) dtype=bool, doc="Scale kernelSize, alardGaussians by input Fwhm", default=True, ) dtype=float, doc="""How much to scale the kernel size based on the largest AL Sigma""", default=6.0, check=lambda x: x >= 1.0 ) dtype=int, doc="""Minimum Kernel Size""", default=21, ) dtype=int, doc="""Maximum Kernel Size""", default=35, ) dtype=str, doc="Type of spatial functions for kernel and background", default="chebyshev1", allowed={ "chebyshev1": "Chebyshev polynomial of the first kind", "polynomial": "Standard x,y polynomial", } ) dtype=int, doc="Spatial order of convolution kernel variation", default=2, check=lambda x: x >= 0 ) dtype=int, doc="Spatial order of differential background variation", default=1, check=lambda x: x >= 0 ) dtype=int, doc="Size (rows) in pixels of each SpatialCell for spatial modeling", default=128, check=lambda x: x >= 32 ) dtype=int, doc="Size (columns) in pixels of each SpatialCell for spatial modeling", default=128, check=lambda x: x >= 32 ) dtype=int, doc="Number of KernelCandidates in each SpatialCell to use in the spatial fitting", default=3, check=lambda x: x >= 1 ) dtype=int, doc="Maximum number of iterations for rejecting bad KernelCandidates in spatial fitting", default=3, check=lambda x: x >= 1 and x <= 5 ) dtype=bool, doc="""Use Pca to reduce the dimensionality of the kernel basis sets. This is particularly useful for delta-function kernels. Functionally, after all Cells have their raw kernels determined, we run a Pca on these Kernels, re-fit the Cells using the eigenKernels and then fit those for spatial variation using the same technique as for Alard-Lupton kernels. If this option is used, the first term will have no spatial variation and the kernel sum will be conserved.""", default=False, ) dtype=bool, doc="Subtract off the mean feature before doing the Pca", default=True, ) dtype=int, doc="""Number of principal components to use for Pca basis, including the mean kernel if requested.""", default=5, check=lambda x: x >= 3 ) dtype=bool, doc="Do sigma clipping on each raw kernel candidate", default=True, ) dtype=bool, doc="Do sigma clipping on the ensemble of kernel sums", default=True, ) dtype=bool, doc="Do sigma clipping after building the spatial model", default=True, ) dtype=bool, doc="""Test for maximum condition number when inverting a kernel matrix. Anything above maxConditionNumber is not used and the candidate is set as BAD. Also used to truncate inverse matrix in estimateBiasedRisk. However, if you are doing any deconvolution you will want to turn this off, or use a large maxConditionNumber""", default=False, ) dtype=str, doc="""Mask planes to ignore when calculating diffim statistics Options: NO_DATA EDGE SAT BAD CR INTRP""", default=("NO_DATA", "EDGE", "SAT") ) dtype=float, doc="""Rejects KernelCandidates yielding bad difference image quality. Used by BuildSingleKernelVisitor, AssessSpatialKernelVisitor. Represents average over pixels of (image/sqrt(variance)).""", default=0.25, check=lambda x: x >= 0.0 ) dtype=float, doc="""Rejects KernelCandidates yielding bad difference image quality. Used by BuildSingleKernelVisitor, AssessSpatialKernelVisitor. Represents stddev over pixels of (image/sqrt(variance)).""", default=1.50, check=lambda x: x >= 0.0 ) dtype=bool, doc="""Use the core of the footprint for the quality statistics, instead of the entire footprint. WARNING: if there is deconvolution we probably will need to turn this off""", default=False, ) dtype=int, doc="""Radius for calculation of stats in 'core' of KernelCandidate diffim. Total number of pixels used will be (2*radius)**2. This is used both for 'core' diffim quality as well as ranking of KernelCandidates by their total flux in this core""", default=3, check=lambda x: x >= 1 ) dtype=float, doc="""Maximum allowed sigma for outliers from kernel sum distribution. Used to reject variable objects from the kernel model""", default=3.0, check=lambda x: x >= 0.0 ) dtype=float, doc="Maximum condition number for a well conditioned matrix", default=5.0e7, check=lambda x: x >= 0.0 ) dtype=str, doc="Use singular values (SVD) or eigen values (EIGENVALUE) to determine condition number", default="EIGENVALUE", allowed={ "SVD": "Use singular values", "EIGENVALUE": "Use eigen values (faster)", } ) dtype=float, doc="Maximum condition number for a well conditioned spatial matrix", default=1.0e10, check=lambda x: x >= 0.0 ) dtype=bool, doc="""Remake KernelCandidate using better variance estimate after first pass? Primarily useful when convolving a single-depth image, otherwise not necessary.""", default=False, ) dtype=bool, doc="""Use constant variance weighting in single kernel fitting? In some cases this is better for bright star residuals.""", default=True, ) dtype=bool, doc="""Calculate kernel and background uncertainties for each kernel candidate? This comes from the inverse of the covariance matrix. Warning: regularization can cause problems for this step.""", default=False, ) dtype=bool, doc="""Use Bayesian Information Criterion to select the number of bases going into the kernel""", default=False, )
"""!The parameters specific to the "Alard-Lupton" (sum-of-Gaussian) Psf-matching basis"""
dtype=int, doc="Number of Gaussians in alard-lupton basis", default=3, check=lambda x: x >= 1 ) dtype=int, doc="Polynomial order of spatial modification of Gaussians. Must in number equal alardNGauss", default=(4, 2, 2), ) dtype=float, doc="""Sigma in pixels of Gaussians (FWHM = 2.35 sigma). Must in number equal alardNGauss""", default=(0.7, 1.5, 3.0), ) dtype=float, doc="""Default scale factor between Gaussian sigmas """, default=2.0, check=lambda x: x >= 0.0, ) dtype=float, doc="""Minimum Sigma (pixels) for Gaussians""", default=0.7, check=lambda x: x >= 0.25 ) dtype=int, doc="""Degree of spatial modification of ALL gaussians in AL basis during deconvolution""", default=3, check=lambda x: x >= 1 ) dtype=float, doc="""Minimum Sigma (pixels) for Gaussians during deconvolution; make smaller than alardMinSig as this is only indirectly used""", default=0.4, check=lambda x: x >= 0.25 ) dtype=int, doc="Number of Gaussians in AL basis during deconvolution", default=3, check=lambda x: x >= 1 )
"""!The parameters specific to the delta-function (one basis per-pixel) Psf-matching basis"""
dtype=bool, doc="Use regularization to smooth the delta function kernels", default=True, ) dtype=str, doc="Type of regularization.", default="centralDifference", allowed={ "centralDifference": "Penalize second derivative using 2-D stencil of central finite difference", "forwardDifference": "Penalize first, second, third derivatives using forward finite differeces" } ) dtype=int, doc="Type of stencil to approximate central derivative (for centralDifference only)", default=9, allowed={ 5: "5-point stencil including only adjacent-in-x,y elements", 9: "9-point stencil including diagonal elements" } ) dtype=int, doc="Array showing which order derivatives to penalize (for forwardDifference only)", default=(1, 2), itemCheck=lambda x: (x > 0) and (x < 4) ) dtype=float, doc="Value of the penalty for kernel border pixels", default=3.0, check=lambda x: x >= 0.0 ) dtype=str, doc="How to choose the value of the regularization strength", default="absolute", allowed={ "absolute": "Use lambdaValue as the value of regularization strength", "relative": "Use lambdaValue as fraction of the default regularization strength (N.R. 18.5.8)", "minimizeBiasedRisk": "Minimize biased risk estimate", "minimizeUnbiasedRisk": "Minimize unbiased risk estimate", } ) dtype=float, doc="Value used for absolute determinations of regularization strength", default=0.2, ) dtype=float, doc="Fraction of the default lambda strength (N.R. 18.5.8) to use. 1e-4 or 1e-5", default=1e-4, ) dtype=str, doc="""If a scan through lambda is needed (minimizeBiasedRisk, minimizeUnbiasedRisk), use log or linear steps""", default="log", allowed={ "log": "Step in log intervals; e.g. lambdaMin, lambdaMax, lambdaStep = -1.0, 2.0, 0.1", "linear": "Step in linear intervals; e.g. lambdaMin, lambdaMax, lambdaStep = 0.1, 100, 0.1", } ) dtype=float, doc="""If scan through lambda needed (minimizeBiasedRisk, minimizeUnbiasedRisk), start at this value. If lambdaStepType = log:linear, suggest -1:0.1""", default=-1.0, ) dtype=float, doc="""If scan through lambda needed (minimizeBiasedRisk, minimizeUnbiasedRisk), stop at this value. If lambdaStepType = log:linear, suggest 2:100""", default=2.0, ) dtype=float, doc="""If scan through lambda needed (minimizeBiasedRisk, minimizeUnbiasedRisk), step in these increments. If lambdaStepType = log:linear, suggest 0.1:0.1""", default=0.1, )
## @addtogroup LSST_task_documentation ## @{ ## @page PsfMatchTask ## @ref PsfMatchTask_ "PsfMatchTask" ## @copybrief PsfMatchTask ## @}
"""!
@anchor PsfMatchTask_
@brief Base class for Psf Matching; should not be called directly
@section ip_diffim_psfmatch_Contents Contents
- @ref ip_diffim_psfmatch_Purpose - @ref ip_diffim_psfmatch_Initialize - @ref ip_diffim_psfmatch_IO - @ref ip_diffim_psfmatch_Config - @ref ip_diffim_psfmatch_Metadata - @ref ip_diffim_psfmatch_Debug - @ref ip_diffim_psfmatch_Example
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@section ip_diffim_psfmatch_Purpose Description
PsfMatchTask is a base class that implements the core functionality for matching the Psfs of two images using a spatially varying Psf-matching lsst.afw.math.LinearCombinationKernel. The Task requires the user to provide an instance of an lsst.afw.math.SpatialCellSet, filled with lsst.ip.diffim.KernelCandidate instances, and a list of lsst.afw.math.Kernels of basis shapes that will be used for the decomposition. If requested, the Task also performs background matching and returns the differential background model as an lsst.afw.math.Kernel.SpatialFunction.
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@ection ip_diffim_psfmatch_Initialize Task initialization
@copydoc \_\_init\_\_
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@section ip_diffim_psfmatch_IO Invoking the Task
As a base class, this Task is not directly invoked. However, run() methods that are implemented on derived classes will make use of the core _solve() functionality, which defines a sequence of lsst.afw.math.CandidateVisitor classes that iterate through the KernelCandidates, first building up a per-candidate solution and then building up a spatial model from the ensemble of candidates. Sigma clipping is performed using the mean and standard deviation of all kernel sums (to reject variable objects), on the per-candidate substamp diffim residuals (to indicate a bad choice of kernel basis shapes for that particular object), and on the substamp diffim residuals using the spatial kernel fit (to indicate a bad choice of spatial kernel order, or poor constraints on the spatial model). The _diagnostic() method logs information on the quality of the spatial fit, and also modifies the Task metadata.
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@section ip_diffim_psfmatch_Config Configuration parameters
See @ref PsfMatchConfig, @ref PsfMatchConfigAL, @ref PsfMatchConfigDF, and @ref DetectionConfig.
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@section ip_diffim_psfmatch_Metadata Quantities set in Metadata
<DL> <DT> spatialConditionNum <DD> Condition number of the spatial kernel fit; via @link lsst.ip.diffim.PsfMatchTask._diagnostic PsfMatchTask._diagnostic @endlink </DD> </DT> <DT> spatialKernelSum <DD> Kernel sum (10^{-0.4 * Δ zeropoint}) of the spatial Psf-matching kernel; via @link lsst.ip.diffim.PsfMatchTask._diagnostic PsfMatchTask._diagnostic @endlink </DD> </DT>
<DT> ALBasisNGauss <DD> If using sum-of-Gaussian basis, the number of gaussians used; via @link lsst.ip.diffim.makeKernelBasisList.generateAlardLuptonBasisList generateAlardLuptonBasisList@endlink </DD> </DT> <DT> ALBasisDegGauss <DD> If using sum-of-Gaussian basis, the degree of spatial variation of the Gaussians; via @link lsst.ip.diffim.makeKernelBasisList.generateAlardLuptonBasisList generateAlardLuptonBasisList@endlink </DD> </DT> <DT> ALBasisSigGauss <DD> If using sum-of-Gaussian basis, the widths (sigma) of the Gaussians; via @link lsst.ip.diffim.makeKernelBasisList.generateAlardLuptonBasisList generateAlardLuptonBasisList@endlink </DD> </DT> <DT> ALKernelSize <DD> If using sum-of-Gaussian basis, the kernel size; via @link lsst.ip.diffim.makeKernelBasisList.generateAlardLuptonBasisList generateAlardLuptonBasisList@endlink </DD> </DT>
<DT> NFalsePositivesTotal <DD> Total number of diaSources; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> <DT> NFalsePositivesRefAssociated <DD> Number of diaSources that associate with the reference catalog; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> <DT> NFalsePositivesRefAssociated <DD> Number of diaSources that associate with the source catalog; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> <DT> NFalsePositivesUnassociated <DD> Number of diaSources that are orphans; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> <DT> metric_MEAN <DD> Mean value of substamp diffim quality metrics across all KernelCandidates, for both the per-candidate (LOCAL) and SPATIAL residuals; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> <DT> metric_MEDIAN <DD> Median value of substamp diffim quality metrics across all KernelCandidates, for both the per-candidate (LOCAL) and SPATIAL residuals; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> <DT> metric_STDEV <DD> Standard deviation of substamp diffim quality metrics across all KernelCandidates, for both the per-candidate (LOCAL) and SPATIAL residuals; via @link lsst.ip.diffim.KernelCandidateQa.aggregate KernelCandidateQa.aggregate@endlink </DD> </DT> </DL>
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@section ip_diffim_psfmatch_Debug Debug variables
The @link lsst.pipe.base.cmdLineTask.CmdLineTask command line task@endlink interface supports a flag @c -d/--debug to import @b debug.py from your @c PYTHONPATH. The relevant contents of debug.py for this Task include:
@code{.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 # ds9 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) return di lsstDebug.Info = DebugInfo lsstDebug.frame = 1
@endcode
Note that if you want addional logging info, you may add to your scripts: @code{.py} import lsst.log.utils as logUtils logUtils.traceSetAt("ip.diffim", 4) @endcode
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@section ip_diffim_psfmatch_Example Example code
As a base class, there is no example code for PsfMatchTask. However, see @link lsst.ip.diffim.imagePsfMatch.ImagePsfMatchTask ImagePsfMatchTask@endlink, @link lsst.ip.diffim.snapPsfMatch.SnapPsfMatchTask SnapPsfMatchTask@endlink, and @link lsst.ip.diffim.modelPsfMatch.ModelPsfMatchTask ModelPsfMatchTask@endlink.
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
"""
"""!Create the psf-matching Task
@param *args arguments to be passed to lsst.pipe.base.task.Task.__init__ @param **kwargs keyword arguments to be passed to lsst.pipe.base.task.Task.__init__
The initialization sets the Psf-matching kernel configuration using the value of self.config.kernel.active. If the kernel is requested with regularization to moderate the bias/variance tradeoff, currently only used when a delta function kernel basis is provided, it creates a regularization matrix stored as member variable self.hMat. """
# else:
"""!Provide logging diagnostics on quality of spatial kernel fit
@param kernelCellSet: Cellset that contains the KernelCandidates used in the fitting @param spatialSolution: KernelSolution of best-fit @param spatialKernel: Best-fit spatial Kernel model @param spatialBg: Best-fit spatial background model
""" # What is the final kernel sum
# Look at how well conditioned the matrix is getattr(diffimLib.KernelSolution, self.kConfig.conditionNumberType))
self.log.warn("Spatial solution exceeds max condition number (%.3e > %.3e)" % ( conditionNum, self.kConfig.maxSpatialConditionNumber))
# Look at how well the solution is constrained
# Not fit for
# Counting statistics self.log.warn("Many more candidates rejected than accepted; %d total, %d rejected, %d used" % ( nTot, nBad, nGood)) else:
# Some judgements on the quality of the spatial models nGood, nKernelTerms, nBasisKernels)) nGood, nKernelTerms, nBasisKernels)) else: nGood, nKernelTerms, nBasisKernels))
self.log.warn("Spatial background model underconstrained; %d candidates, %d terms" % ( nGood, nBgTerms)) self.log.warn("Consider lowering the spatial order") nGood, nBgTerms)) else: nGood, nBgTerms))
"""!Provide visualization of the inputs and ouputs to the Psf-matching code
@param kernelCellSet: the SpatialCellSet used in determining the matching kernel and background @param spatialKernel: spatially varying Psf-matching kernel @param spatialBackground: spatially varying background-matching function
""" import lsstDebug displayCandidates = lsstDebug.Info(__name__).displayCandidates displayKernelBasis = lsstDebug.Info(__name__).displayKernelBasis displayKernelMosaic = lsstDebug.Info(__name__).displayKernelMosaic plotKernelSpatialModel = lsstDebug.Info(__name__).plotKernelSpatialModel showBadCandidates = lsstDebug.Info(__name__).showBadCandidates maskTransparency = lsstDebug.Info(__name__).maskTransparency if not maskTransparency: maskTransparency = 0 ds9.setMaskTransparency(maskTransparency)
if displayCandidates: diutils.showKernelCandidates(kernelCellSet, kernel=spatialKernel, background=spatialBackground, frame=lsstDebug.frame, showBadCandidates=showBadCandidates) lsstDebug.frame += 1 diutils.showKernelCandidates(kernelCellSet, kernel=spatialKernel, background=spatialBackground, frame=lsstDebug.frame, showBadCandidates=showBadCandidates, kernels=True) lsstDebug.frame += 1 diutils.showKernelCandidates(kernelCellSet, kernel=spatialKernel, background=spatialBackground, frame=lsstDebug.frame, showBadCandidates=showBadCandidates, resids=True) lsstDebug.frame += 1
if displayKernelBasis: diutils.showKernelBasis(spatialKernel, frame=lsstDebug.frame) lsstDebug.frame += 1
if displayKernelMosaic: diutils.showKernelMosaic(kernelCellSet.getBBox(), spatialKernel, frame=lsstDebug.frame) lsstDebug.frame += 1
if plotKernelSpatialModel: diutils.plotKernelSpatialModel(spatialKernel, kernelCellSet, showBadCandidates=showBadCandidates)
"""!Create Principal Component basis
If a principal component analysis is requested, typically when using a delta function basis, perform the PCA here and return a new basis list containing the new principal components.
@param kernelCellSet: a SpatialCellSet containing KernelCandidates, from which components are derived @param nStarPerCell: the number of stars per cell to visit when doing the PCA @param policy: input policy controlling the single kernel visitor
@return - nRejectedPca: number of KernelCandidates rejected during PCA loop - spatialBasisList: basis list containing the principal shapes as Kernels
"""
raise RuntimeError("Eigenvalues sum to zero") "Eigenvalue %d : %f (%f)", j, eigenValues[j], eigenValues[j]/eSum)
# Check for NaNs?
# Put all the power in the first kernel, which will not vary spatially
# New Kernel visitor for this new basis list (no regularization explicitly)
"""!Fill a SpatialCellSet with KernelCandidates for the Psf-matching process; override in derived classes""" return
"""!Solve for the PSF matching kernel
@param kernelCellSet: a SpatialCellSet to use in determining the matching kernel (typically as provided by _buildCellSet) @param basisList: list of Kernels to be used in the decomposition of the spatially varying kernel (typically as provided by makeKernelBasisList) @param returnOnExcept: if True then return (None, None) if an error occurs, else raise the exception
@return - psfMatchingKernel: PSF matching kernel - backgroundModel: differential background model
Raise Exception if unable to determine PSF matching kernel and returnOnExcept False """
# Visitor for the single kernel fit else:
# Visitor for the kernel sum rejection
# Main loop
# Make sure there are no uninitialized candidates as active occupants of Cell "Building single kernels...") "Iteration %d, rejected %d candidates due to initial kernel fit", thisIteration, nRejectedSkf)
# Reject outliers in kernel sum
"Iteration %d, rejected %d candidates due to kernel sum", thisIteration, nRejectedKsum)
# Do we jump back to the top without incrementing thisIteration?
# At this stage we can either apply the spatial fit to # the kernels, or we run a PCA, use these as a *new* # basis set with lower dimensionality, and then apply # the spatial fit to these kernels
"Building Pca basis")
"Iteration %d, rejected %d candidates due to Pca kernel fit", thisIteration, nRejectedPca)
# We don't want to continue on (yet) with the # spatial modeling, because we have bad objects # contributing to the Pca basis. We basically # need to restart from the beginning of this loop, # since the cell-mates of those objects that were # rejected need their original Kernels built by # singleKernelFitter.
# Don't count against thisIteration totalIterations += 1 continue else:
# We have gotten on to the spatial modeling part "Spatial kernel built with %d candidates", spatialkv.getNCandidates())
# Check the quality of the spatial fit (look at residuals) "Iteration %d, rejected %d candidates due to spatial kernel fit", thisIteration, nRejectedSpatial) "%d candidates used in fit", nGoodSpatial)
# If only nGoodSpatial == 0, might be other candidates in the cells raise RuntimeError("No kernel candidates for spatial fit")
# Nothing rejected, finished with spatial fit
# Otherwise, iterate on... thisIteration += 1
# Final fit if above did not converge log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG, "Final spatial fit") if (usePcaForSpatialKernel): nRejectedPca, spatialBasisList = self._createPcaBasis(kernelCellSet, nStarPerCell, policy) regionBBox = kernelCellSet.getBBox() spatialkv = diffimLib.BuildSpatialKernelVisitorF(spatialBasisList, regionBBox, policy) kernelCellSet.visitCandidates(spatialkv, nStarPerCell) spatialkv.solveLinearEquation() log.log("TRACE2." + self.log.getName() + "._solve", log.DEBUG, "Spatial kernel built with %d candidates", spatialkv.getNCandidates()) spatialKernel, spatialBackground = spatialkv.getSolutionPair()
except Exception as e: self.log.error("ERROR: Unable to calculate psf matching kernel")
log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG, str(e)) raise e
"Total time to compute the spatial kernel : %.2f s", (t1 - t0))
self._displayDebug(kernelCellSet, spatialKernel, spatialBackground)
|