def run(self, matchLists, filterName, wcsList, butler):

        if self.config.applyColorTerms:
            ct = self.config.colorterms.selectColorTerm(filterName)
        else:
            ct = None

        # Convert matchLists to meas_mosaic specific format
        mlVisit = dict()
        for ccdId in matchLists:
            if matchLists[ccdId] is None:
                continue
            visit, ccd = self.decodeCcdExposureId(ccdId)
            if visit not in mlVisit:
                mlVisit[visit] = list()
            matches = [m for m in matchLists[ccdId] if m[0] is not None]
            keys = self.getKeys(matches[0][1].schema)
            matches = self.selectMatches(matches, keys)
            matches = self.selectStars(matches)

            # Apply color term
            if ct is not None and len(matches) != 0:
                refSchema = matches[0][0].schema
                key_p = refSchema.find(ct.primary).key
                key_s = refSchema.find(ct.secondary).key
                key_f = refSchema.find("flux").key
                refFlux1 = numpy.array([m[0].get(key_p) for m in matches])
                refFlux2 = numpy.array([m[0].get(key_s) for m in matches])
                refMag1 = -2.5 * numpy.log10(refFlux1)
                refMag2 = -2.5 * numpy.log10(refFlux2)
                refMag = ct.transformMags(refMag1, refMag2)
                refFlux = numpy.power(10.0, -0.4 * refMag)
                matches = [
                    self.setCatFlux(m, f, key_f)
                    for m, f in zip(matches, refFlux) if f == f
                ]

            for m in matches:
                if m[0] is not None and m[1] is not None:
                    match = (measMosaic.Source(m[0], wcsList[ccdId]),
                             measMosaic.Source(m[1]))
                    match[1].setExp(visit)
                    match[1].setChip(ccd)
                    mlVisit[visit].append(match)

        matchList = []
        for visit in mlVisit:
            matchList.append(mlVisit[visit])

        rootMat = measMosaic.kdtreeMat(matchList)
        allMat = rootMat.mergeMat()

        # Read CCD information
        ccdSet = {}
        for ccdId in matchLists:
            if matchLists[ccdId] is None:
                continue
            visit, ccd = self.decodeCcdExposureId(ccdId)
            if ccd not in ccdSet:
                ccdDev = cameraGeomUtils.findCcd(butler.mapper.camera,
                                                 cameraGeom.Id(int(ccd)))
                ccdSet[ccd] = ccdDev

        # meas_mosaic specific wcs information
        wcsDic = {}
        for ccdId in wcsList:
            visit, ccd = self.decodeCcdExposureId(ccdId)
            if visit not in wcsDic and wcsList[ccdId] is not None:
                wcs = wcsList[ccdId]
                ccdDev = ccdSet[ccd]
                offset = afwGeom.Extent2D(ccdDev.getCenter().getPixels(
                    ccdDev.getPixelSize()))
                wcsDic[visit] = wcs.copyAtShiftedPixelOrigin(offset)

        # meas_mosaic specific object list
        matchVec = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet)
        sourceVec = []

        # Apply Jocabian correction calculated from wcs
        for m in matchVec:
            wcs = wcsList[m.iexp * 200 + m.ichip]
            m.mag -= 2.5 * math.log10(
                measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y)))

        fluxFitOrder = self.config.fluxFitOrder
        absolute = True
        chebyshev = True
        commonFluxCorr = False
        solveCcdScale = True
        ffpSet = {}
        for visit in wcsDic:
            ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev)
            u_max, v_max = self.getExtent(matchVec)
            ffp.u_max = (math.floor(u_max / 10.) + 1) * 10
            ffp.v_max = (math.floor(v_max / 10.) + 1) * 10
            ffpSet[visit] = ffp

        fexp = {}
        fchip = {}

        matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit(
            absolute, commonFluxCorr, matchVec, len(matchVec), sourceVec,
            len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale)

        self.writeFcr(butler, list(matchLists.keys()), ccdSet, filterName,
                      fexp, fchip, ffpSet)

        return (1.0 / fexp[list(fexp.keys())[0]])
