예제 #1
0
def decam_psf(filt, fwhm):
    if filt not in 'ugrizY':
        tpsf = psfmod.moffat_psf(fwhm, stampsz=511, deriv=False)
        return psfmod.SimplePSF(tpsf)
    fname = os.path.join(os.environ['DECAM_DIR'], 'data', 'psfs',
                         'psf_%s_deconv_mod.fits.gz' % filt[0])
    normalizesz = 59
    tpsf = fits.getdata(fname).T.copy()
    tpsf /= numpy.sum(psfmod.central_stamp(tpsf, normalizesz))
    # omitting central_stamp here places too much
    # emphasis on the wings relative to the pipeline estimate.
    tpsffwhm = psfmod.neff_fwhm(psfmod.central_stamp(tpsf))
    from scipy.ndimage.filters import convolve
    if tpsffwhm < fwhm:
        convpsffwhm = numpy.sqrt(fwhm**2. - tpsffwhm**2.)
        convpsf = psfmod.moffat_psf(convpsffwhm, stampsz=39, deriv=False)
        tpsf = convolve(tpsf, convpsf, mode='constant', cval=0., origin=0)
    else:
        convpsffwhm = 0.
    tpsf = psfmod.stamp2model(numpy.array([tpsf, tpsf, tpsf, tpsf]),
                              normalize=normalizesz)
    nlinperpar = 3
    pixsz = 9
    extraparam = numpy.zeros(1,
                             dtype=[('convparam', 'f4', 3 * nlinperpar + 1),
                                    ('resparam', 'f4', (nlinperpar, pixsz,
                                                        pixsz))])
    extraparam['convparam'][0, 0:4] = [convpsffwhm, 1., 0., 1.]
    extraparam['resparam'][0, :, :, :] = 0.
    tpsf.extraparam = extraparam
    tpsf.fitfun = partial(psfmod.fit_linear_static_wing, filter=filt)
    return tpsf
예제 #2
0
 def objective(par):
     mod = psfmod.moffat_psf(par[0],
                             beta=2.5,
                             xy=par[2],
                             yy=par[3],
                             deriv=False,
                             stampsz=tpsf.shape[0])
     mod /= numpy.sum(mod)
     return ((tpsf - mod)[overlap]).reshape(-1)
예제 #3
0
def make_new_psfs(write=False, **kw):
    path = os.path.join(os.environ['DECAM_DIR'], 'data', 'psfs', 'includeu')
    res = {}
    for f in filt:
        tpsf = fits.getdata(os.path.join(path, 'psf_%s.fits.gz' % f))
        tpsf = psf.center_psf(tpsf)
        fitres = psf.fit_moffat(psf.central_stamp(tpsf, censize=19).copy())
        fit = fitres[0]
        deconvfac = 0.7
        kernel = psf.moffat_psf(fit[1] * deconvfac,
                                yy=fit[4],
                                beta=fit[2],
                                xy=fit[3],
                                stampsz=69,
                                deriv=False)
        psfde = restoration.richardson_lucy(tpsf, kernel, 20)
        psfde = psf.center_psf(psfde)
        res[f] = psfde
    if write:
        for f in filt:
            fits.writeto(os.path.join(path, 'psf_%s_deconv.fits.gz' % f),
                         res[f], **kw)
    return res
예제 #4
0
                        default=numpy.inf,
                        help='pixel brightness limit for saturation')
    args = parser.parse_args()
    imagefn = args.imagefn[0]
    ivarfn = args.ivarfn[0]
    flagfn = args.flagfn[0]
    if getattr(args, 'psffn', None):
        # stamp = numpy.clip(fits.getdata(args.psffn), 1e-10, numpy.inf)
        stamp = fits.getdata(args.psffn)
        stamp[stamp < 0] = 0.
        stamp = stamp / numpy.sum(stamp)
        psf = psfmod.SimplePSF(stamp)
        from functools import partial
        psf.fitfun = partial(psfmod.wise_psf_fit, fname=args.psffn)
    else:
        print('using moffat')
        psf = psfmod.SimplePSF(psfmod.moffat_psf(2.5, beta=2.5)[0])
    res = process(imagefn,
                  ivarfn,
                  flagfn,
                  psf,
                  refit_psf=args.refit_psf,
                  verbose=args.verbose,
                  nx=4,
                  ny=4,
                  satlimit=args.satlimit)
    outfn = args.outfn[0]
    fits.writeto(outfn, res[0])
    fits.append(outfn, res[1])
    fits.append(outfn, res[2])
