示例#1
0
    def setUp(self):
        self.dataDir = os.path.join(os.path.split(__file__)[0], "data")

        # Check the values below against what was written by comparing with
        # the code in `afw/tests/data/makeTestExposure.py`
        nx = ny = 10
        image = afwImage.ImageF(np.arange(nx * ny, dtype='f').reshape(nx, ny))
        variance = afwImage.ImageF(np.ones((nx, ny), dtype='f'))
        mask = afwImage.MaskX(nx, ny)
        mask.array[5, 5] = 5
        self.maskedImage = afwImage.MaskedImageF(image, mask, variance)

        self.v0PhotoCalib = afwImage.makePhotoCalibFromCalibZeroPoint(1e6, 2e4)
        self.v1PhotoCalib = afwImage.PhotoCalib(1e6, 2e4)
        self.v1FilterLabel = afwImage.FilterLabel(physical="ha")
        self.v2FilterLabel = afwImage.FilterLabel(band="N656", physical="ha")
示例#2
0
    def testMultiple(self, pedestal=0.0):
        """Test subtraction of multiple fringe frames

        Paramters
        ---------
        pedestal : `float`, optional
           Pedestal to add into fringe frame.
        """
        xFreqList = [0.1, 0.13, 0.06]
        xOffsetList = [0.0, 0.1, 0.2]
        yFreqList = [0.09, 0.12, 0.07]
        yOffsetList = [0.3, 0.2, 0.1]
        fringeList = [
            createFringe(self.size, self.size, xFreq, xOffset, yFreq,
                         yOffset) for xFreq, xOffset, yFreq, yOffset in zip(
                             xFreqList, xOffsetList, yFreqList, yOffsetList)
        ]

        for fringe in fringeList:
            fMi = fringe.getMaskedImage()
            fMi += pedestal
        # Generate science frame
        scales = [0.33, 0.33, 0.33]
        image = afwImage.ImageF(self.size, self.size)
        image.set(0)
        for s, f in zip(scales, fringeList):
            image.scaledPlus(s, f.getMaskedImage().getImage())
        mi = afwImage.makeMaskedImage(image)
        exp = afwImage.makeExposure(mi)
        exp.setFilter(afwImage.FilterLabel(physical='FILTER'))

        task = FringeTask(name="multiFringe", config=self.config)
        self.checkFringe(task, exp, fringeList, stddevMax=1.0e-2)
示例#3
0
    def test_multiFringes(self):
        """Test that multi-fringe results are handled correctly by the task.
        """
        self.config.large = 16
        task = FringeTask(name="multiFringeMock", config=self.config)

        config = isrMock.IsrMockConfig()
        config.fringeScale = [750.0, 240.0, 220.0]
        config.fringeX0 = [100.0, 150.0, 200.0]
        config.fringeY0 = [0.0, 200.0, 0.0]
        dataRef = isrMock.FringeDataRefMock(config=config)

        exp = dataRef.get("raw")
        exp.setFilter(afwImage.FilterLabel(physical='FILTER'))
        medianBefore = np.nanmedian(exp.getImage().getArray())
        fringes = task.readFringes(dataRef, assembler=None)

        solution, rms = task.run(exp, **fringes.getDict())
        medianAfter = np.nanmedian(exp.getImage().getArray())
        stdAfter = np.nanstd(exp.getImage().getArray())

        self.assertLess(medianAfter, medianBefore)
        self.assertFloatsAlmostEqual(medianAfter, 3000.925, atol=1e-4)
        self.assertFloatsAlmostEqual(stdAfter, 3549.9885, atol=1e-4)

        deviation = np.abs(solution - config.fringeScale)
        self.assertTrue(np.all(deviation / rms < 1.0))
示例#4
0
    def setUp(self):
        super().setUp()

        afwImage.Filter.reset()
        afwImage.FilterProperty.reset()
        defineFilter("g", 470.0)

        self.wcs = afwGeom.makeSkyWcs(
            lsst.geom.Point2D(0.0, 0.0),
            lsst.geom.SpherePoint(2.0, 34.0, lsst.geom.degrees),
            np.identity(2),
        )
        self.photoCalib = afwImage.PhotoCalib(1.5)
        self.psf = DummyPsf(2.0)
        self.detector = DetectorWrapper().detector
        self.summaryStats = afwImage.ExposureSummaryStats(ra=100.0)
        self.polygon = afwGeom.Polygon(
            lsst.geom.Box2D(lsst.geom.Point2D(0.0, 0.0),
                            lsst.geom.Point2D(25.0, 20.0)))
        self.coaddInputs = afwImage.CoaddInputs()
        self.apCorrMap = afwImage.ApCorrMap()
        self.transmissionCurve = afwImage.TransmissionCurve.makeIdentity()

        self.exposureInfo = afwImage.ExposureInfo()
        gFilter = afwImage.Filter("g")
        gFilterLabel = afwImage.FilterLabel(band="g")
        self.exposureInfo.setFilter(gFilter)
        self.exposureInfo.setFilterLabel(gFilterLabel)
示例#5
0
 def testVisitInfoFitsPersistence(self):
     """Test saving an exposure to FITS and reading it back in preserves (some) VisitInfo fields"""
     exposureId = 5
     exposureTime = 12.3
     boresightRotAngle = 45.6 * lsst.geom.degrees
     weather = Weather(1.1, 2.2, 0.3)
     visitInfo = afwImage.VisitInfo(
         exposureId=exposureId,
         exposureTime=exposureTime,
         boresightRotAngle=boresightRotAngle,
         weather=weather,
     )
     photoCalib = afwImage.PhotoCalib(3.4, 5.6)
     exposureInfo = afwImage.ExposureInfo()
     exposureInfo.setVisitInfo(visitInfo)
     exposureInfo.setPhotoCalib(photoCalib)
     exposureInfo.setDetector(self.detector)
     gFilter = afwImage.Filter("g")
     gFilterLabel = afwImage.FilterLabel(band="g")
     exposureInfo.setFilter(gFilter)
     exposureInfo.setFilterLabel(gFilterLabel)
     maskedImage = afwImage.MaskedImageF(inFilePathSmall)
     exposure = afwImage.ExposureF(maskedImage, exposureInfo)
     with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
         exposure.writeFits(tmpFile)
         rtExposure = afwImage.ExposureF(tmpFile)
     rtVisitInfo = rtExposure.getInfo().getVisitInfo()
     self.assertEqual(rtVisitInfo.getWeather(), weather)
     self.assertEqual(rtExposure.getPhotoCalib(), photoCalib)
     self.assertEqual(rtExposure.getFilter(), gFilter)
     self.assertEqual(rtExposure.getFilterLabel(), gFilterLabel)
