예제 #1
0
파일: xdfutils.py 프로젝트: bd-j/xdf
def prep_scene(sourcepars,
               filters=["dummy"],
               splinedata=None,
               free_sersic=True):

    # --- Get Sources and a Scene -----
    sources = []

    for pars in sourcepars:
        flux, x, y, q, pa, n, rh = copy.deepcopy(pars)
        s = Galaxy(filters=filters,
                   splinedata=splinedata,
                   free_sersic=free_sersic)
        s.sersic = n
        s.rh = rh
        s.flux = flux  #np.atleast_1d(flux)
        s.ra = x
        s.dec = y
        s.q = q
        s.pa = np.deg2rad(pa)
        sources.append(s)

    scene = Scene(sources)
    theta = scene.get_all_source_params()
    return scene, theta
def prep_scene(sourcepars, filters=["dummy"], splinedata=None):

    # --- Get Sources and a Scene -----
    sources = []

    for pars in sourcepars:
        flux, x, y, q, pa, n, rh = np.copy(pars)
        if splinedata is not None:
            s = Galaxy(filters=filters,
                       splinedata=splinedata,
                       free_sersic=False)
            s.sersic = n
            s.rh = rh
        else:
            s = SimpleGalaxy(filters=filters)
        s.flux = flux
        s.ra = x
        s.dec = y
        s.q = q
        s.pa = np.deg2rad(pa)
        sources.append(s)

    scene = Scene(sources)
    theta = scene.get_all_source_params()
    return scene, theta
예제 #3
0
def setup_scene(sourceparams=[(1.0, 5., 5., 0.7, 30., 1.0, 0.05)],
                splinedata=None,
                perturb=0,
                filters=['dummy'],
                add_noise=False,
                snr_max=100.,
                stamp_kwargs=[]):

    # --- Get Sources and a Scene -----
    sources = []
    for (flux, x, y, q, pa, n, rh) in sourceparams:
        if splinedata is not None:
            s = Galaxy(filters=filters, splinedata=splinedata)
            s.sersic = n
            s.rh = rh
        else:
            s = SimpleGalaxy(filters=filters)
        s.flux = flux
        s.ra = x
        s.dec = y
        s.q = q
        s.pa = np.deg2rad(pa)
        sources.append(s)

    scene = Scene(sources)
    theta = scene.get_all_source_params()
    label = []

    # get stamps
    stamps = [make_stamp(**sk) for sk in stamp_kwargs]
    if splinedata is not None:
        for stamp in stamps:
            stamp.scale = np.array([[32.0, 0.0], [0.0, 32.0]])

    # --- Generate mock  and add to stamp ---

    ptrue = theta * np.random.normal(1.0, perturb, size=theta.shape)
    for stamp in stamps:
        true_image, _ = make_image(scene, stamp, Theta=ptrue)
        stamp.pixel_values = true_image.copy()
        err = stamp.pixel_values.max() / snr_max
        #err = np.sqrt(err**2 + stamp.pixel_values.flatten())
        err = np.ones(stamp.npix) * err
        stamp.ierr = np.ones(stamp.npix) / err
        if add_noise:
            noise = np.random.normal(0, err)
            stamp.pixel_values += noise.reshape(stamp.nx, stamp.ny)

    return scene, stamps, ptrue, label
예제 #4
0
def set_scene(sourcepars,
              fluxpars,
              filters,
              splinedata=None,
              free_sersic=True):
    """Build a scene from a set of source parameters and fluxes through a set of filters.
    
    Returns
    -------
    scene: Scene object
    """
    sourcepars = sourcepars.astype(np.float)

    # get all sources
    sources = []
    for ii_gal in range(len(sourcepars)):
        gal_id, x, y, q, pa, n, rh = sourcepars[ii_gal]
        #print(x, y, type(pa), pa)
        s = Galaxy(filters=filters.tolist(),
                   splinedata=splinedata,
                   free_sersic=free_sersic)
        s.global_id = gal_id
        s.sersic = n
        s.rh = np.clip(rh, 0.05, 0.10)
        s.flux = fluxpars[ii_gal]
        s.ra = x
        s.dec = y
        s.q = np.clip(q, 0.2, 0.9)
        s.pa = np.deg2rad(pa)
        sources.append(s)

    # generate scene
    scene = Scene(sources)

    return (scene)
예제 #5
0
def set_inactive(scene, stamps, pad=5, nmax=0):
    # set outside sources to be fixed.
    for stamp in stamps:
        for source in scene.sources:
            x, y = stamp.sky_to_pix([source.ra, source.dec])
            good = ((x < stamp.nx + pad) & (x > -pad) & (y < stamp.ny + pad) &
                    (y > -pad))
            if ~good:
                source.fixed = True

    insources = [s for s in scene.sources if not s.fixed]
    fluxes = np.array([s.flux for s in insources])
    order = np.argsort(fluxes.max(axis=-1))
    use = order[-nmax:]
    use_sources = [insources[i] for i in use]
    microscene = Scene(use_sources)
    try:
        microscene.npsf_per_source = scene.npsf_per_source
    except (AttributeError):
        pass
    return microscene
