示例#1
0
def integrated(epos, MCMC=False, Planets=False):
	
	f, (ax, axb) = plt.subplots(1,2, gridspec_kw = {'width_ratios':[20, 1]})
	f.subplots_adjust(wspace=0)
	
	sy= 'M' if (epos.MassRadius or epos.RV) else 'R'
	ax.set_title('Occurrence'+ (' (dln'+sy+' dlnP)' if MCMC else ' (Initial Guess)'))
	
	helpers.set_axes(ax, epos, Trim=True, In=epos.MassRadius)
	
	''' color scale? '''
	cmap='jet' # cool, spring
	vmin, vmax= -5, 0
	ticks=np.linspace(vmin, vmax, (vmax-vmin)+1)
	levels=np.linspace(vmin, vmax, 256)
	
	''' 2D pdf '''
	pps, pdf, _, _= periodradius(epos, Init=not MCMC)
	pdflog= np.log10(pdf) # in %
	cs= ax.contourf(epos.X_in, epos.Y_in, pdflog, cmap=cmap, levels=levels)
	cbar= f.colorbar(cs, cax=axb, ticks=ticks)
	axb.set_yticklabels(100*10.**ticks)
	axb.tick_params(axis='y', direction='out')
	axb.set_title('%')
	
	''' integrated occurrence per bin'''
	occbin= epos.occurrence['bin']
	key = 'eta' if MCMC else 'eta0'
	for k, (xbin, ybin, n, inbin, occ) in enumerate(
			zip(occbin['x'],occbin['y in'],occbin['n'],occbin['i'], occbin[key])
			):
		clr= clrs[k%4]
	
		# colored dots
		#ax.plot(epos.obs_xvar[inbin], epos.obs_yvar[inbin], 
		#	ls='', marker='.', mew=0, ms=5.0, color=clr, zorder=1)
	
		# box
		ax.add_patch(patches.Rectangle( (xbin[0],ybin[0]), 
			xbin[1]-xbin[0], ybin[1]-ybin[0],
			fill=False, zorder=2, ls='-', color='k') )
	
		xnudge=1.01
		ynudge=1.02
		size=16 if not 'textsize' in epos.plotpars else epos.plotpars['textsize'] 
				# 12 fit in box, 16 default
		ax.text(xbin[0]*xnudge,ybin[1]/ynudge,'{:.1%}'.format(occ), va='top',size=size)
		if MCMC:
			ax.text(xbin[0]*xnudge,ybin[1]/ynudge,'\n +{:.1%}\n  -{:.1%}'.format(
				occbin['eta+'][k],occbin['eta-'][k]
				), va='top',size=size)

	''' overplot planets '''
	if Planets:
		ax.plot(epos.obs_xvar, epos.obs_yvar, 
			ls='', marker='.', mew=0, ms=5, alpha=1, color='k')

	fname= 'posterior' if MCMC else 'integrated'
	if Planets: fname+= '.planets'
	helpers.save(plt, epos.plotdir+'occurrence/'+fname)
示例#2
0
def twoD(epos, PlotZoom=False, MCMC=False):

    # where does this go -> run.py
    assert epos.Parametric
    if not epos.Range: epos.set_ranges()

    # pdf
    pps, pdf, _, _ = periodradius(epos, Init=not MCMC)
    pdflog = np.log10(pdf)  # in %

    f, (ax, axb) = plt.subplots(1, 2, gridspec_kw={'width_ratios': [20, 1]})
    f.subplots_adjust(wspace=0)

    ax.set_title('Occurrence [%] / d ln p d ln ' +
                 ('M' if epos.MassRadius else 'R'))
    helpers.set_axes(ax, epos, Trim=True, In=epos.MassRadius)
    ''' color scale? '''
    cmap = 'jet'
    vmin, vmax = -5, 0
    ticks = np.linspace(vmin, vmax, (vmax - vmin) + 1)
    levels = np.linspace(vmin, vmax)
    ax.contourf(epos.X_in, epos.Y_in, pdflog, cmap=cmap, levels=levels)

    # colorbar?
    norm = Normalize(vmin=vmin, vmax=vmax)
    cb1 = clrbar.ColorbarBase(axb,
                              cmap=cmap,
                              norm=norm,
                              ticks=ticks,
                              orientation='vertical')  # horizontal
    axb.set_yticklabels(100 * 10.**ticks)
    axb.tick_params(axis='y', direction='out')

    fname = 'mcmc/posterior' if MCMC else 'input/parametric_initial'
    helpers.save(plt, epos.plotdir + fname)
示例#3
0
def _posterior_per_bin(epos, xbins, ybins, Verbose=True):
    eta, gamma, area = [], [], []
    pos, sigp, sign = [], [], []

    for xbin, ybin in zip(xbins, ybins):
        area.append(np.log(xbin[1] / xbin[0]) * np.log(ybin[1] / ybin[0]))
        _, pdf, _, _ = periodradius(epos, Init=True, xbin=xbin, ybin=ybin)
        gamma.append(np.average(pdf))
        eta.append(gamma[-1] * area[-1])

        if Verbose:
            print '  x: [{:.3g},{:.3g}], y: [{:.2g},{:.2g}], area={:.2f}, eta_0={:.2g}'.format(
                xbin[0], xbin[-1], ybin[0], ybin[-1], area[-1], eta[-1])
        ''' Posterior?'''
        if hasattr(epos, 'samples'):
            posterior = []
            if epos.Parallel:
                pool = multiprocessing.Pool()
                one_arg_func = partial(_posterior, epos, xbin=xbin, ybin=ybin)
                posterior = pool.map(one_arg_func, epos.samples)
            else:
                for sample in epos.samples:
                    _, pdf, _, _ = periodradius(epos,
                                                fpara=sample,
                                                xbin=xbin,
                                                ybin=ybin)
                    posterior.append(np.average(pdf))

            #pos= np.percentile(posterior, [16, 50, 84])
            perc = np.percentile(posterior, [2.3, 15.9, 50., 84.1, 97.7])
            pos.append(perc[2])
            sigp.append(perc[3] - perc[2])
            sign.append(perc[2] - perc[1])
            sig2p = (perc[4] - perc[2])
            sig2n = (perc[2] - perc[0])

            if Verbose:
                print '  gamma= {:.1%} +{:.1%} -{:.1%}'.format(
                    pos[-1], sigp[-1], sign[-1])
                print '  eta= {:.1%} +{:.1%} -{:.1%}'.format(
                    pos[-1] * area[-1], sigp[-1] * area[-1],
                    sign[-1] * area[-1])
                #print '  gamma 2sig= {:.1%} +{:.1%} -{:.1%}'.format(_pos[-1],sig2p,sig2n)

    return eta, gamma, area, pos, sigp, sign