示例#6
0
    def testExposureInfoConstructor(self):
        """Test the Exposure(maskedImage, exposureInfo) constructor"""
        exposureInfo = afwImage.ExposureInfo()
        exposureInfo.setWcs(self.wcs)
        exposureInfo.setDetector(self.detector)
        gFilter = afwImage.Filter("g")
        gFilterLabel = afwImage.FilterLabel(band="g")
        exposureInfo.setFilter(gFilter)
        exposureInfo.setFilterLabel(gFilterLabel)
        maskedImage = afwImage.MaskedImageF(inFilePathSmall)
        exposure = afwImage.ExposureF(maskedImage, exposureInfo)

        self.assertTrue(exposure.hasWcs())
        self.assertEqual(exposure.getWcs().getPixelOrigin(),
                         self.wcs.getPixelOrigin())
        self.assertEqual(exposure.getDetector().getName(),
                         self.detector.getName())
        self.assertEqual(exposure.getDetector().getSerial(),
                         self.detector.getSerial())
        self.assertEqual(exposure.getFilter(), gFilter)
        self.assertEqual(exposure.getFilterLabel(), gFilterLabel)

        self.assertTrue(exposure.getInfo().hasWcs())
        self.assertEqual(exposure.getInfo().getWcs().getPixelOrigin(),
                         self.wcs.getPixelOrigin())
        self.assertEqual(exposure.getInfo().getDetector().getName(),
                         self.detector.getName())
        self.assertEqual(exposure.getInfo().getDetector().getSerial(),
                         self.detector.getSerial())
        self.assertEqual(exposure.getInfo().getFilter(), gFilter)
        self.assertEqual(exposure.getInfo().getFilterLabel(), gFilterLabel)
示例#7
0
def createFringe(width, height, xFreq, xOffset, yFreq, yOffset):
    """Create a fringe frame.

    Parameters
    ----------
    width, height : `int`
       Size of image.
    xFreq, yFreq : `float`
       Frequency of sinusoids in x and y.
    xOffset, yOffset : `float`
       Phase of sinusoids in x and y.

    Returns
    -------
    exp : `lsst.afw.image.ExposureF`
       Fringe frame.
    """
    image = afwImage.ImageF(width, height)
    array = image.getArray()
    x, y = np.indices(array.shape)
    array[x, y] = np.sin(xFreq * x + xOffset) + np.sin(yFreq * y + yOffset)
    mi = afwImage.makeMaskedImage(image)
    exp = afwImage.makeExposure(mi)
    exp.setFilter(afwImage.FilterLabel(band='y', physical='FILTER'))
    return exp
示例#8
0
def main(just_wfs=False, detector_list=None):

    if (just_wfs is True) and (detector_list is not None):
        raise RuntimeError("--just_wfs and --detector_list are exclusive.")

    camera = LsstCam().getCamera()
    if just_wfs:
        ccd_list = [
            camera[name] for name in [
                "R00_SW0", "R00_SW1", "R04_SW0", "R04_SW1", "R44_SW0",
                "R44_SW1", "R40_SW0", 'R40_SW1'
            ]
        ]
    elif (detector_list is not None):
        ccd_list = [camera[name] for name in detector_list]
    else:
        ccd_list = camera

    for filt_name in 'ugrizy':
        for ccd in ccd_list:
            name = ccd.getName()
            CHIPID = "".join([c for c in name if c != "," and c != ":"])
            CHIPID = "_".join(CHIPID.split())
            image = afwImage.ImageF(ccd.getBBox())
            for amp in ccd:
                subim = afwImage.ImageF(image, amp.getBBox())
                subim[:] = 1 / amp.getGain()
                print(amp.getName(), amp.getGain())

            # need to flip the image to match the result of phosim repackager
            oldImageArray = image.array.copy()
            image.array[:] = np.flipud(oldImageArray)

            expInfo = afwImage.ExposureInfo()
            inFilter = afwImage.FilterLabel(filt_name)
            expInfo.setFilterLabel(inFilter)
            exp = afwImage.ExposureF(afwImage.MaskedImageF(image), expInfo)
            md = exp.getMetadata()
            md.set('CHIPID', CHIPID)
            # Set place holder date
            md.set('MJD-OBS', 53005.0)
            md.set('OBSTYPE', 'flat')
            # arbitrary for flats
            md.set('EXPTIME', 100)
            # need to be able to specify any filter
            md.set('CALDATE', 53005.0)
            # Add the CALIB_ID header card
            md.set(
                'CALIB_ID',
                'raftName=%s detectorName=%s detector=%i filter=%s calibDate=%s'
                % (CHIPID.split('_')[0], CHIPID.split('_')[1], ccd.getId(),
                   filt_name, datetime.now()))
            exp.setMetadata(md)
            exp.writeFits("%(name)s_%(filter)s.fits" % ({
                'name': CHIPID,
                'filter': filt_name
            }))
示例#9
0
    def __init__(self,
                 shape=geom.Extent2I(201, 301),
                 offset=geom.Point2I(-123, -45),
                 backgroundLevel=314.592,
                 seed=42,
                 nSrc=37,
                 fluxRange=2.,
                 noiseLevel=5,
                 sourceSigma=200.,
                 minPsfSize=1.5,
                 maxPsfSize=3.,
                 pixelScale=0.2 * arcseconds,
                 ra=209. * degrees,
                 dec=-20.25 * degrees,
                 ccd=37,
                 patch=42,
                 patchGen2="2,3",
                 tract=0):
        self.ra = ra
        self.dec = dec
        self.pixelScale = pixelScale
        self.patch = patch
        self.patchGen2 = patchGen2
        self.tract = tract
        self.filterLabel = afwImage.FilterLabel(band="gTest", physical="gTest")
        self.rngData = np.random.default_rng(seed)
        self.rngMods = np.random.default_rng(seed + 1)
        self.bbox = geom.Box2I(offset, shape)
        if not self.bbox.contains(0, 0):
            raise ValueError(
                f"The bounding box must contain the coordinate (0, 0). {repr(self.bbox)}"
            )
        self.wcs = self.makeDummyWcs()

        # Set up properties of the simulations
        nSigmaForKernel = 5
        self.kernelSize = (int(maxPsfSize * nSigmaForKernel + 0.5) //
                           2) * 2 + 1  # make sure it is odd

        bufferSize = self.kernelSize // 2
        x0, y0 = self.bbox.getBegin()
        xSize, ySize = self.bbox.getDimensions()
        # Set the pixel coordinates and fluxes of the simulated sources.
        self.xLoc = self.rngData.random(nSrc) * (
            xSize - 2 * bufferSize) + bufferSize + x0
        self.yLoc = self.rngData.random(nSrc) * (
            ySize - 2 * bufferSize) + bufferSize + y0
        self.flux = (self.rngData.random(nSrc) *
                     (fluxRange - 1.) + 1.) * sourceSigma * noiseLevel

        self.backgroundLevel = backgroundLevel
        self.noiseLevel = noiseLevel
        self.minPsfSize = minPsfSize
        self.maxPsfSize = maxPsfSize
        self.detector = DetectorWrapper(name=f"detector {ccd}",
                                        id=ccd).detector
