def _set_uncs_and_posterior(self, model):
        """
        Set the symmetric and asymmetric Gaussian uncertainties
        and sets the posteriors to astropy.unc distributions

        Parameters
        ----------
        model : astropy model
            model giving the result from the fitting

        Returns
        -------
        model : astropy model
            model updated with uncertainties
        """
        sampler = self.fit_info["sampler"]
        nwalkers, nsteps = sampler.lnprobability.shape
        # discard the 1st burn_frac (burn in)
        flat_samples = sampler.get_chain(discard=int(self.burnfrac * nsteps),
                                         flat=True)
        nflatsteps, ndim = flat_samples.shape

        nparams = len(model.parameters)
        model.uncs = np.zeros((nparams))
        model.uncs_plus = np.zeros((nparams))
        model.uncs_minus = np.zeros((nparams))
        k = 0
        for i, pname in enumerate(model.param_names):
            if not model.fixed[pname]:
                mcmc = np.percentile(flat_samples[:, k], [16, 50, 84])

                # set the uncertainty arrays - could be done via the parameter objects
                # but would need an update to the model properties to make this happen
                # model.parameters[i] = mcmc[1]
                model.uncs[i] = 0.5 * (mcmc[2] - mcmc[0])
                model.uncs_plus[i] = mcmc[2] - mcmc[1]
                model.uncs_minus[i] = mcmc[1] - mcmc[0]

                # set the posterior distribution to the samples
                param = getattr(model, pname)
                param.value = mcmc[1]
                param.posterior = astrounc.Distribution(flat_samples[:, k])
                k += 1
            else:
                model.uncs[i] = 0.0
                model.uncs_plus[i] = 0.0
                model.uncs_minus[i] = 0.0
                # set the posterior distribution to the samples
                param = getattr(model, pname)
                param.posterior = None

            # now set uncertainties on the parameter objects themselves
            param = getattr(model, pname)
            param.unc = model.uncs[i]
            param.unc_plus = model.uncs_plus[i]
            param.unc_minus = model.uncs_minus[i]

        return model
Beispiel #2
0
def get_values_from_distribution(distribution, unit=None):
    """Assuming a normal distribution, return value+error; includes unit if provided"""

    if isinstance(distribution, (list, np.ndarray)):
        distribution = unc.Distribution(distribution)

    val = distribution.pdf_mean
    err = distribution.pdf_std

    if isinstance(val, u.quantity.Quantity):
        unit = val.unit.to_string()
        val = val.value
        err = err.value

    out_dict = {'value': val, 'error': err}
    if unit is not None:
        out_dict['unit'] = unit

    return out_dict
Beispiel #3
0
    ris = np.full((n_ext), 0.0)
    ris_unc = np.full((2, n_ext), 0.0)

    for k, cname in enumerate(extfnames):

        # get P92 fits
        bfile = f"fits/{cname}"
        cext = ExtData(filename=bfile)

        mcmcfile = bfile.replace(".fits", ".h5")
        reader = emcee.backends.HDFBackend(mcmcfile)
        nsteps, nwalkers = reader.get_log_prob().shape
        samples = reader.get_chain(discard=int(mcmc_burnfrac * nsteps),
                                   flat=True)

        avs_dist = unc.Distribution(samples[:, -1])
        av_per = avs_dist.pdf_percentiles([16.0, 50.0, 84.0])
        avs[k] = av_per[1]
        avs_unc[1, k] = av_per[2] - av_per[1]
        avs_unc[0, k] = av_per[1] - av_per[0]
        # print(avs_dist.pdf_percentiles([33., 50., 87.]))

        (indxs, ) = np.where((cext.waves["BAND"] > 0.4 * u.micron)
                             & (cext.waves["BAND"] < 0.5 * u.micron))
        ebvs_dist = unc.normal(
            cext.exts["BAND"][indxs[0]],
            std=cext.uncs["BAND"][indxs[0]],
            n_samples=avs_dist.n_samples,
        )
        ebvs[k] = ebvs_dist.pdf_mean()
        ebvs_unc[k] = ebvs_dist.pdf_std()
    rvs = np.full((n_ext), 0.0)
    rvs_unc = np.full((2, n_ext), 0.0)

    for k, cname in enumerate(extfnames):

        # get P92 fits
        bfile = f"fits_good_18aug20/{cname}"
        cext = ExtData(filename=bfile)

        mcmcfile = bfile.replace(".fits", ".h5")
        reader = emcee.backends.HDFBackend(mcmcfile)
        nsteps, nwalkers = reader.get_log_prob().shape
        samples = reader.get_chain(discard=int(mcmc_burnfrac * nsteps),
                                   flat=True)

        avs_dist = unc.Distribution(samples[:, -1])
        av_per = avs_dist.pdf_percentiles([16.0, 50.0, 84.0])
        avs[k] = av_per[1]
        avs_unc[1, k] = av_per[2] - av_per[1]
        avs_unc[0, k] = av_per[1] - av_per[0]
        # print(avs_dist.pdf_percentiles([33., 50., 87.]))

        (indxs, ) = np.where((cext.waves["BAND"] > 0.4 * u.micron)
                             & (cext.waves["BAND"] < 0.5 * u.micron))
        ebvs_dist = unc.normal(
            cext.exts["BAND"][indxs[0]],
            std=cext.uncs["BAND"][indxs[0]],
            n_samples=avs_dist.n_samples,
        )
        ebvs[k] = ebvs_dist.pdf_mean()
        ebvs_unc[k] = ebvs_dist.pdf_std()
