Пример #1
0
def time_test(nlayers=5,tpoints=100,nreps=1000):

	spider_params = sp.ModelParams(brightness_model='zhang')

#	spider_params = sp.ModelParams(brightness_model='uniform brightness')

	spider_params.n_layers= nlayers

	spider_params.t0= 200               # Central time of PRIMARY transit [days]
	spider_params.per= 0.81347753       # Period [days]
	spider_params.a_abs= 0.01526        # The absolute value of the semi-major axis [AU]
	spider_params.inc= 82.33            # Inclination [degrees]
	spider_params.ecc= 0.0              # Eccentricity
	spider_params.w= 90                 # Argument of periastron
	spider_params.rp= 0.1594            # Planet to star radius ratio
	spider_params.a= 4.855              # Semi-major axis scaled by stellar radius
	spider_params.p_u1= 0               # Planetary limb darkening parameter
	spider_params.p_u2= 0               # Planetary limb darkening parameter

	spider_params.xi= 0.3       # Ratio of radiative to advective timescale             
	spider_params.T_n= 1128     # Temperature of nightside
	spider_params.delta_T= 942  # Day-night temperature contrast
	spider_params.T_s = 4500    # Temperature of the star

	spider_params.l1 = 1.3e-6    # start of integration channel in microns
	spider_params.l2 = 1.6e-6    # end of integration channel in microns

	spider_params.pb = 0.01    # planet relative brightness

	t= spider_params.t0 + np.linspace(0, + spider_params.per,tpoints)

	print('')
	print('About to generate {} lightcurves with {} layers and {} timepoints'.format(nreps,spider_params.n_layers,tpoints))
	print('')

	start = timing.time()

	star_grid = sp.stellar_grid.gen_grid(spider_params.l1,spider_params.l2)

	ends = []
	for i in range(0,nreps):
		lc = sp.lightcurve(t,spider_params,stellar_grid=star_grid)
		ends += [timing.time()]
	ends = np.array(ends)

	exec_times = np.diff(ends)

	total = ends[-1] - start

	medtime = np.median(exec_times)
	stdtimes = np.std(exec_times)
	medtime = np.median(exec_times)


	print('In total it took {} seconds'.format(round(total,2)))
	print('Each function call was between {:.2E} and {:.2E}seconds'.format(np.min(exec_times),np.max(exec_times)))
	print('Median execution time was {:.2E} seconds'.format(medtime))
	print('Standard deviation was {:.2E} seconds'.format(stdtimes))
	print('{} lightcurves generated per second!'.format(round(1.0/medtime),1))
	print('')
Пример #2
0
def plot_test():
	spider_params = sp.ModelParams(brightness_model='zhang')

	spider_params.n_layers= 20

	spider_params.t0= 200               # Central time of PRIMARY transit [days]
	spider_params.per= 0.81347753       # Period [days]
	spider_params.a_abs= 0.01526        # The absolute value of the semi-major axis [AU]
	spider_params.inc= 82.33            # Inclination [degrees]
	spider_params.ecc= 0.0              # Eccentricity
	spider_params.w= 90                 # Argument of periastron
	spider_params.rp= 0.1594            # Planet to star radius ratio
	spider_params.a= 4.855              # Semi-major axis scaled by stellar radius
	spider_params.p_u1= 0               # Planetary limb darkening parameter
	spider_params.p_u2= 0               # Planetary limb darkening parameter

	spider_params.xi= 0.3       # Ratio of radiative to advective timescale             
	spider_params.T_n= 1128     # Temperature of nightside
	spider_params.delta_T= 942  # Day-night temperature contrast
	spider_params.T_s = 5000    # Temperature of the star

	spider_params.l1 = 1.3e-6    # start of integration channel in microns
	spider_params.l2 = 1.6e-6    # end of integration channel in microns

	t= spider_params.t0 + np.linspace(0, + spider_params.per,100)

	lc = sp.lightcurve(t,spider_params)

	plt.plot(t,lc)
	plt.show()
Пример #3
0
def spider_model(n_layers=20,
                 t0=0,
                 per=2.21857567,
                 a_abs=0.0313,
                 inc=85.71,
                 ecc=0.0,
                 w=90,
                 rp=0.155313,
                 a=8.863,
                 p_u1=0,
                 p_u2=0,
                 ntimes=500,
                 coeff=1,
                 sph=0,
                 degree=3):
    """ Create initial spiderman model """
    # spherical harmonics and 20 layers (WILL NEED TO TEST # OF LAYERS EVENTUALLY)
    spider_params = sp.ModelParams(brightness_model='spherical')
    spider_params.n_layers = n_layers  # (default)

    # SHOULD ALSO TEST DATA AGAINST UNIFORM BRIGHTNESS MODEL (A LA DEWIT) TO GET SIGMA-DETECTION OF STRUCTURE

    # for the system parameters we'll use HD 189733b (from Agol et al. 2010, except where noted)
    spider_params.t0 = t0  # Central time of PRIMARY transit [days]
    spider_params.per = per  # Period [days]
    spider_params.a_abs = a_abs  # The absolute value of the semi-major axis [AU] -- from Southworth 2010
    spider_params.inc = inc  # Inclination [degrees]
    spider_params.ecc = ecc  # Eccentricity
    spider_params.w = w  # Argument of periastron -- arbitrary, MAY NEED TO CHANGE IF E NE 0
    spider_params.rp = rp  # Planet to star radius ratio
    spider_params.a = a  # Semi-major axis scaled by stellar radius
    spider_params.p_u1 = p_u1  # Planetary limb darkening parameter
    spider_params.p_u2 = p_u2  # Planetary limb darkening parameter
    spider_params.degree = degree  # Maximum degree of harmonic (-1): 3 means 0th +8 components (x2 for negatives)
    spider_params.la0 = 0  # Offset of co-ordinte centre from the substellar point in latitude (Degrees)
    spider_params.lo0 = 0  # Offset of co-ordinte centre from the substellar point in longitude (Degrees)

    return spider_params
import spiderman as sp
import pymultinest
import numpy as np
import utils
import json

import seaborn as sns
sns.set_style('ticks')
pal = sns.color_palette("magma", n_colors=5)

ifit = 0
use_phoenix = False

if use_phoenix:
    # Load brigthness map:
    spider_params = sp.ModelParams(brightness_model="spherical",
                                   stellar_model='k2141_star.dat')
else:
    spider_params = sp.ModelParams(brightness_model="spherical")
spider_params.n_layers = 5

# Wavelength arrays:
wlows = np.array([2.87, 3.27, 3.83, 4.23, 4.63])
whighs = np.array([3.27, 3.67, 4.23, 4.63, 5.03])

# Pre-calculated "stellar" grid array:
stellar_grids = [[], [], [], [], []]

# Load datasets:
t1, f1, f1err = np.loadtxt('atmosphere_basaltic_3.07um.dat',
                           unpack=True,
                           usecols=(0, 1, 2))
Пример #5
0
 def __init__(self, brightness_models=['zhang', 'lambertian'], **kwargs):
     self.webs = []
     for i in range(0, len(brightness_models)):
         self.webs += [sp.ModelParams(brightness_models[i], **kwargs)]