示例#10
0
    def setUp(self):
        np.random.seed(1234)
        self.cutoutSize = 35
        self.center = lsst.geom.Point2D(50.1, 49.8)
        self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(-20, -30),
                                    lsst.geom.Extent2I(140, 160))
        self.dataset = lsst.meas.base.tests.TestDataset(self.bbox)
        self.dataset.addSource(100000.0, self.center)
        exposure, catalog = self.dataset.realize(
            10.0, self.dataset.makeMinimalSchema(), randomSeed=0)
        self.exposure = exposure
        detector = DetectorWrapper(id=23, bbox=exposure.getBBox()).detector
        self.exposure.setDetector(detector)

        visit = afwImage.VisitInfo(exposureId=1234,
                                   exposureTime=200.,
                                   date=dafBase.DateTime(
                                       "2014-05-13T17:00:00.000000000",
                                       dafBase.DateTime.Timescale.TAI))
        self.exposure.info.id = 1234
        self.exposure.getInfo().setVisitInfo(visit)

        self.exposure.setFilter(
            afwImage.FilterLabel(band='g', physical="g.MP9401"))

        diaObjects = makeDiaObjects(2, self.exposure)
        diaSourceHistory = makeDiaSources(10, diaObjects["diaObjectId"],
                                          self.exposure)
        diaForcedSources = makeDiaForcedSources(10, diaObjects["diaObjectId"],
                                                self.exposure)
        self.diaObjects, diaSourceHistory, self.diaForcedSources = _roundTripThroughApdb(
            diaObjects, diaSourceHistory, diaForcedSources,
            self.exposure.getInfo().getVisitInfo().getDate())
        self.diaObjects.replace(to_replace=[None], value=np.nan, inplace=True)
        diaSourceHistory.replace(to_replace=[None], value=np.nan, inplace=True)
        self.diaForcedSources.replace(to_replace=[None],
                                      value=np.nan,
                                      inplace=True)
        diaSourceHistory["programId"] = 0

        self.diaSources = diaSourceHistory.loc[[(1, "g", 9), (2, "g", 10)], :]
        self.diaSources["bboxSize"] = self.cutoutSize
        self.diaSourceHistory = diaSourceHistory.drop(labels=[(1, "g",
                                                               9), (2, "g",
                                                                    10)])

        self.cutoutWcs = wcs.WCS(naxis=2)
        self.cutoutWcs.wcs.crpix = [self.center[0], self.center[1]]
        self.cutoutWcs.wcs.crval = [
            self.exposure.getWcs().getSkyOrigin().getRa().asDegrees(),
            self.exposure.getWcs().getSkyOrigin().getDec().asDegrees()
        ]
        self.cutoutWcs.wcs.cd = self.exposure.getWcs().getCdMatrix()
        self.cutoutWcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
示例#11
0
    def testNullWarpExposure(self, interpLength=10):
        """Test that warpExposure maps an image onto itself.

        Note:
        - NO_DATA and off-CCD pixels must be ignored
        - bad mask pixels get smeared out so we have to excluded all bad mask pixels
          from the output image when comparing masks.
        """
        originalExposure = afwImage.ExposureF(originalExposurePath)
        originalExposure.getInfo().setId(10313423)
        originalExposure.getInfo().setVisitInfo(makeVisitInfo())
        originalFilterLabel = afwImage.FilterLabel(band="i")
        originalPhotoCalib = afwImage.PhotoCalib(1.0e5, 1.0e3)
        originalExposure.setFilter(originalFilterLabel)
        originalExposure.setPhotoCalib(originalPhotoCalib)
        afwWarpedExposure = afwImage.ExposureF(originalExposure.getBBox(),
                                               originalExposure.getWcs())
        warpingControl = afwMath.WarpingControl("lanczos4", "", 0,
                                                interpLength)
        afwMath.warpExposure(afwWarpedExposure, originalExposure,
                             warpingControl)
        if SAVE_FITS_FILES:
            afwWarpedExposure.writeFits("afwWarpedExposureNull.fits")

        self.assertEqual(afwWarpedExposure.getFilter().bandLabel,
                         originalFilterLabel.bandLabel)
        self.assertEqual(afwWarpedExposure.getPhotoCalib(), originalPhotoCalib)
        self.assertEqual(afwWarpedExposure.getInfo().getVisitInfo(),
                         originalExposure.getInfo().getVisitInfo())

        afwWarpedMaskedImage = afwWarpedExposure.getMaskedImage()
        afwWarpedMask = afwWarpedMaskedImage.getMask()
        noDataBitMask = afwWarpedMask.getPlaneBitMask("NO_DATA")
        afwWarpedMaskedImageArrSet = afwWarpedMaskedImage.getArrays()
        afwWarpedMaskArr = afwWarpedMaskedImageArrSet[1]

        # compare all non-DATA pixels of image and variance, but relax specs a bit
        # because of minor noise introduced by bad pixels
        noDataMaskArr = afwWarpedMaskArr & noDataBitMask
        msg = "afw null-warped MaskedImage (all pixels, relaxed tolerance)"
        self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage,
                                           originalExposure.getMaskedImage(),
                                           doMask=False,
                                           skipMask=noDataMaskArr,
                                           atol=1e-5,
                                           msg=msg)

        # compare good pixels (mask=0) of image, mask and variance using full
        # tolerance
        msg = "afw null-warped MaskedImage (good pixels, max tolerance)"
        self.assertMaskedImagesAlmostEqual(afwWarpedMaskedImage,
                                           originalExposure.getMaskedImage(),
                                           skipMask=afwWarpedMask,
                                           msg=msg)
示例#12
0
    def testSetMembers(self):
        """
        Test that the MaskedImage and the WCS of an Exposure can be set.
        """
        exposure = afwImage.ExposureF()

        maskedImage = afwImage.MaskedImageF(inFilePathSmall)
        exposure.setMaskedImage(maskedImage)
        exposure.setWcs(self.wcs)
        exposure.setDetector(self.detector)
        exposure.setFilter(afwImage.Filter("g"))
        exposure.setFilterLabel(afwImage.FilterLabel(band="g"))

        self.assertEqual(exposure.getDetector().getName(),
                         self.detector.getName())
        self.assertEqual(exposure.getDetector().getSerial(),
                         self.detector.getSerial())
        self.assertEqual(exposure.getFilter().getName(), "g")
        self.assertEqual(exposure.getFilterLabel().bandLabel, "g")
        self.assertEqual(exposure.getWcs(), self.wcs)

        # The PhotoCalib tests are in test_photoCalib.py;
        # here we just check that it's gettable and settable.
        self.assertIsNone(exposure.getPhotoCalib())

        photoCalib = afwImage.PhotoCalib(511.1, 44.4)
        exposure.setPhotoCalib(photoCalib)
        self.assertEqual(exposure.getPhotoCalib(), photoCalib)

        # Psfs next
        self.assertFalse(exposure.hasPsf())
        exposure.setPsf(self.psf)
        self.assertTrue(exposure.hasPsf())

        exposure.setPsf(DummyPsf(1.0))  # we can reset the Psf

        # extras next
        info = exposure.getInfo()
        for key, value in self.extras.items():
            self.assertFalse(info.hasComponent(key))
            self.assertIsNone(info.getComponent(key))
            info.setComponent(key, value)
            self.assertTrue(info.hasComponent(key))
            self.assertEqual(info.getComponent(key), value)
            info.removeComponent(key)
            self.assertFalse(info.hasComponent(key))

        # Test that we can set the MaskedImage and WCS of an Exposure
        # that already has both
        self.exposureMiWcs.setMaskedImage(maskedImage)
        exposure.setWcs(self.wcs)