Beispiel #5
0
    rvs = np.full((n_ext), 0.0)
    rvs_unc = np.full((2, n_ext), 0.0)

    for k, cname in enumerate(extfnames):

        # get P92 fits
        bfile = cname
        cext = ExtData(filename=bfile)

        mcmcfile = bfile.replace(".fits", ".h5")
        reader = emcee.backends.HDFBackend(mcmcfile)
        nsteps, nwalkers = reader.get_log_prob().shape
        samples = reader.get_chain(discard=int(mcmc_burnfrac * nsteps),
                                   flat=True)

        avs_dist = unc.Distribution(samples[:, -1])
        av_per = avs_dist.pdf_percentiles([16.0, 50.0, 84.0])
        avs[k] = av_per[1]
        avs_unc[1, k] = av_per[2] - av_per[1]
        avs_unc[0, k] = av_per[1] - av_per[0]
        # print(avs_dist.pdf_percentiles([33., 50., 87.]))

        (indxs, ) = np.where((cext.waves["BAND"] > 0.4 * u.micron)
                             & (cext.waves["BAND"] < 0.5 * u.micron))
        ebvs_dist = unc.normal(
            cext.exts["BAND"][indxs[0]],
            std=cext.uncs["BAND"][indxs[0]],
            n_samples=avs_dist.n_samples,
        )
        ebvs[k] = ebvs_dist.pdf_mean()
        ebvs_unc[k] = ebvs_dist.pdf_std()
Beispiel #6
0
from astropy.cosmology import FlatLambdaCDM, Planck15
from astropy.coordinates import SkyCoord
import astropy.units as u
import astropy.uncertainty as aun
import astropy.constants as ac
from uncertainties import ufloat

coords = SkyCoord('09h47m40.156s -30d56m55.44s', frame='fk5')

# from page 64 of
# https://ui.adsabs.harvard.edu/abs/2003AJ....126.2268W/abstract
z = ((2544 * u.km / u.s) / ac.c).to('')
deltaz = ((12 * u.km / u.s) / ac.c).to('')

# from
# http://simbad.u-strasbg.fr/simbad/sim-id?Ident=MCG-5-23-16
z2 = ((2466.09 * u.km / u.s) / ac.c).to('')
deltaz2 = ((47.97 * u.km / u.s) / ac.c).to('')

compat = ufloat(z, deltaz) - ufloat(z, deltaz2)

# cosmo = FlatLambdaCDM(H0=67.8, Om0=.308)
cosmo = Planck15

z_pdf = aun.normal(z.value, std=deltaz.value, n_samples=10_000)

