示例#1
0
def logPairs(obj, pairs, logLevel=Log.DEBUG):
    """Log ``(name, value)`` pairs to ``obj.metadata`` and ``obj.log``

    Parameters
    ----------
    obj : `lsst.pipe.base.Task`-type
        A `~lsst.pipe.base.Task` or any other object with these two attributes:

        - ``metadata`` an instance of `lsst.daf.base.PropertyList`` (or other object with
          ``add(name, value)`` method).
        - ``log`` an instance of `lsst.log.Log`.

    pairs : sequence
        A sequence of ``(name, value)`` pairs, with value typically numeric.
    logLevel : optional
        Log level (an `lsst.log` level constant, such as `lsst.log.Log.DEBUG`).
    """
    strList = []
    for name, value in pairs:
        try:
            # Use LongLong explicitly here in case an early value in the sequence is int-sized
            obj.metadata.addLongLong(name, value)
        except TypeError:
            obj.metadata.add(name, value)
        strList.append("%s=%s" % (name, value))
    log(obj.log.getName(), logLevel, "; ".join(strList))
示例#2
0
def logPairs(obj, pairs, logLevel=Log.DEBUG):
    """Log ``(name, value)`` pairs to ``obj.metadata`` and ``obj.log``

    Parameters
    ----------
    obj : `lsst.pipe.base.Task`-type
        A `~lsst.pipe.base.Task` or any other object with these two attributes:

        - ``metadata`` an instance of `lsst.daf.base.PropertyList`` (or other object with
          ``add(name, value)`` method).
        - ``log`` an instance of `lsst.log.Log`.

    pairs : sequence
        A sequence of ``(name, value)`` pairs, with value typically numeric.
    logLevel : optional
        Log level (an `lsst.log` level constant, such as `lsst.log.Log.DEBUG`).
    """
    strList = []
    for name, value in pairs:
        try:
            # Use LongLong explicitly here in case an early value in the sequence is int-sized
            obj.metadata.addLongLong(name, value)
        except TypeError:
            obj.metadata.add(name, value)
        strList.append("%s=%s" % (name, value))
    log(obj.log.getName(), logLevel, "; ".join(strList))
示例#3
0
文件: test_redir.py 项目: lsst/log
    def testRedir(self):
        """
        Test redirection to stream.
        """
        with TestRedir.StdoutCapture(self.outputFilename):
            log.configure()
            dest = io.StringIO()
            log_utils.enable_notebook_logging(dest)
            log.log(log.getDefaultLogger().getName(), log.INFO, "This is INFO")
            log.info(u"This is unicode INFO")
            log.trace("This is TRACE")
            log.debug("This is DEBUG")
            log.warn("This is WARN")
            log.error("This is ERROR")
            log.fatal("This is FATAL")
            log_utils.disable_notebook_logging()
            log.warn("Format %d %g %s", 3, 2.71828, "foo")
        self.assertEqual(
            dest.getvalue(),
            """root INFO: This is INFO
root INFO: This is unicode INFO
root WARN: This is WARN
root ERROR: This is ERROR
root FATAL: This is FATAL
""",
        )
        self.check(
            """
root WARN: Format 3 2.71828 foo
"""
        )