示例#13
0
    def setUp(self):

        # Load sample input from disk
        testDir = os.path.dirname(__file__)
        self.srcCat = afwTable.SourceCatalog.readFits(
            os.path.join(testDir, "data", "v695833-e0-c000.xy.fits"))

        self.srcCat["slot_ApFlux_instFluxErr"] = 1
        self.srcCat["slot_PsfFlux_instFluxErr"] = 1

        # The .xy.fits file has sources in the range ~ [0,2000],[0,4500]
        # which is bigger than the exposure
        self.bbox = geom.Box2I(geom.Point2I(0, 0), geom.Extent2I(2048, 4612))
        smallExposure = afwImage.ExposureF(
            os.path.join(testDir, "data", "v695833-e0-c000-a00.sci.fits"))
        self.exposure = afwImage.ExposureF(self.bbox)
        self.exposure.setWcs(smallExposure.getWcs())
        self.exposure.setFilter(
            afwImage.FilterLabel(band="i", physical="test-i"))
        self.exposure.setPhotoCalib(smallExposure.getPhotoCalib())

        coordKey = self.srcCat.getCoordKey()
        centroidKey = self.srcCat.getCentroidSlot().getMeasKey()
        wcs = self.exposure.getWcs()
        for src in self.srcCat:
            src.set(coordKey, wcs.pixelToSky(src.get(centroidKey)))

        # Make a reference loader
        filenames = sorted(
            glob.glob(
                os.path.join(RefCatDir, 'ref_cats', 'cal_ref_cat',
                             '??????.fits')))
        self.refObjLoader = MockReferenceObjectLoaderFromFiles(filenames,
                                                               htmLevel=8)
        self.log = logging.getLogger('lsst.testPhotoCal')
        self.log.setLevel(TRACE)

        self.config = PhotoCalConfig()
        self.config.match.matchRadius = 0.5
        self.config.match.referenceSelection.doMagLimit = True
        self.config.match.referenceSelection.magLimit.maximum = 22.0
        self.config.match.referenceSelection.magLimit.fluxField = "i_flux"
        self.config.match.referenceSelection.doFlags = True
        self.config.match.referenceSelection.flags.good = ['photometric']
        self.config.match.referenceSelection.flags.bad = ['resolved']
        self.config.match.sourceSelection.doUnresolved = False  # Don't have star/galaxy in the srcCat

        # The test and associated data have been prepared on the basis that we
        # use the PsfFlux to perform photometry.
        self.config.fluxField = "base_PsfFlux_instFlux"
示例#14
0
    def testFilter(self):
        """Test that the same (patched) filter is returned through all Butler
        retrieval paths.
        """
        mapper = MinMapper2(root=ROOT)

        butler = dafPersist.ButlerFactory(mapper=mapper).create()
        image = butler.get("someExp", ccd=35)
        filter = butler.get("someExp_filterLabel", ccd=35)
        # Test only valid with a complete filter
        self.assertEqual(image.getFilterLabel(),
                         afwImage.FilterLabel(band="r", physical="r.MP9601"))
        # Datasets should give consistent answers
        self.assertEqual(filter, image.getFilterLabel())
示例#15
0
    def _setFilter(self, mapping, item, dataId):
        """To ensure that ctio0m9 exposures get both physical and band set.

        Notes
        -----
        ctio0m9 has very non-typical filters, and uses the physical filter
        name in the refcat loader filterMap, so we want to duplicate the
        physical name into the band name here. These filters don't have a
        standard "band" like "g", so these band names won't get confused
        with anything else.
        """
        idFilter = mapping.need(['filter'], dataId)['filter']
        item.setFilterLabel(
            afwImage.FilterLabel(physical=idFilter, band=idFilter))
示例#16
0
    def testStandardizeFiltersFilterNoDefs(self):
        testLabels = [
            None,
            afwImage.FilterLabel(band="i", physical="i.MP9701"),
            afwImage.FilterLabel(band="i"),
            afwImage.FilterLabel(physical="i.MP9701"),
            afwImage.FilterLabel(band="i", physical="old-i"),
            afwImage.FilterLabel(physical="old-i"),
            afwImage.FilterLabel(physical="i2"),
        ]
        testIds = [{
            "visit": 12345,
            "ccd": 42,
            "filter": f
        } for f in {
            "i",
            "i.MP9701",
            "old-i",
            "i2",
        }]
        testData = []
        # Resolve special combinations where the expected output is different
        for input in testLabels:
            for dataId in testIds:
                if input is None:
                    # Can still get some filter info out of the Filter registry
                    if dataId["filter"] == "i2":
                        data = (input, dataId,
                                afwImage.FilterLabel(band="i",
                                                     physical="HSC-I2"))
                    else:
                        # Data ID maps to filter(s) with aliases; can't
                        # unambiguously determine physical filter.
                        data = (input, dataId, afwImage.FilterLabel(band="i"))
                else:
                    data = (input, dataId, input)
                testData.append(data)

        mapper = MinMapper1(root=ROOT)
        for label, dataId, corrected in testData:
            exposure = afwImage.ExposureF()
            exposure.setFilterLabel(label)
            mapper._setFilter(mapper.exposures['raw'], exposure, dataId)
            self.assertEqual(exposure.getFilterLabel(),
                             corrected,
                             msg=f"Started from {label} and {dataId}")
示例#17
0
 def __init__(self, root, **kwargs):
     self.storage = lsst.daf.persistence.Storage.makeFromURI(root)
     super(SimpleMapper, self).__init__(**kwargs)
     self.root = root
     self.camera = makeSimpleCamera(nX=1,
                                    nY=2,
                                    sizeX=400,
                                    sizeY=200,
                                    gapX=2,
                                    gapY=2)
     # NOTE: we set band/physical here because CoaddsTestCase.testCoaddInputs()
     # expects "r" for both the input dataIds (gen2 dataIds could be either
     # physical or band) and the output CoaddInputRecords.
     # The original data had just `Filter("r")`, so this has always assumed
     # that physicalLabel==bandLabel, even though CoaddInputRecords are physical.
     self.filterLabel = afwImage.FilterLabel(band="r", physical="r")
     self.update()
示例#18
0
    def testCopyExposure(self):
        """Copy an Exposure (maybe changing type)"""

        exposureU = afwImage.ExposureU(inFilePathSmall, allowUnsafe=True)
        exposureU.setWcs(self.wcs)
        exposureU.setDetector(self.detector)
        exposureU.setFilter(afwImage.Filter("g"))
        exposureU.setFilterLabel(afwImage.FilterLabel(band="g"))
        exposureU.setPsf(DummyPsf(4.0))
        infoU = exposureU.getInfo()
        for key, value in self.extras.items():
            infoU.setComponent(key, value)

        exposureF = exposureU.convertF()
        self.cmpExposure(exposureF, exposureU)

        nexp = exposureF.Factory(exposureF, False)
        self.cmpExposure(exposureF, nexp)
示例#19
0
    def run(self, inputExp, inputSources):
        """XXX Docs
        """

        # TODO: Change this to doing this the proper way
        referenceFilterName = self.config.referenceFilterOverride
        referenceFilterLabel = afwImage.FilterLabel(
            physical=referenceFilterName, band=referenceFilterName)
        # there's a better way of doing this with the task I think
        originalFilterLabel = inputExp.getFilterLabel()
        inputExp.setFilterLabel(referenceFilterLabel)

        successfulFit = False
        try:
            astromResult = self.astrometry.run(sourceCat=inputSources,
                                               exposure=inputExp)
            scatter = astromResult.scatterOnSky.asArcseconds()
            inputExp.setFilterLabel(originalFilterLabel)
            if scatter < 1:
                successfulFit = True
        except (RuntimeError, TaskError):
            self.log.warn("Solver failed to run completely")
            inputExp.setFilterLabel(originalFilterLabel)

        if successfulFit:
            target = inputExp.getMetadata()['OBJECT']
            centroid = getTargetCentroidFromWcs(inputExp,
                                                target,
                                                logger=self.log)
        else:
            result = self.qfmTask.run(inputExp)
            centroid = result.brightestObjCentroid

        centroidTuple = (centroid[0], centroid[1]
                         )  # unify Point2D or tuple to tuple
        self.log.info(
            f"Centroid of main star found at {centroidTuple} found"
            f" via {'astrometry' if successfulFit else 'QuickFrameMeasurement'}"
        )
        result = pipeBase.Struct(atmospecCentroid={
            'centroid': centroidTuple,
            'astrometricMatch': successfulFit
        })
        return result