Пример #6
0
def comparison():
    """Run the main comparison function."""
    # Define SPIDERMAN model parameters
    # Parameters adapted from
    # https://github.com/tomlouden/SPIDERMAN/
    # blob/master/examples/Brightness%20maps.ipynb
    spider_params = sp.ModelParams(brightness_model='spherical')

    spider_params.n_layers = 10  # Will be reset later
    spider_params.t0 = 0  # Central time of PRIMARY transit [d]
    spider_params.per = 0.81347753  # Period [days]
    spider_params.a_abs = 1.0e-30  # Nearly 0 a to ignore light travel
    spider_params.inc = 90.0  # Inclination [degrees]
    spider_params.ecc = 0.0  # Eccentricity
    spider_params.w = 0.0  # Argument of periastron
    spider_params.rp = 0.1594  # Planet to star radius ratio
    spider_params.a = 4.855  # Semi-major axis scaled by rstar
    spider_params.p_u1 = 0.0  # Planetary limb darkening parameter
    spider_params.p_u2 = 0.0  # Planetary limb darkening parameter

    # SPIDERMAN spherical harmonics parameters
    ratio = 1.0e-3  # Planet-star flux ratio
    spider_params.sph = [ratio, ratio / 2, 0, 0]  # vector of Ylm coeffs
    spider_params.degree = 2
    spider_params.la0 = 0.0
    spider_params.lo0 = 0.0

    # Define starry model parameters to match SPIDERMAN system

    # Define star
    star = starry.kepler.Primary()

    # Define planet
    planet = starry.kepler.Secondary()
    planet.lambda0 = 90.0
    planet.w = spider_params.w
    planet.r = spider_params.rp
    # Factor of pi to match SPIDERMAN normalization
    planet.L = 1.0e-3 * np.pi
    planet.inc = spider_params.inc
    planet.a = spider_params.a
    planet.porb = spider_params.per
    planet.tref = spider_params.t0
    planet.prot = spider_params.per
    planet.ecc = spider_params.ecc

    # Define spherical harmonic coefficients
    planet[1, -1] = 0.0
    planet[1, 0] = 0.0
    planet[1, 1] = 0.5

    # Make a system
    system = starry.kepler.System(star, planet)

    # Now make a multiprecision system to compute error estimates
    mstar = starry.kepler.Primary(multi=True)
    mplanet = starry.kepler.Secondary(multi=True)
    mplanet.lambda0 = 90.0
    mplanet.w = spider_params.w
    mplanet.r = spider_params.rp
    # Factor of pi to match SPIDERMAN normalization
    mplanet.L = 1.0e-3 * np.pi
    mplanet.inc = spider_params.inc
    mplanet.a = spider_params.a
    mplanet.porb = spider_params.per
    mplanet.tref = spider_params.t0
    mplanet.prot = spider_params.per
    mplanet.ecc = spider_params.ecc
    mplanet[:, :] = planet[:, :]
    msystem = starry.kepler.System(mstar, mplanet)

    # ## Speed test! ## #

    # Number of time array points
    ns = np.array([10, 50, 100, 500, 1000], dtype=int)

    # SPIDERMAN grid resolution points
    ngrid = np.array([5, 10, 20, 50, 100], dtype=int)

    n_repeats = 3
    t_starry = np.nan + np.zeros(len(ns))
    t_spiderman = np.nan + np.zeros((len(ns), len(ngrid)))
    diff1 = np.nan + np.zeros_like(t_starry)
    diff2 = np.nan + np.zeros_like(t_spiderman)
    flux_comp = []

    # Loop over time grid sizes
    for ii, n in enumerate(ns):

        # New time array of length n just around the
        # occulation and some phase curve
        time_arr = np.linspace(0.4 * spider_params.per,
                               0.6 * spider_params.per, n)

        # Compute **exact** flux using multiprecision
        msystem.compute(time_arr)
        mflux = np.array(msystem.lightcurve)

        # Repeat calculation a few times and pick fastest one
        best_starry = np.inf
        for _ in range(n_repeats):

            start = time.time()
            system.compute(time_arr)
            flux = np.array(system.lightcurve)
            dt = time.time() - start

            if dt < best_starry:
                best_starry = dt
                best_starry_flux = flux

        # Save fastest time
        t_starry[ii] = best_starry

        # Compute error
        diff1[ii] = np.max(np.fabs((mflux - best_starry_flux) / mflux))

        # Time batman (for all grid resolutions)
        for jj, ng in enumerate(ngrid):

            # New number of layers
            spider_params.n_layers = ng

            # Repeat calculation a few times
            best_spiderman = np.inf
            for _ in range(n_repeats):

                start = time.time()
                lc = spider_params.lightcurve(time_arr, use_phase=False)
                dt = time.time() - start

                if (ng == 5):
                    spider_lc_5 = np.array(lc)

                if dt < best_spiderman:
                    best_spiderman = dt
                    best_spiderman_flux = lc

            # Save fastest time
            t_spiderman[ii, jj] = best_spiderman

            # Save log maximum relative error
            diff2[ii,
                  jj] = np.max(np.fabs((mflux - best_spiderman_flux) / mflux))

            # For highest time resolution, compute differences
            # between the predictions
            if n == ns[-1]:
                flux_comp.append(
                    np.fabs(best_starry_flux - best_spiderman_flux))

    # ## Generate the figures! ## #

    # First figure: relative error

    fig = plt.figure(figsize=(5, 5))
    ax = plt.subplot2grid((3, 1), (0, 0), colspan=1, rowspan=1)
    ax2 = plt.subplot2grid((3, 1), (1, 0), colspan=1, rowspan=2)

    time_arr = np.linspace(0.4 * spider_params.per, 0.6 * spider_params.per,
                           ns[-1])

    # Flux panel
    ax.plot(time_arr,
            best_starry_flux,
            lw=1,
            alpha=1,
            label='starry',
            color='gray')
    ax.plot(time_arr,
            spider_lc_5,
            lw=1,
            alpha=1,
            ls='--',
            label='spiderman (5)')

    ax.legend(loc='lower left', framealpha=0.0, fontsize=10)
    ax.get_xaxis().set_ticklabels([])
    ax.set_xlim(time_arr.min(), time_arr.max())
    ax.set_ylim(1.000 - 0.001, 1.004 + 0.001)
    ax.set_ylabel("Flux", fontsize=14)

    # Error panel
    for kk in range(len(flux_comp)):
        ax2.plot(time_arr,
                 flux_comp[kk],
                 lw=1,
                 label="n$_{\mathrm{layers}}$=%d" % ngrid[kk])

    ax2.set_ylim(1.0e-11, 1.0e-4)
    ax2.set_xlim(time_arr.min(), time_arr.max())
    ax2.set_yscale("log")
    ax2.set_ylabel("Relative error", fontsize=14)
    ax2.set_xlabel("Time [d]", fontsize=14)
    ax2.legend(loc="best", framealpha=0.0)
    fig.savefig("spidercomp_flux.pdf", bbox_inches="tight")

    # Second figure: speed comparison

    fig = plt.figure(figsize=(7, 4))
    ax = plt.subplot2grid((2, 5), (0, 0), colspan=4, rowspan=2)
    axleg1 = plt.subplot2grid((2, 5), (0, 4))
    axleg2 = plt.subplot2grid((2, 5), (1, 4))
    axleg1.axis('off')
    axleg2.axis('off')
    ax.set_xlabel('Number of points', fontsize=13)
    for tick in ax.get_xticklabels():
        tick.set_fontsize(12)
    ax.set_ylabel('Evaluation time [seconds]', fontsize=13)
    ax.set_yscale("log")
    ax.set_xscale("log")
    for tick in ax.get_yticklabels():
        tick.set_fontsize(12)

    # Starry, loop over all points
    for ii in range(len(ns)):
        ax.plot(ns[ii],
                t_starry[ii],
                "o",
                lw=2,
                color="gray",
                ms=ms(diff1[ii]))
    ax.plot(ns, t_starry, "-", lw=1.5, color="gray", alpha=0.45)

    # Loop over all grid resolutions
    for jj, ng in enumerate(ngrid):
        ax.plot(ns,
                t_spiderman[:, jj],
                "-",
                color="C%d" % (jj),
                alpha=0.25,
                lw=1.5)
        for kk in range(len(ns)):
            ax.plot(ns[kk],
                    t_spiderman[kk, jj],
                    "o",
                    ms=ms(diff2[kk, jj]),
                    color="C%d" % (jj))

    # Legend 1
    axleg1.plot([0, 1], [0, 1], color='gray', label='starry')
    # Loop over all grid resolutions
    for jj, ng in enumerate(ngrid):
        axleg1.plot([0, 1], [0, 1],
                    color="C%d" % (jj),
                    label="n$_{\mathrm{layers}}$=%d" % ng)
    axleg1.set_xlim(2, 3)
    leg = axleg1.legend(loc='center', frameon=False)
    leg.set_title('method', prop={'weight': 'bold'})

    for logerr in [-16, -12, -8, -4, 0]:
        axleg2.plot([0, 1], [0, 1],
                    'o',
                    color='gray',
                    ms=ms(10**logerr),
                    label=r'$%3d$' % logerr)
    axleg2.set_xlim(2, 3)
    leg = axleg2.legend(loc='center', labelspacing=1, frameon=False)
    leg.set_title('log error', prop={'weight': 'bold'})
    fig.savefig("spidercomp.pdf", bbox_inches="tight")
