Ejemplo n.º 1
0
 def runIsr(self, doCrosstalk):
     """Run DecamCpIsrTask with or without crosstalk correction
     """
     dataRef = self.butler.dataRef('raw', dataId=self.dataId)
     rawExposure = self.butler.get('raw', dataId=self.dataId)
     camera = dataRef.get('camera')
     config = getObsDecamConfig(IsrTask)
     config.doCrosstalk = doCrosstalk
     decamCpIsrTask = IsrTask(config=config)
     isrData = decamCpIsrTask.readIsrData(dataRef, rawExposure)
     isrResult = decamCpIsrTask.run(rawExposure, camera=camera, **isrData.getDict())
     return isrResult
class EmpiricalVarianceTestCast(lsst.utils.tests.TestCase):
    def setUp(self):
        """Constructs a CCD with two amplifiers and prepares for ISR"""
        np.random.seed(12345)
        baseValue = 100.0
        gain = 1.0
        readNoise = 123456789.0
        saturation = 987654321.0
        height = 234
        imageSize = Extent2I(123, height)
        overscanSize = Extent2I(16, height)
        self.sigma = 1.234

        # Set up the various regions
        overscan1 = Box2I(Point2I(0, 0), overscanSize)
        image1 = Box2I(Point2I(overscanSize[0], 0), imageSize)
        image2 = Box2I(Point2I(overscanSize[0] + imageSize[0], 0), imageSize)
        overscan2 = Box2I(Point2I(overscanSize[0] + 2*imageSize[0], 0), overscanSize)

        leftBox = Box2I(overscan1.getMin(), Extent2I(overscan1.getWidth() + image1.getWidth(), height))
        rightBox = Box2I(image2.getMin(), Extent2I(image2.getWidth() + overscan2.getWidth(), height))

        target1 = Box2I(Point2I(0, 0), imageSize)
        target2 = Box2I(Point2I(image1.getWidth(), 0), imageSize)

        # Set the pixels
        exposure = ExposureF(Box2I(Point2I(0, 0), Extent2I(imageSize[0]*2 + overscanSize[0]*2, height)))
        yy = np.arange(0, height, 1, dtype=np.float32)
        leftImage = ExposureF(exposure, leftBox)
        leftImage.image.array[:] = baseValue + yy[:, np.newaxis]
        rightImage = ExposureF(exposure, rightBox)
        rightImage.image.array[:] = baseValue - yy[:, np.newaxis]

        leftOverscan = ExposureF(exposure, overscan1)
        leftOverscan.image.array += np.random.normal(0.0, self.sigma, leftOverscan.image.array.shape)
        rightOverscan = ExposureF(exposure, overscan2)
        rightOverscan.image.array += np.random.normal(0.0, self.sigma, leftOverscan.image.array.shape)
        exposure.mask.array[:] = 0.0
        exposure.variance.array[:] = np.nan

        # Construct the detectors
        amps = AmpInfoCatalog(AmpInfoTable.makeMinimalSchema())
        makeAmplifier(amps, "left", target1, image1, overscan1, gain, readNoise, saturation)
        makeAmplifier(amps, "right", target2, image2, overscan2, gain, readNoise, saturation)
        ccdBox = Box2I(Point2I(0, 0), Extent2I(image1.getWidth() + image2.getWidth(), height))
        ccd = Detector("detector", 1, SCIENCE, "det1", ccdBox, amps, Orientation(), Extent2D(1.0, 1.0), {})
        exposure.setDetector(ccd)
        header = PropertyList()
        header.add("EXPTIME", 0.0)
        exposure.getInfo().setVisitInfo(VisitInfo(header))

        self.exposure = exposure
        self.config = IsrTask.ConfigClass()

        # Disable everything we don't care about
        self.config.doBias = False
        self.config.doDark = False
        self.config.doFlat = False
        self.config.doFringe = False
        self.config.doDefect = False
        self.config.doAddDistortionModel = False
        self.config.doWrite = False
        self.config.expectWcs = False
        self.config.doLinearize = False
        self.config.doCrosstalk = False
        self.config.doBrighterFatter = False
        self.config.doAttachTransmissionCurve = False

        # Set the things that match our test setup
        self.config.overscanFitType = "CHEB"
        self.config.overscanOrder = 1
        self.config.doEmpiricalReadNoise = True

        self.task = IsrTask(config=self.config)

    def tearDown(self):
        del self.exposure

    def testEmpiricalVariance(self):
        results = self.task.run(self.exposure)
        postIsr = results.exposure
        self.assertFloatsEqual(postIsr.mask.array, 0)
        # Image is not exactly zero because the noise in the overscan (required to be able to set
        # the empirical variance) leads to a slight misestimate in the polynomial fit.
        self.assertFloatsAlmostEqual(postIsr.image.array, 0.0, atol=5.0e-2)
        self.assertFloatsAlmostEqual(postIsr.variance.array, self.sigma**2, rtol=5.0e-2)