示例#20
0
def make_exp(gsimage, bmask, noise, galsim_wcs, galsim_psf, psf_dim):

    dm_wcs = make_dm_wcs(galsim_wcs)
    dm_psf = make_dm_psf(psf=galsim_psf, psf_dim=psf_dim, wcs=galsim_wcs)

    ny, nx = gsimage.array.shape

    masked_image = afw_image.MaskedImageF(width=nx, height=ny)
    masked_image.image.array[:, :] = gsimage.array
    masked_image.variance.array[:, :] = noise**2
    masked_image.mask.array[:, :] = bmask.array

    exp = afw_image.ExposureF(masked_image)
    filter_label = afw_image.FilterLabel(band='i', physical='i')
    exp.setFilterLabel(filter_label)

    exp.setPsf(dm_psf)
    exp.setWcs(dm_wcs)
    return exp
示例#21
0
    def runAstrometry(self, butler, exp, icSrc):
        refObjLoaderConfig = LoadIndexedReferenceObjectsTask.ConfigClass()
        refObjLoaderConfig.ref_dataset_name = 'gaia_dr2_20191105'
        refObjLoaderConfig.pixelMargin = 1000
        refObjLoader = LoadIndexedReferenceObjectsTask(
            butler=butler, config=refObjLoaderConfig)

        astromConfig = AstrometryTask.ConfigClass()
        astromConfig.wcsFitter.retarget(FitAffineWcsTask)
        astromConfig.referenceSelector.doMagLimit = True
        magLimit = MagnitudeLimit()
        magLimit.minimum = 1
        magLimit.maximum = 15
        astromConfig.referenceSelector.magLimit = magLimit
        astromConfig.referenceSelector.magLimit.fluxField = "phot_g_mean_flux"
        astromConfig.matcher.maxRotationDeg = 5.99
        astromConfig.matcher.maxOffsetPix = 3000
        astromConfig.sourceSelector['matcher'].minSnr = 10
        solver = AstrometryTask(config=astromConfig, refObjLoader=refObjLoader)

        # TODO: Change this to doing this the proper way
        referenceFilterName = self.config.referenceFilterOverride
        referenceFilterLabel = afwImage.FilterLabel(
            physical=referenceFilterName, band=referenceFilterName)
        originalFilterLabel = exp.getFilterLabel(
        )  # there's a better way of doing this with the task I think
        exp.setFilterLabel(referenceFilterLabel)

        try:
            astromResult = solver.run(sourceCat=icSrc, exposure=exp)
            exp.setFilterLabel(originalFilterLabel)
        except (RuntimeError, TaskError):
            self.log.warn("Solver failed to run completely")
            exp.setFilterLabel(originalFilterLabel)
            return None

        scatter = astromResult.scatterOnSky.asArcseconds()
        if scatter < 1:
            return astromResult
        else:
            self.log.warn("Failed to find an acceptable match")
        return None
示例#22
0
    def setUp(self):
        refCatDir = os.path.join(os.path.dirname(__file__), "data",
                                 "sdssrefcat")

        self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0),
                                    lsst.geom.Extent2I(3001, 3001))
        crpix = lsst.geom.Box2D(self.bbox).getCenter()
        self.tanWcs = afwGeom.makeSkyWcs(
            crpix=crpix,
            crval=lsst.geom.SpherePoint(215.5, 53.0, lsst.geom.degrees),
            cdMatrix=afwGeom.makeCdMatrix(scale=5.1e-5 * lsst.geom.degrees))
        self.exposure = afwImage.ExposureF(self.bbox)
        self.exposure.setWcs(self.tanWcs)
        self.exposure.setFilter(
            afwImage.FilterLabel(band="r", physical="rTest"))
        filenames = sorted(
            glob.glob(
                os.path.join(refCatDir, 'ref_cats', 'cal_ref_cat',
                             '??????.fits')))
        self.refObjLoader = MockReferenceObjectLoaderFromFiles(filenames,
                                                               htmLevel=8)
示例#23
0
    def testBBox(self):
        """Test that the default bounding box includes all warped pixels
        """
        kernelName = "lanczos2"
        warper = afwMath.Warper(kernelName)
        originalExposure, swarpedImage, swarpedWcs = self.getSwarpedImage(
            kernelName=kernelName, useSubregion=True, useDeepCopy=False)

        originalFilterLabel = afwImage.FilterLabel(band="i")
        originalPhotoCalib = afwImage.PhotoCalib(1.0e5, 1.0e3)
        originalExposure.setFilterLabel(originalFilterLabel)
        originalExposure.setPhotoCalib(originalPhotoCalib)

        warpedExposure1 = warper.warpExposure(destWcs=swarpedWcs,
                                              srcExposure=originalExposure)
        # the default size must include all good pixels, so growing the bbox
        # should not add any
        warpedExposure2 = warper.warpExposure(destWcs=swarpedWcs,
                                              srcExposure=originalExposure,
                                              border=1)
        # a bit of excess border is allowed, but surely not as much as 10 (in
        # fact it is approx. 5)
        warpedExposure3 = warper.warpExposure(destWcs=swarpedWcs,
                                              srcExposure=originalExposure,
                                              border=-10)
        # assert that warpedExposure and warpedExposure2 have the same number of non-no_data pixels
        # and that warpedExposure3 has fewer
        noDataBitMask = afwImage.Mask.getPlaneBitMask("NO_DATA")
        mask1Arr = warpedExposure1.getMaskedImage().getMask().getArray()
        mask2Arr = warpedExposure2.getMaskedImage().getMask().getArray()
        mask3Arr = warpedExposure3.getMaskedImage().getMask().getArray()
        nGood1 = (mask1Arr & noDataBitMask == 0).sum()
        nGood2 = (mask2Arr & noDataBitMask == 0).sum()
        nGood3 = (mask3Arr & noDataBitMask == 0).sum()
        self.assertEqual(nGood1, nGood2)
        self.assertLess(nGood3, nGood1)

        self.assertEqual(warpedExposure1.getFilterLabel().bandLabel,
                         originalFilterLabel.bandLabel)
        self.assertEqual(warpedExposure1.getPhotoCalib(), originalPhotoCalib)
示例#24
0
    def std_raw(self, item, dataId, filter=True):
        """Standardize a raw dataset by converting it to an
        `~lsst.afw.image.Exposure` instead of an `~lsst.afw.image.Image`."""

        exp = self._standardizeExposure(
            self.exposures['raw'],
            item,
            dataId,
            trimmed=False,
            setVisitInfo=False,  # it's already set, and the metadata's stripped
            setExposureId=False,
            filter=False)

        if filter:
            obsInfo = ObservationInfo(exp.getMetadata(),
                                      translator_class=self.translatorClass)
            band = self.filterDefinitions.physical_to_band[
                obsInfo.physical_filter]
            filt = afwImage.FilterLabel(physical=obsInfo.physical_filter,
                                        band=band)
            exp.setFilterLabel(filt)

        return exp
