Multi-planet Mode

Estimate the intrinsic distribution of planetary systems by fitting a population of multi-planet systems to Kepler data

[1]:
import EPOS
import numpy as np
import matplotlib.pyplot as plt

initialize the EPOS class

[2]:
epos= EPOS.epos(name='example_2')


 |~| epos 3.0.0.dev2 |~|


Using random seed 493439428

Read in the kepler dr25 exoplanets and survey efficiency packaged with EPOS

[3]:
obs, survey= EPOS.kepler.dr25(Huber=True, Vetting=True, score=0.9)
epos.set_observation(**obs)
epos.set_survey(**survey)

Loading planets from temp/q1_q17_dr25_koi.npz
  6853/7995 dwarfs
  3525 candidates, 3328 false positives
  3040+1 with score > 0.90

Observations:
  159238 stars
  3041 planets

  1840 singles, 487 multis
  - single: 1840
  - double: 324
  - triple: 113
  - quad: 38
  - quint: 10
  - sext: 2

Define the function that describes the intrinsic planetary system population. Here we use a double broken power-law from EPOS.fitfunctions to deinfe the location and size of the innermost planet in each system.

[4]:
epos.set_parametric(EPOS.fitfunctions.brokenpowerlaw2D)

brokenpowerlaw2D takes 8 parameters. The two dependent parameters are the period and radius. There are 6 free parameters (xp, p1, p2, yp, p3, p4) and a normalization parameter. Let’s define them:

The normalization parameter, labeled pps, defines the fraction of stars with planetary systems. Let’s assign a planetary system to 40% of stars, and exclude negative numbers with the min keyword.

[5]:
epos.fitpars.add('pps', 0.4, min=0, isnorm=True)

Initialize the 6 parameters that define the distribution of the innermost planets, fixing the radius distribution.

[6]:
epos.fitpars.add('P break', 10., min=2, max=50, is2D=True)
epos.fitpars.add('a_P', 1.5, min=0, is2D=True)
epos.fitpars.add('b_P', -1, max=1, dx=0.1, is2D=True)
epos.fitpars.add('R break', 3.3, fixed=True, is2D=True)
epos.fitpars.add('a_R', -0.5, fixed=True, is2D=True)
epos.fitpars.add('b_R', -6., fixed=True, is2D=True)

define the simulated range (trim) and the range compared to observations (zoom)

[7]:
epos.set_ranges(xtrim=[0,730],ytrim=[0.3,20.],xzoom=[2,400],yzoom=[1,6], Occ=True)

Show the inner planet distribution

[8]:
EPOS.plot.parametric.panels(epos, NB=True)
../_images/tutorials_multiplanet_mode_17_0.png

Define the locations of additional planets in the system. Here, let’s use 10 planets per system, with the spacing drawn from a dimensionless distribution

[9]:
epos.set_multi(spacing='dimensionless')
epos.fitpars.add('npl', 10, fixed=True) # planets per system
epos.fitpars.add('log D', -0.3)
epos.fitpars.add('sigma', 0.2, min=0)
EPOS.plot.multi.periodratio(epos, Input=True, MC=False, NB=True)
../_images/tutorials_multiplanet_mode_19_0.png

Define the mutual inclinations, drawn from Rayleigh distribution with mode 2 degrees

[10]:
epos.fitpars.add('inc', 2.0)                                # mode of mutual inclinations

Fraction of system with high mutual inclunations to fit the Kepler dichotomy

[11]:
epos.fitpars.add('f_iso', 0.4)                              # Fraction of isotropic systems

Add a dispersion to the radii of planets in each system

[12]:
epos.fitpars.add('dR', 0.01, fixed=True)

Generate an observable planet population with the inital guess and compare it to Kepler

[13]:
EPOS.run.once(epos)

Preparing EPOS run...
  6 fit parameters
  Set f_cor to default 0.5

Starting the first MC run
  63695/356370 systems
  Average mutual inc=2.4 degrees

  356370 planets, 9647 transit their star
  - single: 4632
  - double: 1082
  - triple: 456
  - quad: 217
  - quint: 81
  - sext: 24
  - sept: 6
  - oct: 3
  9647 transiting planets, 2145 detectable
  - single: 1263
  - double: 226
  - triple: 87
  - quad: 29
  - quint: 7
  - sext: 3

