コード例 #1
0
def mod_from_row(iso,
                 row,
                 props,
                 name_col='tmass_key',
                 rootdir=os.path.join(PROJECT_DIR, 'fit_results'),
                 halo_fraction=0.5,
                 tag=None,
                 **kwargs):

    kwargs.update({
        p: (np.float64(row[p]), np.float64(row['{}_unc'.format(p)]))
        for p in props if row[p] > 0 and row['{}_unc'.format(p)] > 0
    })
    if 'feh' in props:
        if np.isfinite(row['feh']):
            kwargs.update(
                {'feh': (np.float64(row['feh']), np.float64(row['feh_unc']))})
    name = row[name_col]
    if tag is not None:
        name = '{}_{}'.format(name, tag)
    kwargs.update({'name': name, 'directory': os.path.join(rootdir, name)})

    max_distance = min((1000. / (row['parallax'] - row['parallax_unc'])) * 2,
                       30000)
    kwargs['max_distance'] = max_distance
    kwargs['halo_fraction'] = halo_fraction
    mod = BasicStarModel(iso, **kwargs)
    mod.set_prior('distance', FlatPrior((0, max_distance)))
    AV_inf = get_AV_infinity(row['ra_1'], row['dec_1'])
    mod.set_prior('feh', FehPrior(halo_fraction=halo_fraction, local=False))
    mod.set_prior('AV', GaussianPrior(AV_inf, AV_inf / 2, bounds=(0, 5)))
    mod.set_bounds(mass=(0.1, 20), feh=iso.model_grid.get_limits('feh'))
    print(mod.mnest_basename)
    return mod
コード例 #2
0
    def setUp(self):
        mist = get_ichrone("mist")

        sfh = StarFormationHistory()  # Constant SFR for 10 Gyr; or, e.g., dist=norm(3, 0.2)
        imf = SalpeterPrior(bounds=(0.4, 10))  # bounds on solar masses
        binaries = BinaryDistribution(fB=0.4, gamma=0.3)
        feh = GaussianPrior(-0.2, 0.2)
        distance = DistancePrior(max_distance=3000)  # pc
        AV = AVPrior(bounds=[0, 2])
        pop = StarPopulation(
            mist, sfh=sfh, imf=imf, feh=feh, distance=distance, binary_distribution=binaries, AV=AV
        )

        self.pop = pop
        self.mist = mist
        self.df = pop.generate(1000)
        self.dereddened_df = deredden(mist, self.df)
