コード例 #1
0
def showSipSolutions(srcs, wcs0, andDir, x0, y0, W, H, filterName, plotPrefix):
    '''
    srcs: afw Catalog of sources
    wcs0: original WCS
    andDir: astrometry_net_data directory
    '''
    imargs = dict(imageSize=(W, H), filterName=filterName, x0=x0, y0=y0)

    # Set up astrometry_net_data
    os.environ['ASTROMETRY_NET_DATA_DIR'] = andDir
    andConfig = measAstrom.AstrometryNetDataConfig()
    fn = os.path.join(andDir, 'andConfig.py')
    andConfig.load(fn)

    # Set up meas_astrom
    conf = measAstrom.ANetBasicAstrometryConfig(sipOrder=4)
    ast = measAstrom.ANetBasicAstrometryTask(conf,
                                             andConfig,
                                             logLevel=Log.DEBUG)

    # What reference sources are in the original WCS
    refs = ast.getReferenceSourcesForWcs(wcs0, **imargs)
    print('Got', len(refs), 'reference objects for initial WCS')

    # How does a straight TAN solution look?
    conf2 = measAstrom.ANetBasicAstrometryConfig(sipOrder=4,
                                                 calculateSip=False)
    ast2 = measAstrom.ANetBasicAstrometryTask(conf2,
                                              andConfig,
                                              logLevel=Log.DEBUG)
    solve = ast2.determineWcs2(srcs, **imargs)
    tanwcs = solve.tanWcs

    # How about if we fit a SIP WCS using the *original* WCS?
    wcs2 = ast.getSipWcsFromWcs(wcs0, (W, H), x0=x0, y0=y0)

    # (We determineWcs() for a SIP solution below...)

    # Make some plots in pixel space by pushing ref sources through WCSes
    rx0, ry0 = [], []
    rx2, ry2 = [], []
    rx3, ry3 = [], []
    for src in refs:
        xy = wcs0.skyToPixel(src.getCoord())
        rx0.append(xy[0])
        ry0.append(xy[1])

        xy = tanwcs.skyToPixel(src.getCoord())
        rx2.append(xy[0])
        ry2.append(xy[1])

        xy = wcs2.skyToPixel(src.getCoord())
        rx3.append(xy[0])
        ry3.append(xy[1])

    rx0 = np.array(rx0)
    ry0 = np.array(ry0)
    rx2 = np.array(rx2)
    ry2 = np.array(ry2)
    rx3 = np.array(rx3)
    ry3 = np.array(ry3)

    x = np.array([src.getX() for src in srcs])
    y = np.array([src.getY() for src in srcs])

    from astrometry.libkd.spherematch import match
    from astrometry.util.plotutils import plothist, PlotSequence

    ps = PlotSequence(plotPrefix)

    # Match up various sources...
    R = 2.

    II, d = match(np.vstack((x, y)).T, np.vstack((rx0, ry0)).T, R)
    I = II[:, 0]
    J = II[:, 1]

    pa = dict(range=((-R, R), (-R, R)))

    plt.clf()
    plothist(x[I] - rx0[J], y[I] - ry0[J], 200, **pa)
    plt.title('Source positions - Reference positions (initial WCS)')
    plt.xlabel('delta-X (pixels)')
    plt.ylabel('delta-Y (pixels)')
    ps.savefig()

    II, d = match(np.vstack((x, y)).T, np.vstack((rx2, ry2)).T, R)
    I = II[:, 0]
    J = II[:, 1]

    plt.clf()
    plothist(x[I] - rx2[J], y[I] - ry2[J], 200, **pa)
    plt.title('Source positions - Reference positions (TAN WCS)')
    plt.xlabel('delta-X (pixels)')
    plt.ylabel('delta-Y (pixels)')
    ps.savefig()

    II, d = match(np.vstack((x, y)).T, np.vstack((rx3, ry3)).T, R)
    I = II[:, 0]
    J = II[:, 1]
    plt.clf()
    plothist(x[I] - rx3[J], y[I] - ry3[J], 200, **pa)
    plt.title('Source positions - Reference positions (SIP WCS #2)')
    plt.xlabel('delta-X (pixels)')
    plt.ylabel('delta-Y (pixels)')
    ps.savefig()

    II, d = match(np.vstack((rx0, ry0)).T, np.vstack((rx3, ry3)).T, R)
    I = II[:, 0]
    J = II[:, 1]
    plt.clf()
    plothist(rx0[I] - rx3[J], ry0[I] - ry3[J], 200, **pa)
    plt.title(
        'Reference positions (Original WCS) - Reference positions (SIP WCS #2)'
    )
    plt.xlabel('delta-X (pixels)')
    plt.ylabel('delta-Y (pixels)')
    ps.savefig()

    matches = solve.tanMatches
    msx, msy = [], []
    mrx, mry = [], []
    for m in matches:
        ref, src = m.first, m.second
        xy = tanwcs.skyToPixel(ref.getCoord())
        mrx.append(xy[0])
        mry.append(xy[1])
        msx.append(src.getX())
        msy.append(src.getY())

    plt.clf()
    plt.plot(x, y, 'r.')
    plt.plot(msx, msy, 'o', mec='r')
    plt.plot(rx0, ry0, 'g.')
    plt.plot(mrx, mry, 'gx')
    plt.title('TAN matches')
    ps.savefig()

    # Get SIP solution (4th order)

    solve = ast.determineWcs2(srcs, **imargs)
    wcs1 = solve.sipWcs

    matches = solve.sipMatches
    msx, msy = [], []
    mrx, mry = [], []
    for m in matches:
        ref, src = m.first, m.second
        xy = tanwcs.skyToPixel(ref.getCoord())
        mrx.append(xy[0])
        mry.append(xy[1])
        msx.append(src.getX())
        msy.append(src.getY())

    plt.clf()
    plt.plot(x, y, 'r.')
    plt.plot(msx, msy, 'o', mec='r')
    plt.plot(rx0, ry0, 'g.')
    plt.plot(mrx, mry, 'gx')
    plt.title('SIP matches')
    ps.savefig()

    rx1, ry1 = [], []
    for src in refs:
        xy = wcs1.skyToPixel(src.getCoord())
        rx1.append(xy[0])
        ry1.append(xy[1])
    rx1 = np.array(rx1)
    ry1 = np.array(ry1)

    plt.clf()
    plt.plot(x, y, 'o', mec='r', mfc='none')
    plt.plot(rx0, ry0, 'bx')
    plt.plot(rx1, ry1, 'g+')
    plt.plot(rx2, ry2, 'mx')
    plt.plot(rx3, ry3, 'r+')
    ps.savefig()

    plt.axis([x0, x0 + 500, y0, y0 + 500])
    ps.savefig()

    II, d = match(np.vstack((x, y)).T, np.vstack((rx1, ry1)).T, R)
    I = II[:, 0]
    J = II[:, 1]

    plt.clf()
    plothist(x[I] - rx1[J], y[I] - ry1[J], 200, **pa)
    plt.title('Source positions - Reference positions (SIP WCS)')
    plt.xlabel('delta-X (pixels)')
    plt.ylabel('delta-Y (pixels)')
    ps.savefig()