示例#4
0
    def _createPcaBasis(self, kernelCellSet, nStarPerCell, policy):
        """!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

        """
        nComponents = self.kConfig.numPrincipalComponents
        imagePca = diffimLib.KernelPcaD()
        importStarVisitor = diffimLib.KernelPcaVisitorF(imagePca)
        kernelCellSet.visitCandidates(importStarVisitor, nStarPerCell)
        if self.kConfig.subtractMeanForPca:
            importStarVisitor.subtractMean()
        imagePca.analyze()

        eigenValues = imagePca.getEigenValues()
        pcaBasisList = importStarVisitor.getEigenKernels()

        eSum = np.sum(eigenValues)
        if eSum == 0.0:
            raise RuntimeError("Eigenvalues sum to zero")
        for j in range(len(eigenValues)):
            log.log("TRACE5." + self.log.getName() + "._solve", log.DEBUG,
                    "Eigenvalue %d : %f (%f)", j, eigenValues[j],
                    eigenValues[j] / eSum)

        nToUse = min(nComponents, len(eigenValues))
        trimBasisList = []
        for j in range(nToUse):
            # Check for NaNs?
            kimage = afwImage.ImageD(pcaBasisList[j].getDimensions())
            pcaBasisList[j].computeImage(kimage, False)
            if not (True in np.isnan(kimage.getArray())):
                trimBasisList.append(pcaBasisList[j])

        # Put all the power in the first kernel, which will not vary spatially
        spatialBasisList = diffimLib.renormalizeKernelList(trimBasisList)

        # New Kernel visitor for this new basis list (no regularization explicitly)
        singlekvPca = diffimLib.BuildSingleKernelVisitorF(
            spatialBasisList, policy)
        singlekvPca.setSkipBuilt(False)
        kernelCellSet.visitCandidates(singlekvPca, nStarPerCell)
        singlekvPca.setSkipBuilt(True)
        nRejectedPca = singlekvPca.getNRejected()

        return nRejectedPca, spatialBasisList
示例#5
0
def logPairs(obj, pairs, logLevel=Log.DEBUG):
    """!Log (name, value) pairs to obj.metadata and obj.log

    @param obj      a \ref task.Task "Task", or any other object with these two attributes:
    * metadata an instance of lsst.daf.base.PropertyList (or other object with add(name, value) method)
    * log an instance of lsst.log.Log
    @param pairs    a collection of (name, value) pairs
    @param logLevel log level (an lsst.log level constant, such as lsst.log.Log.DEBUG)
    """
    strList = []
    for name, value in pairs:
        try:
            obj.metadata.add(name, value)
        except Exception as e:
            obj.log.fatal(
                "%s.metadata.add(name=%r, value=%r) failed with error=%s",
                type(obj).__name__, name, value, e)
        strList.append("%s=%s" % (name, value))
    log(obj.log.getName(), logLevel, "; ".join(strList))
示例#6
0
    def testBasic(self):
        """
        Test basic log output with default configuration.
        Since the default threshold is INFO, the DEBUG or TRACE
        message is not emitted.
        """
        with TestLog.StdoutCapture(self.outputFilename):
            log.configure()
            log.log(log.getDefaultLoggerName(), log.INFO, "This is INFO")
            log.info(u"This is unicode INFO")
            log.trace("This is TRACE")
            log.debug("This is DEBUG")
            log.warn("This is WARN")
            log.error("This is ERROR")
            log.fatal("This is FATAL")
            log.warn("Format %d %g %s", 3, 2.71828, "foo")
        self.check("""
root INFO: This is INFO
root INFO: This is unicode INFO
root WARN: This is WARN
root ERROR: This is ERROR
root FATAL: This is FATAL
root WARN: Format 3 2.71828 foo
""")
示例#7
0
    def testBasic(self):
        """
        Test basic log output with default configuration.
        Since the default threshold is INFO, the DEBUG or TRACE
        message is not emitted.
        """
        with TestLog.StdoutCapture(self.outputFilename):
            log.configure()
            log.log(log.getDefaultLoggerName(), log.INFO, "This is INFO")
            log.info(u"This is unicode INFO")
            log.trace("This is TRACE")
            log.debug("This is DEBUG")
            log.warn("This is WARN")
            log.error("This is ERROR")
            log.fatal("This is FATAL")
            log.warn("Format %d %g %s", 3, 2.71828, "foo")
        self.check("""
root INFO: This is INFO
root INFO: This is unicode INFO
root WARN: This is WARN
root ERROR: This is ERROR
root FATAL: This is FATAL
root WARN: Format 3 2.71828 foo
""")
示例#8
0
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# 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 GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#

