From f8538612cb2a47ea62542bedaca34d9be32482fc Mon Sep 17 00:00:00 2001 From: Michael Poon Date: Sun, 24 Sep 2023 01:00:39 -0400 Subject: [PATCH 1/7] add OFTI time warning following issue #303 --- orbitize/sampler.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/orbitize/sampler.py b/orbitize/sampler.py index ca7fe9af..2baa2161 100644 --- a/orbitize/sampler.py +++ b/orbitize/sampler.py @@ -462,6 +462,11 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): """ + # a flag to print out a warning if no OFTI orbits are accepted in x seconds + start_warning = True + time_warning = 60. # seconds + start_time = time.time() + if num_cores!=1: if num_cores==None: num_cores=mp.cpu_count() @@ -491,6 +496,11 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): # print out the number of orbits generated every second while orbits_saved.value < total_orbits: + if start_warning and orbits_saved.value == 0: + check_time = time.time() - start_time + if check_time > time_warning: + print('Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.', end='\n') + start_warning = False print(str(orbits_saved.value)+'/'+str(total_orbits)+' orbits found', end='\r') time.sleep(0.1) @@ -525,13 +535,17 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): n_orbits_saved = 0 output_orbits = np.empty((total_orbits, len(self.priors))) output_lnlikes = np.empty(total_orbits) - + # add orbits to `output_orbits` until `total_orbits` are saved while n_orbits_saved < total_orbits: samples = self.prepare_samples(num_samples) accepted_orbits, lnlikes = self.reject(samples) if len(accepted_orbits) == 0: + check_time = time.time() - start_time + if start_warning and check_time > time_warning: + print('Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.', end='\n') + start_warning = False pass else: n_accepted = len(accepted_orbits) @@ -543,8 +557,8 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): n_accepted] = lnlikes[0:maxindex2save] n_orbits_saved += maxindex2save - # print progress statement - print(str(n_orbits_saved)+'/'+str(total_orbits)+' orbits found', end='\r') + # print progress statement + print(str(n_orbits_saved)+'/'+str(total_orbits)+' orbits found', end='\r') self.results.add_samples( np.array(output_orbits), From afa3f8228ac9ef8048f956ae97a007eeed24cff1 Mon Sep 17 00:00:00 2001 From: Sarah Blunt Date: Mon, 15 Jan 2024 17:47:39 -0800 Subject: [PATCH 2/7] minor pep8 type changes --- orbitize/sampler.py | 682 ++++++++++++++++++++++++++++---------------- 1 file changed, 435 insertions(+), 247 deletions(-) diff --git a/orbitize/sampler.py b/orbitize/sampler.py index 2baa2161..fe181b9a 100644 --- a/orbitize/sampler.py +++ b/orbitize/sampler.py @@ -18,6 +18,7 @@ import orbitize.results import matplotlib.pyplot as plt + class Sampler(abc.ABC): """ Abstract base class for sampler objects. @@ -26,7 +27,9 @@ class Sampler(abc.ABC): Written: Sarah Blunt, 2018 """ - def __init__(self, system, like='chi2_lnlike', custom_lnlike=None, chi2_type='standard'): + def __init__( + self, system, like="chi2_lnlike", custom_lnlike=None, chi2_type="standard" + ): self.system = system # check if `like` is a string or a function @@ -38,7 +41,7 @@ def __init__(self, system, like='chi2_lnlike', custom_lnlike=None, chi2_type='st self.custom_lnlike = custom_lnlike self.chi2_type = chi2_type # check if need to handle covariances - self.has_corr = np.any(~np.isnan(self.system.data_table['quant12_corr'])) + self.has_corr = np.any(~np.isnan(self.system.data_table["quant12_corr"])) @abc.abstractmethod def run_sampler(self, total_orbits): @@ -64,15 +67,18 @@ def _logl(self, params): model, jitter = self.system.compute_model(params) # fold data/errors to match model output shape. In particualr, quant1/quant2 are interleaved - data = np.array([self.system.data_table['quant1'], self.system.data_table['quant2']]).T + data = np.array( + [self.system.data_table["quant1"], self.system.data_table["quant2"]] + ).T # errors below required for lnlike function below - errs = np.array([self.system.data_table['quant1_err'], - self.system.data_table['quant2_err']]).T + errs = np.array( + [self.system.data_table["quant1_err"], self.system.data_table["quant2_err"]] + ).T # covariances/correlations, if applicable # we're doing this check now because the likelihood computation is much faster if we can skip it. if self.has_corr: - corrs = self.system.data_table['quant12_corr'] + corrs = self.system.data_table["quant12_corr"] else: corrs = None @@ -80,80 +86,93 @@ def _logl(self, params): seppa_indices = self.system.all_seppa # compute lnlike - lnlikes = self.lnlike(data, errs, corrs, model, jitter, seppa_indices, chi2_type=self.chi2_type) + lnlikes = self.lnlike( + data, errs, corrs, model, jitter, seppa_indices, chi2_type=self.chi2_type + ) # return sum of lnlikes (aka product of likeliehoods) lnlikes_sum = np.nansum(lnlikes, axis=(0, 1)) if self.custom_lnlike is not None: lnlikes_sum += self.custom_lnlike(params) - - if self.system.hipparcos_IAD is not None: + if self.system.hipparcos_IAD is not None: # compute Ra/Dec predictions at the Hipparcos IAD epochs raoff_model, deoff_model, _ = self.system.compute_all_orbits( params, epochs=self.system.hipparcos_IAD.epochs_mjd - ) + ) - raoff_model_hip_epoch, deoff_model_hip_epoch, _ = self.system.compute_all_orbits( - params, epochs=Time([1991.25], format='decimalyear').mjd - ) + ( + raoff_model_hip_epoch, + deoff_model_hip_epoch, + _, + ) = self.system.compute_all_orbits( + params, epochs=Time([1991.25], format="decimalyear").mjd + ) # subtract off position of star at reference Hipparcos epoch - raoff_model[:,0,:] -= raoff_model_hip_epoch[:,0,:] - deoff_model[:,0,:] -= deoff_model_hip_epoch[:,0,:] + raoff_model[:, 0, :] -= raoff_model_hip_epoch[:, 0, :] + deoff_model[:, 0, :] -= deoff_model_hip_epoch[:, 0, :] # select body 0 raoff/deoff predictions & feed into Hip IAD lnlike fn lnlikes_sum += self.system.hipparcos_IAD.compute_lnlike( - raoff_model[:,0,:], deoff_model[:,0,:], params, self.system.param_idx + raoff_model[:, 0, :], + deoff_model[:, 0, :], + params, + self.system.param_idx, ) if self.system.gaia is not None: - gaiahip_epochs = Time( - [self.system.gaia.hipparcos_epoch, self.system.gaia.gaia_epoch], - format='decimalyear' + [self.system.gaia.hipparcos_epoch, self.system.gaia.gaia_epoch], + format="decimalyear", ).mjd # compute Ra/Dec predictions at the Gaia epoch raoff_model, deoff_model, _ = self.system.compute_all_orbits( params, epochs=gaiahip_epochs - ) + ) # select body 0 raoff/deoff predictions & feed into Gaia module lnlike fn lnlikes_sum += self.system.gaia.compute_lnlike( - raoff_model[:,0,:], deoff_model[:,0,:], params, self.system.param_idx + raoff_model[:, 0, :], + deoff_model[:, 0, :], + params, + self.system.param_idx, ) return lnlikes_sum -class OFTI(Sampler,): +class OFTI( + Sampler, +): """ OFTI Sampler Args: system (system.System): ``system.System`` object like (string): name of likelihood function in ``lnlike.py`` - custom_lnlike (func): ability to include an addition custom likelihood - function in the fit. The function looks like + custom_lnlike (func): ability to include an addition custom likelihood + function in the fit. The function looks like ``clnlikes = custon_lnlike(params)`` where ``params`` is a RxM array - of fitting parameters, where R is the number of orbital paramters + of fitting parameters, where R is the number of orbital paramters (can be passed in system.compute_model()), - and M is the number of orbits we need model predictions for. + and M is the number of orbits we need model predictions for. It returns ``clnlikes`` which is an array of length M, or it can be a single float if M = 1. Written: Isabel Angelo, Sarah Blunt, Logan Pearce, 2018 """ - def __init__(self, system, like='chi2_lnlike', custom_lnlike=None,chi2_type='standard'): - super(OFTI, self).__init__(system, like=like, chi2_type=chi2_type, custom_lnlike=custom_lnlike) + def __init__( + self, system, like="chi2_lnlike", custom_lnlike=None, chi2_type="standard" + ): + super(OFTI, self).__init__( + system, like=like, chi2_type=chi2_type, custom_lnlike=custom_lnlike + ) - if ( - (self.system.hipparcos_IAD is not None) or - (len(self.system.rv[0] > 0)) - ): + if (self.system.hipparcos_IAD is not None) or (len(self.system.rv[0] > 0)): raise NotImplementedError( """ You can only use OFTI with relative astrometry measurements @@ -172,38 +191,63 @@ def __init__(self, system, like='chi2_lnlike', custom_lnlike=None,chi2_type='sta if len(self.system.radec[body_num]) > 0: # only print the warning once. if not convert_warning_print: - print('Converting ra/dec data points in data_table to sep/pa. Original data are stored in input_table.') + print( + "Converting ra/dec data points in data_table to sep/pa. Original data are stored in input_table." + ) convert_warning_print = True self.system.convert_data_table_radec2seppa(body_num=body_num) # these are of type astropy.table.column - self.sep_observed = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'seppa')]['quant1'].copy() - self.pa_observed = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'seppa')]['quant2'].copy() - self.sep_err = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'seppa')]['quant1_err'].copy() - self.pa_err = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'seppa')]['quant2_err'].copy() - self.meas_object = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'seppa')]['object'].copy() + self.sep_observed = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "seppa") + ]["quant1"].copy() + self.pa_observed = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "seppa") + ]["quant2"].copy() + self.sep_err = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "seppa") + ]["quant1_err"].copy() + self.pa_err = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "seppa") + ]["quant2_err"].copy() + self.meas_object = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "seppa") + ]["object"].copy() # this is OK, ONLY IF we are only using self.epochs for computing RA/Dec from Keplerian elements - self.epochs = np.array(self.system.data_table['epoch']) - self.system.tau_ref_epoch + self.epochs = ( + np.array(self.system.data_table["epoch"]) - self.system.tau_ref_epoch + ) # distinguishing all epochs from sep/pa epochs - self.epochs_seppa = np.array(self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'seppa')]['epoch']) - self.system.tau_ref_epoch + self.epochs_seppa = ( + np.array( + self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "seppa") + ]["epoch"] + ) + - self.system.tau_ref_epoch + ) - self.epochs_rv = np.array(self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'rv')]['epoch']) - self.system.tau_ref_epoch + self.epochs_rv = ( + np.array( + self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "rv") + ]["epoch"] + ) + - self.system.tau_ref_epoch + ) # choose scale-and-rotate epoch # for multiplanet support, this is now a list. # For each planet, we find the measurment for it that corresponds to the smallest astrometric error self.epoch_idx = [] - min_sep_indices = np.argsort(self.sep_err) # indices of sep err sorted from smallest to higheset - min_sep_indices_body = self.meas_object[min_sep_indices] # the corresponding body_num that these sorted measurements correspond to + min_sep_indices = np.argsort( + self.sep_err + ) # indices of sep err sorted from smallest to higheset + min_sep_indices_body = self.meas_object[ + min_sep_indices + ] # the corresponding body_num that these sorted measurements correspond to for i in range(self.system.num_secondary_bodies): body_num = i + 1 this_object_meas = np.where(min_sep_indices_body == body_num)[0] @@ -212,17 +256,25 @@ def __init__(self, system, like='chi2_lnlike', custom_lnlike=None,chi2_type='sta self.epoch_idx.append(None) continue # get the smallest measurement belonging to this body - best_epoch = min_sep_indices[this_object_meas][0] # already sorted by argsort + best_epoch = min_sep_indices[this_object_meas][ + 0 + ] # already sorted by argsort self.epoch_idx.append(best_epoch) - if len(self.system.rv[0]) > 0 and self.system.fit_secondary_mass: # checking for RV data - self.rv_observed = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'rv')]['quant1'].copy() - self.rv_err = self.system.data_table[np.where( - self.system.data_table['quant_type'] == 'rv')]['quant1_err'].copy() - - self.epoch_rv_idx = [np.argmin(self.rv_observed), - np.argmax(self.rv_observed)] + if ( + len(self.system.rv[0]) > 0 and self.system.fit_secondary_mass + ): # checking for RV data + self.rv_observed = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "rv") + ]["quant1"].copy() + self.rv_err = self.system.data_table[ + np.where(self.system.data_table["quant_type"] == "rv") + ]["quant1_err"].copy() + + self.epoch_rv_idx = [ + np.argmin(self.rv_observed), + np.argmax(self.rv_observed), + ] # create an empty results object self.results = orbitize.results.Results( @@ -230,7 +282,7 @@ def __init__(self, system, like='chi2_lnlike', custom_lnlike=None,chi2_type='sta sampler_name=self.__class__.__name__, post=None, lnlike=None, - version_number=orbitize.__version__ + version_number=orbitize.__version__, ) def prepare_samples(self, num_samples): @@ -252,62 +304,80 @@ def prepare_samples(self, num_samples): for i in range(len(self.priors)): if hasattr(self.priors[i], "draw_samples"): samples[i, :] = self.priors[i].draw_samples(num_samples) - else: # param is fixed & has no prior + else: # param is fixed & has no prior samples[i, :] = self.priors[i] * np.ones(num_samples) # Make Converison to Standard Basis: samples = self.system.basis.to_standard_basis(samples) - - for body_num in np.arange(self.system.num_secondary_bodies) + 1: - sma = samples[self.system.basis.standard_basis_idx['sma{}'.format(body_num)],:] - ecc = samples[self.system.basis.standard_basis_idx['ecc{}'.format(body_num)],:] - inc = samples[self.system.basis.standard_basis_idx['inc{}'.format(body_num)],:] - argp = samples[self.system.basis.standard_basis_idx['aop{}'.format(body_num)],:] - lan = samples[self.system.basis.standard_basis_idx['pan{}'.format(body_num)],:] - tau = samples[self.system.basis.standard_basis_idx['tau{}'.format(body_num)],:] - plx = samples[self.system.basis.standard_basis_idx['plx'],:] + for body_num in np.arange(self.system.num_secondary_bodies) + 1: + sma = samples[ + self.system.basis.standard_basis_idx["sma{}".format(body_num)], : + ] + ecc = samples[ + self.system.basis.standard_basis_idx["ecc{}".format(body_num)], : + ] + inc = samples[ + self.system.basis.standard_basis_idx["inc{}".format(body_num)], : + ] + argp = samples[ + self.system.basis.standard_basis_idx["aop{}".format(body_num)], : + ] + lan = samples[ + self.system.basis.standard_basis_idx["pan{}".format(body_num)], : + ] + tau = samples[ + self.system.basis.standard_basis_idx["tau{}".format(body_num)], : + ] + plx = samples[self.system.basis.standard_basis_idx["plx"], :] if self.system.fit_secondary_mass: - m0 = samples[self.system.basis.standard_basis_idx['m0'],:] - m1 = samples[self.system.basis.standard_basis_idx['m{}'.format(body_num)],:] + m0 = samples[self.system.basis.standard_basis_idx["m0"], :] + m1 = samples[ + self.system.basis.standard_basis_idx["m{}".format(body_num)], : + ] mtot = m0 + m1 else: - mtot = samples[self.system.basis.standard_basis_idx['mtot'],:] + mtot = samples[self.system.basis.standard_basis_idx["mtot"], :] m1 = None - + min_epoch = self.epoch_idx[body_num - 1] if min_epoch is None: # Don't need to rotate and scale if no astrometric measurments for this body. Brute force rejection sampling continue period_prescale = np.sqrt( - 4*np.pi**2*(sma*u.AU)**3/(consts.G*(mtot*u.Msun)) + 4 * np.pi**2 * (sma * u.AU) ** 3 / (consts.G * (mtot * u.Msun)) ) period_prescale = period_prescale.to(u.day).value - meananno = self.epochs[min_epoch]/period_prescale - tau + meananno = self.epochs[min_epoch] / period_prescale - tau # compute sep/PA of generated orbits ra, dec, _ = orbitize.kepler.calc_orbit( - self.epochs[min_epoch], sma, ecc, inc, argp, lan, tau, plx, mtot, - tau_ref_epoch=0, mass_for_Kamp=m1 + self.epochs[min_epoch], + sma, + ecc, + inc, + argp, + lan, + tau, + plx, + mtot, + tau_ref_epoch=0, + mass_for_Kamp=m1, ) - sep, pa = orbitize.system.radec2seppa(ra, dec) # sep[mas], PA[deg] + sep, pa = orbitize.system.radec2seppa(ra, dec) # sep[mas], PA[deg] # generate Gaussian offsets from observational uncertainties - sep_offset = np.random.normal( - 0, self.sep_err[min_epoch], size=num_samples - ) - pa_offset = np.random.normal( - 0, self.pa_err[min_epoch], size=num_samples - ) + sep_offset = np.random.normal(0, self.sep_err[min_epoch], size=num_samples) + pa_offset = np.random.normal(0, self.pa_err[min_epoch], size=num_samples) # calculate correction factors - sma_corr = (sep_offset + self.sep_observed[min_epoch])/sep - lan_corr = (pa_offset + self.pa_observed[min_epoch] - pa) + sma_corr = (sep_offset + self.sep_observed[min_epoch]) / sep + lan_corr = pa_offset + self.pa_observed[min_epoch] - pa # perform scale-and-rotate - sma *= sma_corr # [AU] - lan += np.radians(lan_corr) # [rad] + sma *= sma_corr # [AU] + lan += np.radians(lan_corr) # [rad] lan = (lan + 2 * np.pi) % (2 * np.pi) if self.system.restrict_angle_ranges: @@ -316,17 +386,25 @@ def prepare_samples(self, num_samples): lan[lan >= np.pi] -= np.pi period_new = np.sqrt( - 4*np.pi**2*(sma*u.AU)**3/(consts.G*(mtot*u.Msun)) + 4 * np.pi**2 * (sma * u.AU) ** 3 / (consts.G * (mtot * u.Msun)) ) period_new = period_new.to(u.day).value - tau = (self.epochs[min_epoch]/period_new - meananno) % 1 + tau = (self.epochs[min_epoch] / period_new - meananno) % 1 # updates samples with new values of sma, pan, tau - samples[self.system.basis.standard_basis_idx['sma{}'.format(body_num)],:] = sma - samples[self.system.basis.standard_basis_idx['aop{}'.format(body_num)],:] = argp - samples[self.system.basis.standard_basis_idx['pan{}'.format(body_num)],:] = lan - samples[self.system.basis.standard_basis_idx['tau{}'.format(body_num)],:] = tau + samples[ + self.system.basis.standard_basis_idx["sma{}".format(body_num)], : + ] = sma + samples[ + self.system.basis.standard_basis_idx["aop{}".format(body_num)], : + ] = argp + samples[ + self.system.basis.standard_basis_idx["pan{}".format(body_num)], : + ] = lan + samples[ + self.system.basis.standard_basis_idx["tau{}".format(body_num)], : + ] = tau return samples @@ -352,34 +430,32 @@ def reject(self, samples): lnp = self._logl(samples) # we just want the chi2 term for rejection, so compute the Gaussian normalization term and remove it - errs = np.array([self.system.data_table['quant1_err'], - self.system.data_table['quant2_err']]).T + errs = np.array( + [self.system.data_table["quant1_err"], self.system.data_table["quant2_err"]] + ).T if self.has_corr: - corrs = self.system.data_table['quant12_corr'] + corrs = self.system.data_table["quant12_corr"] else: corrs = None lnp_scaled = lnp - orbitize.lnlike.chi2_norm_term(errs, corrs) # account for user-set priors on PAN that were destroyed by scale-and-rotate for body_num in np.arange(self.system.num_secondary_bodies) + 1: - - pan_idx = self.system.basis.standard_basis_idx['pan{}'.format(body_num)] + pan_idx = self.system.basis.standard_basis_idx["pan{}".format(body_num)] pan_prior = self.system.sys_priors[pan_idx] if pan_prior is not orbitize.priors.UniformPrior: - # apply PAN prior - lnp_scaled += pan_prior.compute_lnprob(samples[pan_idx,:]) + lnp_scaled += pan_prior.compute_lnprob(samples[pan_idx, :]) # prior is uniform but with different bounds that OFTI expects elif (pan_prior.minval != 0) or ( - (pan_prior.maxval != np.pi) or (pan_prior.maxval != 2*np.pi) + (pan_prior.maxval != np.pi) or (pan_prior.maxval != 2 * np.pi) ): - samples_outside_pan_prior = np.where( - (samples[pan_idx,:] < pan_prior.minval) or - (samples[pan_idx,:] > pan_prior.maxval) + (samples[pan_idx, :] < pan_prior.minval) + or (samples[pan_idx, :] > pan_prior.maxval) )[0] lnp_scaled[samples_outside_pan_prior] = -np.inf @@ -392,7 +468,9 @@ def reject(self, samples): return saved_orbits, lnlikes - def _sampler_process(self, output, total_orbits, num_samples=10000, Value=0, lock=None): + def _sampler_process( + self, output, total_orbits, num_samples=10000, Value=0, lock=None + ): """ Runs OFTI until it finds the number of total accepted orbits desired. Meant to be called by run_sampler. @@ -424,7 +502,6 @@ def _sampler_process(self, output, total_orbits, num_samples=10000, Value=0, loc # add orbits to `output_orbits` until `total_orbits` are saved while n_orbits_saved < total_orbits: - samples = self.prepare_samples(num_samples) accepted_orbits, lnlikes = self.reject(samples) @@ -433,9 +510,12 @@ def _sampler_process(self, output, total_orbits, num_samples=10000, Value=0, loc else: n_accepted = len(accepted_orbits) maxindex2save = np.min([n_accepted, total_orbits - n_orbits_saved]) - output_orbits[n_orbits_saved: n_orbits_saved + - n_accepted] = accepted_orbits[0:maxindex2save] - output_lnlikes[n_orbits_saved: n_orbits_saved+n_accepted] = lnlikes[0:maxindex2save] + output_orbits[ + n_orbits_saved : n_orbits_saved + n_accepted + ] = accepted_orbits[0:maxindex2save] + output_lnlikes[n_orbits_saved : n_orbits_saved + n_accepted] = lnlikes[ + 0:maxindex2save + ] n_orbits_saved += maxindex2save # add to the value of the global variable @@ -445,7 +525,9 @@ def _sampler_process(self, output, total_orbits, num_samples=10000, Value=0, loc output.put((np.array(output_orbits), output_lnlikes)) return (np.array(output_orbits), output_lnlikes) - def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): + def run_sampler( + self, total_orbits, num_samples=10000, num_cores=None, OFTI_warning=True + ): """ Runs OFTI in parallel on multiple cores until we get the number of total accepted orbits we want. @@ -455,6 +537,8 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): rejection sampling on. Defaults to 10000. num_cores (int): the number of cores to run OFTI on. Defaults to number of cores availabe. + OFTI_warning (bool): if True, print a warning if OFTI doesn't accept + any orbits after 60 s. Return: np.array: array of accepted orbits. Size: total_orbits. @@ -463,31 +547,30 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): """ # a flag to print out a warning if no OFTI orbits are accepted in x seconds - start_warning = True - time_warning = 60. # seconds + time_warning = 60.0 # seconds start_time = time.time() - - if num_cores!=1: - if num_cores==None: - num_cores=mp.cpu_count() - - results=[] - # orbits_saved is a global counter for the number of orbits generated - orbits_saved=mp.Value('i',0) - - manager = mp.Manager() + + if num_cores != 1: + if num_cores is not None: + num_cores = mp.cpu_count() + + results = [] + # orbits_saved is a global counter for the number of orbits generated + orbits_saved = mp.Value("i", 0) + + manager = mp.Manager() output = manager.Queue() # setup the processes lock = mp.Lock() - nrun_per_core = int(np.ceil(float(total_orbits)/float(num_cores))) + nrun_per_core = int(np.ceil(float(total_orbits) / float(num_cores))) processes = [ mp.Process( target=self._sampler_process, - args=(output, nrun_per_core, num_samples, - orbits_saved, lock) - ) for x in range(num_cores) + args=(output, nrun_per_core, num_samples, orbits_saved, lock), + ) + for x in range(num_cores) ] # start the processes @@ -496,15 +579,23 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): # print out the number of orbits generated every second while orbits_saved.value < total_orbits: - if start_warning and orbits_saved.value == 0: + if OFTI_warning and orbits_saved.value == 0: check_time = time.time() - start_time if check_time > time_warning: - print('Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.', end='\n') - start_warning = False - print(str(orbits_saved.value)+'/'+str(total_orbits)+' orbits found', end='\r') + print( + "Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.", + end="\n", + ) + OFTI_warning = False + print( + str(orbits_saved.value) + "/" + str(total_orbits) + " orbits found", + end="\r", + ) time.sleep(0.1) - print(str(total_orbits)+'/'+str(total_orbits)+' orbits found', end='\r') + print( + str(total_orbits) + "/" + str(total_orbits) + " orbits found", end="\r" + ) # join the processes for p in processes: @@ -520,14 +611,11 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): for p in results: num_to_fill = np.min([len(p[0]), total_orbits - pos]) - output_orbits[pos:pos+num_to_fill] = p[0][0:num_to_fill] - output_lnlikes[pos:pos+num_to_fill] = p[1][0:num_to_fill] + output_orbits[pos : pos + num_to_fill] = p[0][0:num_to_fill] + output_lnlikes[pos : pos + num_to_fill] = p[1][0:num_to_fill] pos += num_to_fill - self.results.add_samples( - np.array(output_orbits), - output_lnlikes - ) + self.results.add_samples(np.array(output_orbits), output_lnlikes) return output_orbits else: @@ -535,7 +623,7 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): n_orbits_saved = 0 output_orbits = np.empty((total_orbits, len(self.priors))) output_lnlikes = np.empty(total_orbits) - + # add orbits to `output_orbits` until `total_orbits` are saved while n_orbits_saved < total_orbits: samples = self.prepare_samples(num_samples) @@ -543,27 +631,32 @@ def run_sampler(self, total_orbits, num_samples=10000, num_cores=None): if len(accepted_orbits) == 0: check_time = time.time() - start_time - if start_warning and check_time > time_warning: - print('Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.', end='\n') - start_warning = False + if OFTI_warning and check_time > time_warning: + print( + "Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.", + end="\n", + ) + OFTI_warning = False pass else: n_accepted = len(accepted_orbits) maxindex2save = np.min([n_accepted, total_orbits - n_orbits_saved]) - output_orbits[n_orbits_saved: n_orbits_saved + - n_accepted] = accepted_orbits[0:maxindex2save] - output_lnlikes[n_orbits_saved: n_orbits_saved + - n_accepted] = lnlikes[0:maxindex2save] + output_orbits[ + n_orbits_saved : n_orbits_saved + n_accepted + ] = accepted_orbits[0:maxindex2save] + output_lnlikes[ + n_orbits_saved : n_orbits_saved + n_accepted + ] = lnlikes[0:maxindex2save] n_orbits_saved += maxindex2save # print progress statement - print(str(n_orbits_saved)+'/'+str(total_orbits)+' orbits found', end='\r') + print( + str(n_orbits_saved) + "/" + str(total_orbits) + " orbits found", + end="\r", + ) - self.results.add_samples( - np.array(output_orbits), - output_lnlikes - ) + self.results.add_samples(np.array(output_orbits), output_lnlikes) return output_orbits @@ -578,31 +671,40 @@ class MCMC(Sampler): Args: system (system.System): system.System object - num_temps (int): number of temperatures to run the sampler at. + num_temps (int): number of temperatures to run the sampler at. Parallel tempering will be used if num_temps > 1 (default=20) num_walkers (int): number of walkers at each temperature (default=1000) num_threads (int): number of threads to use for parallelization (default=1) chi2_type (str, optional): either "standard", or "log" like (str): name of likelihood function in ``lnlike.py`` - custom_lnlike (func): ability to include an addition custom likelihood - function in the fit. The function looks like - ``clnlikes = custon_lnlike(params)`` where ``params`` is a RxM array - of fitting parameters, where R is the number of orbital paramters - (can be passed in system.compute_model()), and M is the number of - orbits we need model predictions for. It returns ``clnlikes`` + custom_lnlike (func): ability to include an addition custom likelihood + function in the fit. The function looks like + ``clnlikes = custon_lnlike(params)`` where ``params`` is a RxM array + of fitting parameters, where R is the number of orbital paramters + (can be passed in system.compute_model()), and M is the number of + orbits we need model predictions for. It returns ``clnlikes`` which is an array of length M, or it can be a single float if M = 1. - prev_result_filename (str): if passed a filename to an HDF5 file - containing a orbitize.Result data, MCMC will restart from where it - left off. + prev_result_filename (str): if passed a filename to an HDF5 file + containing a orbitize.Result data, MCMC will restart from where it + left off. Written: Jason Wang, Henry Ngo, 2018 """ + def __init__( - self, system, num_temps=20, num_walkers=1000, num_threads=1, chi2_type='standard', - like='chi2_lnlike', custom_lnlike=None, prev_result_filename=None + self, + system, + num_temps=20, + num_walkers=1000, + num_threads=1, + chi2_type="standard", + like="chi2_lnlike", + custom_lnlike=None, + prev_result_filename=None, ): - - super(MCMC, self).__init__(system, like=like, chi2_type=chi2_type, custom_lnlike=custom_lnlike) + super(MCMC, self).__init__( + system, like=like, chi2_type=chi2_type, custom_lnlike=custom_lnlike + ) self.num_temps = num_temps self.num_walkers = num_walkers @@ -614,7 +716,7 @@ def __init__( sampler_name=self.__class__.__name__, post=None, lnlike=None, - version_number=orbitize.__version__ + version_number=orbitize.__version__, ) if self.num_temps > 1: @@ -630,7 +732,6 @@ def __init__( self.sampled_param_idx = {} sampled_param_counter = 0 for i, prior in enumerate(system.sys_priors): - # check for fixed parameters if not hasattr(prior, "draw_samples"): self.fixed_params.append((i, prior)) @@ -649,7 +750,7 @@ def __init__( for prior in self.priors: # draw them uniformly becase we don't know any better right now # TODO: be smarter in the future - random_init = prior.draw_samples(num_walkers*self.num_temps) + random_init = prior.draw_samples(num_walkers * self.num_temps) if self.num_temps > 1: random_init = random_init.reshape([self.num_temps, num_walkers]) @@ -676,7 +777,11 @@ def __init__( if self.use_pt: expected_shape = (self.num_temps,) + expected_shape if prev_pos.shape != expected_shape: - raise ValueError("Unable to restart chain. Saved walker positions has shape {0}, while current sampler needs {1}".format(prev_pos.shape, expected_shape)) + raise ValueError( + "Unable to restart chain. Saved walker positions has shape {0}, while current sampler needs {1}".format( + prev_pos.shape, expected_shape + ) + ) self.curr_pos = prev_pos @@ -685,11 +790,11 @@ def _fill_in_fixed_params(self, sampled_params): Fills in the missing parameters from the chain that aren't being sampled Args: - sampled_params (np.array): either 1-D array of size = number of + sampled_params (np.array): either 1-D array of size = number of sampled params, or 2-D array of shape (num_models, num_params) Returns: - np.array: same number of dimensions as sampled_params, + np.array: same number of dimensions as sampled_params, but with num_params including the fixed parameters """ if len(self.fixed_params) == 0: @@ -732,8 +837,9 @@ def _logl(self, params, include_logp=False): if np.isinf(logp): return -np.inf else: - logp = np.array([orbitize.priors.all_lnpriors(pset, self.priors) - for pset in params]) + logp = np.array( + [orbitize.priors.all_lnpriors(pset, self.priors) for pset in params] + ) else: logp = 0 # don't include prior @@ -760,7 +866,9 @@ def _update_chains_from_sampler(self, sampler, num_steps=None): if self.use_pt: # chain is shape: Ntemp x Nwalkers x Nsteps x Nparams - self.post = sampler.chain[0, :, :num_steps].reshape(-1, num_params) # the reshaping flattens the chain + self.post = sampler.chain[0, :, :num_steps].reshape( + -1, num_params + ) # the reshaping flattens the chain # should also be picking out the lowest temperature logps self.lnlikes = sampler.loglikelihood[0, :, :num_steps].flatten() self.lnlikes_alltemps = sampler.loglikelihood[:, :, :num_steps] @@ -778,21 +886,28 @@ def _update_chains_from_sampler(self, sampler, num_steps=None): def validate_xyz_positions(self): """ - If using the XYZ basis, walkers might be initialized in an invalid - region of parameter space. This function fixes that by replacing invalid + If using the XYZ basis, walkers might be initialized in an invalid + region of parameter space. This function fixes that by replacing invalid positions by new randomly generated positions until all are valid. """ - if self.system.fitting_basis == 'XYZ': + if self.system.fitting_basis == "XYZ": if self.use_pt: all_valid = False while not all_valid: total_invalids = 0 for temp in range(self.num_temps): - to_stand = self.system.basis.to_standard_basis(self.curr_pos[temp,:,:].T.copy()).T + to_stand = self.system.basis.to_standard_basis( + self.curr_pos[temp, :, :].T.copy() + ).T # Get invalids by checking ecc values for each companion - indices = [((i * 6) + 1) for i in range(self.system.num_secondary_bodies)] - invalids = np.where((to_stand[:, indices] < 0.) | (to_stand[:, indices] >= 1.))[0] + indices = [ + ((i * 6) + 1) + for i in range(self.system.num_secondary_bodies) + ] + invalids = np.where( + (to_stand[:, indices] < 0.0) | (to_stand[:, indices] >= 1.0) + )[0] # Redraw samples for the invalid ones if len(invalids) > 0: @@ -800,20 +915,26 @@ def validate_xyz_positions(self): for prior in self.priors: randompos = prior.draw_samples(len(invalids)) newpos.append(randompos) - self.curr_pos[temp, invalids, :] = np.stack(newpos).T + self.curr_pos[temp, invalids, :] = np.stack(newpos).T total_invalids += len(invalids) if total_invalids == 0: all_valid = True - print('All walker positions validated.') + print("All walker positions validated.") else: all_valid = False while not all_valid: total_invalids = 0 - to_stand = self.system.basis.to_standard_basis(self.curr_pos[:,:].T.copy()).T + to_stand = self.system.basis.to_standard_basis( + self.curr_pos[:, :].T.copy() + ).T # Get invalids by checking ecc values for each companion - indices = [((i * 6) + 1) for i in range(self.system.num_secondary_bodies)] - invalids = np.where((to_stand[:, indices] < 0.) | (to_stand[:, indices] >= 1.))[0] + indices = [ + ((i * 6) + 1) for i in range(self.system.num_secondary_bodies) + ] + invalids = np.where( + (to_stand[:, indices] < 0.0) | (to_stand[:, indices] >= 1.0) + )[0] # Redraw saples for the invalid ones if len(invalids) > 0: @@ -821,17 +942,20 @@ def validate_xyz_positions(self): for prior in self.priors: randompos = prior.draw_samples(len(invalids)) newpos.append(randompos) - self.curr_pos[invalids, :] = np.stack(newpos).T + self.curr_pos[invalids, :] = np.stack(newpos).T total_invalids += len(invalids) if total_invalids == 0: all_valid = True - print('All walker positions validated.') - - + print("All walker positions validated.") def run_sampler( - self, total_orbits, burn_steps=0, thin=1, examine_chains=False, - output_filename=None, periodic_save_freq=None + self, + total_orbits, + burn_steps=0, + thin=1, + examine_chains=False, + output_filename=None, + periodic_save_freq=None, ): """ Runs PT MCMC sampler. Results are stored in ``self.chain`` and ``self.lnlikes``. @@ -859,7 +983,9 @@ def run_sampler( """ if periodic_save_freq is not None and output_filename is None: - raise ValueError("output_filename must be defined for periodic saving of the chains") + raise ValueError( + "output_filename must be defined for periodic saving of the chains" + ) if periodic_save_freq is not None and not isinstance(periodic_save_freq, int): raise TypeError("periodic_save_freq must be an integer") @@ -867,100 +993,145 @@ def run_sampler( if nsteps <= 0: raise ValueError("Total_orbits must be greater than num_walkers.") - with Pool(processes=self.num_threads) as pool: + with Pool(processes=self.num_threads) as pool: if self.use_pt: sampler = ptemcee.Sampler( - self.num_walkers, self.num_params, self._logl, orbitize.priors.all_lnpriors, - ntemps=self.num_temps, threads=self.num_threads, logpargs=[self.priors, ] + self.num_walkers, + self.num_params, + self._logl, + orbitize.priors.all_lnpriors, + ntemps=self.num_temps, + threads=self.num_threads, + logpargs=[ + self.priors, + ], ) else: sampler = emcee.EnsembleSampler( - self.num_walkers, self.num_params, self._logl, pool=pool, - kwargs={'include_logp': True} + self.num_walkers, + self.num_params, + self._logl, + pool=pool, + kwargs={"include_logp": True}, ) print("Starting Burn in") - for i, state in enumerate(sampler.sample(self.curr_pos, iterations=burn_steps, thin=thin)): + for i, state in enumerate( + sampler.sample(self.curr_pos, iterations=burn_steps, thin=thin) + ): if self.use_pt: self.curr_pos = state[0] else: self.curr_pos = state.coords - if (i+1) % 5 == 0: - print(str(i+1)+'/'+str(burn_steps)+' steps of burn-in complete', end='\r') + if (i + 1) % 5 == 0: + print( + str(i + 1) + + "/" + + str(burn_steps) + + " steps of burn-in complete", + end="\r", + ) if periodic_save_freq is not None: - if (i+1) % periodic_save_freq == 0: # we've completed i+1 steps + if (i + 1) % periodic_save_freq == 0: # we've completed i+1 steps self.results.curr_pos = self.curr_pos self.results.save_results(output_filename) sampler.reset() - print('') - print('Burn in complete. Sampling posterior now.') + print("") + print("Burn in complete. Sampling posterior now.") - saved_upto = 0 # keep track of how many steps of this chain we've saved. this is the next index that needs to be saved - for i, state in enumerate(sampler.sample(self.curr_pos, iterations=nsteps, thin=thin)): + saved_upto = 0 # keep track of how many steps of this chain we've saved. this is the next index that needs to be saved + for i, state in enumerate( + sampler.sample(self.curr_pos, iterations=nsteps, thin=thin) + ): if self.use_pt: self.curr_pos = state[0] else: self.curr_pos = state.coords - + # print progress statement - if (i+1) % 5 == 0: - print(str(i+1)+'/'+str(nsteps)+' steps completed', end='\r') + if (i + 1) % 5 == 0: + print(str(i + 1) + "/" + str(nsteps) + " steps completed", end="\r") if periodic_save_freq is not None: - if (i+1) % periodic_save_freq == 0: # we've completed i+1 steps - self._update_chains_from_sampler(sampler, num_steps=i+1) + if (i + 1) % periodic_save_freq == 0: # we've completed i+1 steps + self._update_chains_from_sampler(sampler, num_steps=i + 1) # figure out what is the new chunk of the chain and corresponding lnlikes that have been computed before last save # grab the current posterior and lnlikes and reshape them to have the Nwalkers x Nsteps dimension again post_shape = self.post.shape - curr_chain_shape = (self.num_walkers, post_shape[0]//self.num_walkers, post_shape[-1]) + curr_chain_shape = ( + self.num_walkers, + post_shape[0] // self.num_walkers, + post_shape[-1], + ) curr_chain = self.post.reshape(curr_chain_shape) curr_lnlike_chain = self.lnlikes.reshape(curr_chain_shape[:2]) # use the reshaped arrays and find the new steps we computed - curr_chunk = curr_chain[:, saved_upto:i+1] - curr_chunk = curr_chunk.reshape(-1, curr_chunk.shape[-1]) # flatten nwalkers x nsteps dim - curr_lnlike_chunk = curr_lnlike_chain[:, saved_upto:i+1].flatten() + curr_chunk = curr_chain[:, saved_upto : i + 1] + curr_chunk = curr_chunk.reshape( + -1, curr_chunk.shape[-1] + ) # flatten nwalkers x nsteps dim + curr_lnlike_chunk = curr_lnlike_chain[ + :, saved_upto : i + 1 + ].flatten() # add this current chunk to the results object (which already has all the previous chunks saved) - self.results.add_samples(curr_chunk, curr_lnlike_chunk, - curr_pos=self.curr_pos) + self.results.add_samples( + curr_chunk, curr_lnlike_chunk, curr_pos=self.curr_pos + ) self.results.save_results(output_filename) - saved_upto = i+1 + saved_upto = i + 1 - print('') + print("") self._update_chains_from_sampler(sampler) if periodic_save_freq is None: # need to save everything - self.results.add_samples(self.post, self.lnlikes, curr_pos=self.curr_pos) + self.results.add_samples( + self.post, self.lnlikes, curr_pos=self.curr_pos + ) elif saved_upto < nsteps: # just need to save the last few # same code as above except we just need to grab the last few post_shape = self.post.shape - curr_chain_shape = (self.num_walkers, post_shape[0]//self.num_walkers, post_shape[-1]) + curr_chain_shape = ( + self.num_walkers, + post_shape[0] // self.num_walkers, + post_shape[-1], + ) curr_chain = self.post.reshape(curr_chain_shape) curr_lnlike_chain = self.lnlikes.reshape(curr_chain_shape[:2]) curr_chunk = curr_chain[:, saved_upto:] - curr_chunk = curr_chunk.reshape(-1, curr_chunk.shape[-1]) # flatten nwalkers x nsteps dim + curr_chunk = curr_chunk.reshape( + -1, curr_chunk.shape[-1] + ) # flatten nwalkers x nsteps dim curr_lnlike_chunk = curr_lnlike_chain[:, saved_upto:].flatten() - self.results.add_samples(curr_chunk, curr_lnlike_chunk, - curr_pos=self.curr_pos) + self.results.add_samples( + curr_chunk, curr_lnlike_chunk, curr_pos=self.curr_pos + ) if output_filename is not None: self.results.save_results(output_filename) - print('Run complete') + print("Run complete") # Close pool if examine_chains: self.examine_chains() return sampler - def examine_chains(self, param_list=None, walker_list=None, n_walkers=None, step_range=None, transparency = 1): + def examine_chains( + self, + param_list=None, + walker_list=None, + n_walkers=None, + step_range=None, + transparency=1, + ): """ Plots position of walkers at each step from Results object. Returns list of figures, one per parameter Args: @@ -986,13 +1157,17 @@ def examine_chains(self, param_list=None, walker_list=None, n_walkers=None, step # Get the flattened chain from Results object (nwalkers*nsteps, nparams) flatchain = np.copy(self.results.post) total_samples, n_params = flatchain.shape - n_steps = int(total_samples/self.num_walkers) + n_steps = int(total_samples / self.num_walkers) # Reshape it to (nwalkers, nsteps, nparams) chn = flatchain.reshape((self.num_walkers, n_steps, n_params)) # Get list of walkers to use - if n_walkers is not None: # If n_walkers defined, randomly choose that many walkers - walkers_to_plot = np.random.choice(self.num_walkers, size=n_walkers, replace=False) + if ( + n_walkers is not None + ): # If n_walkers defined, randomly choose that many walkers + walkers_to_plot = np.random.choice( + self.num_walkers, size=n_walkers, replace=False + ) elif walker_list is not None: # if walker_list is given, use that list walkers_to_plot = np.array(walker_list) else: # both n_walkers and walker_list are none, so use all walkers @@ -1007,7 +1182,9 @@ def examine_chains(self, param_list=None, walker_list=None, n_walkers=None, step if i in self.system.basis.param_idx: params_plot_list.append(self.system.basis.param_idx[i]) else: - raise Exception('Invalid param name: {}. See system.basis.param_idx.'.format(i)) + raise Exception( + "Invalid param name: {}. See system.basis.param_idx.".format(i) + ) params_to_plot = np.array(params_plot_list) # Loop through each parameter and make plot @@ -1015,8 +1192,8 @@ def examine_chains(self, param_list=None, walker_list=None, n_walkers=None, step for pp in params_to_plot: fig, ax = plt.subplots() for ww in walkers_to_plot: - ax.plot(chn[ww, :, pp], 'k-', alpha = transparency) - ax.set_xlabel('Step') + ax.plot(chn[ww, :, pp], "k-", alpha=transparency) + ax.set_xlabel("Step") if step_range is not None: # Limit range shown if step_range is set ax.set_xlim(step_range) output_figs.append(fig) @@ -1026,8 +1203,8 @@ def examine_chains(self, param_list=None, walker_list=None, n_walkers=None, step def chop_chains(self, burn, trim=0): """ - Permanently removes steps from beginning (and/or end) of chains from the - Results object. Also updates `curr_pos` if steps are removed from the + Permanently removes steps from beginning (and/or end) of chains from the + Results object. Also updates `curr_pos` if steps are removed from the end of the chain. Args: @@ -1042,7 +1219,7 @@ def chop_chains(self, burn, trim=0): # Retrieve information from results object flatchain = np.copy(self.results.post) total_samples, n_params = flatchain.shape - n_steps = int(total_samples/self.num_walkers) + n_steps = int(total_samples / self.num_walkers) flatlnlikes = np.copy(self.results.lnlike) # Reshape chain to (nwalkers, nsteps, nparams) @@ -1064,21 +1241,25 @@ def chop_chains(self, burn, trim=0): self.curr_pos = chopped_chain[:, -1, :] # Flatten likelihoods and samples - flat_chopped_chain = chopped_chain.reshape(self.num_walkers*n_chopped_steps, n_params) - flat_chopped_lnlikes = chopped_lnlikes.reshape(self.num_walkers*n_chopped_steps) + flat_chopped_chain = chopped_chain.reshape( + self.num_walkers * n_chopped_steps, n_params + ) + flat_chopped_lnlikes = chopped_lnlikes.reshape( + self.num_walkers * n_chopped_steps + ) # Update results object associated with this sampler self.results = orbitize.results.Results( - self.system, + self.system, sampler_name=self.__class__.__name__, post=flat_chopped_chain, lnlike=flat_chopped_lnlikes, - version_number = orbitize.__version__, - curr_pos = self.curr_pos + version_number=orbitize.__version__, + curr_pos=self.curr_pos, ) # Print a confirmation - print('Chains successfully chopped. Results object updated.') + print("Chains successfully chopped. Results object updated.") def check_prior_support(self): """ @@ -1090,8 +1271,10 @@ def check_prior_support(self): """ # Flatten the walker/temperature positions for ease of manipulation. - all_positions = self.curr_pos.reshape(self.num_walkers*self.num_temps,self.num_params) - + all_positions = self.curr_pos.reshape( + self.num_walkers * self.num_temps, self.num_params + ) + # Placeholder list to track any bad parameters that come up. bad_parameters = [] @@ -1108,14 +1291,19 @@ def check_prior_support(self): # Throw our ValueError if necessary, if len(bad_parameters) > 0: - raise ValueError("Attempting to start with walkers outside of prior support: check parameter(s) "+', '.join(bad_parameters)) + raise ValueError( + "Attempting to start with walkers outside of prior support: check parameter(s) " + + ", ".join(bad_parameters) + ) # We're not done yet, however. There may be errors in covariant priors; run a check for that. else: for y in all_positions: - lnprob = orbitize.priors.all_lnpriors(y,self.priors) + lnprob = orbitize.priors.all_lnpriors(y, self.priors) if not np.isfinite(lnprob).all(): - raise ValueError("Attempting to start with walkers outside of prior support: covariant prior failure.") - + raise ValueError( + "Attempting to start with walkers outside of prior support: covariant prior failure." + ) + # otherwise exit the function and continue. return From 0b5f85b6f47dfc69c35b8cfdde8e0974d9f17702 Mon Sep 17 00:00:00 2001 From: Sarah Blunt Date: Mon, 15 Jan 2024 18:02:24 -0800 Subject: [PATCH 3/7] bugfix --- orbitize/sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orbitize/sampler.py b/orbitize/sampler.py index fe181b9a..69c44911 100644 --- a/orbitize/sampler.py +++ b/orbitize/sampler.py @@ -551,7 +551,7 @@ def run_sampler( start_time = time.time() if num_cores != 1: - if num_cores is not None: + if num_cores is None: num_cores = mp.cpu_count() results = [] From c8facdff89adcef912568cd4bcebcc069940c701 Mon Sep 17 00:00:00 2001 From: Sarah Blunt Date: Mon, 15 Jan 2024 18:27:12 -0800 Subject: [PATCH 4/7] make warning a float instead of bool --- orbitize/sampler.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/orbitize/sampler.py b/orbitize/sampler.py index 69c44911..5251cb09 100644 --- a/orbitize/sampler.py +++ b/orbitize/sampler.py @@ -526,7 +526,7 @@ def _sampler_process( return (np.array(output_orbits), output_lnlikes) def run_sampler( - self, total_orbits, num_samples=10000, num_cores=None, OFTI_warning=True + self, total_orbits, num_samples=10000, num_cores=None, OFTI_warning=60.0 ): """ Runs OFTI in parallel on multiple cores until we get the number of total accepted orbits we want. @@ -537,8 +537,9 @@ def run_sampler( rejection sampling on. Defaults to 10000. num_cores (int): the number of cores to run OFTI on. Defaults to number of cores availabe. - OFTI_warning (bool): if True, print a warning if OFTI doesn't accept - any orbits after 60 s. + OFTI_warning (float): if OFTI doesn't accept a single orbit before + this amount of time (in seconds), print a warning suggesting to + try MCMC. If None, don't print a warning. Return: np.array: array of accepted orbits. Size: total_orbits. @@ -546,8 +547,6 @@ def run_sampler( """ - # a flag to print out a warning if no OFTI orbits are accepted in x seconds - time_warning = 60.0 # seconds start_time = time.time() if num_cores != 1: @@ -579,14 +578,14 @@ def run_sampler( # print out the number of orbits generated every second while orbits_saved.value < total_orbits: - if OFTI_warning and orbits_saved.value == 0: + if OFTI_warning is not None and orbits_saved.value == 0: check_time = time.time() - start_time - if check_time > time_warning: + if check_time > OFTI_warning: print( "Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.", end="\n", ) - OFTI_warning = False + OFTI_warning = None print( str(orbits_saved.value) + "/" + str(total_orbits) + " orbits found", end="\r", @@ -631,12 +630,13 @@ def run_sampler( if len(accepted_orbits) == 0: check_time = time.time() - start_time - if OFTI_warning and check_time > time_warning: - print( - "Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.", - end="\n", - ) - OFTI_warning = False + if OFTI_warning is not None: + if check_time > OFTI_warning: + print( + "Warning! OFTI is taking a while, and you may want to consider MCMC, check out the MCMC vs OFTI tutorial.", + end="\n", + ) + OFTI_warning = None pass else: n_accepted = len(accepted_orbits) From db0828393c14785a7254e219e514dd089d2ec800 Mon Sep 17 00:00:00 2001 From: Sarah Blunt Date: Mon, 15 Jan 2024 19:35:54 -0800 Subject: [PATCH 5/7] wider tolerances for failed iad test --- orbitize/.nfs000000000004befd000046fe | Bin 0 -> 86304 bytes tests/test_hipparcos.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100755 orbitize/.nfs000000000004befd000046fe diff --git a/orbitize/.nfs000000000004befd000046fe b/orbitize/.nfs000000000004befd000046fe new file mode 100755 index 0000000000000000000000000000000000000000..ac029cef6a2dada583925896eb9be49460bc3809 GIT binary patch literal 86304 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 ut2*D>{!#nXY3G3Q=h!k8( Date: Tue, 16 Jan 2024 11:59:46 -0800 Subject: [PATCH 6/7] wider tolerance for failing chi2 test --- orbitize/.nfs000000000004befd000046fe | Bin 86304 -> 0 bytes tests/test_chi2_lnlike.py | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100755 orbitize/.nfs000000000004befd000046fe diff --git a/orbitize/.nfs000000000004befd000046fe b/orbitize/.nfs000000000004befd000046fe deleted file mode 100755 index ac029cef6a2dada583925896eb9be49460bc3809..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86304 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 ut2*D>{!#nXY3G3Q=h!k8( Date: Tue, 16 Jan 2024 12:31:57 -0800 Subject: [PATCH 7/7] set numpy random seed to prevent getting unlucky --- docs/tutorials/MCMC_vs_OFTI.ipynb | 275 +++++++++++------------------- 1 file changed, 99 insertions(+), 176 deletions(-) diff --git a/docs/tutorials/MCMC_vs_OFTI.ipynb b/docs/tutorials/MCMC_vs_OFTI.ipynb index 114c384d..433d67f4 100644 --- a/docs/tutorials/MCMC_vs_OFTI.ipynb +++ b/docs/tutorials/MCMC_vs_OFTI.ipynb @@ -43,6 +43,8 @@ "import astropy.table\n", "import time\n", "\n", + "np.random.seed(5)\n", + "\n", "from orbitize.kepler import calc_orbit\n", "from orbitize import system, sampler\n", "from orbitize.read_input import read_file" @@ -63,17 +65,18 @@ "metadata": {}, "outputs": [], "source": [ - "mtot = 1.2 # total system mass [M_sol]\n", - "plx = 60.0 # parallax [mas]\n", + "mtot = 1.2 # total system mass [M_sol]\n", + "plx = 60.0 # parallax [mas]\n", + "\n", + "\n", + "def generate_synthetic_data(sma=30.0, num_obs=4, unc=10.0):\n", + " \"\"\"Generate an orbitize-table of synethic data\n", "\n", - "def generate_synthetic_data(sma=30., num_obs=4, unc=10.0):\n", - " \"\"\" Generate an orbitize-table of synethic data\n", - " \n", " Args:\n", " sma (float): semimajor axis (au)\n", " num_obs (int): number of observations to generate\n", " unc (float): uncertainty on all simulated RA & Dec measurements (mas)\n", - " \n", + "\n", " Returns:\n", " 2-tuple:\n", " - `astropy.table.Table`: data table of generated synthetic data\n", @@ -81,41 +84,48 @@ " \"\"\"\n", "\n", " # assumed ground truth for non-input orbital parameters\n", - " ecc = 0.5 # eccentricity\n", - " inc = np.pi/4 # inclination [rad]\n", - " argp = 0.\n", - " lan = 0. \n", - " tau = 0.8 \n", + " ecc = 0.5 # eccentricity\n", + " inc = np.pi / 4 # inclination [rad]\n", + " argp = 0.0\n", + " lan = 0.0\n", + " tau = 0.8\n", "\n", " # calculate RA/Dec at three observation epochs\n", - " observation_epochs = np.linspace(51550., 52650., num_obs) # `num_obs` epochs between ~2000 and ~2003 [MJD]\n", + " observation_epochs = np.linspace(\n", + " 51550.0, 52650.0, num_obs\n", + " ) # `num_obs` epochs between ~2000 and ~2003 [MJD]\n", " num_obs = len(observation_epochs)\n", - " ra, dec, _ = calc_orbit(observation_epochs, sma, ecc, inc, argp, lan, tau, plx, mtot)\n", + " ra, dec, _ = calc_orbit(\n", + " observation_epochs, sma, ecc, inc, argp, lan, tau, plx, mtot\n", + " )\n", "\n", " # add Gaussian noise to simulate measurement\n", " ra += np.random.normal(scale=unc, size=num_obs)\n", " dec += np.random.normal(scale=unc, size=num_obs)\n", - " \n", + "\n", " # define observational uncertainties\n", - " ra_err = dec_err = np.ones(num_obs)*unc\n", - " \n", + " ra_err = dec_err = np.ones(num_obs) * unc\n", + "\n", " # make a plot of the data\n", " plt.figure()\n", - " plt.errorbar(ra, dec, xerr=ra_err, yerr=dec_err, linestyle='')\n", - " plt.xlabel('$\\\\Delta$ RA'); plt.ylabel('$\\\\Delta$ Dec')\n", - " \n", + " plt.errorbar(ra, dec, xerr=ra_err, yerr=dec_err, linestyle=\"\")\n", + " plt.xlabel(\"$\\\\Delta$ RA\")\n", + " plt.ylabel(\"$\\\\Delta$ Dec\")\n", + "\n", " # calculate the orbital fraction\n", - " period = np.sqrt((sma**3)/mtot)\n", - " orbit_coverage = (max(observation_epochs) - min(observation_epochs))/365.25 # [yr]\n", - " orbit_fraction = 100*orbit_coverage/period\n", + " period = np.sqrt((sma**3) / mtot)\n", + " orbit_coverage = (\n", + " max(observation_epochs) - min(observation_epochs)\n", + " ) / 365.25 # [yr]\n", + " orbit_fraction = 100 * orbit_coverage / period\n", "\n", " data_table = astropy.table.Table(\n", - " [observation_epochs, [1]*num_obs, ra, ra_err, dec, dec_err], \n", - " names=('epoch', 'object', 'raoff', 'raoff_err', 'decoff', 'decoff_err')\n", + " [observation_epochs, [1] * num_obs, ra, ra_err, dec, dec_err],\n", + " names=(\"epoch\", \"object\", \"raoff\", \"raoff_err\", \"decoff\", \"decoff_err\"),\n", " )\n", " # read into orbitize format\n", " data_table = read_file(data_table)\n", - " \n", + "\n", " return data_table, orbit_fraction" ] }, @@ -147,8 +157,7 @@ }, { "data": { - "image/png": "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", - "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", + "image/png": "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", "text/plain": [ "
" ] @@ -162,12 +171,12 @@ "source": [ "# generate data with default kwargs\n", "short_data_table, short_orbit_fraction = generate_synthetic_data()\n", - "print('The orbit fraction is {}%'.format(np.round(short_orbit_fraction),1))\n", + "print(\"The orbit fraction is {}%\".format(np.round(short_orbit_fraction), 1))\n", "\n", "# initialize orbitize `System` object\n", "short_system = system.System(1, short_data_table, mtot, plx)\n", "\n", - "num2accept = 500 # run sampler until this many orbits are accepted" + "num2accept = 500 # run sampler until this many orbits are accepted" ] }, { @@ -180,7 +189,19 @@ "output_type": "stream", "text": [ "Converting ra/dec data points in data_table to sep/pa. Original data are stored in input_table.\n", - "OFTI took 4.926873683929443 seconds to accept 500 orbits.\n" + "497/500 orbits found\r" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Input \u001b[0;32mIn [4]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m short_OFTI_sampler \u001b[38;5;241m=\u001b[39m sampler\u001b[38;5;241m.\u001b[39mOFTI(short_system)\n\u001b[1;32m 6\u001b[0m \u001b[38;5;66;03m# perform OFTI fit\u001b[39;00m\n\u001b[0;32m----> 7\u001b[0m short_OFTI_orbits \u001b[38;5;241m=\u001b[39m \u001b[43mshort_OFTI_sampler\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_sampler\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum2accept\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\n\u001b[1;32m 10\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mOFTI took \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m seconds to accept \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m orbits.\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m 11\u001b[0m time\u001b[38;5;241m.\u001b[39mtime() \u001b[38;5;241m-\u001b[39m start_time, num2accept\n\u001b[1;32m 12\u001b[0m )\n\u001b[1;32m 13\u001b[0m )\n", + "File \u001b[0;32m~/Documents/GitHub/orbitize/orbitize/sampler.py:593\u001b[0m, in \u001b[0;36mOFTI.run_sampler\u001b[0;34m(self, total_orbits, num_samples, num_cores, OFTI_warning)\u001b[0m\n\u001b[1;32m 588\u001b[0m OFTI_warning \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m 589\u001b[0m \u001b[38;5;28mprint\u001b[39m(\n\u001b[1;32m 590\u001b[0m \u001b[38;5;28mstr\u001b[39m(orbits_saved\u001b[38;5;241m.\u001b[39mvalue) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(total_orbits) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m orbits found\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 591\u001b[0m end\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\r\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 592\u001b[0m )\n\u001b[0;32m--> 593\u001b[0m \u001b[43mtime\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0.1\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 595\u001b[0m \u001b[38;5;28mprint\u001b[39m(\n\u001b[1;32m 596\u001b[0m \u001b[38;5;28mstr\u001b[39m(total_orbits) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mstr\u001b[39m(total_orbits) \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m orbits found\u001b[39m\u001b[38;5;124m\"\u001b[39m, end\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\r\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 597\u001b[0m )\n\u001b[1;32m 599\u001b[0m \u001b[38;5;66;03m# join the processes\u001b[39;00m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], @@ -193,43 +214,18 @@ "# perform OFTI fit\n", "short_OFTI_orbits = short_OFTI_sampler.run_sampler(num2accept)\n", "\n", - "print(\"OFTI took {} seconds to accept {} orbits.\".format(time.time()-start_time, num2accept))" + "print(\n", + " \"OFTI took {} seconds to accept {} orbits.\".format(\n", + " time.time() - start_time, num2accept\n", + " )\n", + ")" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting Burn in\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/sblunt/Projects/orbitize/orbitize/priors.py:354: RuntimeWarning: invalid value encountered in log\n", - " lnprob = -np.log((element_array*normalizer))\n", - "/home/sblunt/Projects/orbitize/orbitize/priors.py:463: RuntimeWarning: invalid value encountered in log\n", - " lnprob = np.log(np.sin(element_array)/normalization)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "100/100 steps of burn-in complete\n", - "Burn in complete. Sampling posterior now.\n", - "250/250 steps completed\n", - "Run complete\n", - "MCMC took 5000 steps in 47.53257179260254 seconds.\n" - ] - } - ], + "outputs": [], "source": [ "start_time = time.time()\n", "\n", @@ -238,47 +234,40 @@ "short_MCMC_sampler = sampler.MCMC(short_system, num_temps=5, num_walkers=num_walkers)\n", "\n", "# perform MCMC fit\n", - "num2accept_mcmc = 10*num2accept\n", + "num2accept_mcmc = 10 * num2accept\n", "_ = short_MCMC_sampler.run_sampler(num2accept_mcmc, burn_steps=100)\n", "short_MCMC_orbits = short_MCMC_sampler.results.post\n", "\n", - "print(\"MCMC took {} steps in {} seconds.\".format(num2accept_mcmc, time.time()-start_time))" + "print(\n", + " \"MCMC took {} steps in {} seconds.\".format(\n", + " num2accept_mcmc, time.time() - start_time\n", + " )\n", + ")" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEGCAYAAABiq/5QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAVeElEQVR4nO3df5TVdZ3H8ddLoB0RMIVpjwnsgD9KFBdzTK21IPQcRQIzT+CunZSMk2Rriu7q4aiU5i9csfV0duNoqdiCaSmGuUmJZQkmKOoMlCixOpubI7YaKpvIe/+43+HHMD8uM3O/35n7eT7OmcO93/u93+97Pod5zWc+38/9fB0RAgCkY6+iCwAA5IvgB4DEEPwAkBiCHwASQ/ADQGL6F11AOYYNGxZ1dXVFlwEAfcrq1atfi4ja1tv7RPDX1dVp1apVRZcBAH2K7f9qaztDPQCQGIIfABJD8ANAYvrEGD8AtOXdd99VU1OTtmzZUnQphaqpqdHw4cM1YMCAsvYn+AH0WU1NTRo8eLDq6upku+hyChER2rRpk5qamjRq1Kiy3sNQD4A+a8uWLRo6dGiyoS9JtjV06NA9+quH4AfQp6Uc+i32tA0IfgBIDGP8AKrG/GXP9+jxLjzp0E73aWpq0le+8hWtXbtW27Zt0+TJkzVv3jw9/vjjmjp16vZx92HDhmnChAm65557JEnPPfecxo4dK0maMWOGXn/9dQ0aNEgXX3xxj34PbSH4kb/l1+6+bcJl+dcBdFNE6PTTT9d5552nJUuW6L333tPMmTM1Z84cnXrqqTrhhBO0dOnSXd4zZ84cSdKgQYO0Zs2a7dvnzp2bW90EPwB00SOPPKKamhqdc845kqR+/fpp/vz5GjVqlCZMmFBwde1jjB8AuqixsVFHH330LtuGDBmikSNH6oUXXtBjjz2mcePGady4cfrmN79ZUJW7q1iP3/Z3JU2W9GpEHJFt21/S3ZLqJG2U9LmI+FOlagCASoqINmfUtGxva6inN6hkj/92SSe32nappJ9HxCGSfp49B4A+6fDDD99t5eA333xTL7/8sg466KCCqupcxYI/In4p6fVWm6dKuiN7fIek0yp1fgCotIkTJ+rtt9/WnXfeKUl67733NHv2bJ199tkaOHBgwdW1L++Lu38dEa9IUkS8YvsD7e1oe6akmZI0cuTInMoD0JeVM/2yJ9nWfffdp1mzZumqq67Stm3bNGnSJF1zzTVasWJFrrXsiV47qyciFkhaIEn19fVRcDkA0KYRI0boxz/+8W7bx48fr/Hjx7f7vs2bN+/yPM/pnHnP6vmj7QMkKfv31ZzPDwDJyzv4H5D0hezxFyQtyfn8AJC8igW/7UWSVkj6kO0m21+UdJ2kk2yvl3RS9hwAkKOKjfFHxJntvDSxUucEAHSOT+4CQGIIfgBITK+dzgkAe6ytlV+7o4xVY23rrLPO0sKFCyVJW7du1QEHHKBjjz12+3INDz30kC6//HK99dZbighNnjxZN954o+bOnauvf/3rWr9+vQ4++GBJ0vz583XRRRfpySefVH19vTZv3qzZs2frZz/7mWpqajR06FDNmzdPxx57bJe/LXr8ANAN++yzjxoaGvTOO+9IkpYtW6YDDzxw++sNDQ06//zzddddd2ndunVqaGjQ6NGjt78+duxYLV68ePvze++9V2PGjNn+/Nxzz9X++++v9evXq7GxUbfffrtee+21btVM8ANAN51yyil68MEHJUmLFi3SmWfumNtyww03aM6cOfrwhz8sSerfv79mzZq1/fXTTjtNS5aUZrZv2LBB++67r2prayVJL774op544gldffXV2muvUlyPHj1ap556arfqJfgBoJumT5+uxYsXa8uWLXr22Wd3GYZpaGjYbenmnQ0ZMkQjRoxQQ0ODFi1apGnTpm1/rbGxUePGjVO/fv16tF6CHwC66cgjj9TGjRu1aNEiTZo0aY/f3/KL4/7779dnPvOZClS4K4IfAHrAlClTdPHFF+8yzCOVlm5evXp1h+/99Kc/rYULF2rkyJEaMmTILu995plntG3bth6tleAHgB4wY8YMXXHFFdtvoN7ikksu0TXXXKPnny/dCH7btm266aabdtln77331vXXX7/9frwtDjroINXX1+vKK69URGmtyvXr12+/JtBVTOcEUD3KmH5ZKcOHD9cFF1yw2/YjjzxSN998s84880y9/fbbst3mxdnp06e3edxbb71Vs2fP1sEHH6yBAwdun87ZHW75LdKb1dfXR+u73KAPa2uudYE/sOi71q1bp8MOO6zoMnqFttrC9uqIqG+9L0M9AJAYgh8AEkPwA+jT+sJwdaXtaRsQ/AD6rJqaGm3atCnp8I8Ibdq0STU1NWW/h1k9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", - "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "plt.hist(short_OFTI_orbits[:, short_system.param_idx['ecc1']], bins=40, density=True, alpha=.5, label='OFTI')\n", - "plt.hist(short_MCMC_orbits[:, short_system.param_idx['ecc1']], bins=40, density=True, alpha=.5, label='MCMC')\n", - "\n", - "plt.xlabel('Eccentricity'); plt.ylabel('Prob.')\n", + "plt.hist(\n", + " short_OFTI_orbits[:, short_system.param_idx[\"ecc1\"]],\n", + " bins=40,\n", + " density=True,\n", + " alpha=0.5,\n", + " label=\"OFTI\",\n", + ")\n", + "plt.hist(\n", + " short_MCMC_orbits[:, short_system.param_idx[\"ecc1\"]],\n", + " bins=40,\n", + " density=True,\n", + " alpha=0.5,\n", + " label=\"MCMC\",\n", + ")\n", + "\n", + "plt.xlabel(\"Eccentricity\")\n", + "plt.ylabel(\"Prob.\")\n", "plt.legend()" ] }, @@ -302,54 +291,24 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The orbit fraction is 10.0%\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY8AAAEICAYAAACnL3iHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAYsklEQVR4nO3df7BfdX3n8efLRLT+AINE2SbE0F1QqdUULlFQhxQiRFoNVuWH24G1XcJQcCEzVrF0dNGxVWSnTRcdyYSsm11mQRbRuBsawRl06QRN0IAEpUSwkg2tYlgpVKTB9/7xPVe+hu9NcnLv/Z4b7vMx8x3O+Zwf33c+BF73cz7nnpOqQpKkNp7TdQGSpP2P4SFJas3wkCS1ZnhIklozPCRJrc3suoBhOOSQQ2r+/PldlyFJ+5U77rjj4aqaPWjbtAiP+fPns2nTpq7LkKT9SpK/H2ubl60kSa0ZHpKk1gwPSVJrhockqTXDQ5LUmuEhSWrN8JAktWZ4SJJaMzyG7IyrNnDGVRu6LkOSxsXwkCS1ZnhIklozPCRJrRkekqTWOg2PJAuS3J5kc5JNSRY27UuT3NXX/qa+Y85Jcl/zOae76iVp+ur6keyXA5dV1U1JTm3WFwFfBdZWVSV5LfB54FVJDgY+AowABdyRZG1VPdJN+ZI0PXV92aqAA5vlg4DtAFX1WFVV0/7CZj+AU4Cbq2pHExg3A0uGWK8kie5HHhcD65NcQS/Ijh/dkOQdwF8ALwN+t2meAzzYd/y2pu0ZkiwDlgHMmzdvwguXpOls0kceSW5JcveAz1LgfGB5VR0GLAeuHj2uqm6sqlcBpwEfGz3dgK+oAW1U1cqqGqmqkdmzB75FUZK0jyZ95FFVi8falmQNcFGzej2wasDxX0/yr5McQm+ksahv81zg1gkrVpK0V7qe89gOnNAsnwjcB5Dk3yRJs3w0cADwE2A9cHKSWUlmASc3bZKkIep6zuNcYEWSmcATNHMUwDuBs5P8C/Az4IxmAn1Hko8BG5v9PlpVO4ZdtCRNd52GR1XdBhwzoP2TwCfHOGY1sHqSS5Mk7UbXl60kSfshw0OS1JrhIUlqzfCQJLVmeEiSWjM8JEmtGR6SpNYMD0lSa4aHJKk1w0OS1FrXz7baL5xx1YYJO9c9Dz064ee87rzjJuxckrQ3HHlIklpz5LEXJvIn+9ERh6MFSfszRx6SpNYMD0lSa4aHJKm1TsMjyYIktyfZnGRTkoW7bD82yVNJ3tXXdk6S+5rPOcOvWpLU9YT55cBlVXVTklOb9UUASWbQe5vgL99RnuRg4CPACFDAHUnWVtUjwy5ckqazri9bFXBgs3wQsL1v2/uAG4Af9bWdAtxcVTuawLgZWDKMQiVJT+t65HExsD7JFfSC7HiAJHOAdwAnAsf27T8HeLBvfVvTJkkaokkPjyS3AIcO2HQpcBKwvKpuSHI6cDWwGPgr4INV9VSSXzndgPPUGN+7DFgGMG/evH3/A0iSnmHSw6OqFo+1Lcka4KJm9XpgVbM8AlzbBMchwKlJdtIbaSzqO8Vc4NYxvnclsBJgZGRkYMBIkvZN13Me24ETmuUTgfsAqurwqppfVfOB/wn8cVV9kd7k+clJZiWZBZxM34S6JGk4up7zOBdYkWQm8ATNZaaxVNWOJB8DNjZNH62qHZNcoyRpF52GR1XdBhyzh33+3S7rq4HVk1iWJGkPur5sJUnaDxkekqTWDI9p4oyrNkzoC6gkTW+GhySpNcNDktSa4SFJas3wkCS1ZnhIklozPCRJrRkekqTWDA9JUmuGhySpta6fqjvtXHfecV2XIEnj5shDktSa4SFJas3wkCS1ZnhIklrrNDySLEhye5LNSTYlWdi0L0ry06Z9c5IP9x2zJMm9SbYmuaS76iVp+ur6bqvLgcuq6qYkpzbri5pt/6eqfq9/5yQzgE8DbwG2ARuTrK2qe4ZYsyRNe11ftirgwGb5IGD7HvZfCGytqvur6kngWmDpJNYnSRqg65HHxcD6JFfQC7Lj+7Ydl+ROeoHy/qraAswBHuzbZxvw+kEnTrIMWAYwb968SShdkqavSQ+PJLcAhw7YdClwErC8qm5IcjpwNbAY+Bbwiqp6rLmc9UXgCCADzlODvreqVgIrAUZGRgbuI0naN5MeHlW1eKxtSdYAFzWr1wOrmmMe7Tt+XZLPJDmE3kjjsL5TzGXPl7okSROs6zmP7cAJzfKJwH0ASQ5NkmZ5Ib06fwJsBI5IcniSA4AzgbVDr1qSprmu5zzOBVYkmQk8QTNHAbwLOD/JTuBnwJlVVcDOJBcC64EZwOpmLkSSNESdhkdV3QYcM6D9SuDKMY5ZB6yb5NIkSbvR9chDu3HGVRsm7Fz3PPTohJ/TJwRL01fXcx6SpP2QI48pbCJ/sh8dcThakDQRHHlIklozPCRJrRkekqTWDA9JUmuGhySpNcNDktSa4SFJas3wkCS1ZnhIklozPCRJrRkekqTWDA9JUmuGh0TvwZET+bh66dmu0/BIsiDJ7Uk2J9nUvHJ2dNuipn1Lkq/1tS9Jcm+SrUku6aZySZreun4k++XAZVV1U5JTm/VFSV4CfAZYUlU/TPIygCQzgE8DbwG2ARuTrK2qezqqX5Kmpa4vWxVwYLN8ELC9WX4P8IWq+iFAVf2oaV8IbK2q+6vqSeBaYOkQ65Uk0f3I42JgfZIr6AXZ8U37kcBzk9wKvBhYUVVrgDnAg33HbwNeP+jESZYBywDmzZs3KcVL0nQ16eGR5Bbg0AGbLgVOApZX1Q1JTgeuBhY3dR3TbP81YEOS24EMOE8N+t6qWgmsBBgZGRm4jyRp30x6eFTV4rG2JVkDXNSsXg+sapa3AQ9X1ePA40m+DryuaT+s7xRzefpSlyRpSPZ6ziPJf20mskfXZyVZPc7v3w6c0CyfCNzXLH8JeHOSmUleQO/S1HeBjcARSQ5PcgBwJrB2nDVIklpqM/J4bVX9v9GVqnokyW+P8/vPBVYkmQk8QTNHUVXfTfI3wF3AL4BVVXU3QJILgfXADGB1VW0ZZw2SpJbahMdzksyqqkcAkhzc8vhnqKrb6M1tDNr2KeBTA9rXAevG872SpPFp8z///0Rv4vp6epPUpwMfn5SqJElT2l6HR1WtSbKJ3txEgN/3l/P2H9edd1zXJUh6FmkzYR7gaODgqvrPwGP9jxORJE0fbX7D/DPAccBZzfo/0XtUiCRpmmkz5/H6qjo6ybfhl3dbHTBJdUmSprA2I49/aR5MWABJZtO7jVaSNM20CY+/Bm4EXp7k48BtwJ9PSlWSpCmtzd1W1yR5EFgE/AQ4raq+O1mFSZKmrj2GR3OX1UeAC+ndovscYCfwUuCjk1qdJGlK2pvLVhcDbwSOraqXVtUses+aemOS5ZNanSRpStqb8DgbOKuqHhhtqKr7gT9otkmSppm9CY/nVtXDuzZW1Y+B5058SZKkqW5vwuPJfdwmSXqW2pu7rV6X5NEB7QGeP8H1SJL2A3sMj6qaMYxCpLbOuGrDhJ3rnocenfBzgg+k1LNXm18SlCQJGMI7zHcnyQLgs/Quf+0E/riqvpnkT4B/2+w2E3g1MLuqdiRZAqyg9ybBVVX1iQ5K1xQwkT/Vj444HClIe6frkcflwGVVtQD4cLNOVX2qqhY07R8CvtYExwx6T/J9K3AUcFaSozqqXZKmrX0OjyRvTDLeR7IXcGCzfBCwfcA+ZwH/o1leCGytqvur6kngWmDpOGuQJLXU6rJVc5npPfReQfuPwKuAC8bx/RcD65NcQS/Ijt/l+14ALKH3aBSAOcCDfbtso/fb7oNqXQYsA5g3b944SpQk7Wpvnm11JHAmvdB4DLgeWFRVP0jywG4P7h1/C3DogE2XAicBy6vqhiSnA1cDi/v2eRvwt1W1Y/R0A85Tg763qlYCKwFGRkYG7iNJ2jd7M/L4HrAReFdV3b3Ltj3+T7mqFo+1Lcka4KJm9Xpg1S67nMnTl6ygN9I4rG99LoMvdUmSJtHezHm8E/gBcHOS/5bkbUkm6rEk24ETmuUTgftGNyQ5qNn2pb79NwJHJDm8eYvhmcDaCapFkrSX9uaXBG8EbkzyQuA04DxgVZJ1PD3Zva/OBVYkmQk8QTNH0XgH8JWqeryvlp1JLgTW07tVd3VVbRlnDZKkltq8DOpx4BrgmiQHA+8G5o/ny6vqNuCYMbZ9DvjcgPZ1wLrxfK8kaXz26VbdqtpRVVdV1e9MdEGSpKmv618SlCTthwwPSVJrhockqTXDQ9KvOOOqDRP+aHo9+xgekqTWDA9JUmuGhySpNcNDktSa4SFJas3wkCS1ZnhIklozPCRJrRkekqTWDA9JUmt7/T4P6dnsuvOO67oEab/S6cgjyYIktyfZnGRTkoVN+0FJvpzkziRbkry375hzktzXfM7prnpJmr66HnlcDlxWVTclObVZXwRcANxTVW9LMhu4N8k1wIuAjwAjQAF3JFlbVY90U74kTU9dz3kUT78H/SBge1/7i5OEXmDsAHYCpwA3N28yfAS4GVgy3JIlSV2PPC4G1ie5gl6QHd+0XwmspRcmLwbOqKpfJJkDPNh3/DZgzqATJ1kGLAOYN2/e5FQvSdPUpI88ktyS5O4Bn6XA+cDyqjoMWA5c3Rx2CrAZ+HVgAXBlkgOBDPiKGvS9VbWyqkaqamT27NkT/ueSpOls0kceVbV4rG1J1gAXNavXA6ua5fcCn6iqArYmeQB4Fb2RxqK+U8wFbp3gkiVJe9D1nMd24IRm+UTgvmb5h8BJAEleDrwSuB9YD5ycZFaSWcDJTZskaYi6nvM4F1iRZCbwBM0cBfAx4HNJvkPvUtUHq+phgCQfAzY2+320qnYMuWZJmvY6DY+qug04ZkD7dnqjikHHrAZWT3JpkqTd6PqylSRpP2R4SJJaMzwkSa11PWEuaQKccdWGCTvXPQ89OuHn9MGTzz6OPCRJrTnykJ4FJvIn+9ERh6MF7Y4jD0lSa4aHJE0RZ1y1YULnmiaT4SFJas3wkCS1ZnhIklozPCRJrRkekqTWDA9JUmuGhySpNcNDktSa4SFJaq3T8EiyIMntSTYn2ZRkYdM+K8mNSe5K8s0kr+k7ZkmSe5NsTXJJd9VL0vTV9cjjcuCyqloAfLhZB/hTYHNVvRY4G1gBkGQG8GngrcBRwFlJjhp61ZI0zXUdHgUc2CwfBGxvlo8CvgpQVd8D5id5ObAQ2FpV91fVk8C1wNLhlixJ6vqR7BcD65NcQS/Ijm/a7wR+H7ituZT1CmAuMAd4sO/4bcDrB504yTJgGcC8efMmpXhJmq4mfeSR5JYkdw/4LAXOB5ZX1WHAcuDq5rBPALOSbAbeB3wb2AlkwFfUoO+tqpVVNVJVI7Nnz57wP5ckTWeTPvKoqsVjbUuyBrioWb0eWNUc8yjw3mafAA80nxcAh/WdYi5PX+qSJA1J13Me24ETmuUTgfsAkrwkyQFN+78Hvt4EykbgiCSHN9vPBNYOuWZJmva6nvM4F1iRZCbwBM0cBfBqYE2Sp4B7gD8CqKqdSS4E1gMzgNVVtWX4ZUvS9NZpeFTVbcAxA9o3AEeMccw6YN0klyZJ2o2uL1tJkvZDhockqTXDQ5LUmuEhSWqt67utJE0x1513XNclaD/gyEOS1JojD0kahzOu2jBh57rnoUcn/JyTNZJ05CFJas2RhySNw0T+ZD864tgf5p0ceUiSWjM8JEmtGR6SpNYMD0lSa4aHJKk1w0OS1JrhIUlqrdPwSPK6JBuSfCfJl5Mc2LftQ0m2Jrk3ySl97Uuatq1JLummckma3roeeawCLqmq3wJuBP4EIMlR9N5P/pvAEuAzSWYkmQF8GngrcBRwVrOvJGmIug6PVwJfb5ZvBt7ZLC8Frq2qn1fVA8BWYGHz2VpV91fVk8C1zb6SpCHqOjzuBt7eLL8bOKxZngM82LfftqZtrPZnSLIsyaYkm3784x9PaNGSNN1NengkuSXJ3QM+S4E/BC5IcgfwYuDJ0cMGnKp20/7MxqqVVTVSVSOzZ8+eiD+KJKkx6Q9GrKrFe9jlZIAkRwK/27Rt4+lRCMBcYHuzPFa7JGlIur7b6mXNP58D/Bnw2WbTWuDMJM9LcjhwBPBNYCNwRJLDkxxAb1J97fArl6TpretHsp+V5IJm+QvAfwGoqi1JPg/cA+wELqiqpwCSXAisB2YAq6tqy/DLlqTprdPwqKoVwIoxtn0c+PiA9nXAukkuTZK0G13fbSVJ2g8ZHpKk1gwPSVJrhockqTXDQ5LUmuEhSWrN8JAktdb1LwlKkhrXnXdc1yXsNUcekqTWDA9JUmuGhySpNcNDktSa4SFJas3wkCS1ZnhIklozPCRJrRkekqTWUlVd1zDpkvwY+PsJOt0hwMMTdK7JYH3jY33jY33jM9Xqe0VVzR60YVqEx0RKsqmqRrquYyzWNz7WNz7WNz5Tvb5+XraSJLVmeEiSWjM82lvZdQF7YH3jY33jY33jM9Xr+yXnPCRJrTnykCS1ZnhIklozPHYjybuTbEnyiyQju2x7bZINzfbvJHl+035Ms741yV8nSRf1NdvnJXksyfv72pYkubep75LJqm139SV5S5I7mn66I8mJfdumRP8l+VBTw71JTulrH1r/7VLPgiS3J9mcZFOShU17mn7amuSuJEcPq6YBNb6v6ZstSS7vax/Ylx3V+P4kleSQZn1K9F+STyX5XlPDjUle0rdtyvTfr6gqP2N8gFcDrwRuBUb62mcCdwGva9ZfCsxolr8JHAcEuAl467Dr69t+A3A98P5mfQbwfeA3gAOAO4GjOui/3wZ+vVl+DfB/+7Z13n/AUU3fPA84vOmzGcPuv11q/cpoXwCnArf2Ld/U9NcbgG8Mo54B9f0OcAvwvGb9Zbvry45qPAxYT+8Xhg+ZYv13MjCzWf4k8Mmp1n+7fhx57EZVfbeq7h2w6WTgrqq6s9nvJ1X1VJJ/BRxYVRuq929+DXBaB/WR5DTgfmBLX/NCYGtV3V9VTwLXAkuHXV9VfbuqtjerW4DnJ3neFOq/pcC1VfXzqnoA2Eqv74baf7uWCxzYLB8EjPbfUmBN9dwOvKTpx2E7H/hEVf0coKp+1FffoL7swl8CH6DXl6OmRP9V1Veqamezejswt6++qdJ/v8Lw2DdHApVkfZJvJflA0z4H2Na337ambaiSvBD4IHDZLpvmAA/2rXdS3y7eCXy7+Z/OlOg/xu6nLvvvYuBTSR4ErgA+1LRPlX+nRwJvTvKNJF9LcmzTPiXqS/J2eiPcO3fZNCXq28Uf0hsNwdSsD+hdfpnWktwCHDpg06VV9aUxDpsJvAk4Fvhn4KtJ7gAeHbDvuO6F3sf6LgP+sqoe22XKYND8QRf1jR77m/SG6CdPsfrGqmPQD1sTdq/77moFTgKWV9UNSU4HrgYW76bWCbeH+mYCs+hd+jkW+HyS35hC9f0pT/89+5XDBrQNvb7Rv4tJLgV2AtcMu762pn14VNXifThsG/C1qnoYIMk64Gjgv/P0cJNmefszD5/0+l4PvKuZtHwJ8IskTwB30Lvu23V9JJkL3AicXVXfb5q3MTX6bxtj99OE9l+/3dWaZA1wUbN6PbCqWd5drRNqD/WdD3yhudz4zSS/oPeQv87rS/Jb9OYL7mx+mJoLfKu56aDz+vrqPAf4PeCkph8ZZn1tedlq36wHXpvkBUlmAicA91TVQ8A/JXlDc5fQ2cBuf/qeDFX15qqaX1Xzgb8C/ryqrgQ2AkckOTzJAcCZwNph19fcSfK/gQ9V1d/21T0l+o9en5zZzMMcDhxBbyK/y/7bTu/vGcCJwH19tZ7d3DX0BuCnTT8O2xebukhyJL0bCh5m7L4cmqr6TlW9rO+/iW3A0VX1D0yR/kuyhN6l5rdX1T/3beq8/8bU9Yz9VP4A76D3F+3nwD8C6/u2/QG9yd67gcv72keatu8DV9L8Fv+w6+vb5z/S3G3VrJ8K/F1T36Vd9B/wZ8DjwOa+z+jdOVOi/+hd6vg+cC99d3wNs/92qfVN9EaOdwLfAI5p2gN8uqnnOwy4625I9R1Ab+R9N/At4MQ99WVXH+AHPH231VTpv6305jZG/3v47FTtv9GPjyeRJLXmZStJUmuGhySpNcNDktSa4SFJas3wkCS1ZnhIklozPCRJrRke0iRJ8o7m3RGv2s0+TzXv6Lg7yZd3eY/DHo+XumJ4SJPnLGATvceYjOVnVbWgql4D7AAu2OX42/ZwvNQJw0OaBEleRO9ZVH9ELwT2xgaax203x7+xOd7w0JRjeEiT4zTglqq6C3h8T683TTKD3mPXRx+0eBrwN1X1d8COLl8vKw1ieEiT4yzg883y5xl79PFrSTYDPwEOBm7uO/7aZvna3RwvdcIHI0oTLMlLge8Bc6vq582jtL8GvKJ2+Q8uyWNV9aIkBwH/i967Oq6h97TfH9F78c+M5p/POF7qiiMPaeK9C1hXT7/P+wHgH+g9Vn2gqvop8B+A9zfHr6mqV1TvHRSHAQ/s7nhp2AwPaeKdBbwtyQ9GP8Crgffs7qCq+ja993V8gN5bFvvdsKfjpWHyspUkqTVHHpKk1gwPSVJrhockqTXDQ5LUmuEhSWrN8JAktWZ4SJJa+/9c/ayGtcDj4QAAAABJRU5ErkJggg==", - "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# generate data\n", "long_data_table, long_orbit_fraction = generate_synthetic_data(sma=10, num_obs=5)\n", - "print('The orbit fraction is {}%'.format(np.round(long_orbit_fraction),1))\n", + "print(\"The orbit fraction is {}%\".format(np.round(long_orbit_fraction), 1))\n", "\n", "# initialize orbitize `System` object\n", "long_system = system.System(1, long_data_table, mtot, plx)\n", - "num2accept = 500 # run sampler until this many orbits are accepted" + "num2accept = 500 # run sampler until this many orbits are accepted" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Converting ra/dec data points in data_table to sep/pa. Original data are stored in input_table.\n", - "OFTI took 3.6707496643066406 seconds to accept 1 orbit.\n" - ] - } - ], + "outputs": [], "source": [ "start_time = time.time()\n", "\n", @@ -359,27 +318,14 @@ "# perform OFTI fit\n", "long_OFTI_orbits = long_OFTI_sampler.run_sampler(1)\n", "\n", - "print(\"OFTI took {} seconds to accept 1 orbit.\".format(time.time()-start_time))" + "print(\"OFTI took {} seconds to accept 1 orbit.\".format(time.time() - start_time))" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting Burn in\n", - "100/100 steps of burn-in complete\n", - "Burn in complete. Sampling posterior now.\n", - "25/25 steps completed\n", - "Run complete\n", - "MCMC took 500 steps in 35.78284978866577 seconds.\n" - ] - } - ], + "outputs": [], "source": [ "start_time = time.time()\n", "\n", @@ -391,41 +337,18 @@ "_ = long_MCMC_sampler.run_sampler(num2accept, burn_steps=100)\n", "long_MCMC_orbits = long_MCMC_sampler.results.post\n", "\n", - "print(\"MCMC took {} steps in {} seconds.\".format(num2accept, time.time()-start_time))" + "print(\"MCMC took {} steps in {} seconds.\".format(num2accept, time.time() - start_time))" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0, 0.5, 'Prob.')" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "image/svg+xml": "\n\n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "plt.hist(long_MCMC_orbits[:, short_system.param_idx['ecc1']], bins=15, density=True)\n", - "plt.xlabel('Eccentricity'); plt.ylabel('Prob.')" + "plt.hist(long_MCMC_orbits[:, short_system.param_idx[\"ecc1\"]], bins=15, density=True)\n", + "plt.xlabel(\"Eccentricity\")\n", + "plt.ylabel(\"Prob.\")" ] }, { @@ -469,7 +392,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.5" + "version": "3.10.4" } }, "nbformat": 4,