示例#4
0
def panels(epos, PlotZoom=False, MCMC=False):
    ''' Initial distribution, panel layout'''
    f, (ax, axb, axR, axP) = helpers.make_panels_clrbar(plt)

    # pdf
    pps, pdf, pdf_X, pdf_Y = periodradius(epos, Init=not MCMC)
    pdflog = np.log10(pdf)  # in %

    ax.set_title('Planet Occurrence / dlnP dln' +
                 ('M' if epos.MassRadius else 'R'))
    helpers.set_axes(ax, epos, Trim=True, In=epos.MassRadius)

    # Side panels
    axP.plot(epos.MC_xvar, pdf_X, marker='', ls='-', color='k')
    axR.plot(pdf_Y, epos.in_yvar, marker='', ls='-', color='k')

    #helpers.set_axis_distance(axP, epos, Trim=True)
    #helpers.set_axis_size(axR, epos, Trim=True, In= epos.MassRadius)
    axP.set_xlabel(ax.get_xlabel())
    axR.set_ylabel(ax.get_ylabel())

    axP.set_yscale('log')
    axP.set_ylim([2e-3, 5])
    axP.set_yticks([0.01, 0.1, 1])
    axP.set_yticklabels(['1%', '10%', '100%'])
    axP.yaxis.tick_right()
    axP.yaxis.set_ticks_position('both')
    axP.tick_params(axis='y', which='minor', left=False, right=False)

    axR.set_xscale('log')
    axR.set_xlim([2e-3, 5])
    axR.set_xticks([0.01, 0.1, 1])
    axR.set_xticklabels(['1%', '10%', '100%'], rotation=70)
    axR.tick_params(axis='x', which='minor', top=False, bottom=False)
    axP.tick_params(axis='y', which='minor', left=False, right=False)
    axP.tick_params(axis='y', which='major', left=False, right=True)
    ''' color scale? '''
    cmap = 'jet'
    vmin, vmax = -5, 0
    ticks = np.linspace(vmin, vmax, (vmax - vmin) + 1)
    levels = np.linspace(vmin, vmax)
    ax.contourf(epos.X_in, epos.Y_in, pdflog, cmap=cmap, levels=levels)

    # colorbar?
    norm = Normalize(vmin=vmin, vmax=vmax)
    cb1 = clrbar.ColorbarBase(axb,
                              cmap=cmap,
                              norm=norm,
                              ticks=ticks,
                              orientation='vertical')  # horizontal
    axb.set_yticklabels(100 * 10.**ticks)
    axb.tick_params(axis='y', direction='out')
    axb.set_title('%')

    helpers.save(plt, epos.plotdir + 'input/panels')
示例#5
0
def _posterior(epos, sample, xbin, ybin):
    _, pdf, _, _ = periodradius(epos, fpara=sample, xbin=xbin, ybin=ybin)
    return np.average(pdf)
示例#6
0
def panels_mass(epos, Population=False, color='C1'):
    f, (ax, axM, axP) = helpers.make_panels(plt)
    pfm = epos.pfm
    eta = epos.modelpars.get('eta', Init=True)
    ''' Bins '''
    dw = 0.5  # bin width in ln space
    xbins = np.exp(
        np.arange(np.log(pfm['P limits'][0]),
                  np.log(pfm['P limits'][-1]) + dw, dw))
    ybins = np.exp(
        np.arange(np.log(pfm['M limits'][0]),
                  np.log(pfm['M limits'][-1]) + dw, dw))
    ''' Posterior '''
    if Population:
        assert hasattr(epos, 'func')
        fname = '.pop'

        # side panels marginalized over M and P limits
        pps, pdf, pdf_X, pdf_Y = periodradius(epos, Init=True)
        _, _, pdf_X, _ = periodradius(epos, Init=True, ybin=ybins)
        _, _, _, pdf_Y = periodradius(epos, Init=True, xbin=xbins)
        pps, _, _, _ = periodradius(epos, Init=True, xbin=xbins, ybin=ybins)
        #pdf/= np.max(pdf)
        #pdflog= np.log10(pdf) # in %
        levels = np.linspace(0, np.max(pdf))
        lines = np.array([0.1, 0.5]) * np.max(pdf)

        ax.contourf(epos.X_in, epos.Y_in, pdf, cmap='Purples', levels=levels)
        #ax.contour(epos.X_in, epos.Y_in, pdf, levels=lines)

        # Side panels
        #print 'pps model= {}'.format(eta)
        scale = dw
        axP.plot(epos.MC_xvar,
                 pdf_X * scale,
                 marker='',
                 ls='-',
                 color='purple')
        axM.plot(pdf_Y * scale,
                 epos.in_yvar,
                 marker='',
                 ls='-',
                 color='purple')
    else:
        fname = ''
    ''' plot main panel'''
    ax.set_title(epos.name)
    #helpers.set_axes(ax, epos, Trim=True)

    ax.set_xscale('log')
    ax.set_yscale('log')
    #ax.set_xlim(epos.mod_xlim)
    #ax.set_ylim(epos.mod_ylim)

    ax.plot(pfm['P'], pfm['M'], color=color, **fmt_symbol)
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()
    ''' Period side panel '''
    #axP.yaxis.tick_right()
    #axP.yaxis.set_ticks_position('both')
    #axP.tick_params(axis='y', which='minor',left='off',right='off')

    axP.set_xscale('log')
    axP.set_xlim(xlim)
    #ax.set_xlabel('Semi-Major Axis [au]')
    axP.set_xlabel('Orbital Period [days]')

    axP.hist(pfm['P'],
             color=color,
             bins=xbins,
             weights=np.full(pfm['np'], eta / pfm['np']))
    ''' Mass side panel'''
    #helpers.set_axis_size(axR, epos, Trim=True) #, In= epos.MassRadius)
    axM.set_ylabel(r'Planet Mass [M$_\bigoplus$]')
    axM.set_yscale('log')
    axM.set_ylim(ylim)

    axM.hist(pfm['M'],
             bins=ybins,
             orientation='horizontal',
             weights=np.full(pfm['np'], eta / pfm['np']),
             color=color)

    helpers.save(plt, '{}model/input.mass{}'.format(epos.plotdir, fname))