from .version import *   # generated by sconsUtils unless you tell it not to
try:
    from .runEotestTask import *
except ImportError:
    import lsst.log as log
    log.log("cp.pipe __init__", log.WARN, "eotest module not found; runEotestTask not available")

from .makeBrighterFatterKernel import *
from .defects import *
from .ptc import *
from .cpCombine import *
from .measureCrosstalk import *
from .linearity import *
示例#9
0
    def _buildCellSet(self, exposure, referencePsfModel):
        """!Build a SpatialCellSet for use with the solve method

        @param exposure: The science exposure that will be convolved; must contain a Psf
        @param referencePsfModel: Psf model to match to

        @return
            -kernelCellSet: a SpatialCellSet to be used by self._solve
            -referencePsfModel: Validated and/or modified reference model used to populate the SpatialCellSet

        If the reference Psf model and science Psf model have different dimensions,
        adjust the referencePsfModel (the model to which the exposure PSF will be matched)
        to match that of the science Psf. If the science Psf dimensions vary across the image,
        as is common with a WarpedPsf, either pad or clip (depending on config.padPsf)
        the dimensions to be constant.
        """
        scienceBBox = exposure.getBBox()
        sciencePsfModel = exposure.getPsf()

        dimenR = referencePsfModel.getLocalKernel().getDimensions()
        psfWidth, psfHeight = dimenR

        regionSizeX, regionSizeY = scienceBBox.getDimensions()
        scienceX0, scienceY0 = scienceBBox.getMin()

        sizeCellX = self.kConfig.sizeCellX
        sizeCellY = self.kConfig.sizeCellY

        kernelCellSet = afwMath.SpatialCellSet(
            afwGeom.Box2I(afwGeom.Point2I(scienceX0, scienceY0),
                          afwGeom.Extent2I(regionSizeX, regionSizeY)),
            sizeCellX, sizeCellY
        )

        nCellX = regionSizeX//sizeCellX
        nCellY = regionSizeY//sizeCellY

        if nCellX == 0 or nCellY == 0:
            raise ValueError("Exposure dimensions=%s and sizeCell=(%s, %s). Insufficient area to match" %
                             (scienceBBox.getDimensions(), sizeCellX, sizeCellY))

        # Survey the PSF dimensions of the Spatial Cell Set
        # to identify the minimum enclosed or maximum bounding square BBox.
        widthList = []
        heightList = []
        for row in range(nCellY):
            posY = sizeCellY*row + sizeCellY//2 + scienceY0
            for col in range(nCellX):
                posX = sizeCellX*col + sizeCellX//2 + scienceX0
                widthS, heightS = sciencePsfModel.computeBBox(afwGeom.Point2D(posX, posY)).getDimensions()
                widthList.append(widthS)
                heightList.append(heightS)

        psfSize = max(max(heightList), max(widthList))

        if self.config.doAutoPadPsf:
            minPsfSize = nextOddInteger(self.kConfig.kernelSize*self.config.autoPadPsfTo)
            paddingPix = max(0, minPsfSize - psfSize)
        else:
            if self.config.padPsfBy % 2 != 0:
                raise ValueError("Config padPsfBy (%i pixels) must be even number." %
                                 self.config.padPsfBy)
            paddingPix = self.config.padPsfBy

        if paddingPix > 0:
            self.log.info("Padding Science PSF from (%s, %s) to (%s, %s) pixels" %
                          (psfSize, psfSize, paddingPix + psfSize, paddingPix + psfSize))
            psfSize += paddingPix

        # Check that PSF is larger than the matching kernel
        maxKernelSize = psfSize - 1
        if maxKernelSize % 2 == 0:
            maxKernelSize -= 1
        if self.kConfig.kernelSize > maxKernelSize:
            message = """
                Kernel size (%d) too big to match Psfs of size %d.
                Please reconfigure by setting one of the following:
                1) kernel size to <= %d
                2) doAutoPadPsf=True
                3) padPsfBy to >= %s
                """ % (self.kConfig.kernelSize, psfSize,
                       maxKernelSize, self.kConfig.kernelSize - maxKernelSize)
            raise ValueError(message)

        dimenS = afwGeom.Extent2I(psfSize, psfSize)

        if (dimenR != dimenS):
            try:
                referencePsfModel = referencePsfModel.resized(psfSize, psfSize)
                self.log.info("Adjusted dimensions of reference PSF model from %s to %s" % (dimenR, dimenS))
            except Exception as e:
                self.log.warn("Zero padding or clipping the reference PSF model of type %s and dimensions %s"
                              " to the science Psf dimensions %s because: %s",
                              referencePsfModel.__class__.__name__, dimenR, dimenS, e)
            dimenR = dimenS

        policy = pexConfig.makePolicy(self.kConfig)
        for row in range(nCellY):
            # place at center of cell
            posY = sizeCellY * row + sizeCellY//2 + scienceY0

            for col in range(nCellX):
                # place at center of cell
                posX = sizeCellX * col + sizeCellX//2 + scienceX0

                log.log("TRACE4." + self.log.getName(), log.DEBUG,
                        "Creating Psf candidate at %.1f %.1f", posX, posY)

                # reference kernel image, at location of science subimage
                referenceMI = self._makePsfMaskedImage(referencePsfModel, posX, posY, dimensions=dimenR)

                # kernel image we are going to convolve
                scienceMI = self._makePsfMaskedImage(sciencePsfModel, posX, posY, dimensions=dimenR)

                # The image to convolve is the science image, to the reference Psf.
                kc = diffimLib.makeKernelCandidate(posX, posY, scienceMI, referenceMI, policy)
                kernelCellSet.insertCandidate(kc)

        import lsstDebug
        display = lsstDebug.Info(__name__).display
        displaySpatialCells = lsstDebug.Info(__name__).displaySpatialCells
        maskTransparency = lsstDebug.Info(__name__).maskTransparency
        if not maskTransparency:
            maskTransparency = 0
        if display:
            ds9.setMaskTransparency(maskTransparency)
        if display and displaySpatialCells:
            diUtils.showKernelSpatialCells(exposure.getMaskedImage(), kernelCellSet,
                                           symb="o", ctype=ds9.CYAN, ctypeUnused=ds9.YELLOW, ctypeBad=ds9.RED,
                                           size=4, frame=lsstDebug.frame, title="Image to be convolved")
            lsstDebug.frame += 1
        return pipeBase.Struct(kernelCellSet=kernelCellSet,
                               referencePsfModel=referencePsfModel,
                               )
