def localize_emcee(logl,
                   loglargs,
                   logp,
                   logpargs,
                   xmin,
                   xmax,
                   nside=-1,
                   chain_dump=None):
    # Set up sampler
    import emcee
    from sky_area.sky_area_clustering import Clustered3DKDEPosterior
    ntemps = 20
    nwalkers = 100
    nburnin = 1000
    nthin = 10
    niter = 10000 + nburnin
    ndim = len(xmin)
    sampler = emcee.PTSampler(ntemps=ntemps,
                              nwalkers=nwalkers,
                              dim=ndim,
                              logl=logl,
                              logp=logp,
                              loglargs=loglargs,
                              logpargs=logpargs)

    # Draw initial state from multivariate uniform distribution
    p0 = np.random.uniform(xmin, xmax, (ntemps, nwalkers, ndim))

    # Collect samples. The .copy() is important because PTSampler.sample()
    # reuses p on every iteration.
    chain = np.vstack([
        p[0, :, :].copy() for p, _, _ in itertools.islice(
            sampler.sample(p0, iterations=niter, storechain=False), nburnin,
            niter, nthin)
    ])

    # Extract polar coordinates. For all likelihoodds, the first two parameters
    # are ra, sin(dec).
    theta = np.arccos(chain[:, 1])
    phi = chain[:, 0]
    dist = chain[:, 2]

    ra = phi
    dec = 0.5 * np.pi - theta
    pts = np.column_stack((ra, dec, dist))
    # Pass a random subset of 1000 points to the KDE, to save time.
    pts = np.random.permutation(pts)[:1000, :]
    ckde = Clustered3DKDEPosterior(pts)
    _, nside, ipix = zip(*ckde._bayestar_adaptive_grid())
    uniq = (4 * np.square(nside) + ipix).astype(np.uint64)

    pts = np.transpose(hp.pix2vec(nside, ipix, nest=True))

    datasets = [kde.dataset for kde in ckde.kdes]
    inverse_covariances = [kde.inv_cov for kde in ckde.kdes]
    weights = ckde.weights

    # Compute marginal probability, conditional mean, and conditional
    # standard deviation in all directions.
    probdensity, distmean, diststd = np.transpose([
        distance.cartesian_kde_to_moments(pt, datasets, inverse_covariances,
                                          weights) for pt in pts
    ])

    # Optionally save posterior sample chain to file.
    # Read back in with np.load().
    if chain_dump:
        # Undo numerical conditioning of distances; convert back to Mpc
        names = 'ra sin_dec distance cos_inclination twopsi time'.split(
        )[:ndim]
        np.save(chain_dump, np.rec.fromrecords(chain, names=names))

    # Done!
    return Table([uniq, probdensity, distmean, diststd],
                 names='UNIQ PROBDENSITY DISTMEAN DISTSTD'.split())
Exemple #2
0
def emcee_sky_map(logl,
                  loglargs,
                  logp,
                  logpargs,
                  xmin,
                  xmax,
                  nside=-1,
                  kde=False,
                  chain_dump=None,
                  max_horizon=1.0):
    # Set up sampler
    import emcee
    ntemps = 20
    nwalkers = 100
    nburnin = 1000
    nthin = 10
    niter = 10000 + nburnin
    ndim = len(xmin)
    sampler = emcee.PTSampler(ntemps=ntemps,
                              nwalkers=nwalkers,
                              dim=ndim,
                              logl=logl,
                              logp=logp,
                              loglargs=loglargs,
                              logpargs=logpargs)

    # Draw initial state from multivariate uniform distribution
    p0 = np.random.uniform(xmin, xmax, (ntemps, nwalkers, ndim))

    # Collect samples. The .copy() is important because PTSampler.sample()
    # reuses p on every iteration.
    chain = np.vstack([
        p[0, :, :].copy() for p, _, _ in itertools.islice(
            sampler.sample(p0, iterations=niter, storechain=False), nburnin,
            niter, nthin)
    ])

    # Extract polar coordinates. For all likelihoodds, the first two parameters
    # are ra, sin(dec).
    theta = np.arccos(chain[:, 1])
    phi = chain[:, 0]
    dist = chain[:, 2]

    # Do adaptive histogram binning if the user has not selected the KDE,
    # or if the user has selected the KDE but we need to guess the resolution.
    if nside == -1 or not kde:
        samples_per_bin = int(np.ceil(0.005 * len(chain)))
        prob = postprocess.adaptive_healpix_histogram(theta,
                                                      phi,
                                                      samples_per_bin,
                                                      nside=nside,
                                                      nest=True)

        # Determine what nside what actually used.
        nside = hp.npix2nside(len(prob))
        # Go one level finer, because the KDE will find more detail.
        nside *= 2

    if kde:
        from sky_area.sky_area_clustering import Clustered3DKDEPosterior
        ra = phi
        dec = 0.5 * np.pi - theta
        pts = np.column_stack((ra, dec, dist))
        # Pass a random subset of 1000 points to the KDE, to save time.
        pts = np.random.permutation(pts)[:1000, :]
        prob = Clustered3DKDEPosterior(pts).as_healpix(nside)

    # Optionally save posterior sample chain to file.
    # Read back in with np.load().
    if chain_dump:
        # Undo numerical conditioning of distances; convert back to Mpc
        chain[:, 2] *= max_horizon
        names = 'ra sin_dec distance cos_inclination twopsi time'.split(
        )[:ndim]
        np.save(chain_dump, np.rec.fromrecords(chain, names=names))

    # Done!
    return prob