Exemplo n.º 1
0
    def test_auto_convolveScience(self):
        """Test that auto mode gives the same result as convolveScience when
        the science psf is the smaller.
        """
        noiseLevel = 1.
        science, sources = makeTestImage(psfSize=2.0,
                                         noiseLevel=noiseLevel,
                                         noiseSeed=6)
        template, _ = makeTestImage(psfSize=3.0,
                                    noiseLevel=noiseLevel,
                                    noiseSeed=7,
                                    templateBorderSize=20,
                                    doApplyCalibration=True)
        config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
        config.doSubtractBackground = False
        config.mode = "convolveScience"

        task = subtractImages.AlardLuptonSubtractTask(config=config)
        output = task.run(template.clone(), science.clone(), sources)

        config.mode = "auto"
        task = subtractImages.AlardLuptonSubtractTask(config=config)
        outputAuto = task.run(template, science, sources)
        self.assertMaskedImagesEqual(output.difference.maskedImage,
                                     outputAuto.difference.maskedImage)
Exemplo n.º 2
0
    def test_order_equal_images(self):
        """Verify that the result is the same regardless of convolution mode
        if the images are equivalent.
        """
        noiseLevel = .1
        seed1 = 6
        seed2 = 7
        science1, sources1 = makeTestImage(psfSize=2.0,
                                           noiseLevel=noiseLevel,
                                           noiseSeed=seed1)
        template1, _ = makeTestImage(psfSize=2.0,
                                     noiseLevel=noiseLevel,
                                     noiseSeed=seed2,
                                     templateBorderSize=0,
                                     doApplyCalibration=True)
        config1 = subtractImages.AlardLuptonSubtractTask.ConfigClass()
        config1.mode = "convolveTemplate"
        config1.doSubtractBackground = False
        task1 = subtractImages.AlardLuptonSubtractTask(config=config1)
        results_convolveTemplate = task1.run(template1, science1, sources1)

        science2, sources2 = makeTestImage(psfSize=2.0,
                                           noiseLevel=noiseLevel,
                                           noiseSeed=seed1)
        template2, _ = makeTestImage(psfSize=2.0,
                                     noiseLevel=noiseLevel,
                                     noiseSeed=seed2,
                                     templateBorderSize=0,
                                     doApplyCalibration=True)
        config2 = subtractImages.AlardLuptonSubtractTask.ConfigClass()
        config2.mode = "convolveScience"
        config2.doSubtractBackground = False
        task2 = subtractImages.AlardLuptonSubtractTask(config=config2)
        results_convolveScience = task2.run(template2, science2, sources2)
        diff1 = science1.maskedImage.clone()
        diff1 -= template1.maskedImage
        diff2 = science2.maskedImage.clone()
        diff2 -= template2.maskedImage
        self.assertFloatsAlmostEqual(
            results_convolveTemplate.difference.image.array,
            diff1.image.array,
            atol=noiseLevel * 5.)
        self.assertFloatsAlmostEqual(
            results_convolveScience.difference.image.array,
            diff2.image.array,
            atol=noiseLevel * 5.)
        diffErr = noiseLevel * 2
        self.assertMaskedImagesAlmostEqual(
            results_convolveTemplate.difference.maskedImage,
            results_convolveScience.difference.maskedImage,
            atol=diffErr * 5.)
Exemplo n.º 3
0
        def _run_and_check_images(doDecorrelation):
            """Check that the metadata is correct with or without decorrelation.
            """
            config.doDecorrelation = doDecorrelation
            task = subtractImages.AlardLuptonSubtractTask(config=config)
            output = task.run(template.clone(), science.clone(), sources)
            if doDecorrelation:
                # Decorrelation requires recalculating the PSF,
                #  so it will not be the same as the input
                psfOutSize = getPsfFwhm(template.psf)
                self.assertFloatsAlmostEqual(psfSize, psfOutSize)
            else:
                psfOut = output.difference.psf
                psfAvgPos = psfOut.getAveragePosition()
                psfOutImg = psfOut.computeKernelImage(psfAvgPos)
                self.assertImagesAlmostEqual(psfImg, psfOutImg)

            # check PSF, WCS, bbox, filterLabel, photoCalib, aperture correction
            self._compare_apCorrMaps(apCorrMap,
                                     output.difference.info.getApCorrMap())
            self.assertWcsAlmostEqualOverBBox(science.wcs,
                                              output.difference.wcs,
                                              science.getBBox())
            self.assertEqual(science.filter, output.difference.filter)
            self.assertEqual(science.photoCalib, output.difference.photoCalib)
