Example #1
0
def test_OFTI_multiplanet():
    # initialize sampler
    input_file = os.path.join(orbitize.DATADIR, "test_val_multi.csv")
    myDriver = orbitize.driver.Driver(input_file,
                                      'OFTI',
                                      2,
                                      1.52,
                                      24.76,
                                      mass_err=0.15,
                                      plx_err=0.64)

    s = myDriver.sampler
    # change eccentricity prior for b
    myDriver.system.sys_priors[1] = priors.UniformPrior(0.0, 0.1)
    # change eccentricity prior for c
    myDriver.system.sys_priors[7] = priors.UniformPrior(0.0, 0.1)

    orbits = s.run_sampler(500)

    idx = s.system.param_idx
    sma1 = np.median(orbits[:, idx['sma1']])
    sma2 = np.median(orbits[:, idx['sma2']])

    sma1_exp = 66
    sma2_exp = 40
    print(sma1, sma2)
    assert sma1 == pytest.approx(sma1_exp, abs=0.3 * sma1_exp)
    assert sma2 == pytest.approx(sma2_exp, abs=0.3 * sma2_exp)
    assert np.all(orbits[:, idx['ecc1']] < 0.1)
    assert np.all(orbits[:, idx['ecc2']] < 0.1)
Example #2
0
def main():
    #parameters for the system
    num_planets = 1
    data_table = read_input.read_file('../Data/data.csv')
    m0 = 1.01
    mass_err = 0.05
    plx = 78.33591471044681
    plx_err = 0.1

    #initialise a system object
    sys = system.System(num_planets,
                        data_table,
                        m0,
                        plx,
                        mass_err=mass_err,
                        plx_err=plx_err,
                        fit_secondary_mass=True)

    sys.sys_priors[lab['plx1']] = priors.UniformPrior(60, 110)
    sys.sys_priors[lab['sma1']] = priors.UniformPrior(0.5, 1.50)

    #MCMC parameters
    n_temps = 10
    n_walkers = 1000
    n_threads = 10
    total_orbits_MCMC = 75000000
    burn_steps = 15000
    thin = 10
    #set up sampler object and run it
    mcmc_sampler = sampler.MCMC(sys, n_temps, n_walkers, n_threads)
    orbits = mcmc_sampler.run_sampler(total_orbits_MCMC,
                                      burn_steps=burn_steps,
                                      thin=thin)
    #save results
    myResults = mcmc_sampler.results
    try:
        ### CHANGE THIS TO SAVE TO YOUR DESIRED DIRECTORY ##
        filename = 'floatplx.hdf5'
        # 		hdf5_filename=os.path.join(save_path,filename)
        myResults.save_results(
            filename)  # saves results object as an hdf5 file
    except:
        print("Something went wrong while saving the results")
    finally:
        corner_figure = myResults.plot_corner()
        corner_name = 'floatplx_corner.png'
        corner_figure.savefig(corner_name)
        orbit_figure = myResults.plot_orbits(rv_time_series=True)
        orbit_name = 'floatplx_orbit.png'
        orbit_figure.savefig(orbit_name)

    return None
Example #3
0
def test_OFTI_pan_priors():

    # initialize sampler
    myDriver = orbitize.driver.Driver(input_file,
                                      'OFTI',
                                      1,
                                      1.22,
                                      56.95,
                                      mass_err=0.08,
                                      plx_err=0.26)

    s = myDriver.sampler

    # change PAN prior
    new_min = 0.05
    new_max = np.pi - 0.05
    myDriver.system.sys_priors[4] = priors.UniformPrior(new_min, new_max)

    # run sampler
    orbits = s.run_sampler(100)

    # check that bounds were applied correctly
    assert np.max(orbits[:, 4]) < new_max
    assert np.min(orbits[:, 4]) > new_min

    # change PAN prior again
    mu = np.pi / 2
    sigma = 0.05
    myDriver.system.sys_priors[4] = priors.GaussianPrior(mu, sigma=sigma)

    # run sampler again
    orbits = s.run_sampler(250)

    # check that bounds were applied correctly
    assert mu == pytest.approx(np.mean(orbits[:, 4]), abs=0.01)
    assert sigma == pytest.approx(np.std(orbits[:, 4]), abs=0.01)