示例#25
0
def make_exp(
    *,
    rng,
    band,
    noise,
    objlist,
    shifts,
    dim,
    psf,
    psf_dim,
    g1,
    g2,
    star_objlist=None,
    star_shifts=None,
    draw_stars=True,
    bright_objlist=None,
    bright_shifts=None,
    bright_mags=None,
    coadd_bbox_cen_gs_skypos,
    dither=False,
    rotate=False,
    mask_threshold=None,
    cosmic_rays=False,
    bad_columns=False,
    star_bleeds=False,
    sky_n_sigma=None,
    draw_method='auto',
):
    """
    Make an SEObs

    Parameters
    ----------
    rng: numpy.random.RandomState
        The random number generator
    band: str
        Band as a string, e.g. 'i'
    noise: float
        Gaussian noise level
    objlist: list
        List of GSObj
    shifts: array
        List of PositionD representing offsets
    dim: int
        Dimension of image
    psf: GSObject or PowerSpectrumPSF
        the psf
    psf_dim: int
        Dimensions of psf image that will be drawn when psf func is called
    coadd_bbox_cen_gs_skypos: galsim.CelestialCoord
        The sky position of the center (origin) of the coadd we
        will make, as a galsim object not stack object
    dither: bool
        If set to True, dither randomly by a pixel width
    rotate: bool
        If set to True, rotate the image randomly
    star_objlist: list
        List of GSObj for stars
    star_shifts: array
        List of PositionD for stars representing offsets
    draw_stars: bool, optional
        Draw the stars, don't just mask bright ones.  Default True.
    bright_objlist: list, optional
        List of GSObj for bright objects
    bright_shifts: array, optional
        List of PositionD for stars representing offsets
    bright_mags: array, optional
        Mags for the bright objects
    mask_threshold: float
        Bright masks are created such that the profile goes out
        to this threshold
    cosmic_rays: bool
        If True, put in cosmic rays
    bad_columns: bool
        If True, put in bad columns
    star_bleeds: bool
        If True, add bleed trails to stars
    sky_n_sigma: float
        Number of sigma to set the sky value.  Can be negative to
        mock up a sky oversubtraction.  Default None.
    draw_method: string
        Draw method for galsim objects, default 'auto'.  Set to
        'phot' to get poisson noise.  Note this is much slower.

    Returns
    -------
    exp: lsst.afw.image.ExposureF
        Exposure data
    bright_info: list of structured arrays
        fields are
        ra, dec: sky position of bright stars
        radius_pixels: radius of mask in pixels
        has_bleed: bool, True if there is a bleed trail
    """

    shear = galsim.Shear(g1=g1, g2=g2)
    dims = [dim] * 2
    cen = (np.array(dims) - 1) / 2

    se_origin = galsim.PositionD(x=cen[1], y=cen[0])
    if dither:
        dither_range = 0.5
        off = rng.uniform(low=-dither_range, high=dither_range, size=2)
        offset = galsim.PositionD(x=off[0], y=off[1])
        se_origin = se_origin + offset

    if rotate:
        theta = rng.uniform(low=0, high=2 * np.pi)
    else:
        theta = None

    # galsim wcs
    se_wcs = make_wcs(
        scale=SCALE,
        theta=theta,
        image_origin=se_origin,
        world_origin=coadd_bbox_cen_gs_skypos,
    )

    image = galsim.Image(dim, dim, wcs=se_wcs)

    _draw_objects(
        image,
        objlist,
        shifts,
        psf,
        draw_method,
        coadd_bbox_cen_gs_skypos,
        rng,
        shear=shear,
    )
    if star_objlist is not None and draw_stars:
        assert star_shifts is not None, 'send star_shifts with star_objlist'
        _draw_objects(
            image,
            star_objlist,
            star_shifts,
            psf,
            draw_method,
            coadd_bbox_cen_gs_skypos,
            rng,
        )

    image.array[:, :] += rng.normal(scale=noise, size=dims)
    if sky_n_sigma is not None:
        image.array[:, :] += sky_n_sigma * noise

    # pixels flagged as bad cols and cosmics will get
    # set to np.nan
    bmask = get_bmask_and_set_image(
        image=image,
        rng=rng,
        cosmic_rays=cosmic_rays,
        bad_columns=bad_columns,
    )

    if bright_objlist is not None:
        bright_info = _draw_bright_objects(
            image=image,
            noise=noise,
            origin=se_origin,
            bmask=bmask,
            band=band,
            objlist=bright_objlist,
            shifts=bright_shifts,
            mags=bright_mags,
            psf=psf,
            coadd_bbox_cen_gs_skypos=coadd_bbox_cen_gs_skypos,
            mask_threshold=mask_threshold,
            rng=rng,
            star_bleeds=star_bleeds,
            draw_stars=draw_stars,
        )
    else:
        bright_info = []

    dm_wcs = make_dm_wcs(se_wcs)
    dm_psf = make_dm_psf(psf=psf, psf_dim=psf_dim, wcs=se_wcs)

    variance = image.copy()
    variance.array[:, :] = noise**2

    masked_image = afw_image.MaskedImageF(dim, dim)
    masked_image.image.array[:, :] = image.array
    masked_image.variance.array[:, :] = variance.array
    masked_image.mask.array[:, :] = bmask.array

    exp = afw_image.ExposureF(masked_image)

    filter_label = afw_image.FilterLabel(band=band, physical=band)
    exp.setFilterLabel(filter_label)

    exp.setPsf(dm_psf)

    exp.setWcs(dm_wcs)

    detector = DetectorWrapper().detector
    exp.setDetector(detector)

    return exp, bright_info
示例#26
0
def makeExposure(flipX=False, flipY=False):
    """Create an exposure and flip the x or y (or both) coordinates.

    Returns bounding boxes that are right or left handed around the bounding
    polygon.

    Parameters
    ----------
    flipX : `bool`
        Flip the x coordinate in the WCS.
    flipY : `bool`
        Flip the y coordinate in the WCS.

    Returns
    -------
    exposure : `lsst.afw.image.Exposure`
        Exposure with a valid bounding box and wcs.
    """
    metadata = dafBase.PropertySet()

    metadata.set("SIMPLE", "T")
    metadata.set("BITPIX", -32)
    metadata.set("NAXIS", 2)
    metadata.set("NAXIS1", 1024)
    metadata.set("NAXIS2", 1153)
    metadata.set("RADECSYS", 'FK5')
    metadata.set("EQUINOX", 2000.)

    metadata.setDouble("CRVAL1", 215.604025685476)
    metadata.setDouble("CRVAL2", 53.1595451514076)
    metadata.setDouble("CRPIX1", 1109.99981456774)
    metadata.setDouble("CRPIX2", 560.018167811613)
    metadata.set("CTYPE1", 'RA---SIN')
    metadata.set("CTYPE2", 'DEC--SIN')

    xFlip = 1
    if flipX:
        xFlip = -1
    yFlip = 1
    if flipY:
        yFlip = -1
    metadata.setDouble("CD1_1", xFlip * 5.10808596133527E-05)
    metadata.setDouble("CD1_2", yFlip * 1.85579539217196E-07)
    metadata.setDouble("CD2_2", yFlip * -5.10281493481982E-05)
    metadata.setDouble("CD2_1", xFlip * -8.27440751733828E-07)

    wcs = afwGeom.makeSkyWcs(metadata)
    exposure = afwImage.makeExposure(
        afwImage.makeMaskedImageFromArrays(np.ones((1024, 1153))), wcs)
    detector = DetectorWrapper(id=23, bbox=exposure.getBBox()).detector
    visit = afwImage.VisitInfo(exposureId=1234,
                               exposureTime=200.,
                               date=dafBase.DateTime(
                                   "2014-05-13T17:00:00.000000000",
                                   dafBase.DateTime.Timescale.TAI))
    exposure.info.id = 1234
    exposure.setDetector(detector)
    exposure.getInfo().setVisitInfo(visit)
    exposure.setFilter(afwImage.FilterLabel(band='g'))

    return exposure
示例#27
0
    def _computeReferenceOffsets(self, stdCat, lutCat, physicalFilterMap,
                                 bands):
        """
        Compute offsets relative to a reference catalog.

        This method splits the star catalog into healpix pixels
        and computes the calibration transfer for a sample of
        these pixels to approximate the 'absolute' calibration
        values (on for each band) to apply to transfer the
        absolute scale.

        Parameters
        ----------
        stdCat : `lsst.afw.table.SimpleCatalog`
            FGCM standard stars
        lutCat : `lsst.afw.table.SimpleCatalog`
            FGCM Look-up table
        physicalFilterMap : `dict`
            Dictionary of mappings from physical filter to FGCM band.
        bands : `list` [`str`]
            List of band names from FGCM output
        Returns
        -------
        offsets : `numpy.array` of floats
            Per band zeropoint offsets
        """

        # Only use stars that are observed in all the bands that were actually used
        # This will ensure that we use the same healpix pixels for the absolute
        # calibration of each band.
        minObs = stdCat['ngood'].min(axis=1)

        goodStars = (minObs >= 1)
        stdCat = stdCat[goodStars]

        self.log.info(
            "Found %d stars with at least 1 good observation in each band" %
            (len(stdCat)))

        # Associate each band with the appropriate physicalFilter and make
        # filterLabels
        filterLabels = []

        lutPhysicalFilters = lutCat[0]['physicalFilters'].split(',')
        lutStdPhysicalFilters = lutCat[0]['stdPhysicalFilters'].split(',')
        physicalFilterMapBands = list(physicalFilterMap.values())
        physicalFilterMapFilters = list(physicalFilterMap.keys())
        for band in bands:
            # Find a physical filter associated from the band by doing
            # a reverse lookup on the physicalFilterMap dict
            physicalFilterMapIndex = physicalFilterMapBands.index(band)
            physicalFilter = physicalFilterMapFilters[physicalFilterMapIndex]
            # Find the appropriate fgcm standard physicalFilter
            lutPhysicalFilterIndex = lutPhysicalFilters.index(physicalFilter)
            stdPhysicalFilter = lutStdPhysicalFilters[lutPhysicalFilterIndex]
            filterLabels.append(
                afwImage.FilterLabel(band=band, physical=stdPhysicalFilter))

        # We have to make a table for each pixel with flux/fluxErr
        # This is a temporary table generated for input to the photoCal task.
        # These fluxes are not instFlux (they are top-of-the-atmosphere approximate and
        # have had chromatic corrections applied to get to the standard system
        # specified by the atmosphere/instrumental parameters), nor are they
        # in Jansky (since they don't have a proper absolute calibration: the overall
        # zeropoint is estimated from the telescope size, etc.)
        sourceMapper = afwTable.SchemaMapper(stdCat.schema)
        sourceMapper.addMinimalSchema(afwTable.SimpleTable.makeMinimalSchema())
        sourceMapper.editOutputSchema().addField(
            'instFlux', type=np.float64, doc="instrumental flux (counts)")
        sourceMapper.editOutputSchema().addField(
            'instFluxErr',
            type=np.float64,
            doc="instrumental flux error (counts)")
        badStarKey = sourceMapper.editOutputSchema().addField('flag_badStar',
                                                              type='Flag',
                                                              doc="bad flag")

        # Split up the stars
        # Note that there is an assumption here that the ra/dec coords stored
        # on-disk are in radians, and therefore that starObs['coord_ra'] /
        # starObs['coord_dec'] return radians when used as an array of numpy float64s.
        theta = np.pi / 2. - stdCat['coord_dec']
        phi = stdCat['coord_ra']

        ipring = hp.ang2pix(self.config.referencePixelizationNside, theta, phi)
        h, rev = esutil.stat.histogram(ipring, rev=True)

        gdpix, = np.where(h >= self.config.referencePixelizationMinStars)

        self.log.info(
            "Found %d pixels (nside=%d) with at least %d good stars" %
            (gdpix.size, self.config.referencePixelizationNside,
             self.config.referencePixelizationMinStars))

        if gdpix.size < self.config.referencePixelizationNPixels:
            self.log.warning(
                "Found fewer good pixels (%d) than preferred in configuration (%d)"
                % (gdpix.size, self.config.referencePixelizationNPixels))
        else:
            # Sample out the pixels we want to use
            gdpix = np.random.choice(
                gdpix,
                size=self.config.referencePixelizationNPixels,
                replace=False)

        results = np.zeros(gdpix.size,
                           dtype=[('hpix', 'i4'), ('nstar', 'i4', len(bands)),
                                  ('nmatch', 'i4', len(bands)),
                                  ('zp', 'f4', len(bands)),
                                  ('zpErr', 'f4', len(bands))])
        results['hpix'] = ipring[rev[rev[gdpix]]]

        # We need a boolean index to deal with catalogs...
        selected = np.zeros(len(stdCat), dtype=bool)

        refFluxFields = [None] * len(bands)

        for p_index, pix in enumerate(gdpix):
            i1a = rev[rev[pix]:rev[pix + 1]]

            # the stdCat afwTable can only be indexed with boolean arrays,
            # and not numpy index arrays (see DM-16497).  This little trick
            # converts the index array into a boolean array
            selected[:] = False
            selected[i1a] = True

            for b_index, filterLabel in enumerate(filterLabels):
                struct = self._computeOffsetOneBand(sourceMapper, badStarKey,
                                                    b_index, filterLabel,
                                                    stdCat, selected,
                                                    refFluxFields)
                results['nstar'][p_index, b_index] = len(i1a)
                results['nmatch'][p_index, b_index] = len(struct.arrays.refMag)
                results['zp'][p_index, b_index] = struct.zp
                results['zpErr'][p_index, b_index] = struct.sigma

        # And compute the summary statistics
        offsets = np.zeros(len(bands))

        for b_index, band in enumerate(bands):
            # make configurable
            ok, = np.where(
                results['nmatch'][:, b_index] >= self.config.referenceMinMatch)
            offsets[b_index] = np.median(results['zp'][ok, b_index])
            # use median absolute deviation to estimate Normal sigma
            # see https://en.wikipedia.org/wiki/Median_absolute_deviation
            madSigma = 1.4826 * np.median(
                np.abs(results['zp'][ok, b_index] - offsets[b_index]))
            self.log.info(
                "Reference catalog offset for %s band: %.12f +/- %.12f", band,
                offsets[b_index], madSigma)

        return offsets
示例#28
0
 def bypass_deepCoadd_filterLabel(self, *args, **kwargs):
     """To return a useful filterLabel for MergeDetectionsTask."""
     return afwImage.FilterLabel(band=self.filterLabel.bandLabel)