Exemplo n.º 4
0
        def _run_and_check_images(config, statsCtrl, mode):
            """Check that the fit background matches the input model.
            """
            config.mode = mode
            task = subtractImages.AlardLuptonSubtractTask(config=config)
            output = task.run(template.clone(), science.clone(), sources)

            # We should be fitting the same number of parameters as were in the input model
            self.assertEqual(output.backgroundModel.getNParameters(),
                             background_model.getNParameters())

            # The parameters of the background fit should be close to the input model
            self.assertFloatsAlmostEqual(np.array(
                output.backgroundModel.getParameters()),
                                         np.array(params),
                                         rtol=0.3)

            # stddev of difference image should be close to expected value.
            # This will fail if we have mis-subtracted the background.
            stdVal = _computeRobustStatistics(output.difference.image,
                                              output.difference.mask,
                                              statsCtrl,
                                              statistic=afwMath.STDEV)
            self.assertFloatsAlmostEqual(stdVal,
                                         np.sqrt(2) * noiseLevel,
                                         rtol=0.1)
Exemplo n.º 5
0
 def test_equal_images(self):
     """Test that running with enough sources produces reasonable output,
     with the same size psf in the template and science.
     """
     noiseLevel = 1.
     science, sources = makeTestImage(psfSize=2.4,
                                      noiseLevel=noiseLevel,
                                      noiseSeed=6)
     template, _ = makeTestImage(psfSize=2.4,
                                 noiseLevel=noiseLevel,
                                 noiseSeed=7,
                                 templateBorderSize=20,
                                 doApplyCalibration=True)
     config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
     config.doSubtractBackground = False
     task = subtractImages.AlardLuptonSubtractTask(config=config)
     output = task.run(template, science, sources)
     # There shoud be no NaN values in the difference image
     self.assertTrue(np.all(np.isfinite(output.difference.image.array)))
     # Mean of difference image should be close to zero.
     meanError = noiseLevel / np.sqrt(output.difference.image.array.size)
     # Make sure to include pixels with the DETECTED mask bit set.
     statsCtrl = _makeStats(badMaskPlanes=("EDGE", "BAD", "NO_DATA"))
     differenceMean = _computeRobustStatistics(output.difference.image,
                                               output.difference.mask,
                                               statsCtrl)
     self.assertFloatsAlmostEqual(differenceMean, 0, atol=5 * meanError)
     # stddev of difference image should be close to expected value.
     differenceStd = _computeRobustStatistics(output.difference.image,
                                              output.difference.mask,
                                              _makeStats(),
                                              statistic=afwMath.STDEV)
     self.assertFloatsAlmostEqual(differenceStd,
                                  np.sqrt(2) * noiseLevel,
                                  rtol=0.1)
Exemplo n.º 6
0
        def _run_and_check_images(science,
                                  template,
                                  sources,
                                  statsCtrl,
                                  doDecorrelation,
                                  doScaleVariance,
                                  scaleFactor=1.):
            """Check that the variance plane matches the expected value for
            different configurations of ``doDecorrelation`` and ``doScaleVariance``.
            """

            config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
            config.doSubtractBackground = False
            config.doDecorrelation = doDecorrelation
            config.doScaleVariance = doScaleVariance
            task = subtractImages.AlardLuptonSubtractTask(config=config)
            output = task.run(template.clone(), science.clone(), sources)
            if doScaleVariance:
                self.assertFloatsAlmostEqual(
                    task.metadata["scaleTemplateVarianceFactor"],
                    scaleFactor,
                    atol=0.05)
                self.assertFloatsAlmostEqual(
                    task.metadata["scaleScienceVarianceFactor"],
                    scaleFactor,
                    atol=0.05)

            templateNoise = _computeRobustStatistics(template.variance,
                                                     template.mask, statsCtrl)
            if doDecorrelation:
                scienceNoise = _computeRobustStatistics(
                    science.variance, science.mask, statsCtrl)
            else:
                scienceNoise = _computeRobustStatistics(
                    output.matchedScience.variance, output.matchedScience.mask,
                    statsCtrl)

            if doScaleVariance:
                templateNoise *= scaleFactor
                scienceNoise *= scaleFactor

            varMean = _computeRobustStatistics(output.difference.variance,
                                               output.difference.mask,
                                               statsCtrl)
            self.assertFloatsAlmostEqual(varMean,
                                         scienceNoise + templateNoise,
                                         rtol=0.1)