def eigencurves(dict,plot=False,degree=3):
	waves=dict['wavelength (um)']
	times=dict['time (days)']
	fluxes=dict['flux (ppm)']	#2D array times, waves
	errors=dict['flux err (ppm)']
	
	burnin=200
	nsteps=1000
	nwalkers=32 #number of walkers	
	
	
	#This file is going to be a 3D numpy array 
	## The shape is (nsamples,n parameters,n waves)
	## where nsamples is the number of posterior MCMC samples
	## n parameters is the number of parameters
	## and n waves is the number of wavelengths looped over
	
	alltheoutput=np.zeros(((nsteps-burnin)*nwalkers,int(degree**2.),np.shape(waves)[0]))
	
	if np.shape(fluxes)[0]==np.shape(waves)[0]:
		rows=True
	elif np.shape(fluxes)[0]==np.shape(times)[0]:
		rows=False
	else:
		assert (np.shape(fluxes)[0]==np.shape(times)[0]) | (np.shape(fluxes)[0]==np.shape(waves)[0]),"Flux array dimension must match wavelength and time arrays."

	for counter in np.arange(np.shape(waves)[0]):
		wavelength=waves[counter] #wavelength this secondary eclipse is for
		eclipsetimes=times	#in days
		if rows:
			eclipsefluxes=fluxes[counter,:]*10.**-6.
			eclipseerrors=errors[counter,:]*10.**-6.
		else:
			eclipsefluxes=fluxes[:,counter]*10.**-6.
			eclipseerrors=errors[:,counter]*10.**-6.

		#alltheoutput[counter,0]=wavelength

		#	Calculate spherical harmonic maps using SPIDERMAN
		
		lc,t = sh_lcs(t0=-2.21857/2.,ntimes=eclipsetimes,degree=degree)	#model it for the times of the observations
		
		#Optional add-on above: test whether we want to include higher-order spherical harmonics when making our eigencurves?

		# subtract off stellar flux
		lc = lc-1

		# just analyze time around secondary eclipse (from start to end of observations)
		starttime=np.min(eclipsetimes)
		endtime=np.max(eclipsetimes)
		ok=np.where((t>=starttime) & (t<=endtime))
		et = t[ok]
		elc=np.zeros((np.shape(lc)[0],np.shape(ok)[1]))
		for i in np.arange(np.shape(lc)[0]):
			elc[i,:] = lc[i,ok]

		#  PCA
		ecoeff,escore,elatent = princomp(elc[1:,:].T)
		escore=np.real(escore)

		#sf=0.1
		# delbic=20.
		# nparams=4
		# params0=np.ones(nparams)
		# mpfit=leastsq(mpmodel,params0,args=(eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams))
		# resid=mpmodel(mpfit[0],eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams)
		# chi2i=np.sum((resid//eclipseerrors)**2.)
		# loglike=-0.5*(np.sum((resid//eclipseerrors)**2 + np.log(2.0*np.pi*(eclipseerrors)**2)))
		# bici=-2.*loglike + nparams*np.log(np.shape(eclipseerrors)[0])

		#pdb.set_trace()
		# while delbic>10.:#sf>0.00001:
		# 	nparams+=1
		# 	if nparams==15:
		# 		params0=np.ones(nparams)
		# 		mpfit=leastsq(mpmodel,params0,args=(eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams))
		# 		chi2f=np.sum((mpmodel(mpfit[0],eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams)//eclipseerrors)**2.)
		# 		#dof=np.shape(eclipseerrors)[0]-nparams
		# 		#Fval=(chi2i-chi2f)/(chi2f/dof)
		# 		#sf=0.00000001
		# 		delbic=5.
		# 	else:
		# 		params0=np.ones(nparams)
		# 		mpfit=leastsq(mpmodel,params0,args=(eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams))
		# 		resid=mpmodel(mpfit[0],eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams)
		# 		chi2f=np.sum((resid//eclipseerrors)**2.)
		# 		#dof=np.shape(eclipseerrors)[0]-nparams
		# 		#Fval=(chi2i-chi2f)/(chi2f/dof)
		# 		#sf=stats.f.sf(Fval,nparams-1,nparams)
		# 		loglike=-0.5*(np.sum((resid//eclipseerrors)**2 + np.log(2.0*np.pi*(eclipseerrors)**2)))
		# 		bicf=-2.*loglike + nparams*np.log(np.shape(eclipseerrors)[0])
		# 		delbic=bici-bicf
		# 		#pdb.set_trace()
		# 		#print(np.sum((resid//eclipseerrors)**2),loglike)
		# 		#print(nparams,chi2f,bici,bicf,delbic)
		# 		chi2i=chi2f
		# 		bici=bicf

		#pdb.set_trace()
		#nparams-=1
		nparams=5
		#print nparams
		params0=10.**-4.*np.ones(nparams)
		
		#pdb.set_trace()
		mpfit=leastsq(mpmodel,params0,args=(eclipsetimes,eclipsefluxes,eclipseerrors,elc,np.array(escore),nparams))
		#format parameters for mcmc fit
		theta=mpfit[0]
		ndim=np.shape(theta)[0]	#set number of dimensions
		
		sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=(eclipsetimes,eclipsefluxes,eclipseerrors,elc,escore,nparams),threads=6)
		pos = [theta + 1e-5*np.random.randn(ndim) for i in range(nwalkers)]
		
		print("Running MCMC at {} um".format(waves[counter]))
		sampler.run_mcmc(pos,nsteps)

		samples = sampler.chain[:, burnin:, :].reshape((-1, ndim))
		#pdb.set_trace()
		def quantile(x, q):
			return np.percentile(x, [100. * qi for qi in q])

		bestcoeffs=np.zeros(np.shape(samples)[1])
		for i in np.arange(np.shape(bestcoeffs)[0]):
			bestcoeffs[i]=quantile(samples[:,i],[0.5])
		#pdb.set_trace()
		# translate coefficients
		fcoeffbest=np.zeros_like(ecoeff)
		for i in np.arange(np.shape(bestcoeffs)[0]-2):
			fcoeffbest[:,i] = bestcoeffs[i+2]*ecoeff[:,i]

		# how to go from coefficients to best fit map
		spheresbest=np.zeros(int(degree**2.))
		for j in range(0,len(fcoeffbest)):
			for i in range(1,int(degree**2.)):
				spheresbest[i] += fcoeffbest.T[j,2*i-1]-fcoeffbest.T[j,2*(i-1)]
		spheresbest[0] = bestcoeffs[0]#c0_best
		#pdb.set_trace()
		for sampnum in np.arange(np.shape(samples)[0]):
			fcoeff=np.zeros_like(ecoeff)
			for i in np.arange(np.shape(samples)[1]-2):
				fcoeff[:,i] = samples[sampnum,i+2]*ecoeff[:,i]

			# how to go from coefficients to best fit map
			spheres=np.zeros(int(degree**2.))
			for j in range(0,len(fcoeff)):
				for i in range(1,int(degree**2.)):
					spheres[i] += fcoeff.T[j,2*i-1]-fcoeff.T[j,2*(i-1)]
			spheres[0] = samples[sampnum,0]#bestcoeffs[0]#c0_best	
			
			alltheoutput[sampnum,:,counter]=spheres
		#pdb.set_trace()
		#Translate all the coefficients for all of the posterior samples
		#alltheoutput[counter,1:]=spheres
		#print(spheresbest)

		if plot:
			params0=sp.ModelParams(brightness_model='spherical')	#no offset model
			params0.nlayers=20

			params0.t0=-2.21857/2.				# Central time of PRIMARY transit [days]
			params0.per=2.21857567			# Period [days]
			params0.a_abs=0.0313			# The absolute value of the semi-major axis [AU]
			params0.inc=85.71			# Inclination [degrees]
			params0.ecc=0.0			# Eccentricity
			params0.w=90.			# Argument of periastron
			params0.rp=0.155313				# Planet to star radius ratio
			params0.a=8.863				# Semi-major axis scaled by stellar radius
			params0.p_u1=0.			# Planetary limb darkening parameter
			params0.p_u2=0.			# Planetary limb darkening parameter

			params0.degree=degree	#maximum harmonic degree
			params0.la0=0.
			params0.lo0=0.
			params0.sph=list(spheresbest)

			times=eclipsetimes
			templc=params0.lightcurve(times)

			params0.plot_square()

			# doing a test spiderman run to see if the output lightcurve is similar
			# #PERSON CHECKING THIS: You can use this to make sure the spherical harmonics fit is doing the right thing!

			plt.figure()
			plt.plot(times,templc,color='k')
			plt.errorbar(eclipsetimes,eclipsefluxes,yerr=eclipseerrors,linestyle='none',color='r')
			plt.show()

	finaldict={'wavelength (um)':waves,'spherical coefficients':alltheoutput}
	return finaldict
Пример #8
0
def spiderman_sph(params, t, etc=[]):
    """
  This function creates a model that fits spherical harmonics 

  Parameters
  ----------
    	t0:		time of conjunction 
	per:		orbital period
	a_abs:		semi-major axis (AU)
	cos(i):	        cosine of the orbital inclination	
	ecc:		eccentricity
	w:		arg of periastron (deg)
	rp:		planet radius (stellar radii)
	a:		semi-major axis (stellar radii)
	p_u1:		planet linear limb darkening parameter
	p_u2:		planet quadratic limb darkening
	T_s:		stellar Teff
	l1:		short wavelength (m)
	l2:		long wavelength (m)
	degree:		maximum degree of harmonic (typically no more than 2)
	la0:		latitudinal offset of coordinate center from substellar point (degrees)
	lo0:		latitudinal offset of coordinate center from substellar point (degrees)
	sph0:		coefficient1
	sph1:		coefficient2	
	sph2:		coefficient3
	sph3:		coefficient4
        npoints:        number of phase bins for light curve interpolation


	**Note: 4 harmonic coefficients are needed for a model of degree 2

  Returns
  -------
	This function returns an array of planet/star flux values 

  Revisions
  ---------
  2016-11-19 	Laura Kreidberg	
                [email protected] 
                Original version
  2019-02-24	update interpolation, add to github version 
  TODO          add response function, nlayers to etc
   """
    p = spiderman.ModelParams(brightness_model='spherical',
                              stellar_model='blackbody')
    p.nlayers = 5

    p.t0 = params[0]
    p.per = params[1]
    p.a_abs = params[2]
    p.inc = np.arccos(params[3]) * 180. / np.pi
    p.ecc = params[4]
    p.w = params[5]
    p.rp = params[6]
    p.a = params[7]
    p.p_u1 = params[8]
    p.p_u2 = params[9]
    p.T_s = params[10]
    p.l1 = params[11]
    p.l2 = params[12]
    p.degree = int(params[13])
    p.la0 = params[14]
    p.lo0 = params[15]
    #   sph0        = params[16]
    #   sph1        = params[17]
    #   sph2        = params[18]
    #   sph3        = params[19]
    #   sph0      = params[16:int(16+p.degree**2)]
    p.n_layers = 5

    sph = []
    for i in range(0, p.degree**2):
        sph.append(params[16 + i])
    p.sph = sph

    npoints = int(params[-1])

    #p.filter = "/Users/lkreidberg/Desktop/Util/Throughput/spitzer_irac_ch2.txt"

    #calculate light curve over npoints phase bins
    phase = (t - p.t0) / p.per
    phase -= np.round(phase)

    phase_bin = np.linspace(phase.min(), phase.max(), npoints)
    t_bin = phase_bin * p.per + p.t0

    lc_bin = spiderman.web.lightcurve(t_bin, p)

    #interpolate the binned light curve to the original t array
    lc = np.interp(phase, phase_bin, lc_bin)

    return lc
Пример #9
0
def comparison():

    ### Define SPIDERMAN model parameters ###

    # Parameters adapted from https://github.com/tomlouden/SPIDERMAN/blob/master/examples/Brightness%20maps.ipynb
    spider_params = sp.ModelParams(brightness_model='spherical')

    spider_params.n_layers = 10        # Will be reset later

    spider_params.t0 = 0                # Central time of PRIMARY transit [days]
    spider_params.per = 0.81347753      # Period [days]
    spider_params.a_abs = 1.0e-30       # Nearly 0 a to ignore light travel effects
    spider_params.inc = 90.0            # Inclination [degrees]
    spider_params.ecc = 0.0             # Eccentricity
    spider_params.w = 0.0               # Argument of periastron
    spider_params.rp = 0.1594           # Planet to star radius ratio
    spider_params.a = 4.855             # Semi-major axis scaled by stellar radius
    spider_params.p_u1 = 0.0            # Planetary limb darkening parameter
    spider_params.p_u2 = 0.0            # Planetary limb darkening parameter

    # SPIDERMAN spherical harmonics parameters
    ratio = 1.0e-3                                  # Planet-star flux ratio
    spider_params.sph = [ratio, ratio/2, 0, 0]      # vector of spherical harmonic weights
    spider_params.degree = 2
    spider_params.la0 = 0.0
    spider_params.lo0 = 0.0

    ### Define starry model parameters to match SPIDERMAN system ###

    # Define star
    star = starry.Star()

    # Define planet
    planet = starry.Planet(lmax=2,
                           lambda0=90.0,
                           w=spider_params.w,
                           r=spider_params.rp,
                           L=1.0e-3 * np.pi, # Factor of pi to match SPIDERMAN normalization
                           inc=spider_params.inc,
                           a=spider_params.a,
                           porb=spider_params.per,
                           tref=spider_params.t0,
                           prot=spider_params.per,
                           ecc=spider_params.ecc)

    # Define spherical harmonic coefficients
    planet.map[0,0] = 1.0
    planet.map[1,-1] = 0.0
    planet.map[1,0] = 0.0
    planet.map[1,1] = 0.5

    # Make a system
    system = starry.System([star,planet])

    ### Speed test! ###

    # Number of time array points
    ns = np.array([20, 100, 500, 1000], dtype=int)

    # SPIDERMAN grid resolution points
    ngrid = np.array([5, 10, 20, 50, 100], dtype=int)

    n_repeats = 3
    t_starry = np.nan + np.zeros(len(ns))
    t_spiderman = np.nan + np.zeros((len(ns),len(ngrid)))
    diff = np.nan + np.zeros_like(t_spiderman)
    flux_comp = []

    # Loop over time grid sizes
    for ii, n in enumerate(ns):

        # New time array of length n just around the occulation and some phase curve
        time_arr = np.linspace(0.4*spider_params.per, 0.6*spider_params.per, n)

        # Repeat calculation a few times and pick fastest one
        best_starry = np.inf
        for _ in range(n_repeats):

            start = time.time()
            system.compute(time_arr)
            flux = np.array(system.flux)
            dt = time.time() - start

            if dt < best_starry:
                best_starry = dt
                best_starry_flux = flux

        # Save fastest time
        t_starry[ii] = best_starry

        # Time batman (for all grid resolutions)
        for jj, ng in enumerate(ngrid):

            # New number of layers
            spider_params.n_layers = ng

            # Repeat calculation a few times
            best_spiderman = np.inf
            for _ in range(n_repeats):

                start = time.time()
                lc = spider_params.lightcurve(time_arr, use_phase=False)
                dt = time.time() - start

                if dt < best_spiderman:
                    best_spiderman = dt
                    best_spiderman_flux = lc

            # Save fastest time
            t_spiderman[ii,jj] = best_spiderman

            # Save log maximum relative error
            diff[ii,jj] = np.max(np.fabs((best_starry_flux - best_spiderman_flux)/best_starry_flux))

            # For highest time resolution, compute differences between the predictions
            if n == ns[-1]:
                flux_comp.append(np.fabs(best_starry_flux - best_spiderman_flux))

    ### Generate the figures! ###

    # First figure: relative error

    fig = plt.figure(figsize=(5, 5))
    ax = plt.subplot2grid((3, 1), (0, 0), colspan=1, rowspan=1)
    ax2 = plt.subplot2grid((3, 1), (1, 0), colspan=1, rowspan=2)

    time_arr = np.linspace(0.4*spider_params.per, 0.6*spider_params.per, ns[-1])

    # Flux panel
    ax.plot(time_arr, best_starry_flux)
    ax.get_xaxis().set_ticklabels([])
    ax.set_xlim(time_arr.min(), time_arr.max())
    ax.set_ylabel("Flux")

    # Error panel
    for kk in range(len(flux_comp)):
           ax2.plot(time_arr, flux_comp[kk],
                   label="n$_{\mathrm{layers}}$=%d" % ngrid[kk])

    ax2.set_ylim(1.0e-11, 1.0e-4)
    ax2.set_xlim(time_arr.min(), time_arr.max())
    ax2.set_yscale("log")
    ax2.set_ylabel("Relative error")
    ax2.set_xlabel("Time [d]")
    ax2.legend(loc="best", framealpha=0.0)
    fig.savefig("spidercomp_flux.png", bbox_inches="tight")

    # Second figure: speed comparison

    fig = plt.figure(figsize=(7, 4))
    ax = plt.subplot2grid((2, 5), (0, 0), colspan=4, rowspan=2)
    axleg1 = plt.subplot2grid((2, 5), (0, 4))
    axleg2 = plt.subplot2grid((2, 5), (1, 4))
    axleg1.axis('off')
    axleg2.axis('off')
    ax.set_xlabel('Number of points', fontsize=14, fontweight='bold')
    for tick in ax.get_xticklabels():
        tick.set_fontsize(12)
    ax.set_ylabel('Evaluation time [seconds]', fontsize=14, fontweight='bold')
    ax.set_yscale("log")
    ax.set_xscale("log")
    for tick in ax.get_yticklabels():
        tick.set_fontsize(12)

    # Starry, loop over all points
    for ii in range(len(ns)):
        ax.plot(ns[ii], t_starry[ii], "o", lw=2, color="C0", ms=ms(1.0e-16))
    ax.plot(ns, t_starry, "-", lw=1.5, color="C0", alpha=0.25)

    # Loop over all grid resolutions
    for jj, ng in enumerate(ngrid):
        ax.plot(ns, t_spiderman[:,jj], "-", color="C%d" % (jj+1), alpha=0.25, lw=1.5)
        for kk in range(len(ns)):
            ax.plot(ns[kk], t_spiderman[kk,jj], "o", ms=ms(diff[kk,jj]),
                    color="C%d" % (jj+1))

    # Legend 1
    axleg1.plot([0, 1], [0, 1], color='C0', label='starry')
    # Loop over all grid resolutions
    for jj, ng in enumerate(ngrid):
        axleg1.plot([0, 1], [0, 1], color="C%d" % (jj+1), label="n$_{\mathrm{layers}}$=%d" % ng)
    axleg1.set_xlim(2, 3)
    axleg1.legend(loc='center', frameon=False, title=r'\textbf{method}')

    for logerr in [-16, -12, -8, -4, 0]:
        axleg2.plot([0, 1], [0, 1], 'o', color='gray',
                    ms=ms(10 ** logerr),
                    label=r'$%3d$' % logerr)
    axleg2.set_xlim(2, 3)
    leg = axleg2.legend(loc='center', labelspacing=1, frameon=False,
                        title=r'\textbf{log error}')

    fig.savefig("spidercomp.png", bbox_inches="tight")