示例#29
0
    def setUp(self):
        # metadata taken from CFHT data
        # v695856-e0/v695856-e0-c000-a00.sci_img.fits
        self.metadata = dafBase.PropertySet()

        self.metadata.set("SIMPLE", "T")
        self.metadata.set("BITPIX", -32)
        self.metadata.set("NAXIS", 2)
        self.metadata.set("NAXIS1", 1024)
        self.metadata.set("NAXIS2", 1153)
        self.metadata.set("RADECSYS", 'FK5')
        self.metadata.set("EQUINOX", 2000.)

        self.metadata.setDouble("CRVAL1", 215.604025685476)
        self.metadata.setDouble("CRVAL2", 53.1595451514076)
        self.metadata.setDouble("CRPIX1", 1109.99981456774)
        self.metadata.setDouble("CRPIX2", 560.018167811613)
        self.metadata.set("CTYPE1", 'RA---SIN')
        self.metadata.set("CTYPE2", 'DEC--SIN')

        self.metadata.setDouble("CD1_1", 5.10808596133527E-05)
        self.metadata.setDouble("CD1_2", 1.85579539217196E-07)
        self.metadata.setDouble("CD2_2", -5.10281493481982E-05)
        self.metadata.setDouble("CD2_1", -8.27440751733828E-07)

        self.wcs = afwGeom.makeSkyWcs(self.metadata)

        self.calibration = 10000
        self.calibrationErr = 100
        self.exposureId = 1234
        self.exposureTime = 200.
        self.imageSize = [1024, 1153]
        self.dateTime = "2014-05-13T17:00:00.000000000"

        # Make images  with one source in them and distinct values and
        # variance for each image.
        # Direct Image
        source_image = afwImage.MaskedImageF(
            lsst.geom.ExtentI(self.imageSize[0] + 1, self.imageSize[1] + 1))
        source_image.image[100, 100, afwImage.LOCAL] = 10
        source_image.getVariance().set(1)
        bbox = lsst.geom.BoxI(
            lsst.geom.PointI(1, 1),
            lsst.geom.ExtentI(self.imageSize[0],
                              self.imageSize[1]))
        masked_image = afwImage.MaskedImageF(source_image, bbox, afwImage.LOCAL)
        self.exposure = afwImage.makeExposure(masked_image, self.wcs)

        detector = DetectorWrapper(
            id=23, bbox=self.exposure.getBBox()).detector
        visit = afwImage.VisitInfo(
            exposureId=self.exposureId,
            exposureTime=self.exposureTime,
            date=dafBase.DateTime(self.dateTime,
                                  dafBase.DateTime.Timescale.TAI))
        self.exposure.info.id = self.exposureId
        self.exposure.setDetector(detector)
        self.exposure.getInfo().setVisitInfo(visit)
        self.exposure.setFilter(afwImage.FilterLabel(band='g', physical='g.MP9401'))
        self.exposure.setPhotoCalib(afwImage.PhotoCalib(self.calibration, self.calibrationErr))

        # Difference Image
        source_image = afwImage.MaskedImageF(
            lsst.geom.ExtentI(self.imageSize[0] + 1, self.imageSize[1] + 1))
        source_image.image[100, 100, afwImage.LOCAL] = 20
        source_image.getVariance().set(2)
        bbox = lsst.geom.BoxI(
            lsst.geom.PointI(1, 1),
            lsst.geom.ExtentI(self.imageSize[0],
                              self.imageSize[1]))
        masked_image = afwImage.MaskedImageF(source_image, bbox, afwImage.LOCAL)
        self.diffim = afwImage.makeExposure(masked_image, self.wcs)
        self.diffim.info.id = self.exposureId
        self.diffim.setDetector(detector)
        self.diffim.getInfo().setVisitInfo(visit)
        self.diffim.setFilter(afwImage.FilterLabel(band='g', physical='g.MP9401'))
        self.diffim.setPhotoCalib(afwImage.PhotoCalib(self.calibration, self.calibrationErr))

        self.expIdBits = 16

        FWHM = 5
        psf = measAlg.DoubleGaussianPsf(15, 15, FWHM/(2*np.sqrt(2*np.log(2))))
        self.exposure.setPsf(psf)
        self.diffim.setPsf(psf)

        self.testDiaObjects = create_test_dia_objects(5, self.wcs)
        # Add additional diaObjects that are outside of the above difference
        # and calexp visit images.
        objects = [
            (10000000, self.wcs.pixelToSky(-100000, -100000)),  # xy outside
            (10000001, self.wcs.pixelToSky(100, -100000)),  # y outside
            (10000002, self.wcs.pixelToSky(-100000, 100)),  # x outside
        ]
        extra = pandas.DataFrame({
            "diaObjectId": np.array([id for id, point in objects], dtype=np.int64),
            "ra": [point.getRa().asDegrees() for id, point in objects],
            "decl": [point.getDec().asDegrees() for id, point in objects]
        })
        self.testDiaObjects = pd.concat([self.testDiaObjects, extra], ignore_index=True)
        # Ids of objects that were "updated" during "ap_association"
        # processing.
        self.updatedTestIds = np.array([1, 2, 3, 4, 10000001], dtype=np.uint64)
        # Expecdted number of sources is the number of updated ids plus
        # any that are within the CCD footprint but are not in the
        # above list of ids.
        self.expectedDiaForcedSources = 6

        self.expected_n_columns = 11
示例#30
0
    def testStandardizeFiltersFilterDefs(self):
        testLabels = [
            (None, None),
            (afwImage.FilterLabel(band="i", physical="i.MP9701"),
             afwImage.FilterLabel(band="i", physical="i.MP9701")),
            (afwImage.FilterLabel(band="i"),
             afwImage.FilterLabel(band="r", physical="i.MP9701")),
            (afwImage.FilterLabel(physical="i.MP9701"),
             afwImage.FilterLabel(band="i", physical="i.MP9701")),
            (afwImage.FilterLabel(band="i", physical="old-i"),
             afwImage.FilterLabel(band="i", physical="i.MP9701")),
            (afwImage.FilterLabel(physical="old-i"),
             afwImage.FilterLabel(band="i", physical="i.MP9701")),
            (afwImage.FilterLabel(physical="i2"),
             afwImage.FilterLabel(band="i", physical="HSC-I2")),
        ]
        testIds = [{
            "visit": 12345,
            "ccd": 42,
            "filter": f
        } for f in {
            "i",
            "i.MP9701",
            "old-i",
            "i2",
        }]
        testData = []
        # Resolve special combinations where the expected output is different
        for input, corrected in testLabels:
            for dataId in testIds:
                if input is None:
                    if dataId["filter"] == "i":
                        data = (input, dataId, afwImage.FilterLabel(band="i"))
                    elif dataId["filter"] == "i2":
                        data = (input, dataId,
                                afwImage.FilterLabel(band="i",
                                                     physical="HSC-I2"))
                    else:
                        data = (input, dataId,
                                afwImage.FilterLabel(band="i",
                                                     physical="i.MP9701"))
                elif input == afwImage.FilterLabel(band="i"):
                    if dataId["filter"] == "i":
                        # There are two "i" filters, can't tell which
                        data = (input, dataId, input)
                    elif dataId["filter"] == "i2":
                        data = (input, dataId,
                                afwImage.FilterLabel(band="i",
                                                     physical="HSC-I2"))
                elif corrected.physicalLabel == "HSC-I2" and dataId[
                        "filter"] in ("i.MP9701", "old-i"):
                    # Contradictory inputs, leave as-is
                    data = (input, dataId, input)
                elif corrected.physicalLabel == "i.MP9701" and dataId[
                        "filter"] == "i2":
                    # Contradictory inputs, leave as-is
                    data = (input, dataId, input)
                else:
                    data = (input, dataId, corrected)
                testData.append(data)

        mapper = MinMapper2(root=ROOT)
        for label, dataId, corrected in testData:
            exposure = afwImage.ExposureF()
            exposure.setFilterLabel(label)
            mapper._setFilter(mapper.exposures['raw'], exposure, dataId)
            self.assertEqual(exposure.getFilterLabel(),
                             corrected,
                             msg=f"Started from {label} and {dataId}")