Exemple #1
0
    def testCalibFromCalibs(self):
        """Test creating a Calib from an array of Calibs"""
        exptime = 20
        mag0, mag0Sigma = 1.0, 0.01
        time0 = dafBase.DateTime.now().get()

        calibs = afwImage.vectorCalib()
        ncalib = 3
        for i in range(ncalib):
            calib = afwImage.Calib()
            calib.setMidTime(dafBase.DateTime(time0 + i))
            calib.setExptime(exptime)
            calib.setFluxMag0(mag0, mag0Sigma)

            calibs.append(calib)

        ocalib = afwImage.Calib(calibs)

        self.assertEqual(ocalib.getExptime(), ncalib * exptime)
        self.assertAlmostEqual(calibs[ncalib // 2].getMidTime().get(),
                               ocalib.getMidTime().get())
        #
        # Check that we can only merge Calibs with the same fluxMag0 values
        #
        calibs[0].setFluxMag0(1.001 * mag0, mag0Sigma)
        self.assertRaises(pexExcept.InvalidParameterError,
                          lambda: afwImage.Calib(calibs))
Exemple #2
0
    def testCtorFromMetadata(self):
        """Test building a Calib from metadata"""

        flux0, flux0Err = 1e12, 1e10
        flux, fluxErr = 1000.0, 10.0

        metadata = dafBase.PropertySet()
        metadata.add("FLUXMAG0", flux0)
        metadata.add("FLUXMAG0ERR", flux0Err)

        self.calib = afwImage.Calib(metadata)

        self.assertEqual(flux0, self.calib.getFluxMag0()[0])
        self.assertEqual(flux0Err, self.calib.getFluxMag0()[1])
        self.assertEqual(22.5, self.calib.getMagnitude(flux))
        # Error just in flux
        self.calib.setFluxMag0(flux0, 0)

        self.assertAlmostEqual(
            self.calib.getMagnitude(flux, fluxErr)[1],
            2.5 / math.log(10) * fluxErr / flux)

        # Check that we can clean up metadata
        afwImage.stripCalibKeywords(metadata)
        self.assertEqual(len(metadata.names()), 0)
Exemple #3
0
def loadData(pixelScale=1.0):
    """Prepare the data we need to run the example"""

    # Load sample input from disk
    mypath = lsst.utils.getPackageDir('afwdata')

    print(
        " mypath = ",
        mypath)  # mssg -- error happens before i can even possibly print this
    #    sys.exit()

    imFile = os.path.join(mypath, "CFHT", "D4",
                          "cal-53535-i-797722_small_1.fits")

    exposure = afwImage.ExposureF(imFile)
    # set the exposure time
    calib = afwImage.Calib()
    calib.setExptime(1.0)
    exposure.setCalib(calib)
    # add a filter
    afwImage.Filter.define(afwImage.FilterProperty(FilterName, 600, True))
    exposure.setFilter(afwImage.Filter(FilterName))
    # and a trivial WCS (needed by MyAstrometryTask)
    pixelScale /= 3600.0  # degrees per pixel
    wcs = afwImage.makeWcs(Coord(PointD(15, 1)), PointD(0, 0), pixelScale, 0.0,
                           0.0, pixelScale)
    exposure.setWcs(wcs)

    return exposure
    def buildExposure(self, dataRef):

        image = dataRef.get(self.config.dataType + "image", immediate=True)
        exposure = afwImage.ExposureF(image.getBBox(afwImage.PARENT))
        exposure.getMaskedImage().getImage().getArray()[:, :] = image.getArray(
        )

        variance = self.computeVariance(image)
        exposure.getMaskedImage().getVariance().set(variance)
        self.algMetadata.set('noise_variance', variance)

        exposure.setPsf(self.psf.run(dataRef, self.config.dataType))

        pixelScale = self.config.PIXEL_SCALE * afwGeom.arcseconds
        cdMatrix = makeCdMatrix(scale=pixelScale)
        crpix = afwGeom.Point2D(0, 0)
        crval = lsst.afw.coord.IcrsCoord(0. * afwGeom.degrees,
                                         0. * afwGeom.degrees)
        wcs = makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cdMatrix)
        exposure.setWcs(wcs)

        calib = afwImage.Calib()
        calib.setFluxMag0(1e12)
        exposure.setCalib(calib)

        return exposure
Exemple #5
0
    def testCtorFromMetadata(self):
        """Test building a Calib from metadata"""

        isoDate = "1995-01-26T07:32:00.000000000Z"
        exptime = 123.4
        flux0, flux0Err = 1e12, 1e10
        flux, fluxErr = 1000.0, 10.0

        metadata = dafBase.PropertySet()
        metadata.add("TIME-MID", isoDate)
        metadata.add("EXPTIME", exptime)
        metadata.add("FLUXMAG0", flux0)
        metadata.add("FLUXMAG0ERR", flux0Err)

        self.calib = afwImage.Calib(metadata)

        self.assertEqual(isoDate, self.calib.getMidTime().toString())
        self.assertAlmostEqual(self.calib.getMidTime().get(), 49743.3142245)
        self.assertEqual(self.calib.getExptime(), exptime)

        self.assertEqual(flux0, self.calib.getFluxMag0()[0])
        self.assertEqual(flux0Err, self.calib.getFluxMag0()[1])
        self.assertEqual(22.5, self.calib.getMagnitude(flux))
        # Error just in flux
        self.calib.setFluxMag0(flux0, 0)

        self.assertAlmostEqual(
            self.calib.getMagnitude(flux, fluxErr)[1],
            2.5 / math.log(10) * fluxErr / flux)

        #
        # Check that we can clean up metadata
        #
        afwImage.stripCalibKeywords(metadata)
        self.assertEqual(len(metadata.names()), 0)
