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('')
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()
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))
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)]
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
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
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")
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
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
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
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
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))
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
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,