Example #4
0
    def __init__(self,
                 num_secondary_bodies,
                 data_table,
                 system_mass,
                 plx,
                 mass_err=0,
                 plx_err=0,
                 restrict_angle_ranges=None,
                 results=None):

        self.num_secondary_bodies = num_secondary_bodies
        self.sys_priors = []
        self.labels = []
        self.results = []

        #
        # Group the data in some useful ways
        #

        self.data_table = data_table

        # List of arrays of indices corresponding to each body
        self.body_indices = []

        # List of arrays of indices corresponding to epochs in RA/Dec for each body
        self.radec = []

        # List of arrays of indices corresponding to epochs in SEP/PA for each body
        self.seppa = []

        radec_indices = np.where(self.data_table['quant_type'] == 'radec')
        seppa_indices = np.where(self.data_table['quant_type'] == 'seppa')

        for body_num in np.arange(self.num_secondary_bodies + 1):

            self.body_indices.append(
                np.where(self.data_table['object'] == body_num))

            self.radec.append(
                np.intersect1d(self.body_indices[body_num], radec_indices))
            self.seppa.append(
                np.intersect1d(self.body_indices[body_num], seppa_indices))

        if (len(radec_indices) + len(seppa_indices) == len(
                self.data_table)) and (restrict_angle_ranges is None):
            restrict_angle_ranges = True

        if restrict_angle_ranges:
            angle_upperlim = np.pi
        else:
            angle_upperlim = 2. * np.pi

        #
        # Set priors for each orbital element
        #

        for body in np.arange(num_secondary_bodies):
            # Add semimajor axis prior
            self.sys_priors.append(priors.JeffreysPrior(0.1, 100.))
            self.labels.append('sma{}'.format(body + 1))

            # Add eccentricity prior
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('ecc{}'.format(body + 1))

            # Add inclination angle prior
            self.sys_priors.append(priors.SinPrior())
            self.labels.append('inc{}'.format(body + 1))

            # Add argument of periastron prior
            self.sys_priors.append(priors.UniformPrior(0., angle_upperlim))
            self.labels.append('aop{}'.format(body + 1))

            # Add position angle of nodes prior
            self.sys_priors.append(priors.UniformPrior(0., angle_upperlim))
            self.labels.append('pan{}'.format(body + 1))

            # Add epoch of periastron prior.
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('epp{}'.format(body + 1))

        #
        # Set priors on total mass and parallax
        #
        self.labels.append('plx')
        self.labels.append('mtot')
        if plx_err > 0:
            self.sys_priors.append(priors.GaussianPrior(plx, plx_err))
        else:
            self.sys_priors.append(plx)
        if mass_err > 0:
            self.sys_priors.append(priors.GaussianPrior(system_mass, mass_err))
        else:
            self.sys_priors.append(system_mass)

        #add labels dictionary for parameter indexing
        self.param_idx = dict(zip(self.labels, np.arange(len(self.labels))))
Example #5
0
    def __init__(self,
                 num_secondary_bodies,
                 data_table,
                 stellar_mass,
                 plx,
                 mass_err=0,
                 plx_err=0,
                 restrict_angle_ranges=None,
                 tau_ref_epoch=58849,
                 fit_secondary_mass=False,
                 results=None):

        self.num_secondary_bodies = num_secondary_bodies
        self.sys_priors = []
        self.labels = []
        self.results = []
        self.fit_secondary_mass = fit_secondary_mass
        self.tau_ref_epoch = tau_ref_epoch
        self.restrict_angle_ranges = restrict_angle_ranges

        #
        # Group the data in some useful ways
        #

        self.data_table = data_table
        # Creates a copy of the input in case data_table needs to be modified
        self.input_table = self.data_table.copy()

        # Rob: check if instrument column is other than default. If other than default, then separate data table into n number of instruments.
        # gather list of instrument: list_instr = self.data_table['instruments'][name of instrument]
        # List of arrays of indices corresponding to each body

        # instruments = np.unique(self.data_table['instruments']) gives a list of unique names

        self.body_indices = []

        # List of arrays of indices corresponding to epochs in RA/Dec for each body
        self.radec = []

        # List of arrays of indices corresponding to epochs in SEP/PA for each body
        self.seppa = []

        # List of index arrays corresponding to each rv for each body
        self.rv = []

        # instr1_tbl = np.where(self.data_table['instruments'] == list_instr[0])
        # loop through the indices per input_table:
        # rv_indices = np.where(instr1_tbl['quant_type'] == 'rv')
        # ... return the parameter labels for each table
        # ...

        self.fit_astrometry = True
        radec_indices = np.where(self.data_table['quant_type'] == 'radec')
        seppa_indices = np.where(self.data_table['quant_type'] == 'seppa')

        if len(radec_indices[0]) == 0 and len(seppa_indices[0]) == 0:
            self.fit_astrometry = False
        rv_indices = np.where(self.data_table['quant_type'] == 'rv')

        # defining all indices to loop through the unique rv instruments to get different offsets and jitters
        instrument_list = np.unique(self.data_table['instrument'])
        inst_indices_all = []
        for inst in instrument_list:
            inst_indices = np.where(self.data_table['instrument'] == inst)
            inst_indices_all.append(inst_indices)

        # defining indices for unique instruments in the data table
        self.rv_instruments = np.unique(
            self.data_table['instrument'][rv_indices])
        self.rv_inst_indices = []
        for inst in self.rv_instruments:
            inst_indices = np.where(self.data_table['instrument'] == inst)
            self.rv_inst_indices.append(inst_indices)

        # astrometry instruments same for radec and seppa:
        self.astr_instruments = np.unique(
            self.data_table['instrument'][np.where(
                self.data_table['quant_type'] != 'rv')])
        # save indicies for all of the ra/dec, sep/pa measurements for convenience
        self.all_radec = radec_indices
        self.all_seppa = seppa_indices

        for body_num in np.arange(self.num_secondary_bodies + 1):

            self.body_indices.append(
                np.where(self.data_table['object'] == body_num))

            self.radec.append(
                np.intersect1d(self.body_indices[body_num], radec_indices))
            self.seppa.append(
                np.intersect1d(self.body_indices[body_num], seppa_indices))
            self.rv.append(
                np.intersect1d(self.body_indices[body_num], rv_indices))

        # we should track the influence of the planet(s) on each other/the star if we are not fitting massless planets and
        # we are not fitting relative astrometry of just a single body
        self.track_planet_perturbs = self.fit_secondary_mass and \
                                     ((len(self.radec[1]) + len(self.seppa[1]) + len(self.rv[1]) < len(data_table)) or \
                                      (self.num_secondary_bodies > 1))

        if restrict_angle_ranges:
            angle_upperlim = np.pi
        else:
            angle_upperlim = 2. * np.pi

        #
        # Set priors for each orbital element
        #

        for body in np.arange(num_secondary_bodies):
            # Add semimajor axis prior
            self.sys_priors.append(priors.LogUniformPrior(0.001, 1e7))
            self.labels.append('sma{}'.format(body + 1))

            # Add eccentricity prior
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('ecc{}'.format(body + 1))

            # Add inclination angle prior
            self.sys_priors.append(priors.SinPrior())
            self.labels.append('inc{}'.format(body + 1))

            # Add argument of periastron prior
            self.sys_priors.append(priors.UniformPrior(0., 2. * np.pi))
            self.labels.append('aop{}'.format(body + 1))

            # Add position angle of nodes prior
            self.sys_priors.append(priors.UniformPrior(0., angle_upperlim))
            self.labels.append('pan{}'.format(body + 1))

            # Add epoch of periastron prior.
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('tau{}'.format(body + 1))

        #
        # Set priors on total mass and parallax
        #
        self.labels.append('plx')
        if plx_err > 0:
            self.sys_priors.append(priors.GaussianPrior(plx, plx_err))
        else:
            self.sys_priors.append(plx)

        # checking for rv data to include appropriate rv priors:

        if len(self.rv[0]) > 0 and self.fit_secondary_mass:
            # Rob and Lea:
            # for instrument in rv_instruments:
            # add gamma and sigma for each and label each unique gamma and sigma per instrument name (gamma+instrument1, ...)
            for instrument in self.rv_instruments:
                self.sys_priors.append(priors.UniformPrior(
                    -5, 5))  # gamma prior in km/s
                self.labels.append('gamma_{}'.format(instrument))

                self.sys_priors.append(priors.LogUniformPrior(
                    1e-4, 0.05))  # jitter prior in km/s
                self.labels.append('sigma_{}'.format(instrument))

        if self.fit_secondary_mass:
            for body in np.arange(num_secondary_bodies) + 1:
                self.sys_priors.append(priors.LogUniformPrior(
                    1e-6, 2))  # in Solar masses for now
                self.labels.append('m{}'.format(body))
            self.labels.append('m0')
        else:
            self.labels.append('mtot')

        # still need to append m0/mtot, even though labels are appended above
        if mass_err > 0:
            self.sys_priors.append(priors.GaussianPrior(
                stellar_mass, mass_err))
        else:
            self.sys_priors.append(stellar_mass)

        # add labels dictionary for parameter indexing
        self.param_idx = dict(zip(self.labels, np.arange(len(self.labels))))
Example #6
0
    def __init__(self,
                 num_secondary_bodies,
                 data_table,
                 stellar_mass,
                 plx,
                 mass_err=0,
                 plx_err=0,
                 restrict_angle_ranges=None,
                 tau_ref_epoch=58849,
                 fit_secondary_mass=False,
                 results=None):

        self.num_secondary_bodies = num_secondary_bodies
        self.sys_priors = []
        self.labels = []
        self.results = []
        self.fit_secondary_mass = fit_secondary_mass
        self.tau_ref_epoch = tau_ref_epoch

        #
        # Group the data in some useful ways
        #

        self.data_table = data_table
        # Creates a copy of the input in case data_table needs to be modified
        self.input_table = self.data_table.copy()

        # List of arrays of indices corresponding to each body
        self.body_indices = []

        # List of arrays of indices corresponding to epochs in RA/Dec for each body
        self.radec = []

        # List of arrays of indices corresponding to epochs in SEP/PA for each body
        self.seppa = []

        # List of index arrays corresponding to each rv for each body
        self.rv = []

        radec_indices = np.where(self.data_table['quant_type'] == 'radec')
        seppa_indices = np.where(self.data_table['quant_type'] == 'seppa')

        rv_indices = np.where(self.data_table['quant_type'] == 'rv')

        # save indicies for all of the ra/dec, sep/pa measurements for convenience
        self.all_radec = radec_indices
        self.all_seppa = seppa_indices

        for body_num in np.arange(self.num_secondary_bodies + 1):

            self.body_indices.append(
                np.where(self.data_table['object'] == body_num))

            self.radec.append(
                np.intersect1d(self.body_indices[body_num], radec_indices))
            self.seppa.append(
                np.intersect1d(self.body_indices[body_num], seppa_indices))
            self.rv.append(
                np.intersect1d(self.body_indices[body_num], rv_indices))

        # we should track the influence of the planet(s) on each other/the star if we are not fitting massless planets and
        # we are not fitting relative astrometry of just a single body
        self.track_planet_perturbs = self.fit_secondary_mass and \
                                     ((len(self.radec[1]) + len(self.seppa[1]) + len(self.rv[1]) < len(data_table)) or \
                                      (self.num_secondary_bodies > 1))

        if restrict_angle_ranges:
            angle_upperlim = np.pi
        else:
            angle_upperlim = 2. * np.pi

        #
        # Set priors for each orbital element
        #

        for body in np.arange(num_secondary_bodies):
            # Add semimajor axis prior
            self.sys_priors.append(priors.LogUniformPrior(0.001, 1e7))
            self.labels.append('sma{}'.format(body + 1))

            # Add eccentricity prior
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('ecc{}'.format(body + 1))

            # Add inclination angle prior
            self.sys_priors.append(priors.SinPrior())
            self.labels.append('inc{}'.format(body + 1))

            # Add argument of periastron prior
            self.sys_priors.append(priors.UniformPrior(0., 2. * np.pi))
            self.labels.append('aop{}'.format(body + 1))

            # Add position angle of nodes prior
            self.sys_priors.append(priors.UniformPrior(0., angle_upperlim))
            self.labels.append('pan{}'.format(body + 1))

            # Add epoch of periastron prior.
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('tau{}'.format(body + 1))

        #
        # Set priors on total mass and parallax
        #
        self.labels.append('plx')
        if plx_err > 0:
            self.sys_priors.append(priors.GaussianPrior(plx, plx_err))
        else:
            self.sys_priors.append(plx)

        # checking for rv data to include appropriate rv priors:

        if len(self.rv[0]) > 0 and self.fit_secondary_mass:
            self.sys_priors.append(priors.UniformPrior(
                -5, 5))  # gamma prior in km/s
            self.labels.append('gamma')

            self.sys_priors.append(priors.LogUniformPrior(
                1e-4, 0.05))  # jitter prior in km/s
            self.labels.append('sigma')

        if self.fit_secondary_mass:
            for body in np.arange(num_secondary_bodies) + 1:
                self.sys_priors.append(priors.LogUniformPrior(
                    1e-6, 2))  # in Solar masses for now
                self.labels.append('m{}'.format(body))
            self.labels.append('m0')
        else:
            self.labels.append('mtot')

        # still need to append m0/mtot, even though labels are appended above
        if mass_err > 0:
            self.sys_priors.append(priors.GaussianPrior(
                stellar_mass, mass_err))
        else:
            self.sys_priors.append(stellar_mass)

        # add labels dictionary for parameter indexing
        self.param_idx = dict(zip(self.labels, np.arange(len(self.labels))))
Example #7
0
else:
    fit_secondary_mass = False
    betaPic_Hip = None
    betaPic_gaia = None