コード例 #3
0
ファイル: stardate.py プロジェクト: shihyuntang/stardate
    def fit(self, inits=[329.58, 9.5596, -.0478, 260, .0045],
            nwalkers=50, max_n=100000, thin_by=100, burnin=0, iso_only=False,
            gyro_only=False, optimize=False, rossby=True, model="praesepe",
            seed=None, save_samples=False):
        """Run MCMC on a star using emcee.

        Explore the posterior probability density function of the stellar
        parameters using MCMC (via emcee).

        Args:
            inits (Optional[array-like]): A list of initial values to use for
                EEP, age (in log10[yrs]), feh, distance (in pc) and Av.
            nwalkers (Optional[int]): The number of walkers to use with emcee.
                The default is 50.
            max_n (Optional[int]): The maximum number of samples to obtain
                (although not necessarily to save -- see thin_by). The default
                is 100000.
            thin_by (Optional[int]): Only one in every thin_by samples will be
                saved. The default is 100. Set = 1 to save every sample (note
                this substantially slows down the MCMC process because of the
                additional I/O time.
            burnin (Optional[int]): The number of SAVED samples to throw away
                when accessing the results. This number cannot exceed the
                number of saved samples (which is max_n/thin_by). Default = 0.
            iso_only (Optional[bool]): If true only the isochronal likelihood
                function will be used.
            gyro_only (Optional[bool]): If true only the gyrochronal
                likelihood function will be used. Beware: this may not do what
                you might assume it does... In general this setting is not
                currently very useful!
            optimize (Optional[bool]): If True, initial parameters will be
                found via optimization. Default is False.
            rossby (Optional[bool]): If True, magnetic braking will cease
                after Ro = 2. Default is True.
            model (Optional[bool]): The gyrochronology model to use. The
                default is "praesepe" (the Praesepe-based model). Can also be
                "angus15" for the Angus et al. (2015) model.
            seed (Optional[int]): The random number seed. Set this if you want
                to regenerate exactly the same samples each time.
            save_samples (Optional[bool]): saving samples is the computational
                bottleneck. If you want to save time and don't need to save
                the samples using the HDF5 backend, set this to False.

        """

        self.max_n = max_n
        self.nwalkers = nwalkers
        self.thin_by = thin_by
        self.save_samples = save_samples

        if burnin > max_n/thin_by:
            burnin = int(max_n/thin_by/3)
            print("Automatically setting burn in to {}".format(burnin))

        p_init = [inits[0], inits[1], inits[2], np.log(inits[3]), inits[4]]
        self.p_init = p_init

        if seed is not None:
            np.random.seed(seed)

        # Create the directory if it doesn't already exist.
        if save_samples:
            if not os.path.exists(self.savedir):
                os.makedirs(self.savedir)

        # Set up the backend
        # Don't forget to clear it in case the file already exists
        ndim = 5
        if save_samples:
            fn = "{0}/{1}.h5".format(self.savedir, self.filename)
            backend = emcee.backends.HDFBackend(fn)
            backend.reset(nwalkers, ndim)
            self.backend = backend

        # Set up the StarModel object needed to calculate the likelihood.
        mod = SingleStarModel(mist, **self.iso_params)  # StarModel isochrones obj
        # mod.set_prior(age=FlatPrior(bounds=(8, 10.14)))

        # Set up a Gaussian prior with the extinction, if provided.
        if self.Av_mean is not None and self.Av_sigma is not None:
            mod.set_prior(AV=GaussianPrior(self.Av_mean, self.Av_sigma,
                                           bounds=(0, 1)))

        # lnprob arguments

        args = [mod, self.prot, self.prot_err, iso_only, gyro_only, rossby,
                model]
        self.args = args

        # Optimize. Try a few inits and pick the best.
        if optimize:
            neep, nage = 5, 5
            likes1, likes2 = np.zeros(nage), np.zeros(neep)
            likes = np.zeros((neep, nage))
            inds = np.zeros(nage)
            result_list = np.zeros((neep, nage, 5))
            EEPS, AGES = np.meshgrid(np.linspace(200, 500, neep),
                                    np.linspace(7, 10., nage), indexing="ij")

            for i in range(neep):
                for j in range(nage):
                    inits = [EEPS[i, j], AGES[i, j], 0., np.log(1000.), .01]
                    results = spo.minimize(nll, inits, args=args)
                    likes1[j] = lnprob(results.x, *args)[0]
                    likes[i, j] = likes1[j]
                    result_list[i, j, :] = results.x
                inds[i] = np.argmax(likes1)
                likes2[i] = max(likes1)
            eep_ind = np.argmax(likes2)
            age_ind = int(inds[eep_ind])
            self.p_init = result_list[eep_ind, age_ind, :]

        # Run the MCMC
        sampler = self.run_mcmc()
        self.sampler = sampler

        nwalkers, nsteps, ndim = np.shape(self.sampler.chain)
        print("nsteps", nsteps, "burnin", burnin)
        self.samples = np.reshape(self.sampler.chain[:, burnin:, :],
                                  (nwalkers*(nsteps-burnin), ndim))
コード例 #4
0
def main(index, overwrite=False):
    # First make sure paths exist:
    # os.makedirs('../cache', exist_ok=True)
    # os.makedirs('../plots/isochrones', exist_ok=True)

    # Load the DECam photometry
    decam = load_data('../data/decam_apw.fits')

    iso = MIST_Isochrone(['PanSTARRS_g', 'PanSTARRS_i', 'SkyMapper_u'])

    row = decam[index]
    name = 'lmcla-{0}-'.format(row['index'])
    model_file = '../cache/starmodels-{0}.hdf5'.format(str(row['index']))

    if path.exists(model_file) and not overwrite:
        print('skipping {0} - already exists'.format(name))
        sys.exit(0)

    # This is our "anchor star": it was identified as being near the turnoff,
    # bright, and positionally consistent with being in the LA cluster:
    j1, = np.where(decam['index'] == 24365)[0]
    j2 = index

    if j1 == j2:
        print('skipping anchor-anchor pair')
        sys.exit(0)

    # To fit pairs as resolved binaries, we have to construct the observation
    # tree manually:
    tree = ObservationTree()
    for b in ['PanSTARRS_g', 'PanSTARRS_i', 'SkyMapper_u']:
        survey, band = b.split('_')

        if band == 'u' and decam[band.capitalize() + 'MAG'][j2] > 21:
            extra_s = 0.2
        else:
            extra_s = 0.005

        o = Observation(survey, b, 1.)
        s0 = Source(
            decam[band.capitalize() + 'MAG'][j1],
            np.sqrt(0.005**2 + decam[band.capitalize() + 'ERR'][j1]**2))
        s1 = Source(decam[band.capitalize() + 'MAG'][j2],
                    np.sqrt(extra_s**2 +
                            decam[band.capitalize() + 'ERR'][j2]**2),
                    separation=100.)
        o.add_source(s0)
        o.add_source(s1)
        tree.add_observation(o)

    model = StarModel(ic=iso, obs=tree, N=[1, 2])
    # model = StarModel(ic=iso, obs=tree)

    print('setting priors')
    dist_bounds = [1 * 1e3, 100 * 1e3]  # pc
    # model._priors['distance'] = FlatPrior(dist_bounds)
    model._priors['distance'] = GaussianPrior(30 * 1e3,
                                              10 * 1e3,
                                              bounds=dist_bounds)
    model.set_bounds(distance=dist_bounds)  # 1 to 100 kpc

    feh_bounds = (-2., 0.5)
    model.set_bounds(feh=feh_bounds)
    # model._priors['feh'] = FlatPrior(feh_bounds)
    model._priors['feh'] = GaussianPrior(-1.1, 0.5, bounds=feh_bounds)

    AV_bounds = (0, 1)
    model.set_bounds(AV=AV_bounds)
    model._priors['AV'] = PowerLawPrior(-1.1, (1e-3, 1))
    # model._priors['AV'] = GaussianPrior(0.2, 0.1, bounds=AV_bounds)

    age_bounds = (7, 9.5)
    model.set_bounds(age=age_bounds)
    # model._priors['age'] = GaussianPrior(8, 0.5, bounds=age_bounds)
    model._priors['age'] = FlatPrior(age_bounds)

    print('sampling star {0}'.format(row['index']))
    model.fit_multinest(basename=name,
                        refit=overwrite,
                        overwrite=overwrite,
                        n_live_points=2048)
    # model.fit_mcmc(nwalkers=nwalkers,
    #                p0=np.array([350., 8., -0.5, 30000., 0.1]),
    #                nburn=1024, niter=2048)
    model.save_hdf(model_file)

    fig = model.corner_physical()
    fig.savefig('../plots/isochrones/{0}-physical.png'.format(row['index']),
                dpi=200)
    plt.close(fig)

    fig = model.corner_observed()
    fig.savefig('../plots/isochrones/{0}-observed.png'.format(row['index']),
                dpi=200)
    plt.close(fig)

    # model._samples = model.samples[::1024]
    # model.save_hdf(sm_model_file)

    sys.exit(0)