Ejemplo n.º 3
0
class IsrTaskUnTrimmedTestCases(lsst.utils.tests.TestCase):
    """Test IsrTask methods using untrimmed raw data.
    """
    def setUp(self):
        self.config = IsrTaskConfig()
        self.config.qa = IsrQaConfig()
        self.task = IsrTask(config=self.config)

        self.mockConfig = isrMock.IsrMockConfig()
        self.mockConfig.isTrimmed = False
        self.doGenerateImage = True
        self.dataRef = isrMock.DataRefMock(config=self.mockConfig)
        self.camera = isrMock.IsrMock(config=self.mockConfig).getCamera()

        self.inputExp = isrMock.RawMock(config=self.mockConfig).run()
        self.amp = self.inputExp.getDetector()[0]
        self.mi = self.inputExp.getMaskedImage()

    def batchSetConfiguration(self, value):
        """Set the configuration state to a consistent value.

        Disable options we do not need as well.

        Parameters
        ----------
        value : `bool`
            Value to switch common ISR configuration options to.
        """
        self.config.qa.flatness.meshX = 20
        self.config.qa.flatness.meshY = 20
        self.config.doWrite = False
        self.config.doLinearize = False
        self.config.doCrosstalk = False

        self.config.doConvertIntToFloat = value
        self.config.doSaturation = value
        self.config.doSuspect = value
        self.config.doSetBadRegions = value
        self.config.doOverscan = value
        self.config.doBias = value
        self.config.doVariance = value
        self.config.doWidenSaturationTrails = value
        self.config.doBrighterFatter = value
        self.config.doDefect = value
        self.config.doSaturationInterpolation = value
        self.config.doDark = value
        self.config.doStrayLight = value
        self.config.doFlat = value
        self.config.doFringe = value
        self.config.doMeasureBackground = value
        self.config.doVignette = value
        self.config.doAttachTransmissionCurve = value
        self.config.doUseOpticsTransmission = value
        self.config.doUseFilterTransmission = value
        self.config.doUseSensorTransmission = value
        self.config.doUseAtmosphereTransmission = value
        self.config.qa.saveStats = value
        self.config.qa.doThumbnailOss = value
        self.config.qa.doThumbnailFlattened = value

        self.config.doApplyGains = not value
        self.config.doCameraSpecificMasking = value

    def validateIsrResults(self):
        """results should be a struct with components that are
        not None if included in the configuration file.

        Returns
        -------
        results : `pipeBase.Struct`
            Results struct generated from the current ISR configuration.
        """
        self.task = IsrTask(config=self.config)
        results = self.task.run(
            self.inputExp,
            camera=self.camera,
            bias=self.dataRef.get("bias"),
            dark=self.dataRef.get("dark"),
            flat=self.dataRef.get("flat"),
            bfKernel=self.dataRef.get("bfKernel"),
            defects=self.dataRef.get("defects"),
            fringes=Struct(fringes=self.dataRef.get("fringe"), seed=1234),
            opticsTransmission=self.dataRef.get("transmission_"),
            filterTransmission=self.dataRef.get("transmission_"),
            sensorTransmission=self.dataRef.get("transmission_"),
            atmosphereTransmission=self.dataRef.get("transmission_"))

        self.assertIsInstance(results, Struct)
        self.assertIsInstance(results.exposure, afwImage.Exposure)
        return results

    def test_overscanCorrection(self):
        """Expect that this should reduce the image variance with a full fit.
        The default fitType of MEDIAN will reduce the median value.

        This needs to operate on a RawMock() to have overscan data to use.

        The output types may be different when fitType != MEDIAN.
        """
        statBefore = computeImageMedianAndStd(
            self.inputExp.image[self.amp.getRawDataBBox()])
        oscanResults = self.task.overscanCorrection(self.inputExp, self.amp)
        self.assertIsInstance(oscanResults, Struct)
        self.assertIsInstance(oscanResults.imageFit, float)
        self.assertIsInstance(oscanResults.overscanFit, float)
        self.assertIsInstance(oscanResults.overscanImage,
                              afwImage.MaskedImageF)

        statAfter = computeImageMedianAndStd(
            self.inputExp.image[self.amp.getRawDataBBox()])
        self.assertLess(statAfter[0], statBefore[0])

    def test_overscanCorrectionMedianPerRow(self):
        """Expect that this should reduce the image variance with a full fit.
        fitType of MEDIAN_PER_ROW will reduce the median value.

        This needs to operate on a RawMock() to have overscan data to use.

        The output types may be different when fitType != MEDIAN_PER_ROW.
        """
        self.config.overscan.fitType = 'MEDIAN_PER_ROW'
        statBefore = computeImageMedianAndStd(
            self.inputExp.image[self.amp.getRawDataBBox()])
        oscanResults = self.task.overscanCorrection(self.inputExp, self.amp)
        self.assertIsInstance(oscanResults, Struct)
        self.assertIsInstance(oscanResults.imageFit, afwImage.ImageF)
        self.assertIsInstance(oscanResults.overscanFit, afwImage.ImageF)
        self.assertIsInstance(oscanResults.overscanImage,
                              afwImage.MaskedImageF)

        statAfter = computeImageMedianAndStd(
            self.inputExp.image[self.amp.getRawDataBBox()])
        self.assertLess(statAfter[0], statBefore[0])

    def test_runDataRef(self):
        """Expect a dataRef to be handled correctly.
        """
        self.config.doLinearize = False
        self.config.doWrite = False
        self.task = IsrTask(config=self.config)
        results = self.task.runDataRef(self.dataRef)

        self.assertIsInstance(results, Struct)
        self.assertIsInstance(results.exposure, afwImage.Exposure)

    def test_run_allTrue(self):
        """Expect successful run with expected outputs when all non-exclusive
        configuration options are on.

        Output results should be tested more precisely by the
        individual function tests.

        """
        self.batchSetConfiguration(True)
        self.validateIsrResults()

    def test_run_allFalse(self):
        """Expect successful run with expected outputs when all non-exclusive
        configuration options are off.

        Output results should be tested more precisely by the
        individual function tests.

        """
        self.batchSetConfiguration(False)
        self.validateIsrResults()

    def test_failCases(self):
        """Expect failure with crosstalk enabled.

        Output results should be tested more precisely by the
        individual function tests.
        """
        self.batchSetConfiguration(True)

        # This breaks it
        self.config.doCrosstalk = True

        with self.assertRaises(RuntimeError):
            self.validateIsrResults()

    def test_maskingCase_negativeVariance(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.doSaturation = False
        self.config.doWidenSaturationTrails = False
        self.config.doSaturationInterpolation = False
        self.config.doSuspect = False
        self.config.doSetBadRegions = False
        self.config.doDefect = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = True
        self.config.doInterpolate = False

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 40800)

    def test_maskingCase_noMasking(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.doSaturation = False
        self.config.doWidenSaturationTrails = False
        self.config.doSaturationInterpolation = False
        self.config.doSuspect = False
        self.config.doSetBadRegions = False
        self.config.doDefect = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False
        self.config.doInterpolate = False

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 0)

    def test_maskingCase_satMasking(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.saturation = 20000.0
        self.config.doSaturation = True
        self.config.doWidenSaturationTrails = True

        self.config.doSaturationInterpolation = False
        self.config.doSuspect = False
        self.config.doSetBadRegions = False
        self.config.doDefect = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False  # These are mock images.

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 0)

    def test_maskingCase_satMaskingAndInterp(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.saturation = 20000.0
        self.config.doSaturation = True
        self.config.doWidenSaturationTrails = True
        self.config.doSaturationInterpolation = True

        self.config.doSuspect = False
        self.config.doSetBadRegions = False
        self.config.doDefect = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False  # These are mock images.

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 0)

    def test_maskingCase_throughEdge(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.saturation = 20000.0
        self.config.doSaturation = True
        self.config.doWidenSaturationTrails = True
        self.config.doSaturationInterpolation = True
        self.config.numEdgeSuspect = 5
        self.config.doSuspect = True

        self.config.doSetBadRegions = False
        self.config.doDefect = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False  # These are mock images.

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 0)

    def test_maskingCase_throughDefects(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.saturation = 20000.0
        self.config.doSaturation = True
        self.config.doWidenSaturationTrails = True
        self.config.doSaturationInterpolation = True
        self.config.numEdgeSuspect = 5
        self.config.doSuspect = True
        self.config.doDefect = True

        self.config.doSetBadRegions = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False  # These are mock images.

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 2000)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 3940)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 2000)

    def test_maskingCase_throughDefectsAmpEdges(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.saturation = 20000.0
        self.config.doSaturation = True
        self.config.doWidenSaturationTrails = True
        self.config.doSaturationInterpolation = True
        self.config.numEdgeSuspect = 5
        self.config.doSuspect = True
        self.config.doDefect = True
        self.config.edgeMaskLevel = 'AMP'

        self.config.doSetBadRegions = False
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False  # These are mock images.

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 2000)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 11280)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 2000)

    def test_maskingCase_throughBad(self):
        """Test masking cases of configuration parameters.
        """
        self.batchSetConfiguration(True)
        self.config.overscanFitType = "POLY"
        self.config.overscanOrder = 1

        self.config.saturation = 20000.0
        self.config.doSaturation = True
        self.config.doWidenSaturationTrails = True
        self.config.doSaturationInterpolation = True

        self.config.doSuspect = True
        self.config.doDefect = True
        self.config.doSetBadRegions = True
        self.config.doBrighterFatter = False

        self.config.maskNegativeVariance = False  # These are mock images.

        results = self.validateIsrResults()

        self.assertEqual(countMaskedPixels(results.exposure, "SAT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "INTRP"), 2000)
        self.assertEqual(countMaskedPixels(results.exposure, "SUSPECT"), 0)
        self.assertEqual(countMaskedPixels(results.exposure, "BAD"), 2000)
Ejemplo n.º 4
0
class EmpiricalVarianceTestCast(lsst.utils.tests.TestCase):
    def setUp(self):
        """Constructs a CCD with two amplifiers and prepares for ISR"""
        np.random.seed(12345)
        baseValue = 100.0
        gain = 1.0
        readNoise = 123456789.0
        saturation = 987654321.0
        height = 234
        imageSize = Extent2I(123, height)
        overscanSize = Extent2I(16, height)
        self.sigma = 1.234

        # Set up the various regions
        overscan1 = Box2I(Point2I(0, 0), overscanSize)
        image1 = Box2I(Point2I(overscanSize[0], 0), imageSize)
        image2 = Box2I(Point2I(overscanSize[0] + imageSize[0], 0), imageSize)
        overscan2 = Box2I(Point2I(overscanSize[0] + 2 * imageSize[0], 0),
                          overscanSize)

        leftBox = Box2I(
            overscan1.getMin(),
            Extent2I(overscan1.getWidth() + image1.getWidth(), height))
        rightBox = Box2I(
            image2.getMin(),
            Extent2I(image2.getWidth() + overscan2.getWidth(), height))

        target1 = Box2I(Point2I(0, 0), imageSize)
        target2 = Box2I(Point2I(image1.getWidth(), 0), imageSize)

        # Set the pixels
        exposure = ExposureF(
            Box2I(Point2I(0, 0),
                  Extent2I(imageSize[0] * 2 + overscanSize[0] * 2, height)))
        yy = np.arange(0, height, 1, dtype=np.float32)
        leftImage = ExposureF(exposure, leftBox)
        leftImage.image.array[:] = baseValue + yy[:, np.newaxis]
        rightImage = ExposureF(exposure, rightBox)
        rightImage.image.array[:] = baseValue - yy[:, np.newaxis]

        leftOverscan = ExposureF(exposure, overscan1)
        leftOverscan.image.array += np.random.normal(
            0.0, self.sigma, leftOverscan.image.array.shape)
        rightOverscan = ExposureF(exposure, overscan2)
        rightOverscan.image.array += np.random.normal(
            0.0, self.sigma, leftOverscan.image.array.shape)
        exposure.mask.array[:] = 0.0
        exposure.variance.array[:] = np.nan

        # Construct the detectors
        amp1 = makeAmplifier("left", target1, image1, overscan1, gain,
                             readNoise, saturation)
        amp2 = makeAmplifier("right", target2, image2, overscan2, gain,
                             readNoise, saturation)
        ccdBox = Box2I(Point2I(0, 0),
                       Extent2I(image1.getWidth() + image2.getWidth(), height))
        camBuilder = cameraGeom.Camera.Builder("fakeCam")
        detBuilder = camBuilder.add("detector", 1)
        detBuilder.setSerial("det1")
        detBuilder.setBBox(ccdBox)
        detBuilder.setPixelSize(Extent2D(1.0, 1.0))
        detBuilder.setOrientation(cameraGeom.Orientation())
        detBuilder.append(amp1)
        detBuilder.append(amp2)
        cam = camBuilder.finish()
        exposure.setDetector(cam.get('detector'))

        header = PropertyList()
        header.add("EXPTIME", 0.0)
        exposure.getInfo().setVisitInfo(VisitInfo(header))

        self.exposure = exposure
        self.config = IsrTask.ConfigClass()

        # Disable everything we don't care about
        self.config.doBias = False
        self.config.doDark = False
        self.config.doFlat = False
        self.config.doFringe = False
        self.config.doDefect = False
        self.config.doWrite = False
        self.config.expectWcs = False
        self.config.doLinearize = False
        self.config.doCrosstalk = False
        self.config.doBrighterFatter = False
        self.config.doAttachTransmissionCurve = False
        self.config.doAssembleCcd = False
        self.config.doNanMasking = False
        self.config.doInterpolate = False

        self.config.maskNegativeVariance = False  # This runs on mocks.
        # Set the things that match our test setup
        self.config.overscan.fitType = "CHEB"
        self.config.overscan.order = 1
        self.config.doEmpiricalReadNoise = True

        self.task = IsrTask(config=self.config)

    def tearDown(self):
        del self.exposure

    def testEmpiricalVariance(self):
        results = self.task.run(self.exposure)
        postIsr = results.exposure

        self.assertFloatsEqual(postIsr.mask.array, 0)
        # Image is not exactly zero because the noise in the overscan (required
        # to be able to set the empirical variance) leads to a slight
        # misestimate in the polynomial fit.
        self.assertFloatsAlmostEqual(np.median(postIsr.image.array),
                                     0.0,
                                     atol=5.0e-2)
        self.assertFloatsAlmostEqual(np.nanmedian(postIsr.variance.array),
                                     self.sigma**2,
                                     rtol=5.0e-2)
    print("finished ingesting spots images")
    spots_butler = Butler(SPOTS_REPO_DIR)

    visits = []
    my_metaData = spots_butler.queryMetadata('raw', ['visit', 'dateObs'])
    for item in my_metaData:
        visits.append(item[0])
    byamp_results = []
    byamp_corrected_results = []
    for visit in visits:
        print("Getting exposure # %d"%visit)
        sys.stdout.flush()
        exposure = spots_butler.get('raw', dataId={'visit': visit, 'detector': DETECTOR})
        # Perform the instrument signature removal (mainly assembling the CCD)
        isrTask = IsrTask(config=isrConfig)
        exposure_isr = isrTask.run(exposure).exposure
        # For now, we're applying the gain manually
        ccd = exposure_isr.getDetector()
        for do_bf_corr in [False, True]:
            exposure_copy=exposure_isr.clone()            
            for amp in ccd:
                if spots_bbox.overlaps(amp.getBBox()):
                    gain = gain_data[amp.getName()]
                    img = exposure_copy.image
                    sim = img.Factory(img, amp.getBBox())
                    sim *= gain
                    print(amp.getName(), gain, amp.getBBox())
                    sys.stdout.flush()                    
                    if do_bf_corr:
                        brighterFatterCorrection(exposure_copy[amp.getBBox()],bf_kernel.kernel[amp.getName()],20,10,False)
                else: