Exemple #1
0
    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
Exemple #2
0
 def test_readIsrData_withTrans(self):
     """Test that all necessary calibration frames are retrieved.
     """
     self.config.doAttachTransmissionCurve = True
     self.task = IsrTask(config=self.config)
     results = self.task.readIsrData(self.dataRef, self.inputExp)
     self.validateIsrData(results)
Exemple #3
0
    def setUp(self):
        self.config = IsrTaskConfig()
        self.config.qa = IsrQaConfig()
        self.task = IsrTask(config=self.config)
        self.dataRef = isrMock.DataRefMock()
        self.camera = isrMock.IsrMock().getCamera()

        self.inputExp = isrMock.TrimmedRawMock().run()
        self.amp = self.inputExp.getDetector()[0]
        self.mi = self.inputExp.getMaskedImage()
Exemple #4
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)
Exemple #5
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
    def testSetPolygonIntersect(self):
        # Create a detector
        detector = DetectorWrapper().detector
        numPolygonPoints = 50
        # Create an exposure with bounding box defined by detector
        exposure = afwImage.ExposureF(detector.getBBox())
        exposure.setDetector(detector)

        pixelSizeMm = exposure.getDetector().getPixelSize()[0]

        pixX0 = exposure.getX0()
        pixY0 = exposure.getY0()
        pixX1 = pixX0 + exposure.getWidth() - 1
        pixY1 = pixY0 + exposure.getHeight() - 1

        fpCenter = exposure.getDetector().getCenter(FOCAL_PLANE)
        fpCenterX = fpCenter[0]
        fpCenterY = fpCenter[1]
        pixCenter = exposure.getDetector().getCenter(PIXELS)

        # Create an instance of IsrTask
        task = IsrTask()

        # Make a polygon that encompases entire ccd (radius of 2*max of width/height)
        fpRadius = 2.0*max(exposure.getWidth()*pixelSizeMm, exposure.getHeight()*pixelSizeMm)
        fpPolygon = makeCircularPolygon(fpCenterX, fpCenterY, fpRadius, numPolygonPoints)
        # Set the polygon that is the intersection of fpPolygon and ccd
        task.setValidPolygonIntersect(exposure, fpPolygon)
        # Since the ccd is fully contained in the fpPolygon, the intersection should be the ccdPolygon itself
        ccdPolygonPix = afwGeom.Polygon(exposure.getDetector().getCorners(PIXELS))
        self.assertEqual(exposure.getInfo().getValidPolygon(), ccdPolygonPix)

        # Make a polygon that is entirely within, but smaller than, the ccd
        # (radius of 0.2*min of width/height)
        fpRadius = 0.2*min(exposure.getWidth()*pixelSizeMm, exposure.getHeight()*pixelSizeMm)
        fpPolygon = makeCircularPolygon(fpCenterX, fpCenterY, fpRadius, numPolygonPoints)
        # Set the polygon that is the intersection of fpPolygon and ccd
        task.setValidPolygonIntersect(exposure, fpPolygon)
        # all vertices of polygon should be contained within the ccd
        for x in exposure.getInfo().getValidPolygon():
            self.assertTrue(ccdPolygonPix.contains(afwGeom.Point2D(x)))
        # intersection is smaller than the ccd
        self.assertNotEqual(exposure.getInfo().getValidPolygon(), ccdPolygonPix)

        # make a simple square polygon that partly intersects the ccd, centered at ccd center
        fpPolygonSize = max(exposure.getWidth()*pixelSizeMm, exposure.getHeight()*pixelSizeMm)
        fpPolygon = makeSquarePolygon(fpCenterX, fpCenterY, fpPolygonSize)
        task.setValidPolygonIntersect(exposure, fpPolygon)
        # Check that the polygon contains the central pixel (offset by one to actually be "contained")
        pixCenterPlusOne = afwGeom.Point2D(pixCenter[0] + 1, pixCenter[1] + 1)
        self.assertTrue(exposure.getInfo().getValidPolygon().contains(afwGeom.Point2D(pixCenterPlusOne)))
        # Check that the polygon contains the upper right ccd edge
        self.assertTrue(exposure.getInfo().getValidPolygon().contains(afwGeom.Point2D(pixX1, pixY1)))
Exemple #7
0
    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 summarizeVisit(butler, *, exp=None, extendedSummary=False, **kwargs):
    from astroquery.simbad import Simbad
    import astropy.units as u
    from astropy.time import Time
    from astropy.coordinates import SkyCoord, EarthLocation, AltAz

    def _airMassFromrRawMd(md):
        auxTelLocation = EarthLocation(lat=-30.244639 * u.deg,
                                       lon=-70.749417 * u.deg,
                                       height=2663 * u.m)
        time = Time(md['DATE-OBS'])
        skyLocation = SkyCoord(md['RASTART'], md['DECSTART'], unit=u.deg)
        altAz = AltAz(obstime=time, location=auxTelLocation)
        observationAltAz = skyLocation.transform_to(altAz)
        return observationAltAz.secz.value

    items = ["OBJECT", "expTime", "FILTER", "imageType"]
    obj, expTime, filterCompound, imageType = butler.queryMetadata(
        'raw', items, **kwargs)[0]
    filt, grating = filterCompound.split('~')
    rawMd = butler.get('raw_md', **kwargs)
    airmass = _airMassFromrRawMd(rawMd)

    print(f"Object name: {obj}")
    print(f"expTime:     {expTime}s")
    print(f"imageType:   {imageType}")
    print(f"Filter:      {filt}")
    print(f"Grating:     {grating}")
    print(f"Airmass:     {airmass:.3f}")

    if imageType not in ['BIAS', 'FLAT', 'DARK']:
        simbadObj = Simbad.query_object(obj)
        if simbadObj is None:
            print(f"Failed to find {obj} in Simbad.")
        else:
            assert (len(simbadObj.as_array()) == 1)
            raStr = simbadObj[0]['RA']
            decStr = simbadObj[0]['DEC']
            skyLocation = SkyCoord(raStr,
                                   decStr,
                                   unit=(u.hourangle, u.degree),
                                   frame='icrs')
            raRad, decRad = skyLocation.ra.rad, skyLocation.dec.rad
            print(f"obj RA  (str):   {raStr}")
            print(f"obj DEC (str):   {decStr}")
            print(f"obj RA  (rad):   {raRad:5f}")
            print(f"obj DEC (rad):   {decRad:5f}")
            print(f"obj RA  (deg):   {raRad*180/math.pi:5f}")
            print(f"obj DEC (deg):   {decRad*180/math.pi:5f}")

            if exp is not None:  # calc source coords from exp wcs
                ra = geom.Angle(raRad)
                dec = geom.Angle(decRad)
                targetLocation = geom.SpherePoint(ra, dec)
                pixCoord = exp.getWcs().skyToPixel(targetLocation)
                print(exp.getWcs())
                print(f"Source location: {pixCoord} using exp provided")
            else:  # try to find one, but not too hard
                datasetTypes = ['calexp', 'quickLookExp', 'postISRCCD']
                for datasetType in datasetTypes:
                    wcs = None
                    typeUsed = None
                    try:
                        wcs = butler.get(datasetType + '_wcs', **kwargs)
                        typeUsed = datasetType
                        break
                    except butlerExcept.NoResults:
                        pass
                if wcs is not None:
                    ra = geom.Angle(raRad)
                    dec = geom.Angle(decRad)
                    targetLocation = geom.SpherePoint(ra, dec)
                    pixCoord = wcs.skyToPixel(targetLocation)
                    print(wcs)
                    print(f"Source location: {pixCoord} using {typeUsed}")

    if extendedSummary:
        print('\n--- Extended Summary ---')
        ranIsr = False
        if exp is None:
            print("Running isr to compute image stats...")

            # catch all the ISR chat
            # logRedirection1 = LogRedirect(1, open(os.devnull, 'w'))
            # logRedirection2 = LogRedirect(2, open(os.devnull, 'w'))
            # import ipdb as pdb; pdb.set_trace()
            from lsst.ip.isr.isrTask import IsrTask
            isrConfig = IsrTask.ConfigClass()
            isrConfig.doLinearize = False
            isrConfig.doBias = False
            isrConfig.doFlat = False
            isrConfig.doDark = False
            isrConfig.doFringe = False
            isrConfig.doDefect = False
            isrConfig.doWrite = False
            isrTask = IsrTask(config=isrConfig)
            dataRef = butler.dataRef('raw', **kwargs)
            exp = isrTask.runDataRef(dataRef).exposure
            wcs = exp.getWcs()
            ranIsr = True
            # logRedirection1.finish()  # end re-direct
            # logRedirection2.finish()  # end re-direct

            print(wcs)
        if simbadObj and ranIsr:
            ra = geom.Angle(raRad)
            dec = geom.Angle(decRad)
            targetLocation = geom.SpherePoint(ra, dec)
            pixCoord = wcs.skyToPixel(targetLocation)
            print(
                f"Source location: {pixCoord} using postISR just-reconstructed wcs"
            )

        print(
            f'\nImage stats from {"just-constructed" if ranIsr else "provided"} exp:\n'
        )
        print(f'Image mean:   {np.mean(exp.image.array):.2f}')
        print(f'Image median: {np.median(exp.image.array):.2f}')
        print(f'Image min:    {np.min(exp.image.array):.2f}')
        print(f'Image max:    {np.max(exp.image.array):.2f}')
        # TODO: quartiles/percentiles here
        # number of masked pixels, saturated pixels

        print()
        print(f'BAD pixels:      {countPixels(exp.maskedImage, "BAD")}')
        print(f'SAT pixels:      {countPixels(exp.maskedImage, "SAT")}')
        print(f'CR pixels:       {countPixels(exp.maskedImage, "CR")}')
        print(f'INTRP pixels:    {countPixels(exp.maskedImage, "INTRP")}')
        print(f'DETECTED pixels: {countPixels(exp.maskedImage, "DETECTED")}')

        # detector = exp.getDetector()
        visitInfo = exp.getInfo().getVisitInfo()
        rotAngle = visitInfo.getBoresightRotAngle()
        boresight = visitInfo.getBoresightRaDec()
        md = butler.get('raw_md', **kwargs)

        print("\n From VisitInfo:")
        print(f"boresight: {boresight}")
        print(f"rotAngle:  {rotAngle}")
        print(f"  →        {rotAngle.asDegrees():.4f} deg")

        print("\n From raw_md:")
        print(f"ROTPA:     {md['ROTPA']} deg")
        print(f"  →        {(md['ROTPA']*math.pi/180):.6f} rad")
Exemple #9
0
    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)
    Popen.wait(ingest)
    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)