示例#7
0
def panels_radius(epos,
                  Population=False,
                  Occurrence=False,
                  Observation=False,
                  Tag=False,
                  color='C0',
                  clr_obs='C3',
                  Shade=True,
                  Fancy=True,
                  Zoom=False):
    f, (ax, axR, axP) = helpers.make_panels(plt, Fancy=Fancy)
    pfm = epos.pfm
    eta = epos.modelpars.get('eta', Init=True)

    title = ''
    if not 'R' in pfm:
        pfm['R'], _ = epos.MR(pfm['M'])

    if Tag:
        # function that return a simulation subset based on the tag
        subset = {
            'Fe/H<=0': lambda tag: tag <= 0,
            'Fe/H>0': lambda tag: tag > 0
        }
    ''' Bins '''
    dwR = 0.2  # bin width in ln space
    dwP = 0.3
    if Zoom:
        xbins = np.exp(
            np.arange(np.log(epos.xzoom[0]),
                      np.log(epos.xzoom[-1]) + dwP, dwP))
        ybins = np.exp(
            np.arange(np.log(epos.yzoom[0]),
                      np.log(epos.yzoom[-1]) + dwR, dwR))
    else:
        xbins = np.exp(
            np.arange(np.log(epos.xtrim[0]),
                      np.log(epos.xtrim[-1]) + dwP, dwP))
        ybins = np.exp(
            np.arange(np.log(epos.ytrim[0]),
                      np.log(epos.ytrim[-1]) + dwR, dwR))
    ''' Plot model occurrence or observed counts'''
    if Observation:
        # plot model planets * completeness
        weights = eta * epos.occurrence['model']['completeness'] / pfm['ns']
    else:
        weights = np.full(pfm['np'], eta / pfm['ns'])

    if 'draw prob' in pfm and not Tag:
        prob = pfm['draw prob'][pfm['ID']]
        weights *= prob * pfm['ns']  # system weights sum up to 1
        #nonzero= np.where(prob>0, 1., 0.)
        #weights*= nonzero*(pfm['np']/nonzero.sum())

    # histograms
    if Tag:
        for key, f in subset.iteritems():
            toplot = f(pfm['tag'])
            #weights= eta*epos.occurrence['model']['completeness'] \
            #		*np.where(toplot,1.,0.)/f(pfm['system tag']).sum()
            weights = np.where(toplot, eta, 0.) / f(pfm['system tag']).sum()
            axP.hist(pfm['P'],
                     bins=xbins,
                     weights=weights,
                     histtype='step',
                     label=key)
            axR.hist(pfm['R'],
                     bins=ybins,
                     orientation='horizontal',
                     weights=weights,
                     histtype='step')
    else:
        # color have to be 1-element lists ??
        axP.hist(pfm['P'], bins=xbins, weights=weights, color=[color])
        axR.hist(pfm['R'],
                 bins=ybins,
                 orientation='horizontal',
                 weights=weights,
                 color=[color])
    ''' Overplot observations? '''
    if Population:
        assert hasattr(epos, 'func')
        fname = '.pop' + ('.zoom' if Zoom else '')

        title = epos.title

        pps, pdf, pdf_X, pdf_Y = periodradius(epos, Init=True)
        _, _, pdf_X, _ = periodradius(epos, Init=True, ybin=ybins)
        _, _, _, pdf_Y = periodradius(epos, Init=True, xbin=xbins)
        pps, _, _, _ = periodradius(epos, Init=True, xbin=xbins, ybin=ybins)
        #pdf/= np.max(pdf)
        #pdflog= np.log10(pdf) # in %
        levels = np.linspace(0, np.max(pdf))
        lines = np.array([0.1, 0.5]) * np.max(pdf)

        if Shade:
            ax.contourf(epos.X_in,
                        epos.Y_in,
                        pdf,
                        cmap='Purples',
                        levels=levels)
            #ax.contour(epos.X_in, epos.Y_in, pdf, levels=lines)

            # Side panels
            #print 'pps model= {}'.format(eta)
            axP.plot(epos.MC_xvar,
                     pdf_X * dwP,
                     marker='',
                     ls='-',
                     color='purple')
            axR.plot(pdf_Y * dwR,
                     epos.in_yvar,
                     marker='',
                     ls='-',
                     color='purple')
        else:
            # renormalize
            xnorm = axP.get_ylim()[1] / max(pdf_X)
            ynorm = axR.get_xlim()[1] / max(pdf_Y)

            axP.plot(epos.MC_xvar,
                     pdf_X * xnorm,
                     marker='',
                     ls='-',
                     color=clr_obs)
            axR.plot(pdf_Y * ynorm,
                     epos.in_yvar,
                     marker='',
                     ls='-',
                     color=clr_obs)

    elif Observation:
        fname = '.obs' + ('.zoom' if Zoom else '')

        title = epos.title + ': Counts'

        ax.plot(epos.obs_xvar,
                epos.obs_yvar,
                ls='',
                marker='.',
                ms=5.0,
                color='0.5')

        weights = np.full(epos.obs_xvar.size, 1. / epos.nstars)
        axP.hist(epos.obs_xvar,
                 bins=xbins,
                 weights=weights,
                 histtype='step',
                 color='0.5')
        axR.hist(epos.obs_yvar,
                 bins=ybins,
                 weights=weights,
                 orientation='horizontal',
                 histtype='step',
                 color='0.5')

    elif Occurrence:
        fname = '.occ' + ('.zoom' if Zoom else '')
        title = epos.title + r': Occurrence, $\eta={:.2g}$'.format(eta)

        ax.plot(epos.obs_xvar,
                epos.obs_yvar,
                ls='',
                marker='.',
                ms=5.0,
                color='0.5')

        cut = epos.obs_yvar > 0.45

        weights = 1. / (epos.occurrence['planet']['completeness'][cut] *
                        epos.nstars)
        axP.hist(epos.obs_xvar[cut],
                 bins=xbins,
                 weights=weights,
                 histtype='step',
                 color='k')
        axR.hist(epos.obs_yvar[cut],
                 bins=ybins,
                 weights=weights,
                 orientation='horizontal',
                 histtype='step',
                 color='k')

    elif Tag:
        fname = '.tag'
        ax.set_title(epos.title + ': Tag')

        axP.legend(frameon=False, fontsize='small')
        # 		for k, tag in enumerate(subset):
        # 			axP.text(0.98,0.95-0.05*k,tag,ha='right',va='top',color='C1',
        # 				transform=axP.transAxes)

    else:
        fname = ''

    if Fancy:
        plt.suptitle(title, ha='center')  #, x=0.05)
    else:
        ax.set_title(title)
    ''' plot main panel'''
    #helpers.set_axes(ax, epos, Trim=True)

    helpers.set_axes(ax, epos, Trim=True)
    if Tag:
        for key, f in subset.iteritems():
            todraw = f(pfm['tag'])
            ax.plot(pfm['P'][todraw], pfm['R'][todraw], **fmt_symbol)
    elif 'draw prob' in pfm:
        #fmt_symbol['alpha']= 0.6*pfm['draw prob'][pfm['ID']] # alpha can't be array
        todraw = pfm['draw prob'][pfm['ID']] > 0
        ax.plot(pfm['P'][todraw], pfm['R'][todraw], color=color, **fmt_symbol)
    else:
        ax.plot(pfm['P'], pfm['R'], color=color, **fmt_symbol)
    ''' Period side panel '''
    #axP.yaxis.tick_right()
    #axP.yaxis.set_ticks_position('both')
    #axP.tick_params(axis='y', which='minor',left='off',right='off')
    helpers.set_axis_distance(axP, epos, Trim=True)
    ''' Mass side panel'''
    helpers.set_axis_size(axR, epos, Trim=True)  #, In= epos.MassRadius)

    helpers.save(plt, '{}model/input.radius{}'.format(epos.plotdir, fname))