Ejemplo n.º 2
0
    def run(self, dataRefList, tractInfo, ct=None, debug=False, diagDir=".",
            diagnostics=False, snapshots=False, numCoresForReadSource=1, readTimeout=9999, verbose=False):

        self.log.info(str(self.config))

        self.outputDir = os.path.join(diagDir, "%04d" % tractInfo.getId())

        if ((diagnostics or snapshots) and not os.path.isdir(self.outputDir)):
            os.makedirs(self.outputDir)

        if self.config.nBrightest != 0:
            self.log.fatal("Config paremeter nBrightest is deprecated.")
            self.log.fatal("Please use cellSize and nStarPerCell.")
            self.log.fatal("Exiting ...")
            return []

        dataRefListOverlapWithTract, dataRefListToUse = self.checkOverlapWithTract(tractInfo, dataRefList)

        sourceSet, matchList, dataRefListUsed = self.readCatalog(dataRefListToUse, ct, numCoresForReadSource,
                                                                 readTimeout, verbose)
        if not matchList:
            raise RuntimeError("No reference source matches found")

        dataRefListToOutput = list(set(dataRefListUsed) & set(dataRefListOverlapWithTract))

        ccdSet = self.readCcd(dataRefListUsed)

        if debug:
            for ccd in ccdSet.values():
                self.log.info(str(ccd.getId().getSerial()) + " " +
                              str(ccd.getCenter().getPixels(ccd.getPixelSize())) + " " +
                              str(ccd.getOrientation().getYaw()))

        wcsDic = self.readWcs(dataRefListUsed, ccdSet)

        self.removeNonExistCcd(dataRefListUsed, ccdSet)

        if debug:
            for iexp, wcs in wcsDic.items():
                self.log.info(str(iexp) + " " + str(wcs.getPixelOrigin()) + " " +
                              str(wcs.getSkyOrigin().getPosition(afwGeom.degrees)))

        self.log.info("frameIds : " + str(list(wcsDic.keys())))
        self.log.info("ccdIds : " + str(list(ccdSet.keys())))

        d_lim = afwGeom.Angle(self.config.radXMatch, afwGeom.arcseconds)
        if debug:
            self.log.info("d_lim : %f" % d_lim)

        allMat, allSource =self.mergeCatalog(sourceSet, matchList, ccdSet, d_lim)

        self.log.info("Flag suspect objects")
        measMosaic.flagSuspect(allMat, allSource, wcsDic)

        if self.config.clipSourcesOutsideTract:
            tractBBox = afwGeom.Box2D(tractInfo.getBBox())
            tractWcs = tractInfo.getWcs()
            allSourceClipped = [ss for ss in allSource if tractBBox.contains(tractWcs.skyToPixel(ss[0].getSky()))]
            self.log.info("Num of allSources: %d" % (len(allSource)))
            self.log.info("Num of clipped allSources: %d" % (len(allSourceClipped)))
            allSource = allSourceClipped

        self.log.info("Make obsVec")
        nmatch  = len(allMat)
        nsource = len(allSource)
        matchVec  = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet)
        sourceVec = measMosaic.obsVecFromSourceGroup(allSource, wcsDic, ccdSet)

        self.log.info("Solve mosaic ...")
        order = self.config.fittingOrder
        internal = self.config.internalFitting
        solveCcd = self.config.solveCcd
        allowRotation = self.config.allowRotation
        fluxFitOrder = self.config.fluxFitOrder
        chebyshev = self.config.chebyshev
        absolute = self.config.fluxFitAbsolute
        solveCcdScale = self.config.fluxFitSolveCcd
        catRMS = self.config.catRMS

        if not internal:
            sourceVec = []

        if debug:
            self.log.info("order : %d" % order)
            self.log.info("internal : %r" % internal)
            self.log.info("solveCcd : %r " % solveCcd)
            self.log.info("allowRotation : %r" % allowRotation)

        if self.config.doSolveWcs:
            if internal:
                coeffSet, matchVec, sourceVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD(order, nmatch, nsource,
                                                      matchVec, sourceVec,
                                                      wcsDic, ccdSet,
                                                      solveCcd, allowRotation,
                                                      verbose, catRMS,
                                                      snapshots, self.outputDir)
            else:
                coeffSet, matchVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD_shot(order, nmatch, matchVec,
                                                           wcsDic, ccdSet,
                                                           solveCcd, allowRotation,
                                                           verbose, catRMS,
                                                           snapshots, self.outputDir)

            self.matchVec = matchVec
            self.sourceVec = sourceVec
            self.wcsDic = wcsDic
            self.ccdSet = ccdSet
            self.coeffSet = coeffSet

            self.writeNewWcs(dataRefListToOutput)

            if diagnostics:
                self.outputDiagWcs()

            for m in matchVec:
                coeff = coeffSet[m.iexp]
                scale = coeff.pixelScale()
                m.mag -= 2.5*math.log10(coeff.detJ(m.u, m.v)/scale**2)

            if len(sourceVec) != 0:
                for s in sourceVec:
                    coeff = coeffSet[s.iexp]
                    scale = coeff.pixelScale()
                    s.mag -= 2.5*math.log10(coeff.detJ(s.u, s.v)/scale**2)

        else:

            wcsAll = dict()

            for dataRef in dataRefListUsed:
                frameId = "%07d-%03d" % (dataRef.dataId["visit"], dataRef.dataId["ccd"])
                md = dataRef.get("calexp_md")
                wcsAll[frameId] = afwGeom.makeSkyWcs(md)
                del md

            for m in matchVec:
                wcs = wcsAll["%07d-%03d" % (m.iexp, m.ichip)]
                m.mag -= 2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y)))

            if len(sourceVec) != 0:
                for s in sourceVec:
                    wcs = wcsAll["%07d-%03d" % (s.iexp, s.ichip)]
                    s.mag -= 2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(s.x, s.y)))

            del wcsAll

        if self.config.doSolveFlux:

            ffpSet = {}
            for visit in wcsDic:
                ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev)
                u_max, v_max = mosaicUtils.getExtent(matchVec)
                ffp.u_max = (math.floor(u_max/10.0) + 1)*10
                ffp.v_max = (math.floor(v_max/10.0) + 1)*10
                ffpSet[visit] = ffp

            fexp = {}
            fchip = {}

            matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit(absolute, self.config.commonFluxCorr, matchVec, len(matchVec), sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale)

            self.ffpSet = ffpSet
            self.fexp = fexp
            self.fchip = fchip

            self.writeFcr(dataRefListToOutput)

            if diagnostics:
                self.outputDiagFlux()

        if diagnostics and self.config.doSolveWcs and self.config.doSolveFlux:
            if len(sourceVec) != 0:
                mosaicUtils.writeCatalog(coeffSet, ffpSet, fexp, fchip, matchVec, sourceVec,
                                         os.path.join(self.outputDir, "catalog.fits"))

        return list(wcsDic.keys())