def setup_scene(galaxy=False, fwhm=1.0, offset=0.0,
                size=(30, 30), peak_snr=1e1, add_noise=False):

    stamp = make_stamp(size, fwhm, offset=offset)

    # --- Get a Source and Scene -----
    if galaxy:
        ngauss = 1
        source = SimpleGalaxy()
        source.radii = np.arange(ngauss) * 0.5 + 1.0
        source.q = 0.5
        source.pa = np.deg2rad(30.)
        theta = [100., 10., 10., 0.5, np.deg2rad(10.)]
        label = ['$\psi$', '$x$', '$y$', '$q$', '$\\varphi$']
        bounds = [(0, 1e4), (0., 30), (0, 30), (0, 1), (0, np.pi/2)]
    else:
        source = Star()
        theta = [100., 10., 10.]
        label = ['$\psi$', '$x$', '$y$']
        bounds = [(-1e6, 1e6), (-1e5, 1e5), (-1e5, 1e5)]

    scene = Scene([source])

    # --- Generate mock  and add to stamp ---
    ptrue = np.array(theta)
    true_image, partials = make_image(scene, stamp, Theta=ptrue)
    stamp.pixel_values = true_image.copy()
    err = stamp.pixel_values.max() / peak_snr
    #err = np.sqrt(err**2 + stamp.pixel_values.flatten())
    err = np.ones(stamp.npix) * err
    stamp.ierr = np.ones(stamp.npix) / err

    if add_noise:
        noise = np.random.normal(0, err)
        stamp.pixel_values += noise.reshape(stamp.nx, stamp.ny)

    return scene, stamp, ptrue, label
예제 #7
0
        stamp.scale = np.eye(2)
        stamp.dpix_dsky = np.eye(2)
        # The sky coordinates of the reference pixel
        stamp.crval = np.zeros([2])
        # The pixel coordinates of the reference pixel
        stamp.crpix = np.zeros([2])

    # override the psf to reflect in both directions
    T = -1.0 * np.eye(2)
    stamp.psf.covariances = np.matmul(T, np.matmul(stamp.psf.covariances, T.T))
    stamp.psf.means = np.matmul(stamp.psf.means, T)

    # --- get the Scene ---
    sources = [Star(filters=["F090W"])]
    label = ['flux', 'x', 'y']
    scene = Scene(sources)
    plans = [WorkPlan(stamp)]

    nll = argfix(negative_lnlike_multi, scene=scene, plans=plans)
    nll_nograd = argfix(negative_lnlike_multi,
                        scene=scene,
                        plans=plans,
                        grad=False)

    # --- Initialize ---
    theta_init = np.array([stamp.pixel_values.sum() * 1.0, ra_init, dec_init])
    if inpixels:
        world = np.array([ra_init, dec_init, 0])
        hdr = fits.getheader(imname)
        ast = apy_wcs.WCS(hdr)
        center = ast.wcs_world2pix(world[None, :], 0)[0, :2] - stamp.lo
예제 #8
0
def fit_source(ra=53.115295, dec=-27.803501, dofit=True, nlive=100):

    # --- Build the postage stamp ----
    ra_init, dec_init = ra, dec
    pos_init = (ra_init, dec_init)
    stamps = [
        make_stamp(im,
                   pos_init,
                   center_type='celestial',
                   size=(50, 50),
                   psfname=psfname) for im in imnames
    ]

    # override the psf to reflect in both directions
    T = -1.0 * np.eye(2)
    for s in stamps:
        s.psf.covariances = np.matmul(T, np.matmul(s.psf.covariances, T.T))
        s.psf.means = np.matmul(s.psf.means, T)

    # --- get the Scene ---
    source = Star(filters=["F090W"])
    scene = Scene([source])
    label = ['Counts', 'RA', 'Dec']

    plans = [WorkPlan(stamp) for stamp in stamps]
    lnlike = argfix(lnlike_multi, scene=scene, plans=plans, grad=False)

    # --- Initialize ---
    theta_init = np.array(
        [stamps[0].pixel_values.sum() * 1.0, ra_init, dec_init])
    # a rough measure of dcoordinate/dpix
    plate_scale, _ = np.linalg.eig(np.linalg.inv(stamps[0].dpix_dsky))
    # make the prior ~10 pixels wide, and 50% of counts
    theta_width = np.array(
        [0.5 * theta_init[0], 10 * plate_scale[0], 10 * plate_scale[1]])
    #print(theta_init, theta_width)

    # --- Nested sampling ---
    ndim = 3

    def prior_transform(unit_coords):
        # convert to uniform -1 to 1
        u = (2 * unit_coords - 1.)
        # now scale and shift
        theta = theta_init + theta_width * u
        return theta

    if dofit:
        import dynesty, time

        # "Standard" nested sampling.
        sampler = dynesty.NestedSampler(lnlike,
                                        prior_transform,
                                        ndim,
                                        nlive=nlive,
                                        bootstrap=0)
        t0 = time.time()
        sampler.run_nested()
        dur = time.time() - t0
        results = sampler.results
        results['duration'] = dur
        indmax = results['logl'].argmax()
        theta_max = results['samples'][indmax, :]

    else:
        results = None
        theta_max = np.zeros(3)
        stamps = None

    return results, theta_max, stamps, scene