示例#8
0
文件: run.py 项目: dsavransky/epos
def mcmc(epos,
         nMC=500,
         nwalkers=100,
         dx=0.1,
         nburn=50,
         threads=1,
         npos=30,
         Saved=True):
    if not 'emcee' in sys.modules:
        raise ImportError('You need to install emcee')
    assert epos.Prep

    runonce = MC if epos.MonteCarlo else noMC
    ''' set starting parameters '''
    fpara = epos.fitpars.getfit(Init=True)

    if not len(fpara) > 0: raise ValueError('no fit paramaters defined')
    ''' Load previous chain?'''
    ndim = len(fpara)
    shape = (nwalkers, nMC, ndim)

    # store, npy is uncompressed, savez returns as dict instead of array
    dir = 'chain/{}'.format(epos.name)
    fname = '{}/{}x{}x{}.npz'.format(dir, nwalkers, nMC, ndim)
    if not os.path.exists(dir): os.makedirs(dir)

    if os.path.isfile(fname) and Saved:
        print '\nLoading saved status from {}'.format(fname)
        npz = np.load(fname)

        epos.chain = npz['chain']
        assert epos.chain.shape == (nwalkers, nMC, ndim)

        if epos.seed != npz['seed']:
            print '\nNOTE: Random seed changed: {} to {}'.format(
                npz['seed'], epos.seed)
        epos.seed = npz['seed']

        # check if same keys (not very flexible)
        if 'fitkeys' in npz:
            for loadkey, key in zip(npz['fitkeys'], epos.fitpars.keysfit):
                if loadkey != key:
                    raise ValueError('Stored key {} doesnt match {}'.format(
                        loadkey, key))
    else:
        ''' start the timer '''
        tstart = time.time()
        nsims = nMC * nwalkers
        runtime = (epos.tMC / 3600.) * nsims  # single-threaded run time
        print '\nPredicted runtime:'
        if runtime > 1:
            print '  {:.3f} hours for {} runs at {:.3f} sec'.format(
                runtime, nsims, epos.tMC)
        else:
            print '  {:.1f} minutes for {} runs at {:.3f} sec'.format(
                runtime * 60., nsims, epos.tMC)
        if threads > 1:
            if runtime / threads > 1:
                print '  {:.3f} hours at 100% scaling'.format(runtime /
                                                              threads)
            else:
                print '  {:.1f} minutes at 100% scaling'.format(runtime /
                                                                threads * 60.)
        ''' Set up a log file '''
        # Note: if logging.debug is called before this, the log file is never created
        fdir = 'log/{}'.format(epos.name)
        if not os.path.exists(fdir): os.makedirs(fdir)
        flog = '{}/{}.log'.format(fdir, time.strftime('%Y-%m-%d_%H.%M.%S'))
        logging.basicConfig(filename=flog, level=logging.DEBUG, filemode='w')
        logging.info('MCMC with random seed {}'.format(epos.seed))
        ''' Wrap function '''
        lnmc = partial(runonce, epos, Verbose=False)
        ''' Set up the MCMC walkers '''
        #p0 = [np.array(fpara)*np.random.uniform(1.-dx,1+dx,len(fpara))
        #		for i in range(nwalkers)]
        dx = np.array(epos.fitpars.getfit(attr='dx'))
        p0 = [
            np.array(fpara) + dx * np.random.uniform(-1, 1, len(fpara))
            for i in range(nwalkers)
        ]
        sampler = emcee.EnsembleSampler(nwalkers,
                                        len(fpara),
                                        lnmc,
                                        threads=threads)
        ''' run the chain '''
        if True:
            # chop to pieces for progress bar?
            for i, result in enumerate(sampler.sample(p0, iterations=nMC)):
                amtDone = float(i) / nMC
                print '\r  [{:50s}] {:5.1f}%'.format('#' * int(amtDone * 50),
                                                     amtDone * 100),
                os.sys.stdout.flush()
        else:
            sampler.run_mcmc(p0, nMC)

        print '\nDone running\n'
        logging.info('Made it to the end')
        print 'Mean acceptance fraction: {0:.3f}'.format(
            np.mean(sampler.acceptance_fraction))
        ''' Print run time'''
        tMC = time.time()
        runtime = tMC - tstart
        if runtime > 3600:
            print '  Runtime was {:.3f} hours at {:.3f} sec'.format(
                runtime / 3600, (tMC - tstart) / nsims)
        else:
            print '  Runtime was {:.1f} minutes at {:.3f} sec'.format(
                runtime / 60., (tMC - tstart) / nsims)

        epos.chain = sampler.chain
        print 'Saving status in {}'.format(fname)
        #np.save(fname, epos.chain)
        # compression slow on loading?
        np.savez_compressed(fname,
                            chain=epos.chain,
                            seed=epos.seed,
                            keys=epos.fitpars.keysfit)
    ''' the posterior samples after burn-in '''
    epos.samples = epos.chain[:, nburn:, :].reshape((-1, ndim))
    epos.burnin = nburn
    fitpars = map(lambda v: (v[1], v[2] - v[1], v[1] - v[0]),
                  zip(*np.percentile(epos.samples, [16, 50, 84], axis=0)))
    epos.fitpars.setfit([p[0] for p in fitpars])
    ''' Generate posterior populations '''
    if npos is not None:
        epos.plotsample = epos.samples[np.random.randint(len(epos.samples),
                                                         size=npos)]
        # run & store
        print '\nMC-ing the {} samples to plot'.format(npos)
        epos.ss_sample = []
        for fpara in epos.plotsample:
            epos.ss_sample.append(\
             runonce(epos, fpara, Store=True, Sample=True, Verbose=False))
        # parallel
        # return & store in structure
    ''' Estimate Solar System Analogs'''
    if epos.Parametric and epos.Multi:
        fMercury = []
        fVenus = []
        for sample in epos.samples:
            _, _, xpdf, _ = periodradius(epos, fpara=sample)
            fMercury.append(np.sum(xpdf[epos.MC_xvar > 88.]) / np.sum(xpdf))
            fVenus.append(np.sum(xpdf[epos.MC_xvar > 225.]) / np.sum(xpdf))

        print
        for name, posterior in zip(['Mercury', 'Venus'], [fMercury, fVenus]):
            eta = np.percentile(posterior, [16, 50, 84])
            print '{} analogues < {:.1%} +{:.1%} -{:.1%}'.format(
                name, eta[1], eta[2] - eta[1], eta[1] - eta[0])
            UL = np.percentile(posterior, [68.2, 95.4, 99.7])
            for i in range(3):
                print '  {} sigma UL {:.1%}'.format(i + 1, UL[i])
    ''' Best-fit values'''
    print '\nBest-fit values'
    for pname, fpar in zip(epos.fitpars.keysfit, fitpars):
        print '  {}= {:.3g} +{:.3g} -{:.3g}'.format(pname, *fpar)

    print '\nStarting the best-fit MC run'
    runonce(epos, np.array([p[0] for p in fitpars]), Store=True)