示例#10
0
    def _solve(self, kernelCellSet, basisList, returnOnExcept=False):
        """Solve for the PSF matching kernel

        Parameters
        ----------
        kernelCellSet : `lsst.afw.math.SpatialCellSet`
            a SpatialCellSet to use in determining the matching kernel
             (typically as provided by _buildCellSet)
        basisList : `list` of `lsst.afw.math.kernel.FixedKernel`
            list of Kernels to be used in the decomposition of the spatially varying kernel
            (typically as provided by makeKernelBasisList)
        returnOnExcept : `bool`, optional
            if True then return (None, None) if an error occurs, else raise the exception

        Returns
        -------
        psfMatchingKernel : `lsst.afw.math.LinearCombinationKernel`
            Spatially varying Psf-matching kernel
        backgroundModel : `lsst.afw.math.Function2D`
            Spatially varying background-matching function

        Raises
        ------
        RuntimeError :
            If unable to determine PSF matching kernel and ``returnOnExcept==False``.
        """

        import lsstDebug
        display = lsstDebug.Info(__name__).display

        maxSpatialIterations = self.kConfig.maxSpatialIterations
        nStarPerCell = self.kConfig.nStarPerCell
        usePcaForSpatialKernel = self.kConfig.usePcaForSpatialKernel

        # Visitor for the single kernel fit
        policy = pexConfig.makePolicy(self.kConfig)
        if self.useRegularization:
            singlekv = diffimLib.BuildSingleKernelVisitorF(
                basisList, policy, self.hMat)
        else:
            singlekv = diffimLib.BuildSingleKernelVisitorF(basisList, policy)

        # Visitor for the kernel sum rejection
        ksv = diffimLib.KernelSumVisitorF(policy)

        # Main loop
        t0 = time.time()
        try:
            totalIterations = 0
            thisIteration = 0
            while (thisIteration < maxSpatialIterations):

                # Make sure there are no uninitialized candidates as active occupants of Cell
                nRejectedSkf = -1
                while (nRejectedSkf != 0):
                    log.log("TRACE1." + self.log.getName() + "._solve",
                            log.DEBUG, "Building single kernels...")
                    kernelCellSet.visitCandidates(singlekv, nStarPerCell)
                    nRejectedSkf = singlekv.getNRejected()
                    log.log(
                        "TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                        "Iteration %d, rejected %d candidates due to initial kernel fit",
                        thisIteration, nRejectedSkf)

                # Reject outliers in kernel sum
                ksv.resetKernelSum()
                ksv.setMode(diffimLib.KernelSumVisitorF.AGGREGATE)
                kernelCellSet.visitCandidates(ksv, nStarPerCell)
                ksv.processKsumDistribution()
                ksv.setMode(diffimLib.KernelSumVisitorF.REJECT)
                kernelCellSet.visitCandidates(ksv, nStarPerCell)

                nRejectedKsum = ksv.getNRejected()
                log.log(
                    "TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                    "Iteration %d, rejected %d candidates due to kernel sum",
                    thisIteration, nRejectedKsum)

                # Do we jump back to the top without incrementing thisIteration?
                if nRejectedKsum > 0:
                    totalIterations += 1
                    continue

                # 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

                if (usePcaForSpatialKernel):
                    log.log("TRACE0." + self.log.getName() + "._solve",
                            log.DEBUG, "Building Pca basis")

                    nRejectedPca, spatialBasisList = self._createPcaBasis(
                        kernelCellSet, nStarPerCell, policy)
                    log.log(
                        "TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                        "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
                    if (nRejectedPca > 0):
                        totalIterations += 1
                        continue
                else:
                    spatialBasisList = basisList

                # We have gotten on to the spatial modeling part
                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()

                # Check the quality of the spatial fit (look at residuals)
                assesskv = diffimLib.AssessSpatialKernelVisitorF(
                    spatialKernel, spatialBackground, policy)
                kernelCellSet.visitCandidates(assesskv, nStarPerCell)
                nRejectedSpatial = assesskv.getNRejected()
                nGoodSpatial = assesskv.getNGood()
                log.log(
                    "TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                    "Iteration %d, rejected %d candidates due to spatial kernel fit",
                    thisIteration, nRejectedSpatial)
                log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                        "%d candidates used in fit", nGoodSpatial)

                # If only nGoodSpatial == 0, might be other candidates in the cells
                if nGoodSpatial == 0 and nRejectedSpatial == 0:
                    raise RuntimeError("No kernel candidates for spatial fit")

                if nRejectedSpatial == 0:
                    # Nothing rejected, finished with spatial fit
                    break

                # Otherwise, iterate on...
                thisIteration += 1

            # Final fit if above did not converge
            if (nRejectedSpatial > 0) and (thisIteration
                                           == maxSpatialIterations):
                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()

            spatialSolution = spatialkv.getKernelSolution()

        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

        t1 = time.time()
        log.log("TRACE0." + self.log.getName() + "._solve", log.DEBUG,
                "Total time to compute the spatial kernel : %.2f s", (t1 - t0))

        if display:
            self._displayDebug(kernelCellSet, spatialKernel, spatialBackground)

        self._diagnostic(kernelCellSet, spatialSolution, spatialKernel,
                         spatialBackground)

        return spatialSolution, spatialKernel, spatialBackground