Exemplo n.º 7
0
    def test_symmetry(self):
        """Test that convolving the science and convolving the template are
        symmetric: if the psfs are switched between them, the difference image
        should be nearly the same.
        """
        noiseLevel = 1.
        # Don't include a border for the template, in order to make the results
        #  comparable when we swap which image is treated as the "science" image.
        science, sources = makeTestImage(psfSize=2.0,
                                         noiseLevel=noiseLevel,
                                         noiseSeed=6,
                                         templateBorderSize=0)
        template, _ = makeTestImage(psfSize=3.0,
                                    noiseLevel=noiseLevel,
                                    noiseSeed=7,
                                    templateBorderSize=0,
                                    doApplyCalibration=True)
        config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
        config.mode = 'auto'
        config.doSubtractBackground = False
        task = subtractImages.AlardLuptonSubtractTask(config=config)

        # The science image will be modified in place, so use a copy for the second run.
        science_better = task.run(template.clone(), science.clone(), sources)
        template_better = task.run(science, template, sources)

        delta = template_better.difference.clone()
        delta.image -= science_better.difference.image
        delta.variance -= science_better.difference.variance
        delta.mask.array -= science_better.difference.mask.array

        statsCtrl = _makeStats()
        # Mean of delta should be very close to zero.
        nGoodPix = np.sum(np.isfinite(delta.image.array))
        meanError = 2 * noiseLevel / np.sqrt(nGoodPix)
        deltaMean = _computeRobustStatistics(delta.image, delta.mask,
                                             statsCtrl)
        deltaStd = _computeRobustStatistics(delta.image,
                                            delta.mask,
                                            statsCtrl,
                                            statistic=afwMath.STDEV)
        self.assertFloatsAlmostEqual(deltaMean, 0, atol=5 * meanError)
        # stddev of difference image should be close to expected value
        self.assertFloatsAlmostEqual(deltaStd,
                                     2 * np.sqrt(2) * noiseLevel,
                                     rtol=.1)
Exemplo n.º 8
0
 def test_mismatched_template(self):
     """Test that an error is raised if the template
     does not fully contain the science image.
     """
     xSize = 200
     ySize = 200
     science, sources = makeTestImage(psfSize=2.4,
                                      xSize=xSize + 20,
                                      ySize=ySize + 20)
     template, _ = makeTestImage(psfSize=2.4,
                                 xSize=xSize,
                                 ySize=ySize,
                                 doApplyCalibration=True)
     config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
     task = subtractImages.AlardLuptonSubtractTask(config=config)
     with self.assertRaises(AssertionError):
         task.run(template, science, sources)
Exemplo n.º 9
0
 def test_few_sources(self):
     """Test with only 1 source, to check that we get a useful error.
     """
     xSize = 256
     ySize = 256
     science, sources = makeTestImage(psfSize=2.4,
                                      nSrc=1,
                                      xSize=xSize,
                                      ySize=ySize)
     template, _ = makeTestImage(psfSize=2.0,
                                 nSrc=1,
                                 xSize=xSize,
                                 ySize=ySize,
                                 doApplyCalibration=True)
     config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
     task = subtractImages.AlardLuptonSubtractTask(config=config)
     with self.assertRaisesRegex(
             lsst.pex.exceptions.Exception,
             'Unable to determine kernel sum; 0 candidates'):
         task.run(template, science, sources)
Exemplo n.º 10
0
        def _run_and_check_images(statsCtrl, statsCtrlDetect,
                                  scienceNoiseLevel, templateNoiseLevel):
            science, sources = makeTestImage(psfSize=3.0,
                                             noiseLevel=scienceNoiseLevel,
                                             noiseSeed=6)
            template, _ = makeTestImage(psfSize=2.0,
                                        noiseLevel=templateNoiseLevel,
                                        noiseSeed=7,
                                        templateBorderSize=20,
                                        doApplyCalibration=True)
            config = subtractImages.AlardLuptonSubtractTask.ConfigClass()
            config.doSubtractBackground = False
            task = subtractImages.AlardLuptonSubtractTask(config=config)
            output = task.run(template, science, sources)
            self.assertFloatsAlmostEqual(
                task.metadata["scaleTemplateVarianceFactor"], 1., atol=.05)
            self.assertFloatsAlmostEqual(
                task.metadata["scaleScienceVarianceFactor"], 1., atol=.05)
            # There should be no NaNs in the image if we convolve the template with a buffer
            self.assertTrue(np.all(np.isfinite(output.difference.image.array)))
            # Mean of difference image should be close to zero.
            meanError = (scienceNoiseLevel + templateNoiseLevel) / np.sqrt(
                output.difference.image.array.size)

            diffimMean = _computeRobustStatistics(output.difference.image,
                                                  output.difference.mask,
                                                  statsCtrlDetect)
            self.assertFloatsAlmostEqual(diffimMean, 0, atol=5 * meanError)
            # stddev of difference image should be close to expected value.
            noiseLevel = np.sqrt(scienceNoiseLevel**2 + templateNoiseLevel**2)
            varianceMean = _computeRobustStatistics(output.difference.variance,
                                                    output.difference.mask,
                                                    statsCtrl)
            diffimStd = _computeRobustStatistics(output.difference.image,
                                                 output.difference.mask,
                                                 statsCtrl,
                                                 statistic=afwMath.STDEV)
            self.assertFloatsAlmostEqual(varianceMean, noiseLevel**2, rtol=0.1)
            self.assertFloatsAlmostEqual(diffimStd, noiseLevel, rtol=0.1)