Exemple #6
0
    def bypass_instcal(self, datasetType, pythonType, butlerLocation, dataId):
        # Workaround until I can access the butler
        instcalMap = self.map_instcal(dataId)
        dqmaskMap = self.map_dqmask(dataId)
        wtmapMap = self.map_wtmap(dataId)
        rawMap = self.map_raw(dataId)
        instcalType = getattr(afwImage,
                              instcalMap.getPythonType().split(".")[-1])
        rawType = getattr(afwImage, rawMap.getPythonType().split(".")[-1])
        dqmaskType = getattr(afwImage,
                             dqmaskMap.getPythonType().split(".")[-1])
        wtmapType = getattr(afwImage, wtmapMap.getPythonType().split(".")[-1])
        instcal = instcalType(instcalMap.getLocations()[0])
        dqmask = dqmaskType(dqmaskMap.getLocations()[0])
        wtmap = wtmapType(wtmapMap.getLocations()[0])
        raw = rawType(rawMap.getLocations()[0])
        mask = self.translate_dqmask(dqmask)
        variance = self.translate_wtmap(wtmap)

        mi = afwImage.MaskedImageF(afwImage.ImageF(instcal.getImage()), mask,
                                   variance)
        md = raw.getMetadata()
        wcs = afwImage.makeWcs(md)
        exp = afwImage.ExposureF(mi, wcs)

        # Set the calib by hand; need to grab the zeroth extension
        header = re.sub(r'[\[](\d+)[\]]$', "[0]", rawMap.getLocations()[0])
        md0 = afwImage.readMetadata(header)
        calib = afwImage.Calib()
        calib.setExptime(md0.get("EXPTIME"))
        calib.setFluxMag0(10**(0.4 * md0.get("MAGZERO")))
        exp.setCalib(calib)

        exp.setMetadata(md)  # Do we need to remove WCS/calib info?
        return exp
Exemple #7
0
 def _getCalibData(self, dataType, **id):
     """
     Get the zero magnitude flux for the given data type and data id
     It also returns the psf associated with the data id in case it's needed
     later (e.g. when withSeeing=True)
     """
     calexpType = self._getCalexpType(dataType)
     if self.butler.datasetExists(calexpType, **id):
         calexp = self.butler.get(calexpType, **id)
         try:
             calib = afwImage.Calib(calexp)
         except NotImplementedError:
             calib = calexp.getCalib()
     else:
         calexpType = dataType[:-4]
         if calexpType[-1] == '_':
             calexpType = calexpType[:-1]
         #try:
         calexp = self.butler.get(calexpType, **id)
         calib = calexp.getCalib()
         #except LsstCppException:
         #    fName = 'calexp-{0}-{1}-{2}.fits'.format(id['filter'], id['tract'], id['patch'])
         #    fName = os.path.join(self.dataRoot, 'deepCoadd', id['filter'], str(id['tract']), id['patch'], fName)
         #    calexp = afwImage.ExposureF(fName)
         #    calib = calexp.getCalib()
     psf = calexp.getPsf()
     fluxMag0, fluxMag0Err = calib.getFluxMag0()
     if 'deepCoadd' in dataType:
         exptime = self._getCoaddExpTime(calexp)
     else:
         exptime = calib.getExptime()
     return fluxMag0, fluxMag0Err, psf, exptime
Exemple #8
0
def getFluxFitParams(dataRef):
    """Retrieve the flux correction parameters determined by meas_mosaic

    If the flux correction parameters do not exist, an exception will
    be raised.
    """
    calexp_md = dataRef.get("calexp_md", immediate=True)
    hscRun = mosaicUtils.checkHscStack(calexp_md)
    if hscRun is not None:
        wcsHeader = dataRef.get("wcs_hsc_md", immediate=True)
        ffpHeader = dataRef.get("fcr_hsc_md", immediate=True)
    else:
        wcsHeader = dataRef.get("wcs_md", immediate=True)
        ffpHeader = dataRef.get("fcr_md", immediate=True)
    calib = afwImage.Calib(ffpHeader)
    ffp = FluxFitParams(ffpHeader)

    wcs = getWcs(dataRef)

    if hscRun is None:
         detector = dataRef.get("camera")[dataRef.dataId["ccd"]]
         nQuarter = detector.getOrientation().getNQuarter()
         if nQuarter%4 != 0:
             # Have to put this import here due to circular dependence in forcedPhotCcd.py in meas_base
             import lsst.meas.astrom as measAstrom
             dimensions = afwGeom.Extent2I(calexp_md.get("NAXIS1"), calexp_md.get("NAXIS2"))
             wcs = measAstrom.rotateWcsPixelsBy90(wcs, nQuarter, dimensions)
    return Struct(ffp=ffp, calib=calib, wcs=wcs)
Exemple #9
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 * afwGeom.degrees
     weather = afwCoord.Weather(1.1, 2.2, 0.3)
     visitInfo = afwImage.makeVisitInfo(
         exposureId = exposureId,
         exposureTime = exposureTime,
         boresightRotAngle = boresightRotAngle,
         weather = weather,
     )
     # Calib used to have exposure time and exposure date, so check for lack of interference
     calib = afwImage.Calib(3.4)
     exposureInfo = afwImage.ExposureInfo()
     exposureInfo.setVisitInfo(visitInfo)
     exposureInfo.setCalib(calib)
     exposureInfo.setDetector(self.detector)
     gFilter = afwImage.Filter("g")
     exposureInfo.setFilter(gFilter)
     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.getCalib(), calib)
     self.assertEqual(rtExposure.getFilter(), gFilter)
    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.
        """
        filterPolicyFile = pexPolicy.DefaultPolicyFile("afw",
                                                       "SdssFilters.paf",
                                                       "tests")
        filterPolicy = pexPolicy.Policy.createPolicy(
            filterPolicyFile, filterPolicyFile.getRepositoryPath(), True)
        imageUtils.defineFiltersFromPolicy(filterPolicy, reset=True)

        originalExposure = afwImage.ExposureF(originalExposurePath)
        originalFilter = afwImage.Filter("i")
        originalCalib = afwImage.Calib()
        originalCalib.setFluxMag0(1.0e5, 1.0e3)
        originalExposure.setFilter(originalFilter)
        originalExposure.setCalib(originalCalib)
        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().getName(),
                         originalFilter.getName())
        self.assertEqual(afwWarpedExposure.getCalib().getFluxMag0(),
                         originalCalib.getFluxMag0())

        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)
Exemple #11
0
    def testCalibEquality(self):
        self.assertEqual(self.calib, self.calib)
        self.assertFalse(self.calib != self.calib)

        calib2 = afwImage.Calib()
        calib2.setExptime(12)

        self.assertNotEqual(calib2, self.calib)
Exemple #12
0
    def testCalibEquality(self):
        self.assertEqual(self.calib, self.calib)
        # using assertFalse to directly test != operator
        self.assertFalse(self.calib != self.calib)

        calib2 = afwImage.Calib()
        calib2.setFluxMag0(1200)

        self.assertNotEqual(calib2, self.calib)
    def __init__(self, *args, **kwargs):
        """Construct a ScaleZeroPointTask
        """
        pipeBase.Task.__init__(self, *args, **kwargs)

        #flux at mag=0 is 10^(zeroPoint/2.5)   because m = -2.5*log10(F/F0)
        fluxMag0 = 10**(0.4 * self.config.zeroPoint)
        self._calib = afwImage.Calib()
        self._calib.setFluxMag0(fluxMag0)
Exemple #14
0
 def _performTransform(self, transformClass, inCat, doExtend=True):
     """Operate on inCat with a transform of class transformClass"""
     mapper = afwTable.SchemaMapper(inCat.schema)
     config = SillyCentroidConfig()
     transform = transformClass(config, self.pluginName, mapper)
     outCat = afwTable.BaseCatalog(mapper.getOutputSchema())
     if doExtend:
         outCat.extend(inCat, mapper=mapper)
     transform(inCat, outCat, makeWcs(), afwImage.Calib())
     return outCat
Exemple #15
0
    def setUp(self):
        '''Create two calibs, one with a valid zero-point and one without. Use these to create two UnitSystem
        objects.
        '''
        self.mag2Flux = lambda m: 10.0**(m / 2.5)
        self.flux2Mag = lambda f: 2.5 * np.log10(f)

        calibNoZero = afwImage.Calib()
        calibWithZero = afwImage.Calib()
        calibWithZero.setFluxMag0(self.mag2Flux(25))

        scale = 0.2 * afwGeom.arcseconds
        wcs = afwGeom.makeSkyWcs(crpix=afwGeom.Point2D(),
                                 crval=afwGeom.SpherePoint(
                                     45.0, 45.0, afwGeom.degrees),
                                 cdMatrix=afwGeom.makeCdMatrix(scale=scale))

        self.unitNoZero = measModel.UnitSystem(wcs, calibNoZero)
        self.unitWithZero = measModel.UnitSystem(wcs, calibWithZero)
    def setUp(self):
        '''Create two calibs, one with a valid zero-point and one without. Use these to create two UnitSystem
        objects.
        '''
        self.mag2Flux = lambda m: 10.0**(m / 2.5)
        self.flux2Mag = lambda f: 2.5 * np.log10(f)

        calibNoZero = afwImage.Calib()
        calibWithZero = afwImage.Calib()
        calibWithZero.setFluxMag0(self.mag2Flux(25))

        cdelt = (0.2 * afwGeom.arcseconds).asDegrees()
        position = afwCoord.IcrsCoord(45.0 * afwGeom.degrees,
                                      45.0 * afwGeom.degrees)
        wcs = afwImage.makeWcs(position, afwGeom.Point2D(), cdelt, 0.0, 0.0,
                               cdelt)

        self.unitNoZero = measModel.UnitSystem(wcs, calibNoZero)
        self.unitWithZero = measModel.UnitSystem(wcs, calibWithZero)
Exemple #17
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"))

        self.assertEqual(exposure.getDetector().getName(),
                         self.detector.getName())
        self.assertEqual(exposure.getDetector().getSerial(),
                         self.detector.getSerial())
        self.assertEqual(exposure.getFilter().getName(), "g")

        try:
            exposure.getWcs()
        except pexExcept.Exception as e:
            print("caught expected exception (getWcs): %s" % e)
            pass
        #
        # Test the Calib member.  The Calib tests are in color.py, here we just check that it's in Exposure
        #
        calib = exposure.getCalib()
        fluxMag0, FluxMag0Err = 1.1e12, 2.2e10
        calib.setFluxMag0(fluxMag0, FluxMag0Err)
        self.assertEqual(exposure.getCalib().getFluxMag0(),
                         (fluxMag0, FluxMag0Err))
        #
        # now check that we can set Calib
        #
        calib = afwImage.Calib()
        fluxMag0_2, fluxMag0Err_2 = (511.1, 44.4)
        calib.setFluxMag0(fluxMag0_2, fluxMag0Err_2)

        exposure.setCalib(calib)

        self.assertEqual(exposure.getCalib().getFluxMag0(),
                         (fluxMag0_2, fluxMag0Err_2))
        #
        # Psfs next
        #
        self.assertFalse(exposure.hasPsf())
        exposure.setPsf(self.psf)
        self.assertTrue(exposure.hasPsf())

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

        # Test that we can set the MaskedImage and WCS of an Exposure
        # that already has both
        self.exposureMiWcs.setMaskedImage(maskedImage)
        exposure.setWcs(self.wcs)
Exemple #18
0
 def testApplyCppTransform(self):
     """Test that we can apply a simple C++ transform"""
     inCat = self._generateCatalog()
     sillyControl = testLib.SillyCentroidControl()
     mapper = afwTable.SchemaMapper(inCat.schema)
     sillyTransform = testLib.SillyTransform(sillyControl, self.pluginName, mapper)
     outCat = afwTable.BaseCatalog(mapper.getOutputSchema())
     outCat.extend(inCat, mapper=mapper)
     self.assertEqual(len(inCat), len(outCat))
     sillyTransform(inCat, outCat, makeWcs(), afwImage.Calib())
     self._checkSillyOutputs(inCat, outCat)
Exemple #19
0
    def testCalibFromCalibs(self):
        """Test creating a Calib from an array of Calibs"""
        mag0, mag0Sigma = 1.0, 0.01

        calibs = afwImage.vectorCalib()
        ncalib = 3
        for i in range(ncalib):
            calib = afwImage.Calib()
            calib.setFluxMag0(mag0, mag0Sigma)

            calibs.append(calib)

        ocalib = afwImage.Calib(calibs)
        # the following is surely incorrect; see DM-7619
        self.assertEqual(ocalib.getFluxMag0(), (0.0, 0.0))

        # Check that we can only merge Calibs with the same fluxMag0 values
        calibs[0].setFluxMag0(1.001 * mag0, mag0Sigma)
        with self.assertRaises(pexExcept.InvalidParameterError):
            afwImage.Calib(calibs)
    def scaleFromFluxMag0(self, fluxMag0):
        """Compute the scale for the specified fluxMag0

        This is a wrapper around scaleFromCalib, which see for more information

        @param[in] fluxMag0
        @return a pipeBase.Struct containing:
        - scale, as described in scaleFromCalib.
        """
        calib = afwImage.Calib()
        calib.setFluxMag0(fluxMag0)
        return self.scaleFromCalib(calib)
Exemple #21
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)

        filterPolicyFile = pexPolicy.DefaultPolicyFile("afw",
                                                       "SdssFilters.paf",
                                                       "tests")
        filterPolicy = pexPolicy.Policy.createPolicy(
            filterPolicyFile, filterPolicyFile.getRepositoryPath(), True)
        imageUtils.defineFiltersFromPolicy(filterPolicy, reset=True)

        originalFilter = afwImage.Filter("i")
        originalCalib = afwImage.Calib()
        originalCalib.setFluxMag0(1.0e5, 1.0e3)
        originalExposure.setFilter(originalFilter)
        originalExposure.setCalib(originalCalib)

        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.getFilter().getName(),
                         originalFilter.getName())
        self.assertEqual(warpedExposure1.getCalib().getFluxMag0(),
                         originalCalib.getFluxMag0())
Exemple #22
0
def converttsField(infile, filt, exptime=53.907456):
    """Extract data from a tsField table

    @param[in] infile  path to tsField FITS file
    @param[in] filt  index of filter in tsField FILTERS metadata entry
    @param[in] exptime  exposure time (sec)

    @return a dict with the following entries:
    - calib: an lsst.afw.Calib
    - gain: gain as a float
    - dateAvg: date of exposure at middle of exposure, as an lsst.daf.base.DateTime
    - exptime: exposure time (sec)
    - airmass: airmass
    """
    ptr = pyfits.open(infile)
    if ptr[0].header['NFIELDS'] != 1:
        print("INVALID TSFIELD FILE")
        sys.exit(1)
    filts = ptr[0].header['FILTERS'].split()
    idx = filts.index(filt)

    mjdTaiStart = ptr[1].data.field('mjd')[0][
        idx]  # MJD(TAI) when row 0 was read
    airmass = ptr[1].data.field("airmass")[0][idx]

    gain = float(
        ptr[1].data.field('gain')[0][idx])  # comes out as numpy.float32
    aa = ptr[1].data.field('aa')[0][idx]  # f0 = 10**(-0.4*aa) counts/second
    aaErr = ptr[1].data.field('aaErr')[0][idx]

    # Conversions
    dateAvg = dafBase.DateTime(mjdTaiStart + 0.5 * exptime / 3600 / 24)
    fluxMag0 = 10**(-0.4 * aa) * exptime
    dfluxMag0 = fluxMag0 * 0.4 * np.log(10.0) * aaErr

    calib = afwImage.Calib()
    calib.setFluxMag0(fluxMag0, dfluxMag0)

    ptr.close()

    return TsField(
        calib=calib,
        gain=gain,
        dateAvg=dateAvg,
        exptime=exptime,
        airmass=airmass,
    )
def filterSources(sources, md, bright, flags=0x80):
    if isinstance(sources, afwDet.PersistableSourceVector):
        sources = sources.getSources()
    calib = afwImage.Calib(md)
    wcs = afwImage.makeWcs(md)
    offsets = numpy.ndarray(len(sources))
    outSources = afwDet.SourceSet()
    for i, src in enumerate(sources):
        try:
            #            psfMag = calib.getMagnitude(src.getPsfFlux())
            apMag = calib.getMagnitude(src.getApFlux())
#            modelMag = calib.getMagnitude(src.getModelFlux())
        except:
            continue

        if bright is not None and apMag > bright:
            continue

        if src.getFlagForDetection() & flags == 0:
            continue

#        src.setPsfFlux(psfMag)
#        src.setApFlux(apMag)
#        src.setModelFlux(modelMag)

        x, y = src.getXAstrom(), src.getYAstrom()
        #if x < 5 or x > 2043 or y < 5 or y > 4172:
        #    src.setRa(4.32)
        #    src.setDec(0.0)
        #    continue
        src.setRa(wcs.pixelToSky(x, y))
        #        x1, y1 = src.getXAstrom(), src.getYAstrom()
        #        sky = wcs.pixelToSky(x1, y1)
        #        pix = wcs.skyToPixel(sky)
        #        offsets[i] = math.hypot(pix.getX()-x1, pix.getY()-y1)
        outSources.push_back(src)


#    print offsets.mean(), offsets.std()
    return outSources
    def bypass_instcal(self, datasetType, pythonType, butlerLocation, dataId):
        # Workaround until I can access the butler
        instcalMap = self.map_instcal(dataId)
        dqmaskMap = self.map_dqmask(dataId)
        wtmapMap = self.map_wtmap(dataId)
        instcalType = getattr(afwImage, instcalMap.getPythonType().split(".")[-1])
        dqmaskType = getattr(afwImage, dqmaskMap.getPythonType().split(".")[-1])
        wtmapType = getattr(afwImage, wtmapMap.getPythonType().split(".")[-1])
        instcal = instcalType(instcalMap.getLocationsWithRoot()[0])
        dqmask = dqmaskType(dqmaskMap.getLocationsWithRoot()[0])
        wtmap = wtmapType(wtmapMap.getLocationsWithRoot()[0])

        mask = self.translate_dqmask(dqmask)
        variance = self.translate_wtmap(wtmap)

        mi = afwImage.MaskedImageF(afwImage.ImageF(instcal.getImage()), mask, variance)
        md = instcal.getMetadata()
        wcs = afwImage.makeWcs(md, True)
        exp = afwImage.ExposureF(mi, wcs)

        # Set the calib by hand; need to grab the zeroth extension
        header = re.sub(r'[\[](\d+)[\]]$', "[0]", instcalMap.getLocationsWithRoot()[0])
        md0 = afwImage.readMetadata(header)
        calib = afwImage.Calib()
        calib.setFluxMag0(10**(0.4 * md0.get("MAGZERO")))
        exp.setCalib(calib)
        exposureId = self._computeCcdExposureId(dataId)
        visitInfo = self.makeRawVisitInfo(md=md0, exposureId=exposureId)
        exp.getInfo().setVisitInfo(visitInfo)

        for kw in ('LTV1', 'LTV2'):
            md.remove(kw)

        # Remove TPV keywords from the metadata
        for kw in md.paramNames():
            if re.match(r'PV\d_\d', kw):
                md.remove(kw)

        exp.setMetadata(md)
        return exp
 def writeFcr(self, butler, ccdIdList, ccdSet, filterName, 
              fexp, fchip, ffpSet):
     for ccdId in ccdIdList:
         iexp, ichip = self.decodeCcdExposureId(ccdId)
         if not ichip in ccdSet.keys():
             continue
         x0 = 0.0
         y0 = 0.0
         newP = measMosaic.convertFluxFitParams(measMosaic.FluxFitParams(ffpSet[iexp]),
                                                ccdSet[ichip], x0, y0)
         metadata = measMosaic.metadataFromFluxFitParams(newP)
         exp = afwImage.ExposureI(0,0)
         exp.getMetadata().combine(metadata)
         scale = fexp[iexp] * fchip[ichip]
         calib = afwImage.Calib()
         calib.setFluxMag0(1.0/scale)
         exp.setCalib(calib)
         exp.setFilter(afwImage.Filter(filterName))
         try:
             butler.put(exp, 'fcr', {'visit': iexp, 'ccd': ichip})
         except Exception, e:
             print "failed to write something: %s" % (e)
def extract_photometry(butler,
                       dataId,
                       forced_dataset,
                       filt,
                       object_id,
                       names_to_copy,
                       phot_type='base_PsfFlux'):
    # Can grab filter, mjd from 'calexp_md' call on visit
    md = butler.get('calexp_md', dataId=dataId, immediate=True)
    mjd = md.get('MJD-OBS')
    #        filt = md.get('FILTER')  # But that's not being set right now so we'll keep using f

    this_measurement = butler.get(forced_dataset, dataId).asAstropy()
    source_row, = np.where(this_measurement['objectId'] == object_id)
    if len(source_row) != 1:
        return None

    # 'this_measurement' is a table, but we're only extracting the first entry from each column
    new_row = {n: this_measurement[n][source_row] for n in names_to_copy}
    #        new_row['filter'] = dataId['filter']
    new_row['filter'] = filt
    new_row['mjd'] = mjd

    # Calibrate to magnitudes
    # The calibration information for the calexp
    # should still apply to the difference image
    calib = afwImage.Calib(md)
    with afwImageUtils.CalibNoThrow():
        new_row['%s_mag' % phot_type], new_row['%s_magSigma' % phot_type] = \
            calib.getMagnitude(new_row['%s_flux' % phot_type],
                               new_row['%s_fluxSigma' % phot_type])
    flux_mag_0, flux_magSigma_0 = calib.getFluxMag0()
    flux_mag_25 = 10**(-0.4 * 25) * flux_mag_0
    flux_norm = 1 / flux_mag_25
    new_row['%s_flux_zp25' % phot_type] = \
        flux_norm * new_row['%s_flux' % phot_type]
    new_row['%s_fluxSigma_zp25' % phot_type] = \
        flux_norm * new_row['%s_fluxSigma' % phot_type]
    return new_row
Exemple #27
0
class ExposureTestCase(unittest.TestCase):
    """
    A test case for the Exposure Class
    """
    def setUp(self):
        maskedImage = afwImage.MaskedImageF(inFilePathSmall)
        maskedImageMD = afwImage.readMetadata(inFilePathSmall)

        self.smallExposure = afwImage.ExposureF(inFilePathSmall)
        self.width = maskedImage.getWidth()
        self.height = maskedImage.getHeight()
        self.wcs = afwImage.makeWcs(maskedImageMD)
        self.psf = DummyPsf(2.0)

        self.exposureBlank = afwImage.ExposureF()
        self.exposureMiOnly = afwImage.makeExposure(maskedImage)
        self.exposureMiWcs = afwImage.makeExposure(maskedImage, self.wcs)
        self.exposureCrWcs = afwImage.ExposureF(
            100, 100, self.wcs)  # n.b. the (100, 100, ...) form
        self.exposureCrOnly = afwImage.ExposureF(afwGeom.ExtentI(
            100, 100))  # test with ExtentI(100, 100) too

        afwImage.Filter.reset()
        afwImage.FilterProperty.reset()

        filterPolicy = pexPolicy.Policy()
        filterPolicy.add("lambdaEff", 470.0)
        afwImage.Filter.define(afwImage.FilterProperty("g", filterPolicy))

    def tearDown(self):
        del self.smallExposure
        del self.wcs
        del self.psf

        del self.exposureBlank
        del self.exposureMiOnly
        del self.exposureMiWcs
        del self.exposureCrWcs
        del self.exposureCrOnly

    def testGetMaskedImage(self):
        """
        Test to ensure a MaskedImage can be obtained from each
        Exposure. An Exposure is required to have a MaskedImage,
        therefore each of the Exposures should return a MaskedImage.

        MaskedImage class should throw appropriate
        lsst::pex::exceptions::NotFound if the MaskedImage can not be
        obtained.
        """
        maskedImageBlank = self.exposureBlank.getMaskedImage()
        blankWidth = maskedImageBlank.getWidth()
        blankHeight = maskedImageBlank.getHeight()
        if blankWidth != blankHeight != 0:
            self.fail("%s = %s != 0" % (blankWidth, blankHeight))

        maskedImageMiOnly = self.exposureMiOnly.getMaskedImage()
        miOnlyWidth = maskedImageMiOnly.getWidth()
        miOnlyHeight = maskedImageMiOnly.getHeight()
        self.assertAlmostEqual(miOnlyWidth, self.width)
        self.assertAlmostEqual(miOnlyHeight, self.height)

        # NOTE: Unittests for Exposures created from a MaskedImage and
        # a WCS object are incomplete.  No way to test the validity of
        # the WCS being copied/created.

        maskedImageMiWcs = self.exposureMiWcs.getMaskedImage()
        miWcsWidth = maskedImageMiWcs.getWidth()
        miWcsHeight = maskedImageMiWcs.getHeight()
        self.assertAlmostEqual(miWcsWidth, self.width)
        self.assertAlmostEqual(miWcsHeight, self.height)

        maskedImageCrWcs = self.exposureCrWcs.getMaskedImage()
        crWcsWidth = maskedImageCrWcs.getWidth()
        crWcsHeight = maskedImageCrWcs.getHeight()
        if crWcsWidth != crWcsHeight != 0:
            self.fail("%s != %s != 0" % (crWcsWidth, crWcsHeight))

        maskedImageCrOnly = self.exposureCrOnly.getMaskedImage()
        crOnlyWidth = maskedImageCrOnly.getWidth()
        crOnlyHeight = maskedImageCrOnly.getHeight()
        if crOnlyWidth != crOnlyHeight != 0:
            self.fail("%s != %s != 0" % (crOnlyWidth, crOnlyHeight))

        # Check Exposure.getWidth() returns the MaskedImage's width
        self.assertEqual(crOnlyWidth, self.exposureCrOnly.getWidth())
        self.assertEqual(crOnlyHeight, self.exposureCrOnly.getHeight())

    def testGetWcs(self):
        """
        Test if a WCS can be obtained from each Exposure created with
        a WCS.
    
        Test that appropriate exceptions are thrown if a WCS is
        requested from an Exposure that was not created with a WCS.
        Python turns the pex::exceptions in the Exposure and
        MaskedImage classes into IndexErrors.

        The exposureBlank, exposureMiOnly, and exposureCrOnly
        Exposures should throw a lsst::pex::exceptions::NotFound.
        """

        self.assertTrue(not self.exposureBlank.getWcs())
        self.assertTrue(not self.exposureMiOnly.getWcs())

        # These two should pass
        self.exposureMiWcs.getWcs()
        self.exposureCrWcs.getWcs()

        self.assertTrue(not self.exposureCrOnly.getWcs())

    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(cameraGeom.Detector(cameraGeom.Id(666)))
        exposure.setFilter(afwImage.Filter("g"))

        self.assertEquals(exposure.getDetector().getId().getSerial(), 666)
        self.assertEquals(exposure.getFilter().getName(), "g")

        try:
            exposure.getWcs()
        except pexExcept.LsstCppException, e:
            print "caught expected exception (getWcs): %s" % e
            pass
        #
        # Test the Calib member.  The Calib tests are in color.py, here we just check that it's in Exposure
        #
        calib = exposure.getCalib()
        dt = 10
        calib.setExptime(dt)
        self.assertEqual(exposure.getCalib().getExptime(), dt)
        #
        # now check that we can set Calib
        #
        calib = afwImage.Calib()
        dt = 666
        calib.setExptime(dt)

        exposure.setCalib(calib)

        self.assertEqual(exposure.getCalib().getExptime(), dt)
        #
        # Psfs next
        #
        w, h = 11, 11
        self.assertFalse(exposure.hasPsf())
        exposure.setPsf(self.psf)
        self.assertTrue(exposure.hasPsf())

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

        # Test that we can set the MaskedImage and WCS of an Exposure
        # that already has both
        self.exposureMiWcs.setMaskedImage(maskedImage)
        exposure.setWcs(self.wcs)
Exemple #28
0
    def _loadAndMatchCatalogs(self, repo, dataIds, matchRadius):
        """Load data from specific visit. Match with reference.

        Parameters
        ----------
        repo : string
            The repository.  This is generally the directory on disk
            that contains the repository and mapper.
        dataIds : list of dict
            List of `butler` data IDs of Image catalogs to compare to
            reference. The `calexp` cpixel image is needed for the photometric
            calibration.
        matchRadius :  afwGeom.Angle(), optional
            Radius for matching. Default is 1 arcsecond.

        Returns
        -------
        afw.table.GroupView
            An object of matched catalog.
        """
        # Following
        # https://github.com/lsst/afw/blob/tickets/DM-3896/examples/repeatability.ipynb
        butler = dafPersist.Butler(repo)
        dataset = 'src'

        # 2016-02-08 MWV:
        # I feel like I could be doing something more efficient with
        # something along the lines of the following:
        #    dataRefs = [dafPersist.ButlerDataRef(butler, vId) for vId in dataIds]

        ccdKeyName = getCcdKeyName(dataIds[0])

        schema = butler.get(dataset + "_schema", immediate=True).schema
        mapper = SchemaMapper(schema)
        mapper.addMinimalSchema(schema)
        mapper.addOutputField(Field[float]('base_PsfFlux_snr', 'PSF flux SNR'))
        mapper.addOutputField(Field[float]('base_PsfFlux_mag',
                                           'PSF magnitude'))
        mapper.addOutputField(Field[float]('base_PsfFlux_magerr',
                                           'PSF magnitude uncertainty'))
        newSchema = mapper.getOutputSchema()

        # Create an object that matches multiple catalogs with same schema
        mmatch = MultiMatch(newSchema,
                            dataIdFormat={
                                'visit': np.int32,
                                ccdKeyName: np.int32
                            },
                            radius=matchRadius,
                            RecordClass=SimpleRecord)

        # create the new extented source catalog
        srcVis = SourceCatalog(newSchema)

        for vId in dataIds:
            try:
                calexpMetadata = butler.get("calexp_md", vId, immediate=True)
            except (FitsError, dafPersist.NoResults) as e:
                print(e)
                print("Could not open calibrated image file for ", vId)
                print("Skipping %s " % repr(vId))
                continue
            except TypeError as te:
                # DECam images that haven't been properly reformatted
                # can trigger a TypeError because of a residual FITS header
                # LTV2 which is a float instead of the expected integer.
                # This generates an error of the form:
                #
                # lsst::pex::exceptions::TypeError: 'LTV2 has mismatched type'
                #
                # See, e.g., DM-2957 for details.
                print(te)
                print("Calibration image header information malformed.")
                print("Skipping %s " % repr(vId))
                continue

            calib = afwImage.Calib(calexpMetadata)

            oldSrc = butler.get('src', vId, immediate=True)
            print(
                len(oldSrc), "sources in ccd %s  visit %s" %
                (vId[ccdKeyName], vId["visit"]))

            # create temporary catalog
            tmpCat = SourceCatalog(SourceCatalog(newSchema).table)
            tmpCat.extend(oldSrc, mapper=mapper)
            tmpCat['base_PsfFlux_snr'][:] = tmpCat['base_PsfFlux_flux'] \
                / tmpCat['base_PsfFlux_fluxSigma']
            with afwImageUtils.CalibNoThrow():
                _ = calib.getMagnitude(tmpCat['base_PsfFlux_flux'],
                                       tmpCat['base_PsfFlux_fluxSigma'])
                tmpCat['base_PsfFlux_mag'][:] = _[0]
                tmpCat['base_PsfFlux_magerr'][:] = _[1]

            srcVis.extend(tmpCat, False)
            mmatch.add(catalog=tmpCat, dataId=vId)

        # Complete the match, returning a catalog that includes
        # all matched sources with object IDs that can be used to group them.
        matchCat = mmatch.finish()

        # Create a mapping object that allows the matches to be manipulated
        # as a mapping of object ID to catalog of sources.
        allMatches = GroupView.build(matchCat)

        return allMatches
Exemple #29
0
    def writeFcr(self, dataRefList):
        self.log.info("Write Fcr ...")
        M_LN10 = math.log(10)
        dmag = list()
        for m in self.matchVec:
            if (m.good == True and m.mag != -9999 and m.jstar != -1
                    and m.mag0 != -9999 and m.mag_cat != -9999):
                mag = m.mag
                mag_cat = m.mag_cat
                exp_cor = -2.5 * math.log10(self.fexp[m.iexp])
                chip_cor = -2.5 * math.log10(self.fchip[m.ichip])
                gain_cor = self.ffpSet[m.iexp].eval(m.u, m.v)
                mag_cor = mag + exp_cor + chip_cor + gain_cor
                dmag.append(mag_cor - mag_cat)
        std, mean, n = mosaicUtils.clippedStd(numpy.array(dmag), 2.1)
        for dataRef in dataRefList:
            iexp = dataRef.dataId["visit"]
            ichip = dataRef.dataId["ccd"]
            try:
                x0 = self.coeffSet[iexp].x0
                y0 = self.coeffSet[iexp].y0
            except:
                x0 = 0.0
                y0 = 0.0
            newP = measMosaic.convertFluxFitParams(
                measMosaic.FluxFitParams(self.ffpSet[iexp]),
                self.ccdSet[ichip], x0, y0)
            metadata = measMosaic.metadataFromFluxFitParams(newP)
            exp = afwImage.ExposureI(0, 0)
            exp.getMetadata().combine(metadata)
            scale = self.fexp[iexp] * self.fchip[ichip]
            calib = afwImage.Calib()
            calib.setFluxMag0(1.0 / scale, 1.0 / scale * std * M_LN10 * 0.4)
            exp.setCalib(calib)
            try:
                dataRef.put(exp, "fcr")
            except Exception as e:
                print("failed to write fcr: %s" % (e))

            # Write the flux fit (including Jacobian) as a PhotoCalib for
            # future compatibility with jointcal.  This is redundant with
            # the above, and should eventually supercede it.
            detector = dataRef.get("camera")[dataRef.dataId["ccd"]]
            nQuarter = detector.getOrientation().getNQuarter()
            bbox = detector.getBBox()
            try:
                # Reading the Wcs we just wrote obviously isn't efficient, but
                # it should be in the noise of the overall runtime and it
                # saves us from doing a bunch of refactoring in a fragile
                # package with no tests.
                wcs = dataRef.get("jointcal_wcs")
            except Exception as e:
                print("failed to read Wcs for PhotoCalib: %s" % (e))
                continue
            instFluxMag0, instFluxMag0Err = calib.getFluxMag0()
            bf = measMosaic.FluxFitBoundedField(bbox,
                                                newP,
                                                wcs,
                                                zeroPoint=instFluxMag0,
                                                nQuarter=nQuarter)
            photoCalib = afwImage.PhotoCalib(1.0 / instFluxMag0,
                                             instFluxMag0Err / instFluxMag0**2,
                                             bf,
                                             isConstant=False)
            dataRef.put(photoCalib, "jointcal_photoCalib")
Exemple #30
0
 def makeCalib(self, zeroPoint):
     calib = afwImage.Calib()
     fluxMag0 = 10**(0.4 * zeroPoint)
     calib.setFluxMag0(fluxMag0, 1.0)
     return calib