示例#11
0
    def _solve(self, kernelCellSet, basisList, returnOnExcept=False):
        """Solve for the PSF matching kernel

        Parameters
        ----------
        kernelCellSet : `lsst.afw.math.SpatialCellSet`
            a SpatialCellSet to use in determining the matching kernel
             (typically as provided by _buildCellSet)
        basisList : `list` of `lsst.afw.math.kernel.FixedKernel`
            list of Kernels to be used in the decomposition of the spatially varying kernel
            (typically as provided by makeKernelBasisList)
        returnOnExcept : `bool`, optional
            if True then return (None, None) if an error occurs, else raise the exception

        Returns
        -------
        psfMatchingKernel : `lsst.afw.math.LinearCombinationKernel`
            Spatially varying Psf-matching kernel
        backgroundModel : `lsst.afw.math.Function2D`
            Spatially varying background-matching function

        Raises
        ------
        RuntimeError :
            If unable to determine PSF matching kernel and ``returnOnExcept==False``.
        """

        import lsstDebug
        display = lsstDebug.Info(__name__).display

        maxSpatialIterations = self.kConfig.maxSpatialIterations
        nStarPerCell = self.kConfig.nStarPerCell
        usePcaForSpatialKernel = self.kConfig.usePcaForSpatialKernel

        # Visitor for the single kernel fit
        policy = pexConfig.makePolicy(self.kConfig)
        if self.useRegularization:
            singlekv = diffimLib.BuildSingleKernelVisitorF(basisList, policy, self.hMat)
        else:
            singlekv = diffimLib.BuildSingleKernelVisitorF(basisList, policy)

        # Visitor for the kernel sum rejection
        ksv = diffimLib.KernelSumVisitorF(policy)

        # Main loop
        t0 = time.time()
        try:
            totalIterations = 0
            thisIteration = 0
            while (thisIteration < maxSpatialIterations):

                # Make sure there are no uninitialized candidates as active occupants of Cell
                nRejectedSkf = -1
                while (nRejectedSkf != 0):
                    log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                            "Building single kernels...")
                    kernelCellSet.visitCandidates(singlekv, nStarPerCell)
                    nRejectedSkf = singlekv.getNRejected()
                    log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                            "Iteration %d, rejected %d candidates due to initial kernel fit",
                            thisIteration, nRejectedSkf)

                # Reject outliers in kernel sum
                ksv.resetKernelSum()
                ksv.setMode(diffimLib.KernelSumVisitorF.AGGREGATE)
                kernelCellSet.visitCandidates(ksv, nStarPerCell)
                ksv.processKsumDistribution()
                ksv.setMode(diffimLib.KernelSumVisitorF.REJECT)
                kernelCellSet.visitCandidates(ksv, nStarPerCell)

                nRejectedKsum = ksv.getNRejected()
                log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                        "Iteration %d, rejected %d candidates due to kernel sum",
                        thisIteration, nRejectedKsum)

                # Do we jump back to the top without incrementing thisIteration?
                if nRejectedKsum > 0:
                    totalIterations += 1
                    continue

                # 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

                if (usePcaForSpatialKernel):
                    log.log("TRACE0." + self.log.getName() + "._solve", log.DEBUG,
                            "Building Pca basis")

                    nRejectedPca, spatialBasisList = self._createPcaBasis(kernelCellSet, nStarPerCell, policy)
                    log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                            "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
                    if (nRejectedPca > 0):
                        totalIterations += 1
                        continue
                else:
                    spatialBasisList = basisList

                # We have gotten on to the spatial modeling part
                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()

                # Check the quality of the spatial fit (look at residuals)
                assesskv = diffimLib.AssessSpatialKernelVisitorF(spatialKernel, spatialBackground, policy)
                kernelCellSet.visitCandidates(assesskv, nStarPerCell)
                nRejectedSpatial = assesskv.getNRejected()
                nGoodSpatial = assesskv.getNGood()
                log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                        "Iteration %d, rejected %d candidates due to spatial kernel fit",
                        thisIteration, nRejectedSpatial)
                log.log("TRACE1." + self.log.getName() + "._solve", log.DEBUG,
                        "%d candidates used in fit", nGoodSpatial)

                # If only nGoodSpatial == 0, might be other candidates in the cells
                if nGoodSpatial == 0 and nRejectedSpatial == 0:
                    raise RuntimeError("No kernel candidates for spatial fit")

                if nRejectedSpatial == 0:
                    # Nothing rejected, finished with spatial fit
                    break

                # Otherwise, iterate on...
                thisIteration += 1

            # Final fit if above did not converge
            if (nRejectedSpatial > 0) and (thisIteration == maxSpatialIterations):
                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()

            spatialSolution = spatialkv.getKernelSolution()

        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

        t1 = time.time()
        log.log("TRACE0." + self.log.getName() + "._solve", log.DEBUG,
                "Total time to compute the spatial kernel : %.2f s", (t1 - t0))

        if display:
            self._displayDebug(kernelCellSet, spatialKernel, spatialBackground)

        self._diagnostic(kernelCellSet, spatialSolution, spatialKernel, spatialBackground)

        return spatialSolution, spatialKernel, spatialBackground