Goodness-of-fit
  logp= -160.4
  - p(n=1548)=1.9e-58
  - p(x)=3.5e-08
  - p(N_k)=0.84
  - p(P ratio)=0.027
  - p(P inner)=0.0014
  observation comparison in 0.044 sec
Finished one MC in 0.475 sec

Show the simulated detections

[14]:
EPOS.plot.periodradius.panels(epos, NB=True)
../_images/tutorials_multiplanet_mode_29_0.png

And the detectable planet architectures, compared to the initial distributions

[15]:
EPOS.plot.multi.multiplicity(epos, MC=True, NB=True)
EPOS.plot.multi.periodratio(epos, Input=True, MC=True, NB=True)
EPOS.plot.multi.periodinner(epos, MC=True, NB=True)
../_images/tutorials_multiplanet_mode_31_0.png
../_images/tutorials_multiplanet_mode_31_1.png
../_images/tutorials_multiplanet_mode_31_2.png

The simulated distributions are a bit different from what is observed. Let’s minimize the distance between the distributions using emcee. (Note the counter doesn’t work yet)

[16]:
EPOS.run.mcmc(epos, nMC=100, nwalkers=20, nburn=20, threads= 8, Saved=True) # ~20 mins
#EPOS.run.mcmc(epos, nMC=500, nwalkers=50, nburn=200, threads= 8, Saved=True) # ~20 mins
#EPOS.run.mcmc(epos, nMC=1000, nwalkers=100, nburn=200, threads=20, Saved=True) # ~5 hrs

Loading saved status from chain/example_2/20x100x8.npz

NOTE: Random seed changed: 3119675631 to 493439428

MC-ing the 30 samples to plot
Mercury analogues < 3.3% +1.2% -1.1%
  1 sigma UL 3.9%
  2 sigma UL 5.1%
  3 sigma UL 12.2%
Venus analogues < 0.9% +0.4% -0.3%
  1 sigma UL 1.2%
  2 sigma UL 1.6%
  3 sigma UL 4.9%

Best-fit values
  pps= 0.57 +0.0583 -0.0365
  P break= 10.8 +1.87 -1.39
  a_P= 1.61 +0.246 -0.191
  b_P= -1.3 +0.171 -0.107
  log D= -0.345 +0.0311 -0.0343
  sigma= 0.187 +0.0225 -0.019
  inc= 1.92 +0.684 -0.67
  f_iso= 0.418 +0.0635 -0.0459

Starting the best-fit MC run
  90776/565953 systems
  Average mutual inc=2.3 degrees

  565953 planets, 14997 transit their star
  - single: 6926
  - double: 1572
  - triple: 783
  - quad: 353
  - quint: 133
  - sext: 52
  - sept: 20
  - oct: 5
  - nint: 1
  14997 transiting planets, 3087 detectable
  - single: 1743
  - double: 354
  - triple: 135
  - quad: 34
  - quint: 14
  - sext: 3
  - sept: 1

Goodness-of-fit
  logp= -13.7
  - p(n=2277)=0.47
  - p(x)=0.0014
  - p(N_k)=0.94
  - p(P ratio)=0.11
  - p(P inner)=0.016

  Akaike/Bayesian Information Criterion
  - k=8, n=2336
  - BIC= 89.4
  - AIC= 43.4, AICc= 2.7
  observation comparison in 0.083 sec

Let’s look at the posterior distributions

[17]:
EPOS.plot.periodradius.panels(epos, MCMC=True, NB=True)
EPOS.plot.multi.multiplicity(epos, MCMC=True, MC=True, NB=True)
EPOS.plot.multi.periodratio(epos, MCMC=True, MC=True, NB=True)
EPOS.plot.multi.periodinner(epos, MCMC=True, MC=True, NB=True)
../_images/tutorials_multiplanet_mode_35_0.png
../_images/tutorials_multiplanet_mode_35_1.png
../_images/tutorials_multiplanet_mode_35_2.png
../_images/tutorials_multiplanet_mode_35_3.png

Save the planet populations to a csv file

[18]:
popdict= dict(all_systems=epos.population,
              transiting_systems= epos.population['system'],
             transiting_planets= epos.synthetic_survey)

for key, pop in popdict.items():
    fname= 'csv/'+epos.name+'_'+key
    EPOS.save.to_csv(fname, starID= pop['ID'], Period_days= pop['P'], Radius_earth= pop['Y'])
[ ]: