Overview
Octopodes take as input independent MCMC runs, one for each star/system. Each of these MCMC runs approximates the posterior of exoplanet(s) parameters given the data of only that system (for example, in our work, we use Octofitter to produce these independent MCMC runs).
We assume the results of these MCMC runs have been serialized as a Julia Dict in a format described below. From a user's point of view, the main point of this page is to explain the expected organization of that Dict.
Internally, we transform that Dict into a IndepRuns object. We then bin the IndepRuns into a BinnedIndepRuns object. We give some information on that lower level process as well in this page.
Expected format for the input Dict
Here is an example:
using Octopodes
dict = Octopodes.Examples.small_dict()Dict{String, Any} with 4 entries:
"log_P_yr_prior" => Distributions.Uniform{Float64}(a=-2.56259, b=4.0)
"log_q_prior" => Distributions.Uniform{Float64}(a=-5.0, b=0.0)
"n_planets_prior" => Truncated(Distributions.NegativeBinomial{Float64}(r=1.0,…
"star_data" => NamedTuple[(n_planets = [1, 0, 0, 0, 0, 0, 0, 0, 0, 1 ……If the Dict contains other keys it is not a problem.
We assume the prior used in the independent MCMC runs are specified using Distributions.jl objects.
At the moment we assume that the independent MCMC runs use uniform priors over log10 periods (log_P_yr_prior) and log10 mass ratios (log_q_prior). The support of these priors are used to construct correct discretization bins.
The prior on the number of companions can be any discrete distribution on 0:max_n_companions.
Precise infomation on all these priors is essential to have correct joint inference as we need to "cancel them out" in a precise way.
The dictionary's star_data key should point to a Vector where each item in the Vector corresponds to an independent MCMC run for one system:
typeof(dict["star_data"])Vector{NamedTuple} (alias for Array{NamedTuple, 1})Here are the fields required for each of these items:
traces_for_one_system = first(dict["star_data"])
typeof(traces_for_one_system)@NamedTuple{n_planets::Vector{Int64}, log_P_yr::Matrix{Float64}, log_q::Matrix{Float64}, n_samples::Int64, name::String}Again, if your NamedTuple has other fields this is not a problem.
The period (log_P_yr) and mass (log_q) are encoded as matrices where the number of rows is the maximum number of companions allowed, and the number of columns is the number of MCMC samples. If at iteration i, n_planets is n, we will ignore the elements in log_P_yr[:, i] past index n (this setup comes from the use of model saturation in the transdimensional MCMC context).
We assume they are in log10 scale.
traces_for_one_system.log_P_yr3×4096 Matrix{Float64}:
2.05097 1.84525 0.907102 -2.05821 … 1.96666 -1.69923 1.94597
1.9077 -2.26056 -1.41125 -2.28821 -1.95554 2.78201 -1.25171
1.22702 0.202589 -1.3816 -1.63504 2.97699 1.55623 2.54585Loading and validating the data
Use:
runs = IndepRuns(dict)IndepRuns(max_n_companions=3, n_systems=2)This will perform several validation checks.
Binning
To bin the data, proceed as follows.
First, create a binning by choosing how many grid points for the mass-ratio and period parameters:
b = Binning(runs, n_log_P_yr_intervals = 20, n_log_q_intervals = 20)Binning{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Tuple{Int64, Int64}}(-2.5625902246063346:0.32812951123031675:4.0, -5.0:0.25:0.0, (20, 20), 400)Then use bin to perform the binning. You can select star subsets using the star_selector option. The bin function also shuffle the samples. See bin for details.
using Random
binned = bin(b, runs; star_selector = (x -> startswith(x, "HIP")))Octopodes.BinnedIndepRuns{Binning{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Tuple{Int64, Int64}}, Matrix{Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}}, Vector{Float64}}(Binning{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Tuple{Int64, Int64}}(-2.5625902246063346:0.32812951123031675:4.0, -5.0:0.25:0.0, (20, 20), 400), Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}[Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)) Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)) … Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)) Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)); Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)) Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)) … Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(0, (0, 0, 0)) Octopodes.BinnedSample{Tuple{Int64, Int64, Int64}}(1, (50, 0, 0))], [0.5333333333333333, 0.2666666666666667, 0.13333333333333336, 0.0666666666666667], 3, ["HIP100017", "HIP100223"])Binarizing
To test our code, it is useful to consider the special case where we collapse the number of companions into two cases, no companion versus at least one companion, and where we also collapse all masses and periods in the same bin. This makes each independent MCMC run over a binary space (at least one companion versus no companion). In that case the true posterior can be computed analytically.
To re-bin into binary samples, use:
Octopodes.binarize(binned)Octopodes.BinnedIndepRuns{Binning{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Tuple{Int64, Int64}}, Matrix{Octopodes.BinnedSample{Tuple{Int64}}}, Vector{Float64}}(Binning{StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, Tuple{Int64, Int64}}(-2.5625902246063346:6.562590224606335:4.0, -5.0:5.0:0.0, (1, 1), 1), Octopodes.BinnedSample{Tuple{Int64}}[Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)) Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)) … Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)) Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)); Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)) Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)) … Octopodes.BinnedSample{Tuple{Int64}}(0, (0,)) Octopodes.BinnedSample{Tuple{Int64}}(1, (1,))], [0.5333333333333333, 0.4666666666666667], 1, ["HIP100017", "HIP100223"])