dist = aun.Distribution(cosmo.comoving_distance(z_pdf.distribution))
def ESO280_params(PRINT=True):
    params_dict = {
        "eso_280_m_M_V": 17.011,
        "eso_280_e_m_M_V": 0.045,
        "eso_280_ebv": 0.141,
        "eso_280_e_ebv": 0.006,
        "rv": 94.644,
        "e_rv": 0.476,
        "std_rv": 2.305,
        "e_std_rv": 0.363,
        "r_t": [0.14693 * u.deg, 0.04126 * u.deg],
        "r_c": [0.00410 * u.deg, 0.00009 * u.deg]
    }
    n_samples = 10000
    eso_280_m_M_V_dist = unc.normal(params_dict['eso_280_m_M_V'],
                                    std=params_dict['eso_280_e_m_M_V'],
                                    n_samples=n_samples)
    eso_280_ebv_dist = unc.normal(params_dict['eso_280_ebv'],
                                  std=params_dict['eso_280_e_ebv'],
                                  n_samples=n_samples)
    eso_280_m_M_0_dist = eso_280_m_M_V_dist - 3.1 * eso_280_ebv_dist
    eso_280_dist_dist = unc.Distribution(
        10**(1 + eso_280_m_M_0_dist / 5).distribution * u.pc)

    # Hardcoded values. Calculated using velocity_estimate.py
    rv_dist = unc.normal(params_dict['rv'] * u.km / u.s,
                         std=params_dict['e_rv'] * u.km / u.s,
                         n_samples=n_samples)
    rv_std_dist = unc.normal(params_dict['std_rv'] * u.km / u.s,
                             std=params_dict['e_std_rv'] * u.km / u.s,
                             n_samples=10000)
    # Size values from ASteCA
    r_0_dist = unc.normal(params_dict['r_c'][0],
                          std=params_dict['r_c'][1],
                          n_samples=10000)
    r_t_dist = unc.normal(params_dict['r_t'][0],
                          std=params_dict['r_t'][1],
                          n_samples=10000)
    size_dist = (np.tan(r_0_dist) * eso_280_dist_dist)
    tidal_dist = (np.tan(r_t_dist) * eso_280_dist_dist)
    cluster_mass = ((7.5 * rv_std_dist**2 * 4 / 3 * size_dist) / const.G)

    sc_best = SkyCoord(ra=cluster_centre.ra,
                       dec=cluster_centre.dec,
                       radial_velocity=rv_dist.pdf_mean(),
                       distance=eso_280_dist_dist.pdf_mean(),
                       pm_ra_cosdec=-0.548 * u.mas / u.yr,
                       pm_dec=-2.688 * u.mas / u.yr)
    eso_280_pmra_dist = unc.normal(sc_best.pm_ra_cosdec,
                                   std=0.073 * u.mas / u.yr,
                                   n_samples=n_samples)
    eso_280_pmdec_dist = unc.normal(sc_best.pm_dec,
                                    std=0.052 * u.mas / u.yr,
                                    n_samples=n_samples)
    sc_dist = SkyCoord(
        ra=np.ones(eso_280_dist_dist.n_samples) * cluster_centre.ra,
        dec=np.ones(eso_280_dist_dist.n_samples) * cluster_centre.dec,
        radial_velocity=rv_dist.distribution,
        distance=eso_280_dist_dist.distribution,
        pm_ra_cosdec=eso_280_pmra_dist.distribution,
        pm_dec=eso_280_pmdec_dist.distribution)
    if PRINT:
        print(
            rf"$r_c$ & ${params_dict['r_c'][0].to(u.arcsec).value:0.2f}\pm{params_dict['r_c'][1].to(u.arcsec).value:0.2f}$~arcsec\\"
        )
        print(
            rf"$r_t$ & ${params_dict['r_t'][0].to(u.arcmin).value:0.2f}\pm{params_dict['r_t'][1].to(u.arcmin).value:0.2f}$~arcmin\\"
        )
        print(
            rf"$(m-M)_V$ & ${params_dict['eso_280_m_M_V']:0.2f}\pm{params_dict['eso_280_e_m_M_V']:0.2f}$\\"
        )
        print(
            rf"$\ebv$ & ${params_dict['eso_280_ebv']:0.2f}\pm{params_dict['eso_280_e_ebv']:0.2f}$\\"
        )
        print(
            rf"$(m-M)_0$ & ${eso_280_m_M_0_dist.pdf_mean:0.2f}\pm{eso_280_m_M_0_dist.pdf_std:0.2f}$\\"
        )
        print(
            rf"$d_\odot$ & ${eso_280_dist_dist.pdf_mean.to(u.kpc).value:0.1f}\pm{eso_280_dist_dist.pdf_std.to(u.kpc).value:0.1f}$~kpc\\"
        )
        print(
            rf"$r_c$ & ${size_dist.pdf_mean.to(u.pc).value:0.2f}\pm{size_dist.pdf_std.to(u.pc).value:0.2f}$~pc\\"
        )
        print(
            rf"$r_t$ & ${tidal_dist.pdf_mean.to(u.pc).value:0.1f}\pm{tidal_dist.pdf_std.to(u.pc).value:0.1f}$~pc\\"
        )
        print(
            rf"Mass & $({cluster_mass.pdf_mean.to(u.solMass).value/1000:0.1f}\pm{cluster_mass.pdf_std.to(u.solMass).value/1000:0.1f})\times10^3$~M$_\odot$\\"
        )
        print(
            rf"$v_r$ & ${params_dict['rv']:0.2f}\pm{params_dict['e_rv']:0.2f}$\kms\\"
        )
        print(
            rf"$\sigma_r$ & ${params_dict['std_rv']:0.2f}\pm{params_dict['e_std_rv']:0.2f}$\kms\\"
        )
    return params_dict, sc_best, sc_dist