Пример #10
0
def find_groups(dataDir,ngroups=4,degree=2,
                londim=100, latdim=100,
                trySamples=45,extent=0.5,sortMethod='avg',isspider=True):
    """ 
    Find the eigenspectra using k means clustering
    
    Parameters
    ----------
    ngroups: int
        Number of eigenspectra to group results into
    degree: int
        Spherical harmonic degree to draw samples from
    testNum: int
        Test number (ie. lightcurve number 1,2, etc.)
    trySamples: int
        Number of samples to find groups with
        All samples take a long time so this takes a random
        subset of samples from which to draw posteriors
    sortMethod: str
        Method to sort the groups returned by K means clustering
        None, will not sort the output
        'avg' will sort be the average of the spectrum
        'middle' will sort by the flux in the middle of the spectrum
    extent: time covered by the eclipse/phase curve. 
        Sets what portion of the map is used for clustering (e.g. full planet or dayside only)
    """
    #samplesDir = "data/sph_harmonic_coefficients_full_samples"
    #dataDir = "{}/eclipse_lightcurve_test{}/".format(samplesDir,testNum)
    tmp = np.load("{}spherearray_deg_{}.npz".format(dataDir,degree))
    outDictionary = tmp['arr_0'].tolist()
    samples = outDictionary['spherical coefficients'] # output from eigencurves

    if trySamples>len(samples):
    	assert(trySamples<=len(samples)),("trySamples must be less than the total number of MCMC samples, "+str(len(samples)))

    eigenspectra_draws = []
    kgroup_draws = []
    uber_eigenlist=[[[[] for i in range(10)] for i in range(ngroups)] for i in range(trySamples)]
    
    if isspider:
        params0=sp.ModelParams(brightness_model='spherical') #megan added stuff
        params0.nlayers=20
        params0.t0=-2.21857/2.
        params0.per=2.21857567
        params0.a_abs=0.0313
        params0.inc=85.71
        params0.ecc=0.0
        params0.w=90.
        params0.rp=0.155313
        params0.a=8.863
        params0.p_u1=0.
        params0.p_u2=0.
        params0.degree=degree
        params0.la0=0.
        params0.lo0=0.
        waves=np.array([2.41,2.59,2.77,2.95,3.13,3.31,3.49,3.67,3.85,4.03])
    minlon=np.around(extent/2.*londim)
    #print(minlon)

    randomIndices = np.random.randint(0,len(samples),trySamples)
    for drawInd,draw in enumerate(samples[randomIndices]):
        ## Re-formatting here into a legacy system
        ## 1st dimension is wavelength
        ## 2nd dimensions is data (0th element = wavelength)
        ##                        (1: elements are spherical harmonic coefficients)
        if not isspider:
            inputArr = np.zeros([10,samples.shape[1]+1])
            inputArr[:,0] = np.array([2.41,2.59,2.77,2.95,3.13,3.31,3.49,3.67,3.85,4.03])
            inputArr[:,1:] = draw.transpose()

            waves, lats, lons, maps = eigenmaps.generate_maps(inputArr, N_lon=londim, N_lat=latdim)
            maps=maps[:,:,int(londim/2.-minlon):int(londim/2.+minlon)]

        #maps=np.zeros((np.shape(waves)[0],londim,latdim)) #full map

        else:
            maps=np.zeros((np.shape(waves)[0],latdim,int(minlon*2))) #only dayside
        #print(np.shape(maps))

            for i in np.arange(np.shape(waves)[0]):
                params0.sph=list(samples[drawInd,:,i])
                nla=latdim
                nlo=londim
                las = np.linspace(-np.pi/2,np.pi/2,nla)
                los = np.linspace(-np.pi,np.pi,nlo)
                fluxes = []
                for la in las:
                    row = []
                    for lo in los:
                        flux = sp.call_map_model(params0,la,lo)
                        row += [flux[0]]
                    fluxes += [row]
                fluxes = np.array(fluxes)
                lons, lats = np.meshgrid(los,las)
                #print(np.min(lats),np.min(lons),np.min(las),np.min(los))
                #lats, lons, maps = testgenmaps.spmap(inputArr,londim, latdim)
                #pdb.set_trace()
                maps[i,:,:] = fluxes[:,int(londim/2.-minlon):int(londim/2.+minlon)]
            
        kgroups = kmeans.kmeans(maps, ngroups)
        
        eigenspectra,eigenlist = bin_eigenspectra.bin_eigenspectra(maps, kgroups)

        eigenspectra_draws.append(eigenspectra)
        kgroup_draws.append(kgroups)
        for groupind in range(ngroups):
            for waveind in range(10):
                uber_eigenlist[drawInd][groupind][waveind]=eigenlist[groupind][waveind,:]

    if sortMethod is not None:
        eigenspectra_draws_final, kgroup_draws_final,uber_eigenlist_final = kmeans.sort_draws(eigenspectra_draws,
                                                                         kgroup_draws,uber_eigenlist,
                                                                         method=sortMethod)
    else:
        eigenspectra_draws_final, kgroup_draws_final,uber_eigenlist_final = eigenspectra_draws, kgroup_draws,uber_eigenlist
    return eigenspectra_draws_final, kgroup_draws_final,uber_eigenlist_final, maps
Пример #11
0
def spiderman_zhang(params, t, etc=[]):
    """
  This function creates a model that fits a physical motivated model based on Zhang et al. 2017, ApJ, 836, 73

  Parameters
  ----------
    	t0:		time of conjunction 
	per:		orbital period
	a_abs:		semi-major axis (AU)
	cos(i):	        cosine of the orbital inclination	
	ecc:		eccentricity
	w:		arg of periastron (deg)
	rp:		planet radius (stellar radii)
	a:		semi-major axis (stellar radii)
	p_u1:		planet linear limb darkening parameter
	p_u2:		planet quadratic limb darkening
	T_s:		stellar Teff
	l1:		short wavelength (m)
	l2:		long wavelength (m)
	xi:		radiative/advective timescale
	T_n:		nightside temperature
	delta_T:	day-night temperature contrast
        npoints:        number of phase bins for light curve interpolation
	

  Returns
  -------
	This function returns planet-to-star flux at each time t. 

  Revisions
  ---------
  2016-11-19 	Laura Kreidberg	
                [email protected] 
                Original version
  2019-02-24	update interpolation, add to github version 
  TODO          add response function, nlayers to etc
   """
    p = spiderman.ModelParams(brightness_model='zhang',
                              stellar_model='blackbody')
    p.nlayers = 5

    p.t0 = params[0]
    p.per = params[1]
    p.a_abs = params[2]
    p.inc = np.arccos(params[3]) * 180. / np.pi
    p.ecc = params[4]
    p.w = params[5]
    p.rp = params[6]
    p.a = params[7]
    p.p_u1 = params[8]
    p.p_u2 = params[9]
    p.T_s = params[10]
    p.l1 = params[11]
    p.l2 = params[12]
    p.xi = params[13]
    p.T_n = params[14]
    p.delta_T = params[15]
    npoints = int(params[16])

    #TODO: add filter path to etc
    #p.filter = "/Users/lkreidberg/Desktop/Util/Throughput/spitzer_irac_ch2.txt"

    #calculate light curve over npoints phase bins
    phase = (t - p.t0) / p.per
    phase -= np.round(phase)

    phase_bin = np.linspace(phase.min(), phase.max(), npoints)
    t_bin = phase_bin * p.per + p.t0

    lc_bin = spiderman.web.lightcurve(t_bin, p)

    #interpolate the binned light curve to the original t array
    lc = np.interp(phase, phase_bin, lc_bin)

    return lc