betaPic_system = system.System(num_secondary_bodies,
                               data_table,
                               1.75,
                               plx,
                               hipparcos_IAD=betaPic_Hip,
                               gaia=betaPic_gaia,
                               fit_secondary_mass=fit_secondary_mass,
                               mass_err=0.01,
                               plx_err=0.01)

m0_or_mtot_prior = priors.UniformPrior(1.5, 2.0)

# set uniform parallax prior
plx_index = betaPic_system.param_idx['plx']
betaPic_system.sys_priors[plx_index] = priors.UniformPrior(
    plx - 1.0, plx + 1.0)

# set prior on Omega, since we know that know direction of orbital motion from RV
pan_index = betaPic_system.param_idx['pan1']
betaPic_system.sys_priors[pan_index] = priors.UniformPrior(0, np.pi)

# set uniform prior on m1 as Nielsen+ 2020 do
m1_index = betaPic_system.param_idx['m1']
betaPic_system.sys_priors[m1_index] = priors.UniformPrior(0, 0.1)

if fit_IAD:
Example #8
0
    def __init__(self,
                 num_secondary_bodies,
                 data_table,
                 stellar_mass,
                 plx,
                 mass_err=0,
                 plx_err=0,
                 restrict_angle_ranges=None,
                 tau_ref_epoch=58849,
                 fit_secondary_mass=False,
                 results=None):

        self.num_secondary_bodies = num_secondary_bodies
        self.sys_priors = []
        self.labels = []
        self.results = []
        self.fit_secondary_mass = fit_secondary_mass
        self.tau_ref_epoch = tau_ref_epoch

        #
        # Group the data in some useful ways
        #

        self.data_table = data_table
        # Creates a copy of the input in case data_table needs to be modified
        self.input_table = self.data_table.copy()

        # List of arrays of indices corresponding to each body
        self.body_indices = []

        # List of arrays of indices corresponding to epochs in RA/Dec for each body
        self.radec = []

        # List of arrays of indices corresponding to epochs in SEP/PA for each body
        self.seppa = []

        radec_indices = np.where(self.data_table['quant_type'] == 'radec')
        seppa_indices = np.where(self.data_table['quant_type'] == 'seppa')

        for body_num in np.arange(self.num_secondary_bodies + 1):

            self.body_indices.append(
                np.where(self.data_table['object'] == body_num))

            self.radec.append(
                np.intersect1d(self.body_indices[body_num], radec_indices))
            self.seppa.append(
                np.intersect1d(self.body_indices[body_num], seppa_indices))

        if restrict_angle_ranges:
            angle_upperlim = np.pi
        else:
            angle_upperlim = 2. * np.pi

        #
        # Set priors for each orbital element
        #

        for body in np.arange(num_secondary_bodies):
            # Add semimajor axis prior
            self.sys_priors.append(priors.LogUniformPrior(0.001, 1e7))
            self.labels.append('sma{}'.format(body + 1))

            # Add eccentricity prior
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('ecc{}'.format(body + 1))

            # Add inclination angle prior
            self.sys_priors.append(priors.SinPrior())
            self.labels.append('inc{}'.format(body + 1))

            # Add argument of periastron prior
            self.sys_priors.append(priors.UniformPrior(0., 2. * np.pi))
            self.labels.append('aop{}'.format(body + 1))

            # Add position angle of nodes prior
            self.sys_priors.append(priors.UniformPrior(0., angle_upperlim))
            self.labels.append('pan{}'.format(body + 1))

            # Add epoch of periastron prior.
            self.sys_priors.append(priors.UniformPrior(0., 1.))
            self.labels.append('tau{}'.format(body + 1))

        #
        # Set priors on total mass and parallax
        #
        self.labels.append('plx')
        if plx_err > 0:
            self.sys_priors.append(priors.GaussianPrior(plx, plx_err))
        else:
            self.sys_priors.append(plx)

        if self.fit_secondary_mass:
            for body in np.arange(num_secondary_bodies):
                self.sys_priors.append(priors.LogUniformPrior(
                    1e-6, 1))  # in Solar masses for now
                self.labels.append('m{}'.format(body))
            self.labels.append('m0')
        else:
            self.labels.append('mtot')

        # still need to append m0/mtot, even though labels are appended above
        if mass_err > 0:
            self.sys_priors.append(priors.GaussianPrior(
                stellar_mass, mass_err))
        else:
            self.sys_priors.append(stellar_mass)

        # add labels dictionary for parameter indexing
        self.param_idx = dict(zip(self.labels, np.arange(len(self.labels))))