示例#9
0
文件: run.py 项目: dsavransky/epos
def noMC(epos,
         fpara,
         Store=False,
         Sample=False,
         StorePopulation=False,
         Extra=None,
         Verbose=True):
    ''' 
	Do the Simulations without Monte Carlo
	'''
    if Verbose: tstart = time.time()
    #if not Store: logging.debug(' '.join(['{:.3g}'.format(fpar) for fpar in fpara]))

    if epos.Multi: raise ValueError('Multi-planets need Monte Carlo (?)')
    if not epos.Parametric:
        raise ValueError('Planet Formation models need Monte Carlo (?)')
    ''' parameters within bounds? '''
    try:
        epos.pdfpars.checkbounds(fpara)
    except ValueError as message:
        if Store: raise
        else:
            logging.debug(message)
            return -np.inf
    ''' Generate observable period-radius distribution, in counts'''
    if epos.RV:
        pps, pdf, pdf_X, pdf_Y = periodradius(epos,
                                              fpara=fpara,
                                              fdet=epos.MC_eff * epos.nstars)
    elif epos.MassRadius:
        raise ValueError('Generate pdf on radius grid here')
    else:
        pps, pdf, pdf_X, pdf_Y = periodradius(epos,
                                              fpara=fpara,
                                              fdet=epos.f_det * epos.nstars)
    '''
	Probability that simulated data matches observables
	'''
    tstart = time.time()
    prob = {}
    lnp = {}

    pdf_x = np.interp(epos.noMC_zoom_x, epos.MC_xvar, pdf_X)
    pdf_y = np.interp(epos.noMC_zoom_y, epos.MC_yvar, pdf_Y)
    cdf_x = np.cumsum(pdf_x)
    cdf_y = np.cumsum(pdf_y)
    cdf_x /= cdf_x[-1]
    cdf_y /= cdf_y[-1]
    ''' Wrap functions '''
    func_cdf_X = partial(np.interp,
                         xp=epos.noMC_zoom_x,
                         fp=cdf_x,
                         left=0,
                         right=0)
    func_cdf_Y = partial(np.interp,
                         xp=epos.noMC_zoom_y,
                         fp=cdf_y,
                         left=0,
                         right=0)

    prob['xvar'], lnp['xvar'] = _prob_ks_func(epos.obs_zoom['x'], func_cdf_X)
    prob['yvar'], lnp['yvar'] = _prob_ks_func(epos.obs_zoom['y'], func_cdf_Y)

    #nobs= int(pdf[epos.trim_to_zoom].sum())
    nobs_x = int(np.sum(pdf_x) / epos.noMC_scale_x)
    nobs_y = int(np.sum(pdf_y) / epos.noMC_scale_y)
    nobs = int(np.sqrt(nobs_x * nobs_y))
    if Verbose: print 'nobs={} (x:{},y:{})'.format(nobs, nobs_x, nobs_y)  # ??

    chi2 = (epos.obs_zoom['x'].size - nobs)**2. / epos.obs_zoom['x'].size
    lnp['N'] = -0.5 * chi2
    prob['N'] = np.exp(-0.5 * chi2)

    prob_keys = ['N', 'xvar', 'yvar']

    # combine with Fischer's rule:
    lnprob = np.sum([lnp[key] for key in prob_keys])
    #dof= len(prob_keys)
    chi_fischer = -2. * lnprob

    if Verbose:
        print '\nGoodness-of-fit'
        print '  logp= {:.1f}'.format(lnprob)
        print '  - p(n={})={:.2g}'.format(nobs, prob['N'])
        print '  - p(x)={:.2g}'.format(prob['xvar'])
        print '  - p(y)={:.2g}'.format(prob['yvar'])

    tgof = time.time()
    if Verbose:
        print '  observation comparison in {:.3f} sec'.format(tgof - tstart)
    ''' Store detectable planet population '''
    if Store:
        ss = {}
        ss['nobs'] = nobs

        ss['pdf'] = pdf

        ss['P'] = epos.MC_xvar
        ss['P pdf'] = pdf_X

        ss['Y'] = epos.MC_yvar
        ss['Y pdf'] = pdf_Y

        ss['P zoom'] = epos.noMC_zoom_x
        ss['P zoom pdf'] = pdf_x  # /scale?
        ss['P zoom cdf'] = cdf_x

        ss['Y zoom'] = epos.noMC_zoom_y
        ss['Y zoom pdf'] = pdf_y  # /scale?
        ss['Y zoom cdf'] = cdf_y

        epos.prob = prob
        epos.lnprob = lnprob

        if Sample:
            return ss
        elif Extra is not None:
            ss['name'] = Extra
            if not hasattr(epos, 'ss_extra'):
                epos.ss_extra = []
            epos.ss_extra.append(ss)
            #print 'saving extra {}'.format(Extra)
        else:
            epos.synthetic_survey = ss
    else:
        ''' return probability '''
        if np.isnan(lnprob):
            return -np.inf
        return lnprob