예제 #9
0
def fit_source(ra=53.115295,
               dec=-27.803501,
               mag=None,
               dofit='dynesty',
               nlive=100,
               nburn=600,
               niter=200):

    # --- Get the data ---
    stamps = prep_stamps(ra, dec)

    # --- Get the Scene ---
    source = Star(filters=filters)
    scene = Scene([source])
    label = ['Counts', 'RA', 'Dec']

    plans = [WorkPlan(stamp) for stamp in stamps]

    # --- Initialize and set scales ---
    if mag is None:
        counts = [
            np.clip(stamp.pixel_values.sum(), 1, np.inf) for stamp in stamps
        ]
    else:
        counts = [
            10**(0.4 * (stamp.full_header["ABMAG"] - mag)) for stamp in stamps
        ]
    theta_init = np.array(counts + [ra, dec])
    # a rough measure of dcoordinate/dpix - this doesn't work so great
    plate_scale = np.linalg.eigvals(np.linalg.inv(stamps[0].dpix_dsky))
    plate_scale = np.abs(plate_scale)
    # make the prior ~5 pixels wide, and 100% of expected counts
    theta_width = np.array(
        [theta_init[0], 5 * plate_scale[0], 5 * plate_scale[1]])
    print(theta_init, theta_width)

    # --- Sampling ---
    ndim = 3
    p0 = theta_init.copy()
    upper = theta_init + theta_width / 2.
    lower = theta_init - theta_width / 2.
    scales = theta_width

    if dofit == 'dynesty':

        lnlike = argfix(lnlike_multi, scene=scene, plans=plans, grad=False)

        def prior_transform(unit_coords):
            # convert to uniform -1 to 1
            u = (2 * unit_coords - 1.)
            # now scale and shift
            theta = theta_init + theta_width * u
            return theta

        import dynesty, time

        # "Standard" nested sampling.
        sampler = dynesty.NestedSampler(lnlike,
                                        prior_transform,
                                        ndim,
                                        bootstrap=0,
                                        nlive=nlive)
        t0 = time.time()
        sampler.run_nested()
        dur = time.time() - t0
        results = sampler.results
        results['duration'] = dur
        indmax = results['logl'].argmax()
        theta_max = results['samples'][indmax, :]

    elif dofit == "hmc":

        from hmc import BasicHMC

        model = Posterior(scene, plans, upper=upper, lower=lower)
        hsampler = BasicHMC(model, verbose=False)
        hsampler.ndim = len(p0)
        hsampler.set_mass_matrix(1 / scales**2)
        eps = hsampler.find_reasonable_stepsize(p0)
        pos, prob, grad = hsampler.sample(p0,
                                          iterations=nburn,
                                          mass_matrix=1 / scales**2,
                                          epsilon=eps * 1.5,
                                          length=10,
                                          sigma_length=3,
                                          store_trajectories=False)
        pos, prob, grad = hsampler.sample(pos,
                                          iterations=niter,
                                          mass_matrix=1 / scales**2,
                                          epsilon=eps,
                                          length=20,
                                          sigma_length=5,
                                          store_trajectories=True)

        results = {
            "samples": sampler.chain.copy(),
            "lnprobability": sampler.lnp.copy()
        }
        theta_max = sampler.chain[np.argmax(sampler.lnprob), :]

    elif dofit == "hemcee":

        from hemcee import NoUTurnSampler
        from hemcee.metric import DiagonalMetric

        model = Posterior(scene, plans, upper=np.inf, lower=-np.inf)
        metric = DiagonalMetric(scales**2)
        usampler = NoUTurnSampler(model.lnprob,
                                  model.lnprob_grad,
                                  metric=metric)
        pos, lnp0 = usampler.run_warmup(p0, nburn)
        chain, lnp = usampler.run_mcmc(pos, niter)

        results = {"samples": chain, "lnprobability": lnp}
        theta_max = chain[np.argmax(lnp), :]

    else:
        results = None
        theta_max = np.zeros(3)

    return results, theta_max, stamps, scene
예제 #10
0
        return a.reshape((m,M/m,n,N/n)).mean(3).mean(1)
    else:
        return np.repeat(np.repeat(a, m/M, axis=0), n/N, axis=1)


def compare(x, y, source, native, oversampled):
    
    image = get_image(x, y, source, native)
    oimage = get_image(x, y, source, oversampled)
    rimage = rebin(oimage, image.shape) * oversample**2


if __name__ == "__main__":

    source = Star()
    scene = Scene([source])
     
    # FWHM in native pixels
    fwhm = 2.0
    sigma = fwhm/2.355
    ck = {"second_order": False}

    # native resolution
    native = get_stamp(10)
    native.psf.covariances = np.array([np.eye(2) * sigma**2])
    native.crpix = np.array([5, 5])

    # oversampled image
    oversample = 8
    dx = 1./oversample
    oversampled = get_stamp(int(10 / dx), dx)