示例#12
0
    def _createPcaBasis(self, kernelCellSet, nStarPerCell, policy):
        """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.

        Parameters
        ----------
        kernelCellSet : `lsst.afw.math.SpatialCellSet`
            a SpatialCellSet containing KernelCandidates, from which components are derived
        nStarPerCell : `int`
            the number of stars per cell to visit when doing the PCA
        policy : `lsst.pex.policy.Policy`
            input policy controlling the single kernel visitor

        Returns
        -------
        nRejectedPca : `int`
            number of KernelCandidates rejected during PCA loop
        spatialBasisList : `list` of `lsst.afw.math.kernel.FixedKernel`
            basis list containing the principal shapes as Kernels

        Raises
        ------
        RuntimeError
            If the Eigenvalues sum to zero.
        """
        nComponents = self.kConfig.numPrincipalComponents
        imagePca = diffimLib.KernelPcaD()
        importStarVisitor = diffimLib.KernelPcaVisitorF(imagePca)
        kernelCellSet.visitCandidates(importStarVisitor, nStarPerCell)
        if self.kConfig.subtractMeanForPca:
            importStarVisitor.subtractMean()
        imagePca.analyze()

        eigenValues = imagePca.getEigenValues()
        pcaBasisList = importStarVisitor.getEigenKernels()

        eSum = np.sum(eigenValues)
        if eSum == 0.0:
            raise RuntimeError("Eigenvalues sum to zero")
        for j in range(len(eigenValues)):
            log.log("TRACE5." + self.log.getName() + "._solve", log.DEBUG,
                    "Eigenvalue %d : %f (%f)", j, eigenValues[j], eigenValues[j]/eSum)

        nToUse = min(nComponents, len(eigenValues))
        trimBasisList = []
        for j in range(nToUse):
            # Check for NaNs?
            kimage = afwImage.ImageD(pcaBasisList[j].getDimensions())
            pcaBasisList[j].computeImage(kimage, False)
            if not (True in np.isnan(kimage.getArray())):
                trimBasisList.append(pcaBasisList[j])

        # Put all the power in the first kernel, which will not vary spatially
        spatialBasisList = diffimLib.renormalizeKernelList(trimBasisList)

        # New Kernel visitor for this new basis list (no regularization explicitly)
        singlekvPca = diffimLib.BuildSingleKernelVisitorF(spatialBasisList, policy)
        singlekvPca.setSkipBuilt(False)
        kernelCellSet.visitCandidates(singlekvPca, nStarPerCell)
        singlekvPca.setSkipBuilt(True)
        nRejectedPca = singlekvPca.getNRejected()

        return nRejectedPca, spatialBasisList