示例#10
0
def oneD_x(epos, PlotZoom=False, MCMC=False, Occ=False, Log=True):

    if Occ:
        fname = 'occurrence/posterior' if MCMC else 'occurrence/input'
        ybin = epos.yzoom
        unit = r'$M_\bigoplus$' if epos.RV else r'$R_\bigoplus$'
        title = r'Planet Occurrence ({1:.1f}-{2:.0f} {0})'.format(
            unit, *epos.yzoom)
    else:
        fname = 'mcmc/posterior' if MCMC else 'input/parametric_initial'
        ybin = None
        title = r'Marginalized Distribution ({:.1f}-{:.0f} $R_\bigoplus$)'.format(
            *epos.ytrim)

    if not Log:
        fname += '.linear'

    # initial guess
    pps, _, pdf0_X, _ = periodradius(epos, Init=True, ybin=ybin)
    if MCMC:
        # best-fit parameters
        pps, _, pdf_X, _ = periodradius(epos, ybin=ybin)
    ''' construct the posterior parameters '''
    if MCMC:
        plotsample = epos.samples[np.random.randint(len(epos.samples),
                                                    size=100)]
    ''' Orbital Period '''
    f, ax = plt.subplots()
    ax.set_title(title)
    ax.set_ylabel('Occurrence / {}P'.format(epos.plotpars['area']))

    #ax.set_xlabel('Orbital Period [days]')
    #ax.set_xscale('log')
    #ax.set_xlim(epos.xtrim)
    helpers.set_axis_distance(ax, epos, Trim=True)

    if Log:
        ax.set_yscale('log')
        if 'occrange' in epos.plotpars:
            ax.set_ylim(epos.plotpars['occrange'])
        else:
            ax.set_ylim([1e-3, 1e1])
    else:
        ax.set_ylim([0, 0.45])

    if MCMC:
        for fpara in plotsample:
            _, _, xpdf, _ = periodradius(epos, fpara=fpara, ybin=ybin)
            ax.plot(epos.MC_xvar, xpdf, color='b', alpha=0.1)

        ax.plot(epos.MC_xvar,
                pdf0_X,
                marker='',
                ls=':',
                color='k',
                label='Starting Guess')
        ax.plot(epos.MC_xvar,
                pdf_X,
                marker='',
                ls='-',
                color='k',
                label='Best Fit')
    else:
        if 'P break' in epos.fitpars.keys2d:
            ax.axvline(epos.fitpars.get('P break', Init=True),
                       ls='-',
                       color='gray')
        ax.plot(epos.MC_xvar, pdf0_X, marker='', ls='-', color='k')

    # plot posterior excluding low detection regions (arbitrary 2000 planets assumed)
    if not (epos.RV or epos.MassRadius):
        cens = np.where(epos.f_det < 1. / 3000., 0, 1.)
        _, _, cens_pdf_X, _ = periodradius(epos, ybin=ybin, fdet=cens)
        ax.plot(epos.MC_xvar,
                cens_pdf_X,
                marker='',
                ls='-',
                color='green',
                label='biased')

    if epos.Zoom:
        for zoom in epos.xzoom:
            ax.axvline(zoom, ls='--', color='k')

    if Occ:
        occbin = epos.occurrence['yzoom']
        ax.errorbar(occbin['xc'],
                    occbin['occ'] / occbin['dlnx'],
                    yerr=occbin['err'] / occbin['dlnx'],
                    color='r',
                    marker='_',
                    ls='',
                    capsize=3)  #,capthick=2

    # lognormal inner disk edge?
    #from scipy.stats import norm
    #gauss= 2.*norm(loc=1., scale=0.4).pdf(np.log10(epos.MC_xvar))
    #ax.plot(epos.MC_xvar, gauss, ls='-', marker='', color='r')

    if not Log:
        if 'Pinner all' in epos.plotpars:
            xx = np.geomspace(20, 400)
            a, b, c = epos.plotpars['Pinner all']
            ax.plot(xx,
                    a * (xx / b)**c,
                    marker='',
                    ls='-',
                    color='g',
                    label='All Planets')
        if 'Pinner ylim' in epos.plotpars:
            ax.set_ylim(epos.plotpars['Pinner ylim'])

    if MCMC:
        ax.legend(loc='upper left')

    helpers.save(plt, epos.plotdir + fname + '_x')
