def depth2rp(P_days, depth, duration_days, Ms, Rs): '''Compute the planet radius from the transit depth and duration using the analtyical treatment from Mandel & Agol 2002''' assert 0 < depth < 1 # compute distance from centres at T0 sma = rvs.semimajoraxis(P_days, Ms, 0) a_Rs = rvs.AU2m(sma) / rvs.Rsun2m(Rs) assert a_Rs > 1 b = rvs.impactparam_T(P_days, Ms, Rs, duration_days) assert abs(b) <= 1 inc = float(rvs.inclination(P_days, Ms, Rs, b)) z = compute_distance_center(a_Rs, inc) # compute size ratio (p=rp/Rs) p_simple = unp.sqrt(depth) if z <= 1 - p_simple: p = p_simple else: ps = np.logspace(-6, 0, 1000) depths = p2depth_grazing(ps, z) if (np.nanmax(depths) < z) or (np.nanmin(depths) > z): p = p_simple else: fint = interp1d(ps, depths) p = float(fint(depth)) # compute planet radius rp = rvs.m2Rearth(rvs.Rsun2m(p * Rs)) return rp
def compute_transit_prob(self): self.transit_prob, self.etransit_prob = np.zeros_like(self.sens), \ np.zeros_like(self.sens) self.logtransit_prob,self.elogtransit_prob = np.zeros_like(self.sens), \ np.zeros_like(self.sens) for i in range(self._xlen): for j in range(self._ylen): # compute transit probability in log-linear space Pmid = 10**(np.log10(self.logPgrid[i]) + \ np.diff(np.log10(self.logPgrid[:2])/2)) rpmid = self.rpgrid[j] + np.diff(self.rpgrid)[0] / 2. sma = rvs.AU2m( rvs.semimajoraxis(Pmid, unp.uarray(self.Ms, self.e_Ms), 0)) transit_prob = (rvs.Rsun2m(unp.uarray(self.Rs, self.e_Rs)) + \ rvs.Rearth2m(rpmid)) / sma self.transit_prob[i, j] = unp.nominal_values(transit_prob) self.etransit_prob[i, j] = unp.std_devs(transit_prob) # compute transit probability in log-linear space rpmid = 10**(np.log10(self.logrpgrid[j]) + \ np.diff(np.log10(self.logrpgrid[:2])/2)) transit_prob = (rvs.Rsun2m(unp.uarray(self.Rs, self.e_Rs)) + \ rvs.Rearth2m(rpmid)) / sma self.logtransit_prob[i, j] = unp.nominal_values(transit_prob) self.elogtransit_prob[i, j] = unp.std_devs(transit_prob) # correction from beta distribution fit (Kipping 2013) factor = 1.08 self.transit_prob *= factor self.etransit_prob *= factor self.logtransit_prob *= factor self.elogtransit_prob *= factor
def sampleK218incdeg_uncorr(incbb, sig=1.5): '''Sample incc from a Gaussian but reject inclinations that result in a transit.''' #sig = 2.2 * 3 # 3sigma on mode of mutual inclination distribution from Fabrycky+2014 smac = .06 incc = incbb + np.random.randn() * sig b = rvs.impactparam_inc(smac / rvs.m2AU(rvs.Rsun2m(Rs)), incc) while abs(b) < 1: incc = incbb + np.random.randn() * sig b = rvs.impactparam_inc(smac / rvs.m2AU(rvs.Rsun2m(Rs)), incc) return incc
def _fit_params(params, bjd, fcorr, ef, Ms, Rs, Teff, Kep=False, TESS=False): '''Get best-fit parameters.''' assert params.shape == (4, ) P, T0, depth, duration = params if Kep: u1, u2 = llnl.get_LDcoeffs_Kepler(Ms, Rs, Teff) elif TESS: u1, u2 = llnl.get_LDcoeffs_TESS(Ms, Rs, Teff) aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs) rpRs = np.sqrt(depth) p0 = aRs, rpRs, 90. bnds = ((aRs * .9, 0, float(rvs.inclination(P, Ms, Rs, 1.1))), (aRs * 1.1, 1, float(rvs.inclination(P, Ms, Rs, -1.1)))) try: popt, _ = curve_fit(transit_model_func_curve_fit(P, T0, u1, u2), bjd, fcorr, p0=p0, sigma=ef, absolute_sigma=True, bounds=bnds) aRs, rpRs, inc = popt depth = rpRs**2 b = rvs.impactparam_inc(P, Ms, Rs, inc) duration = P / (np.pi * aRs) * np.sqrt((1 + np.sqrt(depth))**2 - b * b) return P, T0, depth, duration except RuntimeError: return params
def _is_Vshaped(params, bjd, fcorr, ef, Ms, Rs, Teff, Kep, TESS, duration_frac=.05): '''check if transit is V-shaped although this does not imply an EB because inclined transiting planets can look like this as well.''' # fit transit model assert params.shape == (4, ) P, T0, depth = params[:3] if Kep: u1, u2 = llnl.get_LDcoeffs_Kepler(Ms, Rs, Teff) elif TESS: u1, u2 = llnl.get_LDcoeffs_TESS(Ms, Rs, Teff) aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs) rpRs = np.sqrt(depth) p0 = aRs, rpRs, 90. bnds = ((aRs * .9, 0, float(rvs.inclination(P, Ms, Rs, 1.1))), (aRs * 1.1, 1, float(rvs.inclination(P, Ms, Rs, -1.1)))) try: popt, _ = curve_fit(transit_model_func_curve_fit(P, T0, u1, u2), bjd, fcorr, p0=p0, sigma=ef, absolute_sigma=True, bounds=bnds) aRs, rpRs, inc = popt except RuntimeError: return False, 0. # get ingress, egress times and duration transit_func = transit_model_func_curve_fit(P, T0, 0, 0) fmodel = transit_func(bjd, *popt) phase = foldAt(bjd, P, T0) phase[phase > .5] -= 1 depth = fmodel.min() T1, T4 = phase[(phase<=0) & (fmodel==1)].max()*P, \ phase[(phase>=0) & (fmodel==1)].min()*P in_ingress = (phase <= 0) & np.isclose(fmodel, depth, rtol=1e-4) T2 = phase[in_ingress].min() * P if in_ingress.sum() > 0 else (T4 - T1) * .1 in_egress = (phase >= 0) & np.isclose(fmodel, depth, rtol=1e-4) T3 = phase[in_egress].max() * P if in_egress.sum() > 0 else (T4 - T1) * .1 Tingress, Tegress, duration = T2 - T1, T4 - T3, T4 - T1 Tedge = Tingress + Tegress # V-shaped if T2==T3 or if ingress+egress time is the same as the duration if T2 == T3: return True, duration elif np.isclose(Tedge, duration, rtol=duration_frac): return True, duration else: return False, duration
def _compute_sigrp(frac_sigRs=.1): ''' Use the TESS parameters to estimate the measurement uncertainty on the planet's radius. See http://adsabs.harvard.edu/abs/2008ApJ...689..499C for equations. ''' # Get the 3sigma results starnums, Nharps, Nnirps, Nspirou, texpharps, texpnirps, texpspirou, tobsharps, tobsnirps, tobsspirou, min_Nrv, bestspectrograph_Nrv, min_tobs, bestspectrograph_tobs = np.loadtxt( 'Results/median_results_3sigma_mp.dat', delimiter=',').T # Get TESS parameters including photometric uncertainty inds = np.array([2, 3, 5, 6, 14]) rp, P, K, Rs, logsigV = np.ascontiguousarray(get_TESS_data())[inds] # Compute transit depth uncertainty depth = compute_depth(rp, Rs) Gamma = compute_Gamma() T = compute_transit_duration(rp, P, K, Rs) Q = compute_Q(Gamma, T, depth, logsigV) sigdepth = compute_sigdepth(depth, Q) # compute corresponding planet radius uncertainty depth = unp.uarray(depth, sigdepth) Rs2 = rvs.m2Rearth(rvs.Rsun2m(unp.uarray(Rs, frac_sigRs * Rs))) rp2 = unp.sqrt(depth) * Rs2 return rp, unp.std_devs(rp2)
def __init__(self, folder, index, index2, Nyrs=1e6, Nout=500): self.index, self.index2, self.Nyrs, self.Nout = int(index), int( index2), int(Nyrs), int(Nout) self.Ms = 0. while self.Ms <= 0: self.Ms = Ms + np.random.randn() * .0032 self.bjd0 = 2458354.101878819 # first TESS photometry epoch self.DONE = False # Setup simulation self.folder = folder self.outname = '%s/SimArchive/archived%.4d_%.4d' % ( self.folder, self.index, self.index2) sim = setupsim(self, self.outname) self.mps, self.sma0, self.ecc0, self.inc0, self.omega0, self.Omega0, self.theta0 = get_initial_parameters( sim) self.inc0 += 90 #self.Rhill = get_Rhill_init(self.mps, self.Ms, self.sma0) self.pickleobject() # Integrate simulation print 'Integrating system...' self.bjds,self.RVs,self.smas,self.eccs,self.incs,self.dist,self.stable = \ integrate_sim(np.linspace(0, rvs.yrs2days(self.Nyrs), self.Nout) + self.bjd0, sim) self.bs = np.zeros(self.incs.shape) for i in range(self.bjds.size): self.bs[i] = rvs.impactparam_inc(rvs.AU2m(self.smas[i]) / rvs.Rsun2m(Rs), self.incs[i] + 90, ecc=self.eccs[i]) self.DONE = True self.pickleobject()
def compute_transit_duration(rp, P, K, Rs, b=0): mp = np.array([runTESS.get_planet_mass(i) for i in rp]) Ms = runTESS.get_stellar_mass(P, mp, K) sma = rvs.AU2m(rvs.semimajoraxis(P, Ms, mp)) Rs2 = rvs.Rsun2m(Rs) tau0 = P * Rs2 / (2 * np.pi * sma) return 2. * tau0 * np.sqrt(1. - b**2)
def estimate_box_transit_model(P, T0, Rs, t, f, ef): '''Estimate the transit depth and duration given P and T0. Return the box transit model.''' phase = foldAt(t, P, T0) phase[phase > .5] -= 1 intransit_approx = (phase * P <= 15. / 60 / 24) & (phase * P >= -15. / 60 / 24) depth = np.median(f[intransit_approx]) duration = rvs.transit_width(P, Rs, Rs, rvs.m2Rearth(np.sqrt(depth) * rvs.Rsun2m(Rs)), 0) model = llnl.box_transit_model((P, T0, depth, duration), t) return model
def optimize_singletransit_params(params, bjd, fcorr, ef, Ms, Rs, u1, u2, pltt=True): '''Get best-fit parameters using the periodic fit parameters for initialization (i.e. P_input < P_singletransit).''' assert params.shape == (4, ) P, T0, depth, duration = params if depth >= .9: # sometimes the dimming is passed instead of depth return np.nan, np.nan, np.nan, np.nan, \ np.repeat(np.nan, bjd.size), np.repeat(np.nan, 7) # focus on data centered around T0 g = (bjd >= T0 - 10 * duration) & (bjd <= T0 + 10 * duration) bjdred, fcorrred, efred = bjd[g], fcorr[g], ef[g] # initialize aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs) rpRs = np.sqrt(depth) p0 = P, T0, aRs, rpRs, 90. incs = np.array([ float(rvs.inclination(P, Ms, Rs, 1)), float(rvs.inclination(P, Ms, Rs, -1)) ]) bnds = ((0, T0 - .2, 0, 0, incs.min()), (P * 100, T0 + .2, aRs * 100, 1, incs.max())) try: popt, _ = curve_fit(llnl.transit_model_func_curve_fit(u1, u2), bjdred, fcorrred, p0=p0, sigma=efred, absolute_sigma=True, bounds=bnds) P, T0, aRs, rpRs, inc = popt depth = rpRs**2 b = rvs.impactparam_inc(P, Ms, Rs, inc) duration = P / (np.pi * aRs) * np.sqrt((1 + np.sqrt(depth))**2 - b * b) func = llnl.transit_model_func_curve_fit(u1, u2) fmodel = func(bjdred, P, T0, aRs, rpRs, inc) params = np.array([P, T0, aRs, rpRs, inc, u1, u2]) except RuntimeError, ValueError: func = llnl.transit_model_func_curve_fit(u1, u2) fmodel = func(bjdred, P, T0, aRs, rpRs, 90.) P, T0, depth, duration = np.repeat(np.nan, 4) params = np.repeat(np.nan, 7)
def sampleK218cincdeg(smac, eccc): '''Sample the orbital inclination from its eccentrcitity (<i^2>=<e^2>/4) ensuring that the planet does not transit. smac in AU.''' b, ind = 0, 0 while abs(b) < 1: incc = incb + np.rad2deg(np.sqrt(eccc**2 / 4.)) * np.random.choice( [-1, 1]) # Add noise to inc if cannot find solution if ind > 100: incc += np.random.randn() * ind / 100. b = rvs.impactparam_inc(smac / rvs.m2AU(rvs.Rsun2m(Rs)), incc) ind += 1 return incc
def get_LDcoeffs_TESS(Ms, Rs, Teff, Z=0): '''Interpolate Claret 2017 grid of limb darkening coefficients to a given star.''' # get LD coefficient grid (Z is always 0 for some reason) clarlogg, clarTeff, clarZ, clar_a, clar_b = \ np.loadtxt('LDcoeffs/claret17.tsv', delimiter=';', skiprows=37).T # interpolate to get the stellar LD coefficients logg = np.log10(6.67e-11 * rvs.Msun2kg(Ms) * 1e2 / rvs.Rsun2m(Rs)**2) lint_a = lint(np.array([clarTeff, clarlogg]).T, clar_a) lint_b = lint(np.array([clarTeff, clarlogg]).T, clar_b) return float(lint_a(Teff, logg)), float(lint_b(Teff, logg))
def create_input_file(g, rp, Rs, cloudP, outfile='GCM/terminator/GCM.dat'): ''' Create ExoTransmit input file. Parameters ---------- `outfile': str Name of the output file containing the transmission spectrum `g': scalar Planetary surface gravity in m/s^2 `rp': scalar Planetary radius in Earth radii `Rs': scalar Stellar radius in Solar radii `cloudP': scalar Pressure level of the grey cloud deck in Pascals ''' # create subdirectories if necessary dirs = outfile.split('/')[:-1] for i in range(len(dirs)): try: dirr = '/'.join(dirs[:i + 1]) os.mkdir('%s/Spectra/%s' % (path2exotransmit, dirr)) except OSError: pass # get template fname = '%s/userInput_template.in' % path2exotransmit f = open(fname, 'r') h = f.readlines() f.close() h[3] = '%s\n' % path2exotransmit h[5] = '/T_P/%s\n' % TPfile h[7] = '/EOS/%s\n' % EOSfile h[9] = '/Spectra/%s\n' % outfile h[11] = '%.2f\n' % g h[13] = '%.2e\n' % rvs.Rearth2m(rp) h[15] = '%.2e\n' % rvs.Rsun2m(Rs) h[17] = '%.2e\n' % cloudP h[19] = '1.0\n' # write file f = open('%s/%s' % (path2exotransmit, userfile), 'w') f.write(''.join(h)) f.close()
def get_LDcoeffs_Kepler(Ms, Rs, Teff, Z=0): '''Interpolate Claret+2012 grid of limb darkening coefficients to a given star.''' # get LD coefficient grid (Z is always 0 for some reason) clarlogg, clarTeff, clarZ, clar_a, clar_b = \ np.loadtxt('LDcoeffs/claret12.tsv', delimiter=';', skiprows=43, usecols=(0,1,2,3,4)).T # interpolate to get the stellar LD coefficients logg = np.log10(6.67e-11 * rvs.Msun2kg(Ms) * 1e2 / rvs.Rsun2m(Rs)**2) logg = 5. if logg > 5 else float(logg) logg = 3.5 if logg < 3.5 else float(logg) lint_a = lint(np.array([clarTeff, clarlogg]).T, clar_a) lint_b = lint(np.array([clarTeff, clarlogg]).T, clar_b) return float(lint_a(Teff, logg)), float(lint_b(Teff, logg))
def _draw_prot(Ms, Rs, fname): ''' Draw a rotation period and compute vsini or use the existing parameters for this system. ''' # If a simulation of this system exists, read in those parameters fs = np.array( glob.glob('%s_*_%s' % (fname.split('_')[0], fname.split('_')[-1]))) if fs.size > 0: Prot, vsini = np.loadtxt(fs[0], usecols=(11, 12)) # Otherwise sample new rotation information else: Prot = draw_prot_empirical(Ms) I = abs(np.arccos(np.random.uniform(-1, 1))) vsini = 2 * np.pi * rvs.Rsun2m(Rs) * 1e-3 * np.sin(I) / rvs.days2sec( Prot) return Prot, vsini
def fit_params(params, bjd, fcorr, ef, Ms, Rs, Teff, Kep=False, TESS=False): '''Get best-fit parameters.''' assert params.shape == (4, ) P, T0, depth, duration = params if depth >= .9: # sometimes the dimming is passed instead of depth return np.nan, np.nan, np.nan, np.nan, \ np.repeat(np.nan, bjd.size), np.repeat(np.nan, 7) if Kep: u1, u2 = get_LDcoeffs_Kepler(Ms, Rs, Teff) if TESS: u1, u2 = get_LDcoeffs_TESS(Ms, Rs, Teff) assert np.all(np.isfinite([u1, u2])) aRs = rvs.AU2m(rvs.semimajoraxis(P, Ms, 0)) / rvs.Rsun2m(Rs) rpRs = np.sqrt(depth) p0 = P, T0, aRs, rpRs, 90. incs = np.array([ float(rvs.inclination(P, Ms, Rs, 1)), float(rvs.inclination(P, Ms, Rs, -1)) ]) bnds = ((P * .9, T0 - P * 1.1, aRs * .9, 0, incs.min()), (P * 1.1, T0 + P * 1.1, aRs * 1.1, 1, incs.max())) try: popt, _ = curve_fit(transit_model_func_curve_fit(u1, u2), bjd, fcorr, p0=p0, sigma=ef, absolute_sigma=True, bounds=bnds) P, T0, aRs, rpRs, inc = popt depth = rpRs**2 b = rvs.impactparam_inc(P, Ms, Rs, inc) duration = P / (np.pi * aRs) * np.sqrt((1 + np.sqrt(depth))**2 - b * b) func = transit_model_func_curve_fit(u1, u2) fmodel = func(bjd, P, T0, aRs, rpRs, inc) params = np.array([P, T0, aRs, rpRs, inc, u1, u2]) except RuntimeError, ValueError: func = transit_model_func_curve_fit(u1, u2) fmodel = func(bjd, P, T0, aRs, rpRs, 90.) P, T0, depth, duration = np.repeat(np.nan, 4) params = np.repeat(np.nan, 7)
def estimate_Nrv_TESS(planetindex, band_strs, R, aperture_m, QE=.1, Z=0, sigmaRV_activity=0, sigmaRV_planets=0, sigmaRV_noisefloor=.5, testingseed=False, testplanet_sigmaKfrac=0, systnum=0, verbose=True): ''' Estimate the number of RVs required to measure the mass of a transiting TESS planet at a particular detection significance with a particular instrument. Parameters ---------- `planetindex': scalar Index of the TESS planet from the results of the predicted TESS planets from Sullivan et al 2015 `band_strs': list of strs A list of the spectral bands that span the wavelength coverage of the spectrograph used to measure the radial velocities of the TESS star. All band_strs entries must be in ['U','B','V','R','I','Y','J','H','K'] and at least one of ['V','I','J','K'] must be included for scaling of the TESS stars from Sullivan `R': scalar The spectral resolution of the spectrograph (lambda / d_lambda) `aperture_m': float The telescope's aperture diameter in meters `QE': scalar The quantum efficiency of the detector (0<QE<=1) `Z': scalar The assumed metallicity ([Fe/H]) of the TESS star in solar units `sigmaRV_activity': scalar An additive source of RV uncertainty from RV activity or jitter in m/s. To be added in quadrature to the photon-noise RV precision derived for the TESS star `sigmaRV_planets': scalar An additive source of RV uncertainty from unseen planets in m/s. To be added in quadrature to the photon-noise RV precision derived for the TESS star `testingseed': boolean If True, use a seed for the random number generator used to draw the stellar rotation period, RV activity, and RV from planets. Useful for testing `testplanet_sigmaKfrac': scalar If 0, assume we are calculating a TESS planet and use its mass to determine the required constraint on the K measurement uncertainty (sigmaK). Otherwise, set this value to the fractional K measurement uncertainty as is done for test cases (e.g. 0.33 for GJ1132) `systnum': scalar System index used when saving the simulation results `verbose': boolean If True, results for this star are printed to screen Returns ------- `Nrv': int The number of radial velocity measurements required to detect the TESS planet's mass at a given significance `texp': float The exposure time in minutes for each radial velocity measurement `tobserving': float The total observing time in hours including a constant estimate of overheads `sigmaRV_phot': float The photon-noise limit on the RV measurement precision in m/s `sigmaRV_eff': float The effective RV measurement precision from the combined effects of photon-noise, instrument stability, multiple planets, and stellar activity in m/s ''' # Read-in TESS data for this planetary system ra,dec,rp,P,S,K,Rs,Teff,Vmag,Imag,Jmag,Kmag,dist,_,_,_,mult = \ get_TESS_data() nplanets, planetindex = ra.size, int(planetindex) assert 0 <= planetindex < nplanets ra, dec = ra[planetindex], dec[planetindex] rp,P,S,K,Rs,Teff,Vmag,Imag,Jmag,Kmag,dist,mult = rp[planetindex], \ P[planetindex], \ S[planetindex], \ K[planetindex], \ Rs[planetindex], \ Teff[planetindex], \ Vmag[planetindex], \ Imag[planetindex], \ Jmag[planetindex], \ Kmag[planetindex], \ dist[planetindex], \ mult[planetindex] mult = 1. if mult == 0 else mult # Compute parameters of interest mp = get_planet_mass(rp) Ms = get_stellar_mass(P, mp, K) logg = np.log10(G * rvs.Msun2kg(Ms) / rvs.Rsun2m(Rs)**2 * 1e2) # Round Teff and logg Teffs = np.append(np.arange(23e2, 7e3, 1e2), np.arange(7e3, 121e2, 2e2)) Teff_round = Teffs[abs(Teffs - Teff) == np.min(abs(Teffs - Teff))][0] loggs = np.arange(0, 6.1, .5) logg_round = loggs[abs(loggs - logg) == np.min(abs(loggs - logg))][0] # Get the stellar magnitudes in the desired bands scaled to the results # from Sullivan known_mags = [Vmag, Imag, Jmag, Kmag] band_strs_tmp = list(np.append(band_strs, 'B')) mags = _get_magnitudes(band_strs_tmp, known_mags, Teff_round, logg_round, Z, Ms) mags, Bmag = mags[:-1], float(mags[-1]) B_V = Bmag - Vmag # compute vsini if testingseed: np.random.seed(1) fname = 'Results/star%.4d/TESSplanet%.4d_%s_%.4d.dat' % ( planetindex, planetindex, ''.join(band_strs), systnum) Prot, vsini = _draw_prot(Ms, Rs, fname) # Estimate Nrv for this TESS planet startheta = mags, float(Teff_round), float(logg_round), Z, vsini, Ms, \ Prot, B_V planettheta = rp, mp, K, P, mult instrumenttheta = band_strs, R, aperture_m, QE Nrv,NrvGP,texp,tobs,tobsGP,sigK_target,sig_phot,sig_act,sig_planets,sig_eff = \ estimate_Nrv(startheta, planettheta, instrumenttheta, fname=fname, sigmaRV_activity=sigmaRV_activity, sigmaRV_planets=sigmaRV_planets, sigmaRV_noisefloor=sigmaRV_noisefloor, testplanet_sigmaKfrac=testplanet_sigmaKfrac) if verbose: print '\n%40s = %.3f m/s' % ('Photon-noise limited RV uncertainty', sig_phot) print '%40s = %.3f m/s' % ('Effective RV uncertainty', sig_eff) print '%40s = %.3f' % ('Target fractional K uncertainty', sigK_target / K) print '%40s = %i' % ('Number of RVs', Nrv) print '%40s = %i' % ('Number of RVs (GP)', NrvGP) print '%40s = %.3f minutes' % ('Exposure time', texp) print '%40s = %.3f hours' % ('Total observing time', tobs) print '%40s = %.3f hours' % ('Total observing time (GP)', tobsGP) # Save values save_results(planetindex, band_strs, mags, ra, dec, P, rp, mp, K, S, Ms, Rs, Teff, dist, Prot, vsini, Z, sig_act, sig_planets, R, aperture_m, QE, sigK_target / K, sig_phot, sig_eff, texp, tobs, Nrv, tobsGP, NrvGP, fname)
def rpRs2rp(rpRs, Rs): rp = rvs.m2Rearth(rvs.Rsun2m(rpRs * Rs)) return unp.nominal_values(rp), unp.std_devs(rp)
def compute_depth(rp, Rs): return (rvs.Rearth2m(rp) / rvs.Rsun2m(Rs))**2
def sample_planet_params(self, index, postGAIA=True): '''sample distribution of planet parameters from observables and stellar pdfs''' # get stellar parameters PDFs either from derived from GAIA distances # or from original Kepler parameters (approximate distributions as skewnormal) g = int(index) print self.KepIDs[g] if postGAIA: path = '../GAIAMdwarfs/Gaia-DR2-distances_custom/DistancePosteriors/' try: samp_Rs, samp_Teff, samp_Ms = np.loadtxt('%s/KepID_allpost_%i' % (path, self.KepIDs[g]), delimiter=',', usecols=(9, 10, 11)).T except IOError: samp_Rs, samp_Teff, samp_Ms = np.zeros(1000), np.zeros( 1000), np.zeros(1000) if np.all(np.isnan(samp_Rs)) or np.all(np.isnan(samp_Teff)) or np.all( np.isnan(samp_Ms)): samp_Rs, samp_Teff, samp_Ms = np.zeros(1000), np.zeros( 1000), np.zeros(1000) samp_Rs = resample_PDF(samp_Rs[np.isfinite(samp_Rs)], samp_Rs.size, sig=1e-3) samp_Teff = resample_PDF(samp_Teff[np.isfinite(samp_Teff)], samp_Teff.size, sig=5) samp_Ms = resample_PDF(samp_Ms[np.isfinite(samp_Ms)], samp_Ms.size, sig=1e-3) else: _, _, samp_Rs = get_samples_from_percentiles(self.Rss1[g], self.ehi_Rss1[g], self.elo_Rss1[g], Nsamp=1e3) _, _, samp_Teff = get_samples_from_percentiles(self.Teffs1[g], self.ehi_Teffs1[g], self.elo_Teffs1[g], Nsamp=1e3) _, _, samp_Ms = get_samples_from_percentiles(self.Mss1[g], self.ehi_Mss1[g], self.elo_Mss1[g], Nsamp=1e3) # sample rp/Rs distribution from point estimates _, _, samp_rpRs = get_samples_from_percentiles(self.rpRs[g], self.ehi_rpRs[g], self.elo_rpRs[g], Nsamp=samp_Rs.size) # compute planet radius PDF samp_rp = rvs.m2Rearth(rvs.Rsun2m(samp_rpRs * samp_Rs)) v = np.percentile(samp_rp, (16, 50, 84)) rps = v[1], v[2] - v[1], v[1] - v[0] # compute semi-major axis PDF samp_Ps = np.random.normal(self.Ps[g], self.e_Ps[g], samp_Ms.size) samp_as = rvs.semimajoraxis(samp_Ps, samp_Ms, 0) v = np.percentile(samp_as, (16, 50, 84)) smas = v[1], v[2] - v[1], v[1] - v[0] # compute equilibrium T PDF (Bond albedo=0) samp_Teq = samp_Teff * np.sqrt( .5 * rvs.Rsun2m(samp_Rs) / rvs.AU2m(samp_as)) v = np.percentile(samp_Teq, (16, 50, 84)) Teqs = v[1], v[2] - v[1], v[1] - v[0] # compute insolation samp_F = samp_Rs**2 * (samp_Teff / 5778.)**4 / samp_as**2 v = np.percentile(samp_F, (16, 50, 84)) Fs = v[1], v[2] - v[1], v[1] - v[0] return rps, smas, Teqs, Fs
def compute_logg(Ms, Rs): G = 6.67e-11 return unp.log10(G * rvs.Msun2kg(Ms) * 1e2 / rvs.Rsun2m(Rs)**2)
def get_Kepler_Mdwarf_planets(fname): ''' I have a list of Kepler M dwarfs with stellar parameters based on GAIA distances. I also have a list of confirmed Kepler planets from the NASA exoplanet archive. Match the two lists to get the empirical population of Kepler M dwarf planets with high precision radii and updated stellar parameters. ''' # get Kepler Mdwarfs parameters from GAIA dG = np.loadtxt(KepMdwarffile, delimiter=',') KepID, isMdwarf, badGAIA, bad2MASS, baddistpost, badTeff, ra_deg, dec_deg, GBPmag, e_GBPmag, GRPmag, e_GRPmag, Kepmag, Jmag, e_Jmag, Hmag, e_Hmag, Kmag, e_Kmag, parallax_mas, e_parallax, dist_pc, ehi_dist, elo_dist, mu, ehi_mu, elo_mu, AK, e_AK, BCK, e_BCK, MK, ehi_MK, elo_MK, Rs_RSun, ehi_Rs, elo_Rs, Teff_K, ehi_Teff, elo_Teff, Ms_MSun, ehi_Ms, elo_Ms, logg_dex, ehi_logg, elo_logg = dG.T # get planet transits parameters from NASA exoplanet archive dK = np.genfromtxt( 'Keplertargets/NASAarchive_confirmed_Keplerlowmassstars.csv', delimiter=',', skip_header=66) loc_rowid, kepid, kepler_name, koi_disposition, koi_score, koi_period, koi_period_err1, koi_period_err2, koi_time0, koi_time0_err1, koi_time0_err2, koi_impact, koi_impact_err1, koi_impact_err2, koi_duration, koi_duration_err1, koi_duration_err2, koi_depth, koi_depth_err1, koi_depth_err2, koi_ror, koi_ror_err1, koi_ror_err2, koi_prad, koi_prad_err1, koi_prad_err2, koi_incl, koi_incl_err1, koi_incl_err2, koi_dor, koi_dor_err1, koi_dor_err2, koi_limbdark_mod, koi_ldm_coeff4, koi_ldm_coeff3, koi_ldm_coeff2, koi_ldm_coeff1, koi_model_snr, koi_steff, koi_steff_err1, koi_steff_err2, koi_slogg, koi_slogg_err1, koi_slogg_err2, koi_smet, koi_smet_err1, koi_smet_err2, koi_srad, koi_srad_err1, koi_srad_err2, koi_kepmag, koi_jmag, koi_hmag, koi_kmag = dK.T # match stellar parameters to confirmed Kepler stars Nplanets = kepid.size self = KepConfirmedMdwarfPlanets(fname, Nplanets) self._initialize_arrays() for i in range(Nplanets): print float(i) / Nplanets g = np.in1d(KepID, kepid[i]) print g.sum() # stellar parameters (both pre (1) and post-GAIA (2)) self.KepIDs[i] = kepid[i] self.isMdwarf[i] = isMdwarf[g] if g.sum() == 1 else np.nan self.badGAIA[i] = badGAIA[g] if g.sum() == 1 else np.nan self.bad2MASS[i] = bad2MASS[g] if g.sum() == 1 else np.nan self.baddistpost[i] = baddistpost[g] if g.sum() == 1 else np.nan self.badTeff[i] = badTeff[g] if g.sum() == 1 else np.nan self.Jmags[i] = Jmag[g] if g.sum() == 1 else np.nan self.e_Jmags[i] = e_Jmag[g] if g.sum() == 1 else np.nan self.Hmags[i] = Hmag[g] if g.sum() == 1 else np.nan self.e_Hmags[i] = e_Hmag[g] if g.sum() == 1 else np.nan self.Kmags[i] = Kmag[g] if g.sum() == 1 else np.nan self.e_Kmags[i] = e_Kmag[g] if g.sum() == 1 else np.nan self.pars[i] = parallax_mas[g] if g.sum() == 1 else np.nan self.e_pars[i] = e_parallax[g] if g.sum() == 1 else np.nan self.mus[i] = mu[g] if g.sum() == 1 else np.nan self.ehi_mus[i] = ehi_mu[g] if g.sum() == 1 else np.nan self.elo_mus[i] = elo_mu[g] if g.sum() == 1 else np.nan self.dists[i] = dist_pc[g] if g.sum() == 1 else np.nan self.ehi_dists[i] = ehi_dist[g] if g.sum() == 1 else np.nan self.elo_dists[i] = elo_dist[g] if g.sum() == 1 else np.nan self.AKs[i] = AK[g] if g.sum() == 1 else np.nan self.e_AKs[i] = e_AK[g] if g.sum() == 1 else np.nan self.BCKs[i] = BCK[g] if g.sum() == 1 else np.nan self.e_BCKs[i] = e_BCK[g] if g.sum() == 1 else np.nan self.MKs[i] = MK[g] if g.sum() == 1 else np.nan self.ehi_MKs[i] = ehi_MK[g] if g.sum() == 1 else np.nan self.elo_MKs[i] = elo_MK[g] if g.sum() == 1 else np.nan # pre-GAIA self.Rss1[i] = koi_srad[i] self.ehi_Rss1[i] = koi_srad_err1[ i] if koi_srad_err1[i] > 0 else koi_srad[i] * .07 self.elo_Rss1[i] = abs( koi_srad_err2[i]) if koi_srad_err2[i] < 0 else koi_srad[i] * .08 self.Teffs1[i] = koi_steff[i] self.ehi_Teffs1[i] = koi_steff_err1[ i] if koi_steff_err1[i] > 0 else koi_steff[i] * .02 self.elo_Teffs1[i] = abs( koi_steff_err2[i]) if koi_steff_err2[i] < 0 else koi_steff[i] * .02 self.loggs1[i] = koi_slogg[i] self.ehi_loggs1[i] = koi_slogg_err1[ i] if koi_slogg_err1[i] > 0 else koi_slogg[i] * .009 self.elo_loggs1[i] = abs( koi_slogg_err2[i] ) if koi_slogg_err2[i] < 0 else koi_slogg[i] * .006 _, _, samp_Rs = get_samples_from_percentiles(self.Rss1[i], self.ehi_Rss1[i], self.elo_Rss1[i], Nsamp=1e3) _, _, samp_logg = get_samples_from_percentiles(self.loggs1[i], self.ehi_loggs1[i], self.elo_loggs1[i], Nsamp=1e3) samp_Ms = rvs.kg2Msun(10**samp_logg * rvs.Rsun2m(samp_Rs)**2 * 1e-2 / G) v = np.percentile(samp_Ms, (16, 50, 84)) self.Mss1[i], self.ehi_Mss1[i], self.elo_Mss1[i] = v[ 1], v[2] - v[1], v[1] - v[0] self.FeHs1[i] = koi_smet[i] self.ehi_FeHs1[i] = koi_smet_err1[i] self.elo_FeHs1[i] = abs(koi_smet_err1[i]) # post-GAIA self.Rss2[i] = Rs_RSun[g] if g.sum() == 1 else np.nan self.ehi_Rss2[i] = ehi_Rs[g] if g.sum() == 1 else np.nan self.elo_Rss2[i] = elo_Rs[g] if g.sum() == 1 else np.nan self.Teffs2[i] = Teff_K[g] if g.sum() == 1 else np.nan self.ehi_Teffs2[i] = ehi_Teff[g] if g.sum() == 1 else np.nan self.elo_Teffs2[i] = elo_Teff[g] if g.sum() == 1 else np.nan self.Mss2[i] = Ms_MSun[g] if g.sum() == 1 else np.nan self.ehi_Mss2[i] = ehi_Ms[g] if g.sum() == 1 else np.nan self.elo_Mss2[i] = elo_Ms[g] if g.sum() == 1 else np.nan self.loggs2[i] = logg_dex[g] if g.sum() == 1 else np.nan self.ehi_loggs2[i] = ehi_logg[g] if g.sum() == 1 else np.nan self.elo_loggs2[i] = elo_logg[g] if g.sum() == 1 else np.nan # planet parameters self.Ps[i] = koi_period[i] self.e_Ps[i] = np.abs([koi_period_err1[i], koi_period_err2[i]]).mean() self.T0s[i] = koi_time0[i] self.e_T0s[i] = np.abs([koi_time0_err1[i], koi_time0_err2[i]]).mean() self.Ds[i] = koi_duration[i] self.e_Ds[i] = np.abs([koi_duration_err1[i], koi_duration_err2[i]]).mean() self.Zs[i] = koi_depth[i] self.e_Zs[i] = np.abs([koi_depth_err1[i], koi_depth_err2[i]]).mean() self.aRs[i] = koi_dor[i] self.e_aRs[i] = np.abs([koi_dor_err1[i], koi_dor_err2[i]]).mean() self.rpRs[i] = koi_ror[i] self.ehi_rpRs[i] = koi_ror_err1[i] self.elo_rpRs[i] = abs(koi_ror_err2[i]) self.bs[i] = koi_impact[i] self.ehi_bs[i] = koi_impact_err1[i] self.elo_bs[i] = abs(koi_impact_err2[i]) # completeness parameters self.CDPPs[i] = get_fitted_cdpp(self.KepIDs[i], self.Ds[i]) self.data_spans[i] = data_spanC[kepidC == self.KepIDs[i]] self.SNRtransits[i] = self.Zs[i] / self.CDPPs[i] * np.sqrt( get_Ntransits(self.KepIDs[i], self.Ps[i])) # computed planet parameters if self.isMdwarf[i]: rps1, smas1, Teqs1, Fs1 = sample_planet_params(self, i, postGAIA=False) self.rps1[i], self.ehi_rps1[i], self.elo_rps1[i] = rps1 self.smas1[i], self.ehi_smas1[i], self.elo_smas1[i] = smas1 self.Teqs1[i], self.ehi_Teqs1[i], self.elo_Teqs1[i] = Teqs1 self.Fs1[i], self.ehi_Fs1[i], self.elo_Fs1[i] = Fs1 rps2, smas2, Teqs2, Fs2 = sample_planet_params(self, i, postGAIA=True) self.rps2[i], self.ehi_rps2[i], self.elo_rps2[i] = rps2 self.smas2[i], self.ehi_smas2[i], self.elo_smas2[i] = smas2 self.Teqs2[i], self.ehi_Teqs2[i], self.elo_Teqs2[i] = Teqs2 self.Fs2[i], self.ehi_Fs2[i], self.elo_Fs2[i] = Fs2 # save Kepler M dwarf planet population self._pickleobject()
def identify_EBs(params, bjd, fcorr, ef, Ms, Rs, Teff, SNRthresh=3., rpmax=30, detthresh=5, Kep=False, TESS=False): '''For each proposed planet in params, run through a variety of checks to vetting the planetary candidates and identify EB false positives.''' assert len(params.shape) == 2 Nplanets = params.shape[0] paramsout, isEB, maybeEB = np.zeros_like(params), np.zeros(Nplanets), \ np.zeros(Nplanets) EBconditions = np.zeros((Nplanets, 5)).astype(bool) EBcondition_labels = np.array([ 'rpRs > 0.5', 'rp>%.1f' % rpmax, 'secondary eclipse detected', 'transit is V-shaped', 'transit duration is too long for a planet' ]) for i in range(Nplanets): # get best fit parameters paramsout[i] = _fit_params(params[i], bjd, fcorr, ef, Ms, Rs, Teff, Kep=Kep, TESS=TESS) # ensure the planet is not too big rpRs = np.sqrt(params[i, 2]) isEB[i] = 1 if rpRs > .5 else isEB[i] EBconditions[i, 0] = True if rpRs > .5 else False rp = rvs.m2Rearth(rvs.Rsun2m(rpRs * Rs)) isEB[i] = 1 if rp > rpmax else isEB[i] EBconditions[i, 1] = True if rp > rpmax else False # check for secondary eclipse eclipse = _is_eclipse(params[i], bjd, fcorr, ef, detthresh) isEB[i] = 1 if eclipse else isEB[i] EBconditions[i, 2] = True if eclipse else False # check for ellipsoidal variations #ellipsoidal = _is_ellipsoidal() #isEB[i] = 1 if ellipsoidal else isEB[i] # how can I do this without knowing the parameters of the binary? # flag V-shaped transits (does not implies an EB) Vshaped, duration = _is_Vshaped(params[i], bjd, fcorr, ef, Ms, Rs, Teff, Kep, TESS) maybeEB[i] = 1 if Vshaped else maybeEB[i] EBconditions[i, 3] = True if Vshaped else False # is duration reasonable? # Gunther+2016 EBduration = _is_EB_duration(duration, paramsout[i, 0], Ms, Rs) isEB[i] = 1 if EBduration else isEB[i] EBconditions[i, 4] = True if EBduration else False # save planet and EB parameters maybeEB[isEB == 1] = 1 isEB, maybeEB = isEB.astype(bool), maybeEB.astype(bool) params, EBparams, maybeEBparams = params[np.invert(isEB)], params[isEB], \ params[maybeEB] return params, EBparams, maybeEBparams, EBconditions, EBcondition_labels
def run_mcmc(params, bjd, fcorr, ef, Ms, eMs, Rs, eRs, Teff, eTeff, u1, u2, nwalkers=200, burnin=500, nsteps=400, pltt=True): assert params.shape == (4, ) params_optimized = np.zeros(5) nwalkers, burnin, nsteps = int(nwalkers), int(burnin), int(nsteps) params_results = np.zeros((3, 5)) # get optimized parameters and get the LC around T0 bjdred, fcorrred, efred, fmodel_opt, theta = \ optimize_singletransit_params(params, bjd, fcorr, ef, Ms, Rs, u1, u2, pltt=1) params_opt = theta[:5] print params, params_opt # run MCMC on transit LC initialize = [1, 1e-3, 1, 1e-2, 1] print 'Running MCMC on single-transit model' sampler, samples = run_emcee(params_opt, bjd, bjdred, fcorrred, efred, initialize, u1, u2, Ms, Rs, a=2, nwalkers=nwalkers, burnin=burnin, nsteps=nsteps, zeroplanetmodel=False) results = get_results(samples) params_results = results func = llnl.transit_model_func_curve_fit(u1, u2) fmodel_mcmc = func(bjdred, *params_results[0]) # estimate single transit P, aRs, rpRs, and inc Nsamp = samples.shape[0] samp_Ms = np.random.randn(Nsamp) * eMs + Ms samp_Rs = np.random.randn(Nsamp) * eRs + Rs samp_rho = rvs.Msun2kg(samp_Ms) / rvs.Rsun2m(samp_Rs)**3 samp_aRs = samples[:, 2] v = np.percentile(samp_aRs, (16, 50, 84)) aRs_est = [v[1], v[2] - v[1], v[1] - v[0]] samp_rpRs = samples[:, 3] v = np.percentile(samp_rpRs, (16, 50, 84)) rpRs_est = [v[1], v[2] - v[1], v[1] - v[0]] samp_inc = samples[:, 4] v = np.percentile(samp_inc, (16, 50, 84)) inc_est = [v[1], v[2] - v[1], v[1] - v[0]] #samp_P=rvs.sec2days(np.sqrt(4*np.pi*np.pi/(6.67e-11*samp_rho)*samp_aRs**3)) samp_P = samples[:, 0] v = np.percentile(samp_P, (16, 50, 84)) P_est = [v[1], v[2] - v[1], v[1] - v[0]] # estimate F samp_Teff = np.random.randn(Nsamp) * eTeff + Teff samp_Ls = compute_Ls(samp_Rs, samp_Teff) samp_F = compute_F(samp_Ls, rvs.semimajoraxis(samp_P, samp_Ms, 0)) v = np.percentile(samp_F, (16, 50, 84)) F_est = [v[1], v[2] - v[1], v[1] - v[0]] # plotting if pltt: t0 = 2457000 plt.figure(1) plt.plot(bjdred - t0, fcorrred, '.') plt.plot(bjdred - t0, fmodel_opt, '-', lw=3, label='optimized') plt.plot(bjdred - t0, fmodel_mcmc, '-', lw=2, label='MCMC model') plt.legend(loc='upper left') plt.figure(2) plt.hist(samp_P, bins=30) plt.show() return bjd, fcorr, ef, params_opt, fmodel_opt, samples, params_results, fmodel_mcmc, samp_P, P_est, samp_F, F_est, aRs_est, rpRs_est, inc_est
def get_data(self): self.fs = np.array( glob.glob('%s/%s_%i/*LC*' % (self.folder, self.prefix, self.epicnum))) # remove planet search result (i.e. with index -99) if np.any( np.in1d( self.fs, '%s/%s_%i/%sLC_-00099' % (self.folder, self.prefix, self.epicnum, self.prefix))): g = np.where( np.in1d( self.fs, '%s/%s_%i/LC_-00099' % (self.folder, self.prefix, self.epicnum)))[0][0] self.fs = np.delete(self.fs, g) if self.fs.size == 0: return None self.Nsim = 0 d = loadpickle(self.fs[0]) self.Kepmag, self.logg, self.Ms, self.Rs, self.Teff = d.Kepmag, \ d.logg, \ d.Ms, d.Rs, \ d.Teff self.e_logg, self.e_Ms, self.e_Rs, self.e_Teff = d.e_logg, \ d.e_Ms, d.e_Rs, \ d.e_Teff Nmax = 20 self.Nplanets_true, self.Nplanets_found = np.zeros(0), np.zeros(0) self.Ps, self.rps, self.isdet = np.zeros((0, Nmax)), np.zeros( (0, Nmax)), np.zeros((0, Nmax)) self.Psfound, self.rpsfound, self.isFP = np.zeros((0, Nmax)), np.zeros( (0, Nmax)), np.zeros((0, Nmax)) for i in range(self.fs.size): print float(i) / self.fs.size d = loadpickle(self.fs[i]) if d.DONE: self.Nsim += 1 self.Nplanets_true = np.append(self.Nplanets_true, d.Ptrue.size) filler = np.repeat(np.nan, Nmax - self.Nplanets_true[-1]) Pin = np.append(d.Ptrue, filler) rpin = np.append(d.rptrue, filler) isdetin = np.append(d.is_detected, filler) self.Ps = np.append(self.Ps, Pin.reshape(1, Nmax), axis=0) self.rps = np.append(self.rps, rpin.reshape(1, Nmax), axis=0) self.isdet = np.append(self.isdet, isdetin.reshape(1, Nmax), axis=0) # get false positives TEMP because d.is_FP doesnt exist yet until # the simulation is rerun params = d.params_guess self.Nplanets_found = np.append(self.Nplanets_found, params.shape[0]) filler2 = np.repeat(np.nan, Nmax - self.Nplanets_found[-1]) Pinfound = np.append(params[:, 0], filler2) rpinfound = np.append( rvs.m2Rearth(rvs.Rsun2m(np.sqrt(params[:, 2]) * d.Rs)), filler2) self.Psfound = np.append(self.Psfound, Pinfound.reshape(1, Nmax), axis=0) self.rpsfound = np.append(self.rpsfound, rpinfound.reshape(1, Nmax), axis=0) is_FPin = np.array([ int( np.invert( np.any(np.isclose(d.Ptrue, params[i, 0], rtol=.02)))) for i in range(params.shape[0]) ]).astype(bool) self.isFP = np.append(self.isFP, np.append(is_FPin, filler2).reshape(1, Nmax), axis=0) # trim excess planets end = np.where(np.all(np.isnan(self.Ps), axis=0))[0][0] self.Ps = self.Ps[:, :end] self.rps = self.rps[:, :end] self.isdet = self.isdet[:, :end] #end2 = np.where(np.all(np.isnan(self.PsFP), axis=0))[0][0] self.Psfound = self.Psfound[:, :end] self.rpsfound = self.rpsfound[:, :end] self.isFP = self.isFP[:, :end]
def run_emcee(theta, bjd, bjdred, fred, efred, initialize, u1, u2, Ms, Rs, nwalkers=200, burnin=200, nsteps=400, a=2, zeroplanetmodel=False): '''Run mcmc on an input light curve with no transit model.''' # get limits on P and aRs P, T0 = theta[:2] Plim = np.max([T0 - bjd.min(), bjd.max() - T0]) aRslim = rvs.AU2m(rvs.semimajoraxis(Plim, Ms, 0)) / rvs.Rsun2m(Rs) print 'Plim = %.4f' % Plim print 'aRslim = %.4f' % aRslim # initialize chains assert len(theta) == len(initialize) assert len(theta) == 5 theta[0], theta[2] = Plim + 10, aRslim + 10 p0 = [] for i in range(nwalkers): p0.append(theta + initialize * np.random.randn(len(theta))) # initialize sampler P = theta[0] inclims = np.array([ float(rvs.inclination(P, Ms, Rs, 1)), float(rvs.inclination(P, Ms, Rs, -1)) ]) args = (theta, bjdred, fred, efred, Plim, aRslim, inclims, u1, u2, zeroplanetmodel) sampler = emcee.EnsembleSampler(nwalkers, len(theta), lnprob, args=args, a=a) # run burnin print 'Running burnin...' t0 = time.time() p0, _, _ = sampler.run_mcmc(p0, burnin) print 'Burnin acceptance fraction is %.4f' % np.mean( sampler.acceptance_fraction) print 'Burnin took %.4f minutes\n' % ((time.time() - t0) / 60.) sampler.reset() # run MCMC print 'Running full MCMC...' p0, _, _ = sampler.run_mcmc(p0, nsteps) samples = sampler.chain.reshape((-1, len(theta))) print "Mean acceptance fraction: %.4f" % np.mean( sampler.acceptance_fraction) print 'Full MCMC took %.4f minutes' % ((time.time() - t0) / 60.) return sampler, samples