コード例 #2
0
    def run(self, dataRefList, ct=None, debug=False, verbose=False):
        ccdSet = self.readCcd(dataRefList)
        self.removeNonExistCcd(dataRefList, ccdSet)

        sourceSet = []
        matchList = []
        astrom = measAstrom.ANetBasicAstrometryTask(self.config.astrom)
        ssVisit = dict()
        mlVisit = dict()
        dataRefListUsed = list()
        wcsDic = dict()
        calibDic = dict()
        ffpDic = dict()
        for dataRef in dataRefList:
            if dataRef.dataId['visit'] not in ssVisit:
                ssVisit[dataRef.dataId['visit']] = list()
                mlVisit[dataRef.dataId['visit']] = list()
                wcsDic[dataRef.dataId['visit']] = dict()
                calibDic[dataRef.dataId['visit']] = dict()
                ffpDic[dataRef.dataId['visit']] = dict()

            try:
                if not dataRef.datasetExists('src'):
                    raise RuntimeError("no data for src %s" % (dataRef.dataId))

                if not dataRef.datasetExists('jointcal_wcs'):
                    raise RuntimeError("no data for wcs %s" % (dataRef.dataId))

                if not dataRef.datasetExists('fcr'):
                    raise RuntimeError("no data for fcr %s" % (dataRef.dataId))

                wcs = dataRef.get('jointcal_wcs')

                md = dataRef.get('calexp_md')
                filterName = afwImage.Filter(md).getName()

                md = dataRef.get('fcr_md')
                ffp = measMosaic.FluxFitParams(md)
                photoCalib = afwImage.makePhotoCalibFromMetadata(md)

                sources = dataRef.get('src',
                              flags=afwTable.SOURCE_IO_NO_FOOTPRINTS,
                              immediate=True)

                icSrces = dataRef.get('icSrc',
                              flags=afwTable.SOURCE_IO_NO_FOOTPRINTS,
                              immediate=True)
                packedMatches = dataRef.get('icMatch')
                matches = astrom.joinMatchListWithCatalog(packedMatches, icSrces)

                matches = [m for m in matches if m[0] is not None]

                if matches:
                    refSchema = matches[0][0].schema
                    if ct:
                        # Add a "flux" field to the match records which contains the
                        # colorterm-corrected reference flux. The field name is hard-coded in
                        # lsst::meas::mosaic::Source.
                        mapper = afwTable.SchemaMapper(refSchema)
                        for key, field in refSchema:
                            mapper.addMapping(key)
                        key_f = mapper.editOutputSchema().addField("flux", type=float, doc="Reference flux")
                        table = afwTable.SimpleTable.make(mapper.getOutputSchema())
                        table.preallocate(len(matches))
                        for match in matches:
                            newMatch = table.makeRecord()
                            newMatch.assign(match[0], mapper)
                            match[0] = newMatch

                        key_p = refSchema.find(refSchema.join(ct.primary, "flux")).key
                        key_s = refSchema.find(refSchema.join(ct.secondary, "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 = [setCatFlux(m, f, key_f) for m, f in zip(matches, refFlux) if f == f]
                    else:
                        # No colorterm; we can get away with aliasing the reference flux.
                        refFluxField = measAlg.getRefFluxField(refSchema, filterName)
                        refSchema.getAliasMap().set("flux", refFluxField)

                sources = self.selectStars(sources)
                matches = self.selectStars(matches, True)
            except Exception as e:
                print("Failed to read: %s" % (e))
                sources = None
                continue

            if sources is not None:
                for s in sources:
                    if numpy.isfinite(s.getRa().asDegrees()): # get rid of NaN
                        src = measMosaic.Source(s)
                        src.setExp(dataRef.dataId['visit'])
                        src.setChip(dataRef.dataId['ccd'])
                        ssVisit[dataRef.dataId['visit']].append(src)
                for m in matches:
                    if m[0] is not None and m[1] is not None:
                        match = (measMosaic.Source(m[0], wcs), measMosaic.Source(m[1]))
                        match[1].setExp(dataRef.dataId['visit'])
                        match[1].setChip(dataRef.dataId['ccd'])
                        mlVisit[dataRef.dataId['visit']].append(match)
                wcsDic[dataRef.dataId['visit']][dataRef.dataId['ccd']] = wcs
                calibDic[dataRef.dataId['visit']][dataRef.dataId['ccd']] = photoCalib
                ffpDic[dataRef.dataId['visit']][dataRef.dataId['ccd']] = ffp
                dataRefListUsed.append(dataRef)

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

        d_lim = afwGeom.Angle(self.config.radXMatch, afwGeom.arcseconds)
        nbrightest = self.config.nBrightest

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

        dx_m, dy_m, dx_s, dy_s, m0_m, dm_m, m0_s, dm_s  = self.makeDiffPosFlux(allMat, allSource, wcsDic, calibDic, ffpDic)
        self.plotFlux(m0_m, dm_m, m0_s, dm_s)
        self.makeFluxStat(allMat, allSource, calibDic, ffpDic, wcsDic)
        self.plotPos(dx_m, dy_m, dx_s, dy_s)
        self.plotPosAsMag(m0_s, dx_s, dy_s)
        self.writeCatalog(allSource, wcsDic, calibDic, ffpDic)