示例#11
0
def oneD_y(epos, PlotZoom=False, MCMC=False, PlotQ=False, Occ=False):
    if Occ:
        fname = 'occurrence/posterior' if MCMC else 'occurrence/input'
        xbin = epos.xzoom
        title = 'Planet occurrence ({:.2g}-{:.0f} days)'.format(*epos.xzoom)

    else:
        fname = 'mcmc/posterior' if MCMC else 'input/parametric_initial'
        xbin = None
        title = 'Marginalized Distribution ({:.2g}-{:.0f} days)'.format(
            *epos.xtrim)

    # initial guess
    pps, _, _, pdf0_Y = periodradius(epos, Init=True, xbin=xbin)
    if MCMC:
        # best-fit parameters
        pps, _, _, pdf_Y = periodradius(epos, xbin=xbin)
    ''' construct the posterior parameters '''
    if MCMC:
        plotsample = epos.samples[np.random.randint(len(epos.samples),
                                                    size=100)]
    ''' Planet Radius, Mass, or q '''
    # TODO: zip into previous block
    f, ax = plt.subplots()
    ax.set_title(title)
    if PlotQ:
        ax.set_xlabel(r'Planet Mass Ratio')
        ax.set_ylabel('Occurrence / {}q dloga'.format(epos.plotpars['area']))
        area = 2. / 3. * np.log10(epos.MC_xvar[-1] / epos.MC_xvar[0])
        yscale = 1. / area
    elif epos.RV or epos.MassRadius:
        ax.set_xlabel(r'Planet Mass [M$_\bigoplus$]')
        ax.set_ylabel('Occurrence / {}M'.format(epos.plotpars['area']))
        yscale = 1.
    else:
        ax.set_xlabel(r'Planet Radius [R$_\bigoplus$]')
        ax.set_ylabel('Occurrence / {}R'.format(epos.plotpars['area']))
        yscale = 1.

    M_to_q = 1. / (epos.Mstar * cgs.Msun / cgs.Mearth)
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlim(np.array(epos.in_ytrim) * (M_to_q if PlotQ else 1.))
    if 'occrange' in epos.plotpars:
        ax.set_ylim(epos.plotpars['occrange'])
    else:
        ax.set_ylim([1e-3, 1e1])

    yvar = epos.in_yvar * (M_to_q if PlotQ else 1.)

    if MCMC:
        for fpara in plotsample:
            _, _, _, ypdf = periodradius(epos, fpara=fpara, xbin=xbin)
            ax.plot(yvar, ypdf * yscale, color='b', alpha=0.1)
        ax.plot(yvar,
                pdf0_Y * yscale,
                marker='',
                ls=':',
                color='k',
                label='starting guess')
        ax.plot(yvar,
                pdf_Y * yscale,
                marker='',
                ls='-',
                color='k',
                label='best-fit')
    else:
        if 'R break' in epos.fitpars.keys2d:
            ax.axvline(epos.fitpars.get('R break', Init=True),
                       ls='-',
                       color='gray')

        ax.plot(yvar, pdf0_Y * yscale, marker='', ls='-', color='k')

    # plot posterior excluding low detection regions (arbitrary 2000 planets assumed)
    if not (epos.RV or epos.MassRadius):
        cens = np.where(epos.f_det < 1. / 3000., 0, 1.)
        _, _, _, cens_pdf_Y = periodradius(epos, xbin=xbin, fdet=cens)
        ax.plot(yvar,
                cens_pdf_Y * yscale,
                marker='',
                ls='-',
                color='green',
                label='biased')

    if epos.Zoom and not epos.MassRadius:
        for zoom in epos.yzoom:
            ax.axvline(zoom, ls='--', color='k')

    if PlotQ and 'q Suzuki' in epos.plotpars:
        A, qbr, p1, p2 = epos.plotpars['q Suzuki']
        ax.plot(yvar, A*(yvar/qbr)**np.where(yvar<qbr,p1,p2), color='g', \
         label='Suzuki+ 2016' )

        #ax.legend(loc='lower right', shadow=False, prop={'size':14}, numpoints=1)

    if Occ:
        occbin = epos.occurrence['xzoom']
        ax.errorbar(occbin['yc'],
                    occbin['occ'] / occbin['dlny'],
                    yerr=occbin['err'] / occbin['dlny'],
                    color='r',
                    marker='_',
                    ls='',
                    capsize=3)

    # 	for y, occ, err in zip(occbin['yc'], occbin['occ']/occbin['dlny'],
    # 						occbin['err']/occbin['dlny']):
    # 		print '{:.3g} {:.3g} {:.3g}'.format(y, occ, err)

    #if Occ or MCMC:
    if MCMC:
        ax.legend(loc='upper right')

    helpers.save(plt, epos.plotdir + fname + ('_q' if PlotQ else '_y'))