コード例 #5
0
    #=============== Observations =======================
    for true, obs, unc in zip(list_mod, list_obs, list_unc):
        if np.isfinite(datum[obs]):
            params[true] = (datum[obs], datum[unc])
    #======================================================

    #------ Start the model ---------------------
    model = SingleStarModel(mist, **params)

    model.mnest_basename = dir_chain + str(ID) + "-"

    #--------- Prior -------------------
    model.set_prior(age=AgePrior(),
                    AV=GaussianPrior(prior_Av["loc"],
                                     prior_Av["scale"],
                                     bounds=(prior_Av["lower"],
                                             prior_Av["upper"])),
                    distance=GaussianPrior(prior_distance["loc"],
                                           prior_distance["scale"],
                                           bounds=(prior_distance["lower"],
                                                   prior_distance["upper"])))

    #------ Fit ---------------------------------
    model.fit(n_live_points=1000, verbose=False)
    #-------------------------------------------

    #------ Statistics -------
    mean = model.derived_samples.mean()
    stds = model.derived_samples.std()

    row = {identifier: str(ID)}
コード例 #6
0
ファイル: isochrone.py プロジェクト: zzxihep/astroARIADNE
def estimate(bands, params, logg=True, out_folder='.'):
    """Estimate logg using MIST isochrones."""
    mist = get_ichrone('mist', bands=bands)
    model = SingleStarModel(mist, **params)
    if 'distance' in params.keys():
        dist, dist_e = params['distance']
    elif 'parallax' in params.keys():
        dist = 1 / (params['parallax'][0] * 0.001)
        dist_e = dist * params['parallax'][1] / params['parallax'][0]
    else:
        msg = 'No parallax or distance found.'
        msg += 'Aborting age and mass calculation.'
        InputError(msg).warn()
        return np.zeros(10), np.zeros(10)
    if 'feh' in params.keys():
        fe, fe_e = params['feh']
        if fe + fe_e >= 0.5:
            model._priors['feh'] = FlatPrior([-0.5, 0.5])
        else:
            model._priors['feh'] = GaussianPrior(fe, fe_e)
    if 'mass' in params.keys():
        m, m_e = params['mass']
        model._priors['mass'] = GaussianPrior(m, m_e)
    if 'AV' in params.keys():
        av, av_e = params['AV']
        model._priors['AV'] = GaussianPrior(av, av_e)
    model._priors['distance'] = GaussianPrior(dist, dist_e)
    sampler = dynesty.NestedSampler(
        loglike, prior_transform, model.n_params + len(bands),
        nlive=500, bound='multi', sample='rwalk',
        logl_args=([model, params, bands]),
        ptform_args=([model])
    )
    try:
        sampler.run_nested(dlogz=0.01)
    except ValueError as e:
        dump_out = f'{out_folder}/isochrone_DUMP.pkl'
        pickle.dump(sampler.results, open(dump_out, 'wb'))
        DynestyError(dump_out, 'isochrone', e).__raise__()
    results = sampler.results
    samples = resample_equal(
        results.samples, np.exp(results.logwt - results.logz[-1])
    )
    ###########################################################################
    # Written by Dan Foreman-mackey
    # https://github.com/dfm/gaia-isochrones
    df = model._samples = pd.DataFrame(
        dict(
            zip(
                list(model.param_names),
                samples.T,
            )
        )
    )
    model._derived_samples = model.ic(
        *[df[c].values for c in model.param_names])
    model._derived_samples["parallax"] = 1000.0 / df["distance"]
    model._derived_samples["distance"] = df["distance"]
    model._derived_samples["AV"] = df["AV"]
    ###########################################################################
    if logg:
        samples = model._derived_samples['logg']
        med, lo, up = credibility_interval(samples, 5)
        med_e = max([med - lo, up - med])
        return med, med_e
    else:
        age_samples = 10 ** (model._derived_samples['age'] - 9)
        mass_samples = model._derived_samples['mass']
        eep_samples = model._derived_samples['eep']
        return age_samples, mass_samples, eep_samples