Пример #12
0
def spiderman_spot(params, t, etc = []):
   """
  This function creates a model that fits a hotspot model 

  Parameters
  ----------
    	t0:		time of conjunction 
	per:		orbital period
	a_abs:		semi-major axis (AU)
	inc:		inclinations (deg)
	ecc:		eccentricity
	w:		arg of periastron (deg)
	rp:		planet radius (stellar radii)
	a:		semi-major axis (stellar radii)
	p_u1:		planet linear limb darkening parameter
	p_u2:		planet quadratic limb darkening
	T_s:		stellar Teff
	l1:		blue wavelength (m)
	l2:		red wavelength (m)
	la0:		latitude of hotspot		
	lo0:		longitude of hotspot
	spotsize:	 hot spot radius in degrees	
	spot_T:		the surface temperature of the hotspot as a fraction of temperature of the star
	p_T:		the temperature of the planet that is not in the hotspot

  Returns
  -------
	This function returns planet-to-star flux at each time t. 

  Revisions
  ---------
  2017-09-11 	Laura Kreidberg	
                [email protected] 
                Original version
  2019-02-24	update interpolation, add to github version 
  TODO          add response function, nlayers to etc
   """
   p = spiderman.ModelParams(brightness_model =  'hotspot_t', stellar_model = 'blackbody')
   p.nlayers = 5

   p.t0    	    = params[0]
   p.per       	    = params[1]
   p.a_abs 	    = params[2]
   p.inc	    = np.arccos(params[3])*180./np.pi
   p.ecc	    = params[4]
   p.w	   	    = params[5]
   p.rp	    	    = params[6]
   p.a	   	    = params[7]
   p.p_u1	    = params[8]
   p.p_u2	    = params[9]
   p.T_s	    = params[10]
   p.l1	   	    = params[11]
   p.l2	    	    = params[12]
   p.la0	    = params[13]
   p.lo0	    = params[14]
   p.size	    = params[15]
   p.spot_T	    = params[16]
   p.p_T	    = params[17]
   npoints          = int(params[18])
 
   #p.filter = "/Users/lkreidberg/Desktop/Util/Throughput/spitzer_irac_ch2.txt"

   #calculate light curve over npoints phase bins
   phase = (t - p.t0)/p.per
   phase -= np.round(phase)

   phase_bin = np.linspace(phase.min(), phase.max(), npoints)
   t_bin = phase_bin*p.per + p.t0

   lc_bin = spiderman.web.lightcurve(t_bin, p)

   #interpolate the binned light curve to the original t array
   lc = np.interp(phase, phase_bin, lc_bin)

   return lc 
Пример #13
0
def eigensphere(params, t, etc=[]):
    """
	This function creates a model that fits spherical harmonics and uses PCA to fit for orthogonal phase curves

	Parameters
	----------
	t0:		time of conjunction 
	per:		orbital period
	a_abs:		semi-major axis (AU)
	cos(i):	        cosine of the orbital inclination	
	ecc:		eccentricity
	w:		arg of periastron (deg)
	rp:		planet radius (stellar radii)
	a:		semi-major axis (stellar radii)
	p_u1:		planet linear limb darkening parameter
	p_u2:		planet quadratic limb darkening
	T_s:		stellar Teff
	l1:		short wavelength (m)
	l2:		long wavelength (m)
	degree:		maximum degree of harmonic (typically no more than 2)
	la0:		latitudinal offset of coordinate center from substellar point (degrees)
	lo0:		latitudinal offset of coordinate center from substellar point (degrees)
	npoints:        number of phase bins for light curve interpolation
	coeff0-3: four coefficients for eigencurves 
	
	
	**Note: 4 harmonic coefficients are needed for a model of degree 2
	
	Returns
	-------
	This function returns an array of planet/star flux values 
	
	Revisions
	---------
	2016-11-19 	Megan Mansfield
				[email protected]

	"""
    p = spiderman.ModelParams(brightness_model='spherical',
                              stellar_model='blackbody')
    p.nlayers = 5
    p.t0 = params[0]  #I want these to be values, not parameters
    p.per = params[1]
    p.a_abs = params[2]
    p.inc = np.arccos(params[3]) * 180. / np.pi
    p.ecc = params[4]
    p.w = params[5]
    p.rp = params[6]
    p.a = params[7]
    p.p_u1 = params[8]
    p.p_u2 = params[9]
    p.T_s = params[10]
    p.l1 = params[11]
    p.l2 = params[12]
    p.degree = int(params[13])
    p.la0 = params[14]
    p.lo0 = params[15]
    sph = 0
    ntimes = int(params[16])
    degree = int(params[13])

    #stuff from sh_lcs
    #lctimes=np.linspace(np.min(t),np.max(t),ntimes)
    #if np.size(ntimes) == 1:
    #		t= spider_params.t0 + np.linspace(0, spider_params.per,ntimes)  # TEST TIME RESOLUTION
    #	else:
    #		t= ntimes
    #		ntimes = t.size

    phase = (t - p.t0) / p.per
    phase -= np.round(phase)
    phase_bin = np.linspace(phase.min(), phase.max(), ntimes)
    lctimes = phase_bin * p.per + p.t0

    if np.size(sph) == 1:

        allLterms = [0] * int(params[13])**2
        allLterms[0] = 1
        p.sph = allLterms  # * coeff   # this is l0, so don't need a negative version
        lc = spiderman.web.lightcurve(lctimes, p)
        #lc = p.lightcurve(lctimes)
        # set up size of lc to be able to append full set of LCs
        lc = np.resize(lc, (1, ntimes))

        p.sph = [0] * int(params[13])**2
        # set up 2-d array of LCs for all SHs
        for i in range(1, len(p.sph)):
            p.sph[i] = -1  #*coeff
            tlc = spiderman.web.lightcurve(lctimes, p)
            #tlc = p.lightcurve(lctimes)
            tlc = np.resize(tlc, (1, ntimes))
            lc = np.append(lc, tlc, axis=0)
            p.sph[i] = 1  #*coeff
            tlc = spiderman.web.lightcurve(lctimes, p)
            #tlc = p.lightcurve(lctimes)
            tlc = np.resize(tlc, (1, ntimes))
            lc = np.append(lc, tlc, axis=0)
            p.sph[i] = 0
    else:
        # calcualte single lightcurve for single set of spherical harmonic coefficients
        p.sph = sph  # spherical harmonic coefficients
        lc = spiderman.web.lightcurve(lctimes, p)
        #lc = p.lightcurve(lctimes)

    # subtract off stellar flux
    lc = lc - 1
    #print(p.sph)
    elc = np.zeros((np.shape(lc)[0], np.shape(lctimes)[0]))
    for i in np.arange(np.shape(lc)[0]):
        elc[i, :] = lc[i, :]

    #  PCA
    ecoeff, escore, elatent = princomp(elc[1:, :].T)
    escore = np.real(escore)

    #construct light curve model
    model = params[17] * elc[0, :] + params[18] + params[19] * escore[
        0, :] + params[20] * escore[
            1, :]  #these are the params I want to fit for!!!
    #finallc=np.interp(phase,phase_bin,model)
    #print(np.max(model))

    fcoeffbest = np.zeros_like(ecoeff)
    fcoeffbest[:, 0] = params[19] * ecoeff[:, 0]
    fcoeffbest[:, 1] = params[20] * ecoeff[:, 1]

    spheresbest = np.zeros(int(degree**2.))
    for j in range(0, len(fcoeffbest)):
        for i in range(1, int(degree**2.)):
            spheresbest[i] += fcoeffbest.T[j, 2 * i -
                                           1] - fcoeffbest.T[j, 2 * (i - 1)]
    spheresbest[0] = params[17]
    #print(spheresbest)
    p.sph = list(spheresbest)
    finallc_bin = spiderman.web.lightcurve(lctimes, p)
    finallc = np.interp(phase, phase_bin, finallc_bin)
    #print(np.max(finallc))
    return finallc
Пример #14
0
import os
import matplotlib.pyplot as plt
import pickle
import juliet

plt.style.use('ggplot')

import spiderman as sp
import pymultinest
import numpy as np
import utils
import json

# Load brigthness map:
spider_params = sp.ModelParams(brightness_model="zhang")
spider_params.n_layers = 5

# Wavelength arrays:
wlows = np.array([2.87, 3.27, 3.83, 4.23, 4.63])
whighs = np.array([3.27, 3.67, 4.23, 4.63, 5.03])