예제 #5
0
def find_psf(xcen, shiftx, ycen, shifty, psfstack, weightstack,
             imstack, stampsz=59, nkeep=100):
    """Find PSF from stamps."""
    # let's just go ahead and correlate the noise
    xr = numpy.round(shiftx)
    yr = numpy.round(shifty)
    psfqf = (numpy.sum(psfstack*(weightstack > 0), axis=(1, 2)) /
             numpy.sum(psfstack, axis=(1, 2)))
    totalflux = numpy.sum(psfstack, axis=(1, 2))
    timflux = numpy.sum(imstack, axis=(1, 2))
    toneflux = numpy.sum(psfstack, axis=(1, 2))
    tmedflux = numpy.median(psfstack, axis=(1, 2))
    tfracflux = toneflux / numpy.clip(timflux, 100, numpy.inf)
    tfracflux2 = ((toneflux-tmedflux*psfstack.shape[1]*psfstack.shape[2]) /
                  numpy.clip(timflux, 100, numpy.inf))
    okpsf = ((numpy.abs(psfqf - 1) < 0.03) &
             (tfracflux > 0.5) & (tfracflux2 > 0.2))
    if numpy.sum(okpsf) > 0:
        shiftxm = numpy.median(shiftx[okpsf])
        shiftym = numpy.median(shifty[okpsf])
        okpsf = (okpsf &
                 (numpy.abs(shiftx-shiftxm) < 1.) &
                 (numpy.abs(shifty-shiftym) < 1.))
    if numpy.sum(okpsf) <= 5:
        print('Fewer than 5 stars accepted in image, keeping original PSF')
        return None
    if numpy.sum(okpsf) > nkeep:
        okpsf = okpsf & (totalflux > -numpy.sort(-totalflux[okpsf])[nkeep-1])
    psfstack = psfstack[okpsf, :, :]
    weightstack = weightstack[okpsf, :, :]
    totalflux = totalflux[okpsf]
    xcen = xcen[okpsf]
    ycen = ycen[okpsf]
    shiftx = shiftx[okpsf]
    shifty = shifty[okpsf]
    for i in range(psfstack.shape[0]):
        psfstack[i, :, :] = shift(psfstack[i, :, :], [-shiftx[i], -shifty[i]])
        if (numpy.abs(xr[i]) > 0) or (numpy.abs(yr[i]) > 0):
            weightstack[i, :, :] = shift(weightstack[i, :, :],
                                         [-xr[i], -yr[i]],
                                         mode='constant', cval=0.)
        # our best guess as to the PSFs & their weights
    # select some reasonable sample of the PSFs
    totalflux = numpy.sum(psfstack, axis=(1, 2))
    psfstack /= totalflux.reshape(-1, 1, 1)
    weightstack *= totalflux.reshape(-1, 1, 1)
    tpsf = numpy.median(psfstack, axis=0)
    tpsf = psfmod.center_psf(tpsf)
    if tpsf.shape == stampsz:
        return tpsf
    xc = numpy.arange(tpsf.shape[0]).reshape(-1, 1)-tpsf.shape[0]//2
    yc = xc.reshape(1, -1)
    rc = numpy.sqrt(xc**2.+yc**2.)
    stampszo2 = psfstack[0].shape[0] // 2
    wt = numpy.clip((stampszo2+1-rc)/4., 0., 1.)
    overlap = (wt != 1) & (wt != 0)

    def objective(par):
        mod = psfmod.moffat_psf(par[0], beta=2.5, xy=par[2], yy=par[3],
                                deriv=False, stampsz=tpsf.shape[0])
        mod /= numpy.sum(mod)
        return ((tpsf-mod)[overlap]).reshape(-1)
    from scipy.optimize import leastsq
    par = leastsq(objective, [4., 3., 0., 1.])[0]
    modpsf = psfmod.moffat_psf(par[0], beta=2.5, xy=par[2], yy=par[3],
                               deriv=False, stampsz=stampsz)
    modpsf /= numpy.sum(psfmod.central_stamp(modpsf))
    npsf = modpsf.copy()
    npsfcen = psfmod.central_stamp(npsf, tpsf.shape[0])
    npsfcen[:, :] = tpsf*wt+(1-wt)*npsfcen[:, :]
    npsf /= numpy.sum(npsf)
    return psfmod.SimplePSF(npsf, normalize=-1)