Ejemplo n.º 3
0
    def mosaic(self,
               dataRefList,
               tractInfo,
               ct=None,
               debug=False,
               diagDir=".",
               diagnostics=False,
               snapshots=False,
               numCoresForReadSource=1,
               readTimeout=9999,
               verbose=False):

        self.log.info(str(self.config))

        self.outputDir = os.path.join(diagDir, "%04d" % tractInfo.getId())

        if ((diagnostics or snapshots) and not os.path.isdir(self.outputDir)):
            os.makedirs(self.outputDir)

        if self.config.nBrightest != 0:
            self.log.fatal("Config paremeter nBrightest is deprecated.")
            self.log.fatal("Please use cellSize and nStarPerCell.")
            self.log.fatal("Exiting ...")
            return []

        dataRefListOverlapWithTract, dataRefListToUse = self.checkOverlapWithTract(
            tractInfo, dataRefList)

        sourceSet, matchList, dataRefListUsed = self.readCatalog(
            dataRefListToUse, ct, numCoresForReadSource, readTimeout, verbose)

        dataRefListToOutput = list(
            set(dataRefListUsed) & set(dataRefListOverlapWithTract))

        ccdSet = self.readCcd(dataRefListUsed)

        if debug:
            for ccd in ccdSet.values():
                self.log.info(
                    str(ccd.getId().getSerial()) + " " +
                    str(ccd.getCenter().getPixels(ccd.getPixelSize())) + " " +
                    str(ccd.getOrientation().getYaw()))

        wcsDic = self.readWcs(dataRefListUsed, ccdSet)

        self.removeNonExistCcd(dataRefListUsed, ccdSet)

        if debug:
            for iexp, wcs in wcsDic.items():
                self.log.info(
                    str(iexp) + " " + str(wcs.getPixelOrigin()) + " " +
                    str(wcs.getSkyOrigin().getPosition(afwGeom.degrees)))

        self.log.info("frameIds : " + str(list(wcsDic.keys())))
        self.log.info("ccdIds : " + str(list(ccdSet.keys())))

        d_lim = afwGeom.Angle(self.config.radXMatch, afwGeom.arcseconds)
        if debug:
            self.log.info("d_lim : %f" % d_lim)

        allMat, allSource = self.mergeCatalog(sourceSet, matchList, ccdSet,
                                              d_lim)

        self.log.info("Flag suspect objects")
        measMosaic.flagSuspect(allMat, allSource, wcsDic)

        if self.config.clipSourcesOutsideTract:
            tractBBox = afwGeom.Box2D(tractInfo.getBBox())
            tractWcs = tractInfo.getWcs()
            allSourceClipped = [
                ss for ss in allSource
                if tractBBox.contains(tractWcs.skyToPixel(ss[0].getSky()))
            ]
            self.log.info("Num of allSources: %d" % (len(allSource)))
            self.log.info("Num of clipped allSources: %d" %
                          (len(allSourceClipped)))
            allSource = allSourceClipped

        self.log.info("Make obsVec")
        nmatch = len(allMat)
        nsource = len(allSource)
        matchVec = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet)
        sourceVec = measMosaic.obsVecFromSourceGroup(allSource, wcsDic, ccdSet)

        self.log.info("Solve mosaic ...")
        order = self.config.fittingOrder
        internal = self.config.internalFitting
        solveCcd = self.config.solveCcd
        allowRotation = self.config.allowRotation
        fluxFitOrder = self.config.fluxFitOrder
        chebyshev = self.config.chebyshev
        absolute = self.config.fluxFitAbsolute
        solveCcdScale = self.config.fluxFitSolveCcd
        catRMS = self.config.catRMS

        if not internal:
            sourceVec = []

        if debug:
            self.log.info("order : %d" % order)
            self.log.info("internal : %r" % internal)
            self.log.info("solveCcd : %r " % solveCcd)
            self.log.info("allowRotation : %r" % allowRotation)

        if self.config.doSolveWcs:
            if internal:
                coeffSet, matchVec, sourceVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD(
                    order, nmatch, nsource, matchVec, sourceVec, wcsDic,
                    ccdSet, solveCcd, allowRotation, verbose, catRMS,
                    snapshots, self.outputDir)
            else:
                coeffSet, matchVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD_shot(
                    order, nmatch, matchVec, wcsDic, ccdSet, solveCcd,
                    allowRotation, verbose, catRMS, snapshots, self.outputDir)

            self.matchVec = matchVec
            self.sourceVec = sourceVec
            self.wcsDic = wcsDic
            self.ccdSet = ccdSet
            self.coeffSet = coeffSet

            self.writeNewWcs(dataRefListToOutput)

            if diagnostics:
                self.outputDiagWcs()

            for m in matchVec:
                coeff = coeffSet[m.iexp]
                scale = coeff.pixelScale()
                m.mag -= 2.5 * math.log10(coeff.detJ(m.u, m.v) / scale**2)

            if len(sourceVec) != 0:
                for s in sourceVec:
                    coeff = coeffSet[s.iexp]
                    scale = coeff.pixelScale()
                    s.mag -= 2.5 * math.log10(coeff.detJ(s.u, s.v) / scale**2)

        else:

            wcsAll = dict()

            for dataRef in dataRefListUsed:
                frameId = "%07d-%03d" % (dataRef.dataId["visit"],
                                         dataRef.dataId["ccd"])
                md = dataRef.get("calexp_md")
                wcsAll[frameId] = afwGeom.makeSkyWcs(md)
                del md

            for m in matchVec:
                wcs = wcsAll["%07d-%03d" % (m.iexp, m.ichip)]
                m.mag -= 2.5 * math.log10(
                    measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y)))

            if len(sourceVec) != 0:
                for s in sourceVec:
                    wcs = wcsAll["%07d-%03d" % (s.iexp, s.ichip)]
                    s.mag -= 2.5 * math.log10(
                        measMosaic.computeJacobian(wcs,
                                                   afwGeom.Point2D(s.x, s.y)))

            del wcsAll

        if self.config.doSolveFlux:

            ffpSet = {}
            for visit in wcsDic:
                ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute,
                                               chebyshev)
                u_max, v_max = mosaicUtils.getExtent(matchVec)
                ffp.u_max = (math.floor(u_max / 10.0) + 1) * 10
                ffp.v_max = (math.floor(v_max / 10.0) + 1) * 10
                ffpSet[visit] = ffp

            fexp = {}
            fchip = {}

            matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit(
                absolute, self.config.commonFluxCorr, matchVec, len(matchVec),
                sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet,
                solveCcdScale)

            self.ffpSet = ffpSet
            self.fexp = fexp
            self.fchip = fchip

            self.writeFcr(dataRefListToOutput)

            if diagnostics:
                self.outputDiagFlux()

        if diagnostics and self.config.doSolveWcs and self.config.doSolveFlux:
            if len(sourceVec) != 0:
                mosaicUtils.writeCatalog(
                    coeffSet, ffpSet, fexp, fchip, matchVec, sourceVec,
                    os.path.join(self.outputDir, "catalog.fits"))

        return list(wcsDic.keys())
    def run(self, matchLists, filterName, wcsList, butler):

        if self.config.applyColorTerms:
            ct = self.config.colorterms.selectColorTerm(filterName)
        else:
            ct = None

        # Convert matchLists to meas_mosaic specific format
        mlVisit = dict()
        for ccdId in matchLists:
            if matchLists[ccdId] is None:
                continue
            visit, ccd = self.decodeCcdExposureId(ccdId)
            if visit not in mlVisit:
                mlVisit[visit] = list()
            matches = [m for m in matchLists[ccdId] if m[0] is not None]
            keys = self.getKeys(matches[0][1].schema)
            matches = self.selectMatches(matches, keys)
            matches = self.selectStars(matches)

            # Apply color term
            if ct is not None and len(matches) != 0:
                refSchema = matches[0][0].schema
                key_p = refSchema.find(ct.primary).key
                key_s = refSchema.find(ct.secondary).key
                key_f = refSchema.find("flux").key
                refFlux1 = numpy.array([m[0].get(key_p) for m in matches])
                refFlux2 = numpy.array([m[0].get(key_s) for m in matches])
                refMag1 = -2.5*numpy.log10(refFlux1)
                refMag2 = -2.5*numpy.log10(refFlux2)
                refMag = ct.transformMags(refMag1, refMag2)
                refFlux = numpy.power(10.0, -0.4*refMag)
                matches = [self.setCatFlux(m, f, key_f) for m, f in zip(matches, refFlux) if f == f]

            for m in matches:
                if m[0] is not None and m[1] is not None:
                    match = (measMosaic.Source(m[0], wcsList[ccdId]), measMosaic.Source(m[1]))
                    match[1].setExp(visit)
                    match[1].setChip(ccd)
                    mlVisit[visit].append(match)


        matchList = []
        for visit in mlVisit:
            matchList.append(mlVisit[visit])

        rootMat = measMosaic.kdtreeMat(matchList)
        allMat = rootMat.mergeMat()

        # Read CCD information
        ccdSet = {}
        for ccdId in matchLists:
            if matchLists[ccdId] is None:
                continue
            visit, ccd = self.decodeCcdExposureId(ccdId)
            if ccd not in ccdSet:
                ccdDev = cameraGeomUtils.findCcd(butler.mapper.camera, cameraGeom.Id(int(ccd)))
                ccdSet[ccd] = ccdDev

        # meas_mosaic specific wcs information
        wcsDic = {}
        for ccdId in wcsList:
            visit, ccd = self.decodeCcdExposureId(ccdId)
            if visit not in wcsDic and wcsList[ccdId] is not None:
                wcs = wcsList[ccdId]
                ccdDev = ccdSet[ccd]
                offset = afwGeom.Extent2D(ccdDev.getCenter().getPixels(ccdDev.getPixelSize()))
                wcsDic[visit] = wcs.copyAtShiftedPixelOrigin(offset)

        # meas_mosaic specific object list
        matchVec  = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet)
        sourceVec = []

        # Apply Jocabian correction calculated from wcs
        for m in matchVec:
            wcs = wcsList[m.iexp*200+m.ichip]
            m.mag -= 2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y)))

        fluxFitOrder = self.config.fluxFitOrder
        absolute = True
        chebyshev = True
        commonFluxCorr = False
        solveCcdScale = True
        ffpSet = {}
        for visit in wcsDic:
            ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev)
            u_max, v_max = self.getExtent(matchVec)
            ffp.u_max = (math.floor(u_max / 10.) + 1) * 10
            ffp.v_max = (math.floor(v_max / 10.) + 1) * 10
            ffpSet[visit] = ffp

        fexp = {}
        fchip = {}

        matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit(absolute, commonFluxCorr, matchVec, len(matchVec), sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale)

        self.writeFcr(butler, list(matchLists.keys()), ccdSet, filterName,
                      fexp, fchip, ffpSet)

        return (1.0/fexp[list(fexp.keys())[0]])