# Pre-calculated "stellar" grid array:
stellar_grids = [[], [], [], [], []]

# Load datasets:
t1, f1, f1err = np.loadtxt('atmosphere_1000_0_3.07um.dat',
                           unpack=True,
                           usecols=(0, 1, 2))
t2, f2, f2err = np.loadtxt('atmosphere_1000_0_3.47um.dat',
                           unpack=True,
                           usecols=(0, 1, 2))
Пример #15
0
def retrieve_map_full_samples(degree=3,dataDir="data/sph_harmonic_coefficients_full_samples/hotspot/",isspider=True):
    tmp = np.load("{}spherearray_deg_{}.npz".format(dataDir,degree))
    outDictionary = tmp['arr_0'].tolist()
    
    londim = 100
    latdim = 100
    samples = outDictionary['spherical coefficients'] # output from eigencurves
    waves = outDictionary['wavelength (um)']
    bestsamples=outDictionary['best fit coefficients'] # best fit sample from eigencurves
    
    randomIndices = np.random.randint(0,len(samples),39)
    nRandom = len(randomIndices)
    
    fullMapArray = np.zeros([nRandom,len(waves),londim,latdim])
    bestMapArray = np.zeros([len(waves),londim,latdim])
    #SPIDERMAN stuff added by Megan
    if isspider:
        params0=sp.ModelParams(brightness_model='spherical')
        params0.nlayers=20
        params0.t0=-2.21857/2.
        params0.per=2.21857567
        params0.a_abs=0.0313
        params0.inc=85.71
        params0.ecc=0.0
        params0.w=90.
        params0.rp=0.155313
        params0.a=8.863
        params0.p_u1=0.
        params0.p_u2=0.
        params0.degree=degree
        params0.la0=0.
        params0.lo0=0.
    
    if not isspider:
        inputArr=np.zeros([len(waves),bestsamples.shape[0]+1])
        inputArr[:,0] = waves
        inputArr[:,1:] = bestsamples.transpose()
        wavelengths, lats, lons, maps = eigenmaps.generate_maps(inputArr,N_lon=londim, N_lat=latdim)
        bestMapArray=maps
    else:
        for i in np.arange(np.shape(waves)[0]):
            params0.sph=list(bestsamples[:,i])
            nla=latdim
            nlo=londim
            las = np.linspace(-np.pi/2,np.pi/2,nla)
            los = np.linspace(-np.pi,np.pi,nlo)
            fluxes = []
            for la in las:
                row = []
                for lo in los:
                    flux = sp.call_map_model(params0,la,lo)
                    row += [flux[0]]
                fluxes += [row]
            fluxes = np.array(fluxes)
            lons, lats = np.meshgrid(los,las)
            bestMapArray[i,:,:] = fluxes


    for drawInd, draw in enumerate(samples[randomIndices]):
        if not isspider:
            inputArr = np.zeros([len(waves),samples.shape[1]+1])
            inputArr[:,0] = waves
            inputArr[:,1:] = draw.transpose()
        
            wavelengths, lats, lons, maps = eigenmaps.generate_maps(inputArr,
                                                                N_lon=londim, N_lat=latdim)
            fullMapArray[drawInd,:,:,:] = maps
            #MEGAN ADDED STUFF
        else:
            for i in np.arange(np.shape(waves)[0]):
                params0.sph=list(samples[drawInd,:,i])
                nla=latdim
                nlo=londim
                las = np.linspace(-np.pi/2,np.pi/2,nla)
                los = np.linspace(-np.pi,np.pi,nlo)
                fluxes = []
                for la in las:
                    row = []
                    for lo in los:
                        flux = sp.call_map_model(params0,la,lo)
                        row += [flux[0]]
                    fluxes += [row]
                fluxes = np.array(fluxes)
                lons, lats = np.meshgrid(los,las)
            #print(np.min(lats),np.min(lons),np.min(las),np.min(los))
            #lats, lons, maps = testgenmaps.spmap(inputArr,londim, latdim)
                fullMapArray[drawInd,i,:,:] = fluxes
        
        ## note that the maps have the origin at the top
        ## so we have to flip the latitude array
        lats = np.flip(lats,axis=0)
    
    return fullMapArray, bestMapArray, lats, lons, waves
Пример #16
0
def spiderman_rock(params, t, etc = []):
   """
  This function generates the Kreidberg & Loeb 2016 phase curve model

  Parameters
  ----------
    	t0:		time of conjunction 
	per:		orbital period
	a_abs:		semi-major axis (AU)
	cos(i):	        cosine of the orbital inclination	
	ecc:		eccentricity
	w:		arg of periastron (deg)
	rp:		planet radius (stellar radii)
	a:		semi-major axis (stellar radii)
	p_u1:		planet linear limb darkening parameter
	p_u2:		planet quadratic limb darkening
	T_s:		stellar Teff
	l1:		short wavelength (m)
	l2:		long wavelength (m)
        insol:          insolation (relative to Earth)
        albedo:         Bond albedo
        redist:         fraction of incident flux redistributed to nightside
        npoints:        number of phase bins for light curve interpolation
	

  Returns
  -------
	This function returns planet-to-star flux at each time t. 

  Revisions
  ---------
  2016-02-25 	Laura Kreidberg	
                [email protected] 
                Original version
  TODO          add response function and nlayers to etc
   """


   p = spiderman.ModelParams(brightness_model = 'kreidberg', stellar_model = 'blackbody')

   p.n_layers = 5                  
   p.t0    	    = params[0]
   p.per       	    = params[1]
   p.a_abs 	    = params[2]
   p.inc	    = np.arccos(params[3])*180./np.pi
   p.ecc	    = params[4]
   p.w	   	    = params[5]
   p.rp	    	    = params[6]
   p.a	   	    = params[7]
   p.p_u1	    = params[8]
   p.p_u2	    = params[9]
   p.T_s	    = params[10]
   p.l1	   	    = params[11]
   p.l2	    	    = params[12]
   p.insol          = 1361.*params[13]     #W/m^2
   p.albedo	    = params[14]
   p.redist	    = params[15]
   npoints          = int(params[16])

   #TODO: add filter path to etc
   #p.filter = "/Users/lkreidberg/Desktop/Util/Throughput/spitzer_irac_ch2.txt"


   #calculate light curve over npoints phase bins
   phase = (t - p.t0)/p.per
   phase -= np.round(phase)

   phase_bin = np.linspace(phase.min(), phase.max(), npoints)
   t_bin = phase_bin*p.per + p.t0

   lc_bin = spiderman.web.lightcurve(t_bin, p)

   #interpolate the binned light curve to the original t array
   lc = np.interp(phase, phase_bin, lc_bin)

   return lc 
data = generate_starry_model(times,
                             planet_info,
                             fpfs,
                             lmax=lmax,
                             lambda0=lambda0,
                             Y_1_0=Y_1_0)

nrg_ratio = 0.0
temp_night = 200.
delta_T = 700.
T_star = 4645.

n_layers = 5
brightness_model = "zhang"

spider_params = sp.ModelParams(brightness_model=brightness_model)
spider_params.n_layers = n_layers

n_pts = 100
# times = planet_info.transit_time
# times = times + np.linspace(0, planet_info.orbital_period, n_pts)

init_model = generate_spiderman_model(times, planet_info, nrg_ratio,
                                      temp_night, delta_T, T_star,
                                      spider_params)

data_err = 1.0

args = {
    'data': data,
    'data_err': data_err,