示例#12
0
def binned_metric(epos):
    ''' occurrence for one y bin, along x axis'''
    if 'yzoom' in epos.occurrence:
        xc = epos.occurrence['yzoom']['xc']
        occ_obs = epos.occurrence['yzoom']['occ'] / epos.occurrence['yzoom'][
            'dlnx']
        occ_err = epos.occurrence['yzoom']['err'] / epos.occurrence['yzoom'][
            'dlnx']

        _, _, pdf_X, _ = periodradius(epos,
                                      ybin=epos.yzoom,
                                      xgrid=epos.occurrence['yzoom']['xc'])
        #for args in zip(xc, occ_obs, occ_err, pdf_X):
        #print 'xc= {:.2g}, occ={:.2g}+-{:.2g}, model= {:.2g}'.format(*args)

        squared_residuals = ((occ_obs - pdf_X) / occ_err)**2.

        zoom = (epos.xzoom[0] < xc) & (xc < epos.xzoom[-1])

        rss = np.sum(squared_residuals[zoom])
        nbins = zoom.sum()
        kfree = epos.fitpars.get_kfree()
        dof = nbins - kfree  # kfree includes normalization parameter
        chi2 = rss / dof

        bic = EPOS.analytics.bic_rss(rss, kfree, nbins)
        aic = EPOS.analytics.aic_rss(rss, kfree, nbins)
        aic_c = EPOS.analytics.aic_c_rss(rss, kfree, nbins)

        print '  x: (n={}, k={})'.format(nbins, kfree)
        print '    chi^2= {:.1f}, reduced= {:.1f}'.format(rss, chi2)
        print '    bic= {:.1f}'.format(bic)
        print '    aic= {:.1f}, AICc= {:.1f}'.format(aic, aic_c)

    if 'xzoom' in epos.occurrence:
        yc = epos.occurrence['xzoom']['yc']
        occ_obs = epos.occurrence['xzoom']['occ'] / epos.occurrence['xzoom'][
            'dlny']
        occ_err = epos.occurrence['xzoom']['err'] / epos.occurrence['xzoom'][
            'dlny']

        _, _, _, pdf_Y = periodradius(epos,
                                      xbin=epos.xzoom,
                                      ygrid=epos.occurrence['xzoom']['yc'])
        #for args in zip(yc, occ_obs, occ_err, pdf_Y):
        #print 'yc= {:.2g}, occ={:.2g}+-{:.2g}, model= {:.2g}'.format(*args)

        squared_residuals = ((occ_obs - pdf_Y) / occ_err)**2.

        zoom = (epos.yzoom[0] < yc) & (yc < epos.yzoom[-1])

        rss = np.sum(squared_residuals[zoom])
        nbins = zoom.sum()
        kfree = epos.fitpars.get_kfree()
        dof = nbins - kfree  # kfree includes normalization parameter
        chi2 = rss / dof

        bic = EPOS.analytics.bic_rss(rss, kfree, nbins)
        aic = EPOS.analytics.aic_rss(rss, kfree, nbins)
        aic_c = EPOS.analytics.aic_c_rss(rss, kfree, nbins)

        print '  y: (n={}, k={})'.format(nbins, kfree)
        print '    chi^2= {:.1f}, reduced= {:.1f}'.format(rss, chi2)
        print '    bic= {:.1f}'.format(bic)
        print '    aic= {:.1f}, AICc= {:.1f}'.format(aic, aic_c)