ravest.fit ========== .. py:module:: ravest.fit .. autoapi-nested-parse:: Radial velocity fitting using MCMC and MAP estimation. This module provides the main Fitter class for fitting radial velocity data to planetary models using various parameterisations. Classes ------- .. autoapisummary:: ravest.fit.Fitter ravest.fit.LogPosterior ravest.fit.LogLikelihood ravest.fit.LogPrior ravest.fit.GPFitter ravest.fit.GPLogPosterior ravest.fit.GPLogLikelihood Module Contents --------------- .. py:class:: Fitter(planet_letters: list[str], parameterisation: ravest.param.Parameterisation) Main class for fitting radial velocity data to planetary models. Supports MCMC sampling, MAP estimation, and various parameterisations. Handles multiple planets, trends, and jitter parameters. .. py:attribute:: planet_letters .. py:attribute:: parameterisation .. py:attribute:: _params :type: Dict[str, ravest.param.Parameter] .. py:attribute:: _priors :type: Dict[str, Callable[[float], float]] .. py:method:: add_data(time: numpy.ndarray, vel: numpy.ndarray, velerr: numpy.ndarray, instrument: numpy.ndarray, t0: float) -> None Add the data to the Fitter object. :param time: Time of each observation [days] :type time: array-like :param vel: Radial velocity at each time [m/s] :type vel: array-like :param velerr: Uncertainty on the radial velocity at each time [m/s] :type velerr: array-like :param instrument: Instrument name for each observation (e.g., "HARPS", "HIRES") :type instrument: array-like :param t0: Reference time for the trend [days]. Recommended to set this as mean or median of input `time` array. :type t0: float .. py:property:: params :type: Dict[str, ravest.param.Parameter] fitter.params = param_dict. :type: Parameters dictionary. Set via .. py:property:: priors :type: dict fitter.priors = prior_dict. :type: Priors dictionary. Set via .. py:method:: _validate_complete_params(params: Dict[str, ravest.param.Parameter]) -> None Validate that params dict has required parameters, astrophysically valid values. .. py:method:: _validate_astrophysical_validity(params_values: Dict[str, float]) -> None Validate that all parameter values are astrophysically valid. .. py:method:: _validate_parameter_coupling(params: Dict[str, ravest.param.Parameter]) -> None Validate parameter coupling constraints (e.g., secosw/sesinw must both be free or both fixed). .. py:method:: _set_priors_with_validation(new_priors: dict[str, Callable[[float], float]]) -> None Set priors with validation. Supports partial updates. Can be current or default parameterisation. .. py:method:: _get_default_parameterisation_equivalent_free_param_name(free_param: str) -> Optional[list[str]] Get the names of the default parameterisation equivalent parameter(s), for a single free parameter from the current parameterisation. Note this can be more than one: e.g. if you have secosw, this affects both e & w in the default parameterisation Whereas Tc just maps to Tp alone. :returns: - list[str]: equivalent parameter(s) in the default parameterisation - None: no mapping needed / no alternative priors to look for :rtype: list[str] | None :raises ValueError: If `free_param` is not a recognised planet, instrument, or trend parameter. .. py:method:: _check_params_values_against_priors(validated_priors: dict[str, Callable[[float], float]], current_free_param_names: list[str]) -> None Check parameter values against priors (including if Prior is for the Default parameterisation equivalent parameter). .. py:method:: _convert_single_param_to_default(default_param_name: str) -> float Convert a single parameter from current to default parameterisation. .. py:property:: free_params_dict :type: Dict[str, ravest.param.Parameter] Free parameters as dict. .. py:property:: free_params_values :type: list[float] Values of free parameters as list. .. py:property:: free_params_names :type: list[str] Names of free parameters as list. .. py:property:: fixed_params_dict :type: Dict[str, ravest.param.Parameter] Fixed parameters as dict, mapping names to Parameter objects. .. py:property:: fixed_params_values :type: list[float] Values of fixed parameters, as list. .. py:property:: fixed_params_names :type: list[str] Names of fixed parameters, as list. .. py:property:: fixed_params_values_dict :type: Dict[str, float] Fixed parameters as dict mapping names to just the values. .. py:method:: find_map_estimate(method: str = 'Powell') -> scipy.optimize.OptimizeResult Find Maximum A Posteriori (MAP) estimate of parameters. :param method: Optimization method to use (default: "Powell") :type method: str, optional :returns: The optimization result containing the MAP estimate :rtype: scipy.optimize.OptimizeResult :raises Warning: If MAP optimization fails to converge .. py:method:: generate_initial_walker_positions_random(nwalkers: int, verbose: bool = False, max_attempts: int = 1000) -> numpy.ndarray Generate random initial walker positions that satisfy priors and are astrophysically valid. Creates random starting positions for MCMC walkers by sampling from appropriate distributions based on each parameter's prior type. Ensures that parameter combinations are astrophysically valid (e.g., eccentricity < 1). :param nwalkers: Number of MCMC walkers to generate positions for :type nwalkers: int :param verbose: If True, print walker positions during generation :type verbose: bool, default False :param max_attempts: Maximum attempts to generate a valid walker position :type max_attempts: int, default 1000 :returns: Array of shape (nwalkers, ndim) where ndim is the number of free parameters. Each row represents the starting position for one walker in the order of free_params_names. :rtype: np.ndarray :raises ValueError: If a prior type is not supported for walker generation or if unable to generate valid positions after max_attempts .. rubric:: Examples >>> # Generate positions for 40 walkers >>> nwalkers = 10 * len(fitter.free_params_names) >>> initial_positions = fitter.generate_initial_walker_positions_random(nwalkers) >>> fitter.run_mcmc(initial_positions, nwalkers, max_steps=2000) .. py:method:: generate_initial_walker_positions_around_point(centre: numpy.ndarray | list, nwalkers: int, scale: float = 0.0001, relative: bool = True, verbose: bool = False, max_attempts: int = 1000) -> numpy.ndarray Generate initial walker positions in a ball around a supplied centre point. Creates starting positions for MCMC walkers clustered around a centre point (e.g., MAP estimate). Each walker is generated by adding small random perturbations to the centre values. Validates that both the centre point and all generated walker positions satisfy priors and are astrophysically valid. :param centre: Centre point for walker positions. Must have length equal to the number of free parameters and be in the order of free_params_names. :type centre: np.ndarray or list :param nwalkers: Number of MCMC walkers to generate positions for :type nwalkers: int :param scale: Scale of perturbations around centre point :type scale: float, default 1e-4 :param relative: If True, perturbations scale with parameter values (scale * centre * random). If False, perturbations are absolute (scale * random). :type relative: bool, default True :param verbose: If True, print walker positions during generation :type verbose: bool, default False :param max_attempts: Maximum attempts to generate a valid walker position :type max_attempts: int, default 1000 :returns: Array of shape (nwalkers, ndim) where ndim is the number of free parameters. Each row represents the starting position for one walker in the order of free_params_names. :rtype: np.ndarray :raises ValueError: If centre has wrong length, if centre point is invalid, or if unable to generate valid positions after max_attempts .. rubric:: Examples >>> # Generate walkers around MAP estimate >>> map_result = fitter.find_map_estimate() >>> initial_positions = fitter.generate_initial_walker_positions_around_point( ... centre=map_result.x, nwalkers=40, scale=1e-4 ... ) >>> fitter.run_mcmc(initial_positions, nwalkers=40, max_steps=2000) .. py:method:: generate_initial_walker_positions_from_map(map_result: scipy.optimize.OptimizeResult, nwalkers: int, scale: float = 0.0001, relative: bool = True, verbose: bool = False, max_attempts: int = 1000) -> numpy.ndarray Generate initial walker positions around MAP estimate. Convenience function that generates walker positions clustered around MAP parameter estimates from a pre-computed MAP result. :param map_result: Result from find_map_estimate() :type map_result: scipy.optimize.OptimizeResult :param nwalkers: Number of MCMC walkers to generate positions for :type nwalkers: int :param scale: Scale of perturbations around MAP values :type scale: float, default 1e-4 :param relative: If True, perturbations scale with parameter values. If False, perturbations are absolute. :type relative: bool, default True :param verbose: If True, print walker positions during generation :type verbose: bool, default False :param max_attempts: Maximum attempts to generate a valid walker position :type max_attempts: int, default 1000 :returns: Array of shape (nwalkers, ndim) where ndim is the number of free parameters. Each row represents the starting position for one walker. :rtype: np.ndarray :raises ValueError: If unable to generate valid positions .. rubric:: Examples >>> # Find MAP then generate walkers around it >>> map_result = fitter.find_map_estimate() >>> initial_positions = fitter.generate_initial_walker_positions_from_map( ... map_result=map_result, nwalkers=40 ... ) >>> fitter.run_mcmc(initial_positions, nwalkers=40, max_steps=2000) .. py:method:: run_mcmc(initial_positions: numpy.ndarray, nwalkers: int, max_steps: int = 5000, progress: bool = True, multiprocessing: bool = False, check_convergence: bool = False, convergence_check_interval: int = 1000, convergence_check_start: int = 0) -> None Run MCMC sampling from given initial walker positions. :param initial_positions: Starting positions for all MCMC walkers. Shape must be (nwalkers, ndim) where ndim is the number of free parameters. Each row represents the starting position for one walker in the order of free_params_names. :type initial_positions: np.ndarray :param nwalkers: Number of MCMC walkers (must match first dimension of initial_positions ) :type nwalkers: int :param max_steps: Maximum number of MCMC steps to run. If check_convergence=False, runs for exactly this many steps. If check_convergence=True, runs up to this many steps, stopping early when convergence criteria are met (default: 5000) :type max_steps: int, optional :param progress: Whether to show progress bar during MCMC (default: True) :type progress: bool, optional :param multiprocessing: Whether to use multiprocessing for MCMC (default: False) :type multiprocessing: bool, optional :param check_convergence: If True, check for convergence and stop early when criteria met. Convergence requires: chain length > 50 times max autocorrelation time, and autocorrelation time estimate stable to 1 percent. If False, run for exactly max_steps (default: False) :type check_convergence: bool, optional :param convergence_check_interval: Steps between convergence checks (only used if check_convergence=True) (default: 1000) :type convergence_check_interval: int, optional :param convergence_check_start: Minimum iteration before starting convergence checks. Set this sensibly (e.g. 2x burn-in) to avoid inaccurate tau estimates on short chains (default: 0) :type convergence_check_start: int, optional .. py:method:: get_samples_np(discard_start: int = 0, discard_end: int = 0, thin: int = 1, flat: bool = False) -> numpy.ndarray Return a contiguous numpy array of MCMC samples. Samples can be discarded from the start and/or the end of the array. You can also thin (take only every n-th sample), and you can flatten the array so that each walker's chain is merged into one chain. This is the foundational method for accessing MCMC samples. All the other get_samples methods build on this. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param flat: Whether to flatten each walker's chain into one chain. (default: False) If True, return flattened array with shape (nsteps_after_discard_thin * nwalkers, ndim) If False, return unflattened array with shape (nsteps_after_discard_thin, nwalkers, ndim) :type flat: bool, optional :returns: Contiguous array of MCMC samples. Shape depends on `flat` parameter: - flat=False: (nsteps_after_discard_thin, nwalkers, ndim) - flat=True: (nsteps_after_discard_thin * nwalkers, ndim) :rtype: np.ndarray .. rubric:: Notes We enforce np.ascontiguousarray() on the return, because np.reshape() does not guarantee a contiguous array in memory. .. py:method:: get_samples_df(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> pandas.DataFrame Return a pandas DataFrame of flattened MCMC samples. Each row represents one sample, each column represents one parameter. Built on get_samples_np(). :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: DataFrame with shape (nsteps_after_discard_thin * nwalkers, ndim). Columns are parameter names. :rtype: pd.DataFrame .. py:method:: get_samples_dict(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> Dict[str, numpy.ndarray] Return a dict of flattened MCMC samples. Each parameter gets a 1D (flattened) contiguous array of all its samples. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: Dictionary mapping parameter names to 1D arrays of samples. Each array has shape (nsteps_after_discard_thin * nwalkers,) :rtype: dict .. rubric:: Examples >>> samples_dict = fitter.get_samples_dict(discard_start=1000) >>> K_b_samples = samples_dict['K_b'] # All samples for parameter K for planet b .. py:method:: get_sampler_lnprob(discard_start: int = 0, discard_end: int = 0, thin: int = 1, flat: bool = False) -> numpy.ndarray Returns the log probability at each step of the sampler. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param flat: If True, return flattened array shape (nsteps_after_discard_thin * nwalkers) If False, return unflattened array shape (nsteps_after_discard_thin, nwalkers) (default: False) :type flat: bool, optional :returns: Array of log probabilities of the function at each sample. :rtype: np.ndarray .. py:method:: get_mcmc_posterior_dict(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> dict Return dict combining MCMC samples for free params, and the fixed values for the fixed params. This method creates a unified dictionary containing all model parameters: fixed parameters as single float values, and free parameters as arrays of MCMC samples. This format is ideal for functions like calculate_mpsini that need all parameters (whether free or fixed), and that should propagate uncertainties from the free parameters samples. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: Dictionary of all parameters: - Fixed parameters: single float values - Free parameters: 1D arrays of MCMC samples with shape (nsteps_after_discard_thin * nwalkers,) :rtype: dict .. py:method:: calculate_log_likelihood(params_dict: Dict[str, float]) -> float Calculate log-likelihood for given parameter values. Note this does not include (log-)prior probabilities, this is just the (log-) *likelihood* primarily for use in AICc & BIC calculation. :param params_dict: Dictionary of all parameter values (both fixed and free parameters) :type params_dict: dict :returns: The log-likelihood value :rtype: float .. py:method:: build_params_dict(free_params: numpy.ndarray | list | Dict[str, float]) -> Dict[str, float] Build a params dict by providing free param vals, combine with fixed param vals. Takes free parameter float values (which can be from any source e.g. MAP results, MCMC posteriors, or any custom values) and combines them with the fixed parameter values to create a complete parameter dictionary. This dict is ideal for calculating chi2, log-likelihood, AICc, and BIC. This is designed for a single value per parameter. For combining the MCMC posterior chains for free parameters and the fixed values for fixed parameters, use `get_mcmc_posterior_dict` method. :param free_params: Free parameter values from any source: - list/array: values in order of self.free_params_names - dict: mapping of free param names to values :type free_params: list, np.ndarray, or dict :returns: Complete parameters dict with both free and fixed parameter values :rtype: Dict[str, float] .. rubric:: Examples >>> # From MAP optimization result >>> map_result = fitter.find_map_estimate() >>> params = fitter.build_params_dict(map_result.x) >>> aicc = fitter.calculate_aicc(params) >>> >>> # From best MCMC sample >>> best_sample = fitter.get_sample_with_best_lnprob(discard_start=1000) >>> params = fitter.build_params_dict(best_sample) >>> bic = fitter.calculate_bic(params) >>> >>> # From custom array of values (in order of free_params_names) >>> custom_values = [5.0, 50.0, 0.1, 0.0, 2450000.0] # example values >>> params = fitter.build_params_dict(custom_values) >>> log_like = fitter.calculate_log_likelihood(params) .. py:method:: calculate_chi2(params_dict: Dict[str, float]) -> float Calculate chi-squared for given parameter values. Uses LogLikelihood to avoid code duplication. Works backwards from log-likelihood: .. math:: \ell = -\frac{1}{2} \left( \chi^2 + \text{penalty} \right) :param params_dict: Dictionary of all parameter values (both fixed and free parameters) :type params_dict: dict :returns: Chi-squared value: .. math:: \chi^2 = \sum_i \frac{(d_i - m_i)^2}{\sigma_i^2 + \sigma_{\text{jit}}^2} :rtype: float .. py:method:: calculate_aicc(params_dict: Dict[str, float]) -> float Calculate corrected Akaike Information Criterion (AICc). .. math:: \text{AICc} = 2k - 2\ln\mathcal{L} + \frac{2k^2 + 2k}{n - k - 1} where :math:`k` is the number of free parameters, :math:`n` is the number of observations, and :math:`\mathcal{L}` is the likelihood. Converges to AIC for large :math:`n`. :param params_dict: Dictionary of all parameter values (both fixed and free parameters) :type params_dict: dict :returns: AICc value :rtype: float .. py:method:: calculate_bic(params_dict: Dict[str, float]) -> float Calculate Bayesian Information Criterion (BIC) for given parameters. .. math:: \text{BIC} = k \ln n - 2 \ln \mathcal{L} where :math:`k` is the number of free parameters, :math:`n` is the number of observations, and :math:`\mathcal{L}` is the likelihood. :param params_dict: Dictionary of all parameter values (both fixed and free parameters) :type params_dict: dict :returns: BIC value :rtype: float .. py:method:: get_sample_with_best_lnprob(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> Dict[str, float] Get parameter values from the MCMC sample with the highest log probability. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: Dictionary of parameter names to values from the best sample :rtype: Dict[str, float] .. py:method:: plot_autocorr_estimates(params: list[str] | None = None, plot_mean: bool = False, show_legend: bool = True, title: str | None = 'Autocorrelation Time Estimates', xlabel: str | None = 'Step number', ylabel: str | None = 'Autocorrelation time $\\tau$', save: bool = False, fname: str = 'autocorr_plot.png', dpi: int = 100) -> None Plot autocorrelation time estimates from adaptive MCMC run. Shows how autocorrelation time evolved during the MCMC run and the convergence threshold line (N / 50). Only available if run_mcmc was called with check_convergence=True. :param params: List of parameter names to plot. If None, plots all free parameters (default: None) :type params: list[str] or None, optional :param plot_mean: If True, plot mean tau instead of individual parameter taus. Overrides params argument (default: False) :type plot_mean: bool, optional :param show_legend: Whether to show legend (default: True) :type show_legend: bool, optional :param title: Plot title (default: "Autocorrelation Time Estimates"). Set to None or "" to skip. :type title: str or None, optional :param xlabel: X-axis label (default: "Step number"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel: Y-axis label (default: r"Autocorrelation time $\tau$"). Set to None or "" to skip. :type ylabel: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "autocorr_plot.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional :raises ValueError: If no autocorrelation history is available (run_mcmc was not called with check_convergence=True, or has not been called yet) .. py:method:: plot_chains(discard_start: int = 0, discard_end: int = 0, thin: int = 1, truths: list = None, title: str | None = 'Chains plot', xlabel: str | None = 'Step number', save: bool = False, fname: str = 'chains_plot.png', dpi: int = 100) -> None Plot MCMC chains for all free parameters. Displays the evolution of each free parameter across MCMC steps for all walkers. Useful for diagnosing convergence, burn-in, and mixing of the MCMC chains. Each parameter gets its own subplot showing all walker traces. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param truths: List of true parameter values to overplot as horizontal lines. Must match the number of free parameters. Use None for parameters without known truth values (default: None) :type truths: list, optional :param title: Plot title (default: "Chains plot"). Set to None or "" to skip. :type title: str or None, optional :param xlabel: X-axis label (default: "Step number"). Set to None or "" to skip. :type xlabel: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "chains_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_lnprob(discard_start: int = 0, discard_end: int = 0, thin: int = 1, title: str | None = 'Log Probability Traces', xlabel: str | None = 'Step number', ylabel: str | None = 'Log probability', save: bool = False, fname: str = 'lnprob_plot.png', dpi: int = 100) -> None Plot log probability traces for all walkers. Useful for diagnosing MCMC convergence and identifying problematic walkers/parameters. You can use `discard_start` and `discard_end` to focus in on specific steps in the chains. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param title: Plot title (default: "Log Probability Traces"). Set to None or "" to skip. :type title: str or None, optional :param xlabel: X-axis label (default: "Step number"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel: Y-axis label (default: "Log probability"). Set to None or "" to skip. :type ylabel: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "lnprob_plot.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional .. py:method:: plot_corner(discard_start: int = 0, discard_end: int = 0, thin: int = 1, plot_datapoints: bool = False, truths: list[float] = None, title: str | None = 'Corner plots', save: bool = False, fname: str = 'corner_plot.png', dpi: int = 100) -> None Create a corner plot of MCMC samples. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param plot_datapoints: Show individual data points in addition to contours (default: False) :type plot_datapoints: bool, optional :param truths: True parameter values to overplot as vertical/horizontal lines (default: None). Must match the order of free parameters if provided. :type truths: list of float, optional :param title: Plot title (default: "Corner plots"). Set to None or "" to skip. :type title: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "corner_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: _plot_rv(params: Dict[str, float], title: str = 'RV Model', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', xlim: tuple | None = None, ylim: tuple | None = None, res_xlim: tuple | None = None, res_ylim: tuple | None = None, n_smooth: int = 1000, save: bool = False, fname: str = 'rv_plot.png', dpi: int = 100) -> None Helper function to plot RV model with given parameters. :param params: Dictionary of parameter values (both free and fixed) :type params: dict :param title: Plot title (default: "RV Model"). Set to None or "" to skip. :type title: str, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param xlim: (xmin, xmax) limits for the main RV plot x-axis (default: None, uses data range) :type xlim: tuple or None, optional :param ylim: (ymin, ymax) limits for the main RV plot y-axis (default: None, auto-scaled) :type ylim: tuple or None, optional :param res_xlim: (xmin, xmax) limits for the residuals plot x-axis (default: None, uses data range) :type res_xlim: tuple or None, optional :param res_ylim: (ymin, ymax) limits for the residuals plot y-axis (default: None, symmetric around 0) :type res_ylim: tuple or None, optional :param n_smooth: Number of points in the smooth model curve (default: 1000) :type n_smooth: int, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "rv_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional :returns: * *np.ndarray* -- Time array used for evaluation * *np.ndarray* -- RV values at evaluation times .. py:method:: _plot_phase(planet_letter: str, params: Dict[str, float], title: str = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'phase_plot.png', dpi: int = 100) -> None Helper function to plot phase-folded RV model for a single planet with given parameters. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param params: Dictionary of parameter values (both free and fixed) :type params: dict :param title: Plot title (default: f"Planet {planet_letter} Phase Plot"). Set to None or "" to skip. :type title: str, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "phase_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_posterior_rv(discard_start: int = 0, discard_end: int = 0, thin: int = 1, show_CI: bool = True, title: str | None = 'Posterior RV', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'posterior_rv.png', dpi: int = 100) -> None Plot the posterior RV model with uncertainty bands from MCMC samples. Calculates RV model predictions for each MCMC sample, then plots the median with optional 68% CI (16th-84th percentile) uncertainty bands. Shows both the full model and residuals vs data. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param show_CI: Show 68.3% credible interval band (default: True) :type show_CI: bool, optional :param title: Title for the main RV plot (default: "Posterior RV"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "posterior_rv.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional .. py:method:: plot_posterior_phase(planet_letter: str, discard_start: int = 0, discard_end: int = 0, thin: int = 1, show_CI: bool = True, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'posterior_phase.png', dpi: int = 100) -> None Plot phase-folded RV model with uncertainty bands from MCMC samples. Shows the phase-folded planetary signal with uncertainty bands calculated from MCMC samples. Removes contributions from trends and other planets. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param show_CI: Show 68.3% credible interval band (default: True) :type show_CI: bool, optional :param title: Title for the main phase plot (default: "Posterior Phase Plot - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "posterior_phase.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional .. py:method:: calculate_rv_planet_from_samples(planet_letter: str, times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = False) -> numpy.ndarray Calculate planetary RV for each MCMC sample. This calculates RV(params_i) for each MCMC sample i, preserving parameter correlations. This differs from using median parameters which may not represent actual samples from the posterior. :param planet_letter: Planet letter (e.g., 'b', 'c') :type planet_letter: str :param times: Time points to calculate RV at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: False) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - RV for each sample :rtype: np.ndarray .. py:method:: calculate_rv_trend_from_samples(times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = False) -> numpy.ndarray Calculate trend RV for each MCMC sample. This calculates RV_trend(params_i) for each MCMC sample i, preserving parameter correlations. This differs from using median parameters which may not represent actual samples from the posterior. :param times: Time points to calculate RV at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: False) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - Trend RV for each sample :rtype: np.ndarray .. py:method:: calculate_rv_total_from_samples(times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = False) -> numpy.ndarray Calculate total RV (planets + trend) for each MCMC sample. This calculates RV_total(params_i) for each MCMC sample i, preserving parameter correlations. This differs from using median parameters which may not represent actual samples from the posterior. :param times: Time points to calculate RV at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: False) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - Total RV for each sample :rtype: np.ndarray .. py:method:: calculate_rv_planet_custom(planet_letter: str, times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate planetary RV for a single set of custom parameters. Useful for calculating RV with specific parameter values (e.g., best lnprob sample, median parameters, or experimental values). :param planet_letter: Planet letter (e.g., 'b', 'c') :type planet_letter: str :param times: Time points to calculate RV at :type times: np.ndarray :param params: Complete parameter dictionary (both free and fixed parameters). Can be created using build_params_dict() or manually constructed. :type params: dict[str, float] :returns: RV values at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = fitter.find_map_estimate() >>> params = fitter.build_params_dict(map_result.x) >>> rv = fitter.calculate_rv_planet_custom('b', times, params) >>> >>> # Using best lnprob sample >>> best_params = fitter.get_sample_with_best_lnprob(discard_start=1000) >>> params = fitter.build_params_dict(best_params) >>> rv = fitter.calculate_rv_planet_custom('b', times, params) .. py:method:: calculate_rv_trend_custom(times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate trend RV for a single set of custom parameters. Useful for calculating RV with specific parameter values (e.g., best lnprob sample, median parameters, or experimental values). :param times: Time points to calculate RV at :type times: np.ndarray :param params: Complete parameter dictionary (both free and fixed parameters). Can be created using build_params_dict() or manually constructed. :type params: dict[str, float] :returns: Trend RV values at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = fitter.find_map_estimate() >>> params = fitter.build_params_dict(map_result.x) >>> trend_rv = fitter.calculate_rv_trend_custom(times, params) .. py:method:: calculate_rv_total_custom(times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate total RV (trend + all planets) for a single set of custom parameters. Useful for calculating RV with specific parameter values (e.g., best lnprob sample, median parameters, or experimental values). :param times: Time points to calculate RV at :type times: np.ndarray :param params: Complete parameter dictionary (both free and fixed parameters). Can be created using build_params_dict() or manually constructed. :type params: dict[str, float] :returns: Total RV values (trend + all planets) at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = fitter.find_map_estimate() >>> params = fitter.build_params_dict(map_result.x) >>> total_rv = fitter.calculate_rv_total_custom(times, params) >>> >>> # Using median parameters >>> samples_df = fitter.get_samples_df(discard_start=1000) >>> median_values = samples_df.median().to_dict() >>> params = fitter.build_params_dict(median_values) >>> total_rv = fitter.calculate_rv_total_custom(times, params) .. py:method:: plot_MAP_rv(map_result: scipy.optimize.OptimizeResult, title: str | None = 'MAP RV', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'MAP_rv.png', dpi: int = 100) -> None Plot radial velocity data and model using MAP parameter estimates. :param map_result: Result from find_map_estimate() containing the MAP parameters :type map_result: scipy.optimize.OptimizeResult :param title: Plot title (default: "MAP RV"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "MAP_rv.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_MAP_phase(planet_letter: str, map_result: scipy.optimize.OptimizeResult, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'MAP_phase.png', dpi: int = 100) -> None Plot phase-folded radial velocity data and model using MAP parameter estimates. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param map_result: Result from find_map_estimate() containing the MAP parameters :type map_result: scipy.optimize.OptimizeResult :param title: Plot title (default: f"MAP Phase Plot - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "MAP_phase.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_custom_rv(params: dict, title: str | None = 'Custom RV Plot', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', xlim: tuple | None = None, ylim: tuple | None = None, res_xlim: tuple | None = None, res_ylim: tuple | None = None, n_smooth: int = 1000, save: bool = False, fname: str = 'custom_rv.png', dpi: int = 100) -> None Plot radial velocity data and model using custom parameter values. Allows plotting with arbitrary parameter values for exploring parameter space or comparing theoretical models. :param params: Dictionary of parameter values to use for plotting. Keys should match parameter names, values should be floats. Must include all required parameters for the current parameterisation. :type params: dict :param title: Plot title (default: "Custom RV Plot"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param xlim: (xmin, xmax) limits for the main RV plot x-axis (default: None, uses data range) :type xlim: tuple or None, optional :param ylim: (ymin, ymax) limits for the main RV plot y-axis (default: None, auto-scaled) :type ylim: tuple or None, optional :param res_xlim: (xmin, xmax) limits for the residuals plot x-axis (default: None, uses data range) :type res_xlim: tuple or None, optional :param res_ylim: (ymin, ymax) limits for the residuals plot y-axis (default: None, symmetric around 0) :type res_ylim: tuple or None, optional :param n_smooth: Number of points in the smooth model curve (default: 1000) :type n_smooth: int, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "custom_rv.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. rubric:: Examples >>> # Plot with custom values (must include all required parameters) >>> fitter.plot_custom_rv({"P_b": 4.25, "K_b": 55.0, "e_b": 0.1, ... "w_b": 1.57, "Tc_b": 2456325.5, ... "g_HARPS": -10.2, "jit_HARPS": 2.0, ... "gd": 0.0, "gdd": 0.0}) .. py:method:: plot_custom_phase(planet_letter: str, params: dict, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'custom_phase.png', dpi: int = 100) -> None Plot phase-folded radial velocity data and model using custom parameter values. Allows plotting phase-folded data with arbitrary parameter values for exploring parameter space or comparing theoretical models. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param params: Dictionary of parameter values to use for plotting. Keys should match parameter names, values should be floats. Must include all required parameters for the current parameterisation. :type params: dict :param title: Plot title (default: f"Custom Phase Plot - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "custom_phase.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. rubric:: Examples >>> # Plot phase curve with custom values >>> fitter.plot_custom_phase("b", {"P_b": 4.25, "K_b": 55.0, "e_b": 0.1, ... "w_b": 1.57, "Tc_b": 2456325.5, ... "g_HARPS": -10.2, "jit_HARPS": 2.0, ... "gd": 0.0, "gdd": 0.0}) .. py:method:: plot_best_sample_rv(discard_start: int = 0, discard_end: int = 0, thin: int = 1, title: str | None = 'Best Sample RV Plot', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'best_sample_rv.png', dpi: int = 100) -> None Plot radial velocity data and model using parameter values from the MCMC sample with highest log probability. This is useful for comparing with plot_MAP_rv() to diagnose potential issues with MAP convergence or MCMC mixing. The two plots should be very similar if both MAP and MCMC are working correctly. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param title: Title for the main RV plot (default: "Best Sample RV Plot"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "best_sample_rv.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_best_sample_phase(planet_letter: str, discard_start: int = 0, discard_end: int = 0, thin: int = 1, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'best_sample_phase.png', dpi: int = 100) -> None Plot phase-folded radial velocity data and model using parameter values from the MCMC sample with highest log probability. This is useful for comparing with plot_MAP_phase() to diagnose potential issues with MAP convergence or MCMC mixing. The two plots should be very similar if both MAP and MCMC are working correctly. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param title: Title for the main phase plot (default: "Best Sample Phase Plot - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "best_sample_phase.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:class:: LogPosterior(planet_letters: list[str], parameterisation: ravest.param.Parameterisation, priors: dict[str, Callable[[float], float]], fixed_params: dict[str, float], free_params_names: list[str], time: numpy.ndarray, vel: numpy.ndarray, velerr: numpy.ndarray, instrument: numpy.ndarray, unique_instruments: numpy.ndarray, t0: float) Log posterior probability for MCMC sampling. Combines log likelihood and log prior for Bayesian parameter estimation. .. py:attribute:: planet_letters .. py:attribute:: parameterisation .. py:attribute:: priors .. py:attribute:: fixed_params .. py:attribute:: free_params_names .. py:attribute:: time .. py:attribute:: vel .. py:attribute:: velerr .. py:attribute:: instrument .. py:attribute:: unique_instruments .. py:attribute:: t0 .. py:attribute:: log_likelihood .. py:attribute:: log_prior .. py:method:: _convert_params_for_prior_evaluation(free_params_dict: dict[str, float]) -> Dict[str, float] Convert free parameters for prior evaluation if needed. :param free_params_dict: Free parameters in current parameterisation :type free_params_dict: dict :returns: Parameters with names/values converted for prior evaluation :rtype: dict .. py:method:: log_probability(free_params_dict: Dict[str, float]) -> float Calculate log posterior probability for given free parameters. :param free_params_dict: Dictionary of free parameter values :type free_params_dict: Dict[str, float] :returns: Log posterior probability (log likelihood + log prior) :rtype: float .. py:method:: _negative_log_probability_for_MAP(free_params_vals: list[float]) -> float For MAP: run __call__ only passing in a list, not dict, of params. Because scipy.optimize.minimise only takes list of values, not a dict, we need to assign the values back to their corresponding keys, and pass that to __call__(). This does not check that the values are in the correct order, it is assumed. As we're dealing with dicts, this hopefully is the case. :param free_params_vals: float values of the free parameters :type free_params_vals: list .. py:class:: LogLikelihood(time: numpy.ndarray, vel: numpy.ndarray, velerr: numpy.ndarray, instrument: numpy.ndarray, unique_instruments: numpy.ndarray, t0: float, planet_letters: list[str], parameterisation: ravest.param.Parameterisation) Log likelihood calculation for radial velocity data. Calculates log likelihood given RV model parameters and data. .. py:attribute:: time .. py:attribute:: vel .. py:attribute:: velerr .. py:attribute:: instrument .. py:attribute:: unique_instruments .. py:attribute:: t0 .. py:attribute:: planet_letters .. py:attribute:: parameterisation .. py:attribute:: _instrument_indices .. py:attribute:: _gamma_keys .. py:attribute:: _jitter_keys .. py:attribute:: _log_2pi .. py:attribute:: _velerr_sq .. py:method:: __call__(params: Dict[str, float]) -> float Calculate log likelihood for given parameters. :param params: Dictionary of all parameter values :type params: Dict[str, float] :returns: Log likelihood value :rtype: float .. py:class:: LogPrior(priors: dict[str, Callable[[float], float]]) Log prior probability calculation. Evaluates log prior probabilities for model parameters. .. py:attribute:: priors .. py:method:: __call__(params: Dict[str, float]) -> float Calculate log prior probability for given parameters. :param params: Dictionary of parameter values :type params: Dict[str, float] :returns: Log prior probability :rtype: float .. py:class:: GPFitter(planet_letters: list[str], parameterisation: ravest.param.Parameterisation, gp_kernel: ravest.gp.GPKernel) Gaussian Process fitter for exoplanet radial velocity data. Similar interface to Fitter class, but uses Gaussian Processes to model correlated noise in the data. The planetary RV model serves as the GP mean function. Supports MCMC sampling, MAP estimation, and various parameterisations. Handles multiple planets, trends, jitter parameters, and GP hyperparameters. .. py:attribute:: planet_letters .. py:attribute:: parameterisation .. py:attribute:: gp_kernel .. py:attribute:: _params :type: Dict[str, ravest.param.Parameter] .. py:attribute:: _priors :type: Dict[str, Callable[[float], float]] .. py:attribute:: _hyperparams :type: Dict[str, ravest.param.Parameter] .. py:attribute:: _hyperpriors :type: Dict[str, Callable[[float], float]] .. py:method:: add_data(time: numpy.ndarray, vel: numpy.ndarray, velerr: numpy.ndarray, instrument: numpy.ndarray, t0: float) -> None Add the data to the GPFitter object. :param time: Time of each observation [days] :type time: array-like :param vel: Radial velocity at each time [m/s] :type vel: array-like :param velerr: Uncertainty on the radial velocity at each time [m/s] :type velerr: array-like :param instrument: Instrument name for each observation (e.g., "HARPS", "HIRES") :type instrument: array-like :param t0: Reference time for the trend [days]. Recommended to set this as mean or median of input `time` array. :type t0: float .. py:property:: params :type: Dict[str, ravest.param.Parameter] gpfitter.params = param_dict. :type: Parameters dictionary. Set via .. py:property:: hyperparams :type: Dict[str, ravest.param.Parameter] gpfitter.hyperparams = hyperparam_dict. :type: Hyperparameters dictionary. Set via .. py:property:: priors :type: dict gpfitter.priors = prior_dict. :type: Priors dictionary. Set via .. py:property:: hyperpriors :type: dict gpfitter.hyperpriors = hyperprior_dict. :type: Hyperpriors dictionary. Set via .. py:method:: _validate_complete_params(params: Dict[str, ravest.param.Parameter]) -> None Validate that params dict has required parameters, astrophysically valid values. .. py:method:: _validate_astrophysical_validity(params_values: Dict[str, float]) -> None Validate that all parameter values are astrophysically valid. .. py:method:: _validate_parameter_coupling(params: Dict[str, ravest.param.Parameter]) -> None Validate parameter coupling constraints (e.g., secosw/sesinw must both be free or both fixed). .. py:method:: _set_priors_with_validation(new_priors: dict[str, Callable[[float], float]]) -> None Set priors with validation. Supports partial updates. Can be current or default parameterisation. .. py:method:: _get_default_parameterisation_equivalent_free_param_name(free_param: str) -> Optional[list[str]] Get the names of the default parameterisation equivalent parameter(s), for a single free parameter from the current parameterisation. Note this can be more than one: e.g. if you have secosw, this affects both e & w in the default parameterisation Whereas Tc just maps to Tp alone. :returns: - list[str]: equivalent parameter(s) in the default parameterisation - None: no mapping needed / no alternative priors to look for :rtype: list[str] | None :raises ValueError: If `free_param` is not a recognised planet, instrument, or trend parameter. .. py:method:: _check_params_values_against_priors(validated_priors: dict[str, Callable[[float], float]], current_free_param_names: list[str]) -> None Check parameter values against priors (including if Prior is for the Default parameterisation equivalent parameter). .. py:method:: _convert_single_param_to_default(default_param_name: str) -> float Convert a single parameter from current to default parameterisation. .. py:method:: _set_hyperpriors_with_validation(new_hyperpriors: dict[str, Callable[[float], float]]) -> None Set hyperpriors with validation. .. py:method:: _check_hyperparams_values_against_hyperpriors(validated_hyperpriors: dict[str, Callable[[float], float]], current_free_hyperparam_names: list[str]) -> None Check hyperparameter values against hyperpriors. .. py:property:: free_params_dict :type: Dict[str, ravest.param.Parameter] Free parameters as dict. .. py:property:: free_params_values :type: list[float] Values of free parameters as list. .. py:property:: free_params_names :type: list[str] Names of free parameters as list. .. py:property:: fixed_params_dict :type: Dict[str, ravest.param.Parameter] Fixed parameters as dict, mapping names to Parameter objects. .. py:property:: fixed_params_values :type: list[float] Values of fixed parameters, as list. .. py:property:: fixed_params_names :type: list[str] Names of fixed parameters, as list. .. py:property:: fixed_params_values_dict :type: Dict[str, float] Fixed parameters as dict mapping names to just the values. .. py:property:: free_hyperparams_dict :type: Dict[str, ravest.param.Parameter] Free hyperparameters as dict. .. py:property:: free_hyperparams_values :type: list[float] Values of free hyperparameters as list. .. py:property:: free_hyperparams_names :type: list[str] Names of free hyperparameters as list. .. py:property:: fixed_hyperparams_dict :type: Dict[str, ravest.param.Parameter] Fixed hyperparameters as dict, mapping names to Parameter objects. .. py:property:: fixed_hyperparams_values_dict :type: Dict[str, float] Fixed hyperparameters as dict mapping names to just the values. .. py:property:: fixed_hyperparams_names :type: list[str] Names of fixed hyperparameters, as list. .. py:property:: fixed_hyperparams_values :type: list[float] Values of fixed hyperparameters, as list. .. py:method:: find_map_estimate(method: str = 'Powell') -> scipy.optimize.OptimizeResult Find Maximum A Posteriori (MAP) estimate of parameters and hyperparameters. :param method: Optimization method to use (default: "Powell") :type method: str, optional :returns: The optimization result containing the MAP estimate :rtype: scipy.optimize.OptimizeResult :raises Warning: If MAP optimization fails to converge .. py:method:: generate_initial_walker_positions_random(nwalkers: int, verbose: bool = False, max_attempts: int = 1000) -> numpy.ndarray Generate random initial walker positions that satisfy priors and are astrophysically valid. Creates random starting positions for MCMC walkers by sampling from appropriate distributions based on each parameter's prior type. Ensures that parameter combinations are astrophysically valid (e.g., eccentricity < 1). :param nwalkers: Number of MCMC walkers to generate positions for :type nwalkers: int :param verbose: If True, print walker positions during generation :type verbose: bool, default False :param max_attempts: Maximum attempts to generate a valid walker position :type max_attempts: int, default 1000 :returns: Array of shape (nwalkers, ndim) where ndim is the number of free parameters + hyperparameters. Each row represents the starting position for one walker in the order of free_params_names + free_hyperparams_names. :rtype: np.ndarray :raises ValueError: If a prior type is not supported for walker generation or if unable to generate valid positions after max_attempts .. rubric:: Examples >>> # Generate positions for 40 walkers >>> nwalkers = 10 * len(gpfitter.free_params_names + gpfitter.free_hyperparams_names) >>> initial_positions = gpfitter.generate_initial_walker_positions_random(nwalkers) >>> gpfitter.run_mcmc(initial_positions, nwalkers, max_steps=2000) .. py:method:: generate_initial_walker_positions_around_point(centre: numpy.ndarray | list, nwalkers: int, scale: float = 0.0001, relative: bool = True, verbose: bool = False, max_attempts: int = 1000) -> numpy.ndarray Generate initial walker positions in a ball around a supplied centre point. Creates starting positions for MCMC walkers clustered around a centre point (e.g., MAP estimate). Each walker is generated by adding small random perturbations to the centre values. Validates that both the centre point and all generated walker positions satisfy priors/hyperpriors and are astrophysically valid. :param centre: Centre point for walker positions. Must have length equal to the number of free parameters + free hyperparameters and be in the order of free_params_names + free_hyperparams_names. :type centre: np.ndarray or list :param nwalkers: Number of MCMC walkers to generate positions for :type nwalkers: int :param scale: Scale of perturbations around centre point :type scale: float, default 1e-4 :param relative: If True, perturbations scale with parameter values (scale * centre * random). If False, perturbations are absolute (scale * random). :type relative: bool, default True :param verbose: If True, print walker positions during generation :type verbose: bool, default False :param max_attempts: Maximum attempts to generate a valid walker position :type max_attempts: int, default 1000 :returns: Array of shape (nwalkers, ndim) where ndim is the number of free parameters + free hyperparameters. Each row represents the starting position for one walker in the order of free_params_names + free_hyperparams_names. :rtype: np.ndarray :raises ValueError: If centre has wrong length, if centre point is invalid, or if unable to generate valid positions after max_attempts .. rubric:: Examples >>> # Generate walkers around MAP estimate >>> map_result = gpfitter.find_map_estimate() >>> initial_positions = gpfitter.generate_initial_walker_positions_around_point( ... centre=map_result.x, nwalkers=40, scale=1e-4 ... ) >>> gpfitter.run_mcmc(initial_positions, nwalkers=40, max_steps=2000) .. py:method:: generate_initial_walker_positions_from_map(map_result: scipy.optimize.OptimizeResult, nwalkers: int, scale: float = 0.0001, relative: bool = True, verbose: bool = False, max_attempts: int = 1000) -> numpy.ndarray Generate initial walker positions around MAP estimate. Convenience function that generates walker positions clustered around MAP parameter and hyperparameter estimates from a pre-computed MAP result. :param map_result: Result from find_map_estimate() :type map_result: scipy.optimize.OptimizeResult :param nwalkers: Number of MCMC walkers to generate positions for :type nwalkers: int :param scale: Scale of perturbations around MAP values :type scale: float, default 1e-4 :param relative: If True, perturbations scale with parameter values. If False, perturbations are absolute. :type relative: bool, default True :param verbose: If True, print walker positions during generation :type verbose: bool, default False :param max_attempts: Maximum attempts to generate a valid walker position :type max_attempts: int, default 1000 :returns: Array of shape (nwalkers, ndim) where ndim is the number of free parameters + free hyperparameters. Each row represents the starting position for one walker. :rtype: np.ndarray :raises ValueError: If unable to generate valid positions .. rubric:: Examples >>> # Find MAP then generate walkers around it >>> map_result = gpfitter.find_map_estimate() >>> initial_positions = gpfitter.generate_initial_walker_positions_from_map( ... map_result=map_result, nwalkers=40 ... ) >>> gpfitter.run_mcmc(initial_positions, nwalkers=40, max_steps=2000) .. py:method:: run_mcmc(initial_positions: numpy.ndarray, nwalkers: int, max_steps: int = 5000, progress: bool = True, multiprocessing: bool = False, check_convergence: bool = False, convergence_check_interval: int = 1000, convergence_check_start: int = 0) -> None Run MCMC sampling from given initial walker positions. :param initial_positions: Starting positions for all MCMC walkers. Shape must be (nwalkers, ndim) where ndim is the number of free parameters + hyperparameters. Each row represents the starting position for one walker in the order of free_params_names + free_hyperparams_names. :type initial_positions: np.ndarray :param nwalkers: Number of MCMC walkers (must match first dimension of initial_positions) :type nwalkers: int :param max_steps: Maximum number of MCMC steps to run. If check_convergence=False, runs for exactly this many steps. If check_convergence=True, runs up to this many steps, stopping early when convergence criteria are met (default: 5000) :type max_steps: int, optional :param progress: Whether to show progress bar during MCMC (default: True) :type progress: bool, optional :param multiprocessing: Whether to use multiprocessing for MCMC (default: False) :type multiprocessing: bool, optional :param check_convergence: If True, check for convergence and stop early when criteria met. Convergence requires: chain length > 50 times max autocorrelation time, and autocorrelation time estimate stable to 1 percent. If False, run for exactly max_steps (default: False) :type check_convergence: bool, optional :param convergence_check_interval: Steps between convergence checks (only used if check_convergence=True) (default: 1000) :type convergence_check_interval: int, optional :param convergence_check_start: Minimum iteration before starting convergence checks. Set this sensibly (e.g. 2x burn-in) to avoid inaccurate tau estimates on short chains (default: 0) :type convergence_check_start: int, optional .. py:method:: get_samples_np(discard_start: int = 0, discard_end: int = 0, thin: int = 1, flat: bool = False) -> numpy.ndarray Return a contiguous numpy array of MCMC samples. Samples can be discarded from the start and/or the end of the array. You can also thin (take only every n-th sample), and you can flatten the array so that each walker's chain is merged into one chain. This is the foundational method for accessing MCMC samples. All the other get_samples methods build on this. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param flat: Whether to flatten each walker's chain into one chain. (default: False) If True, return flattened array with shape (nsteps_after_discard_thin * nwalkers, ndim) If False, return unflattened array with shape (nsteps_after_discard_thin, nwalkers, ndim) :type flat: bool, optional :returns: Contiguous array of MCMC samples. Shape depends on `flat` parameter: - flat=False: (nsteps_after_discard_thin, nwalkers, ndim) - flat=True: (nsteps_after_discard_thin * nwalkers, ndim) :rtype: np.ndarray .. rubric:: Notes We enforce np.ascontiguousarray() on the return, because np.reshape() does not guarantee a contiguous array in memory. .. py:method:: get_samples_df(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> pandas.DataFrame Return a pandas DataFrame of flattened MCMC samples. Each row represents one sample, each column represents one parameter or hyperparameter. Built on get_samples_np(). :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: DataFrame with shape (nsteps_after_discard_thin * nwalkers, ndim). Columns are parameter and hyperparameter names. :rtype: pd.DataFrame .. py:method:: get_samples_dict(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> Dict[str, numpy.ndarray] Return a dict of flattened MCMC samples. Each parameter and hyperparameter gets a 1D (flattened) contiguous array of all its samples. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: Dictionary mapping parameter and hyperparameter names to 1D arrays of samples. Each array has shape (nsteps_after_discard_thin * nwalkers,) :rtype: dict .. rubric:: Examples >>> samples_dict = gpfitter.get_samples_dict(discard_start=1000) >>> K_b_samples = samples_dict['K_b'] # All samples for parameter K for planet b >>> gp_amp_samples = samples_dict['gp_amp'] # All samples for GP amplitude .. py:method:: get_sampler_lnprob(discard_start: int = 0, discard_end: int = 0, thin: int = 1, flat: bool = False) -> numpy.ndarray Returns the log probability at each step of the sampler. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param flat: If True, return flattened array shape (nsteps_after_discard_thin * nwalkers) If False, return unflattened array shape (nsteps_after_discard_thin, nwalkers) (default: False) :type flat: bool, optional :returns: Array of log probabilities of the function at each sample. :rtype: np.ndarray .. py:method:: get_mcmc_posterior_dict(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> dict Return dict combining fixed parameter values, and MCMC samples for the free ones. This method creates a unified dictionary containing all model parameters: fixed parameters as single float values, and free parameters as arrays of MCMC samples. This format is ideal for functions like calculate_mpsini that need all parameters (whether free or fixed), and that should propagate uncertainties from the free parameters samples. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: Dictionary of all parameters and hyperparameters: - Fixed parameters: single float values - Free parameters: 1D arrays of MCMC samples with shape (nsteps_after_discard_thin * nwalkers,) - Fixed hyperparameters: single float values - Free hyperparameters: 1D arrays of MCMC samples with shape (nsteps_after_discard_thin * nwalkers,) :rtype: dict .. py:method:: calculate_log_likelihood(params_hyperparams_dict: Dict[str, float]) -> float Calculate log-likelihood for given parameter and hyperparameter values. Note this does not include (log-)prior probabilities, this is just the (log-) *likelihood* primarily for use in AICc & BIC calculation. :param params_hyperparams_dict: Dictionary of all parameter and hyperparameter values (both fixed and free) :type params_hyperparams_dict: dict :returns: The log-likelihood value :rtype: float .. py:method:: build_params_dict(free_params_hyperparams: numpy.ndarray | list | Dict[str, float]) -> Dict[str, float] Build complete parameter dictionary by combining free and fixed parameters and hyperparameters. Takes free parameter and hyperparameter values from various sources (MAP results, MCMC samples, or custom values) and combines them with the fixed parameter and hyperparameter values to create a complete dictionary suitable for calculating log-likelihood, chi2, AICc, and BIC. :param free_params_hyperparams: Free parameter and hyperparameter values from any source: - list/array: values in order of self.free_params_names + self.free_hyperparams_names - dict: mapping of free param/hyperparam names to values :type free_params_hyperparams: list, np.ndarray, or dict :returns: Complete parameters and hyperparameters dict with both free and fixed values :rtype: Dict[str, float] .. rubric:: Examples >>> # From MAP optimization result >>> map_result = gpfitter.find_map_estimate() >>> params = gpfitter.build_params_dict(map_result.x) >>> aicc = gpfitter.calculate_aicc(params) >>> >>> # From best MCMC sample >>> best_sample = gpfitter.get_sample_with_best_lnprob(discard_start=1000) >>> params = gpfitter.build_params_dict(best_sample) >>> bic = gpfitter.calculate_bic(params) >>> >>> # From custom array (params then hyperparams, in order of names) >>> custom_values = [5.0, 50.0, 0.1, 0.0, 2450000.0, # params ... 10.0, 5.0, 0.5, 30.0] # hyperparams >>> params = gpfitter.build_params_dict(custom_values) >>> log_like = gpfitter.calculate_log_likelihood(params) .. py:method:: _compute_gp_chi2(kernel: tinygp.kernels.Kernel, time_array: jax.numpy.ndarray, verr_squared_array: jax.numpy.ndarray, residuals: jax.numpy.ndarray) -> float :staticmethod: JIT-compiled GP chi-squared computation. Calculates chi^2 = r^T @ K^(-1) @ r where K is the full covariance matrix. :param kernel: GP kernel :type kernel: tinygp.kernels.Kernel :param time_array: Observation times :type time_array: jnp.ndarray :param verr_squared_array: Observational variances (error^2 + jitter^2) :type verr_squared_array: jnp.ndarray :param residuals: Data - mean_model :type residuals: jnp.ndarray :returns: Chi-squared value incorporating full covariance structure :rtype: float .. rubric:: Notes This uses the efficient Cholesky-based method. The mathematically equivalent (but much slower) direct computation would be: # K = kernel(time_array, time_array) + jnp.diag(verr_squared_array) # K_inv = jnp.linalg.inv(K) # chi2 = jnp.dot(residuals, jnp.dot(K_inv, residuals)) Instead, we use the Cholesky decomposition K = L @ L^T: - alpha = L^(-1) @ residuals (via _get_alpha) - chi^2 = alpha^T @ alpha = r^T @ K^(-1) @ r .. py:method:: calculate_chi2(params_hyperparams_dict: Dict[str, float]) -> float Calculate chi-squared for given parameter and hyperparameter values. For GP models, this calculates: .. math:: \chi^2 = \mathbf{r}^T \mathbf{K}^{-1} \mathbf{r} where :math:`\mathbf{K}` is the full covariance matrix including GP kernel and observational uncertainties. This properly accounts for correlated noise structure. Uses GPLogLikelihood._calculate_mean_model to avoid code duplication. :param params_hyperparams_dict: Dictionary of all parameter and hyperparameter values (both fixed and free) :type params_hyperparams_dict: dict :returns: Chi-squared value :rtype: float .. py:method:: calculate_aicc(params_hyperparams_dict: Dict[str, float]) -> float Calculate corrected Akaike Information Criterion (AICc). .. math:: \text{AICc} = 2k - 2\ln\mathcal{L} + \frac{2k^2 + 2k}{n - k - 1} where :math:`k` is the number of free parameters and hyperparameters, :math:`n` is the number of observations, and :math:`\mathcal{L}` is the likelihood. Converges to AIC for large :math:`n`. :param params_hyperparams_dict: Dictionary of all parameter and hyperparameter values (both fixed and free) :type params_hyperparams_dict: dict :returns: AICc value :rtype: float .. py:method:: calculate_bic(params_hyperparams_dict: Dict[str, float]) -> float Calculate Bayesian Information Criterion (BIC) for given parameters and hyperparameters. .. math:: \text{BIC} = k \ln n - 2 \ln \mathcal{L} where :math:`k` is the number of free parameters and hyperparameters, :math:`n` is the number of observations, and :math:`\mathcal{L}` is the likelihood. :param params_hyperparams_dict: Dictionary of all parameter and hyperparameter values (both fixed and free) :type params_hyperparams_dict: dict :returns: BIC value :rtype: float .. py:method:: get_sample_with_best_lnprob(discard_start: int = 0, discard_end: int = 0, thin: int = 1) -> Dict[str, float] Get parameter and hyperparameter values from the MCMC sample with the highest log probability. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :returns: Dictionary of parameter and hyperparameter names to values from the best sample :rtype: Dict[str, float] .. py:method:: plot_autocorr_estimates(params: list[str] | None = None, hyperparams: list[str] | None = None, plot_mean: bool = False, show_legend: bool = True, title: str | None = 'Autocorrelation Time Estimates', xlabel: str | None = 'Step number', ylabel: str | None = 'Autocorrelation time $\\tau$', save: bool = False, fname: str = 'autocorr_plot.png', dpi: int = 100) -> None Plot autocorrelation time estimates from adaptive MCMC run. Shows how autocorrelation time evolved during the MCMC run and the convergence threshold line (N / 50). Only available if run_mcmc was called with check_convergence=True. :param params: List of parameter names to plot. If None, plots all free parameters (default: None) :type params: list[str] or None, optional :param hyperparams: List of hyperparameter names to plot. If None, plots all free hyperparameters (default: None) :type hyperparams: list[str] or None, optional :param plot_mean: If True, plot mean tau instead of individual parameter/hyperparameter taus. Overrides params and hyperparams arguments (default: False) :type plot_mean: bool, optional :param show_legend: Whether to show legend (default: True) :type show_legend: bool, optional :param title: Plot title (default: "Autocorrelation Time Estimates"). Set to None or "" to skip. :type title: str or None, optional :param xlabel: X-axis label (default: "Step number"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel: Y-axis label (default: r"Autocorrelation time $\tau$"). Set to None or "" to skip. :type ylabel: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "autocorr_plot.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional :raises ValueError: If no autocorrelation history is available (run_mcmc was not called with check_convergence=True, or has not been called yet) .. py:method:: plot_chains(discard_start: int = 0, discard_end: int = 0, thin: int = 1, truths: list = None, title: str | None = 'Chains plot', xlabel: str | None = 'Step number', save: bool = False, fname: str = 'chains_plot.png', dpi: int = 100) -> None Plot MCMC chains for all free parameters and hyperparameters. Displays the evolution of each free parameter and hyperparameter across MCMC steps for all walkers. Useful for diagnosing convergence, burn-in, and mixing of the MCMC chains. Each parameter/hyperparameter gets its own subplot showing all walker traces. For GP fitting, this includes both planetary/trend parameters and GP kernel hyperparameters. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param truths: List of true parameter/hyperparameter values to overplot as horizontal lines. Must match the number of free parameters + hyperparameters. Use None for parameters without known truth values (default: None) :type truths: list, optional :param title: Plot title (default: "Chains plot"). Set to None or "" to skip. :type title: str or None, optional :param xlabel: X-axis label (default: "Step number"). Set to None or "" to skip. :type xlabel: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "chains_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_lnprob(discard_start: int = 0, discard_end: int = 0, thin: int = 1, title: str | None = 'Log Probability Traces', xlabel: str | None = 'Step number', ylabel: str | None = 'Log probability', save: bool = False, fname: str = 'lnprob_plot.png', dpi: int = 100) -> None Plot log probability traces for all walkers. Useful for diagnosing MCMC convergence and identifying problematic walkers/parameters. You can use `discard_start` and `discard_end` to focus in on specific steps in the chains. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param title: Plot title (default: "Log Probability Traces"). Set to None or "" to skip. :type title: str or None, optional :param xlabel: X-axis label (default: "Step number"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel: Y-axis label (default: "Log probability"). Set to None or "" to skip. :type ylabel: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "lnprob_plot.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional .. py:method:: plot_corner(discard_start: int = 0, discard_end: int = 0, thin: int = 1, plot_datapoints: bool = False, truths: list[float] = None, title: str | None = 'Corner plots', save: bool = False, fname: str = 'corner_plot.png', dpi: int = 100) -> None Create a corner plot of MCMC samples. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param plot_datapoints: Show individual data points in addition to contours (default: False) :type plot_datapoints: bool, optional :param truths: True parameter values to overplot as vertical/horizontal lines (default: None). Must match the order of free parameters if provided. :type truths: list of float, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "corner_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: _plot_rv(params_hyperparams: Dict[str, float], title: str = 'RV Model', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', xlim: tuple | None = None, ylim: tuple | None = None, res_xlim: tuple | None = None, res_ylim: tuple | None = None, n_smooth: int = 1000, save: bool = False, fname: str = 'rv_plot.png', dpi: int = 100) -> None Helper function to plot RV model with given parameters. For GP fitting, this plots both the mean model (planets + trend) and the GP component. The GP component is predicted at smooth time points using the posterior conditioned on observed data residuals, including 1-sigma uncertainty bands. :param params: Dictionary of parameter values (both free and fixed) :type params: dict :param title: Plot title (default: "RV Model"). Set to None or "" to skip. :type title: str, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param xlim: (xmin, xmax) limits for the main RV plot x-axis (default: None, uses data range) :type xlim: tuple or None, optional :param ylim: (ymin, ymax) limits for the main RV plot y-axis (default: None, auto-scaled) :type ylim: tuple or None, optional :param res_xlim: (xmin, xmax) limits for the residuals plot x-axis (default: None, uses data range) :type res_xlim: tuple or None, optional :param res_ylim: (ymin, ymax) limits for the residuals plot y-axis (default: None, symmetric around 0) :type res_ylim: tuple or None, optional :param n_smooth: Number of points in the smooth model curve (default: 1000) :type n_smooth: int, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "rv_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: _plot_phase(planet_letter: str, params_hyperparams: Dict[str, float], title: str = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'phase_plot.png', dpi: int = 100) -> None Helper function to plot phase-folded RV model for a single planet with given parameters. For GP fitting, this handles the challenge that the GP component cannot be easily separated per planet. The approach is to show the target planet signal after subtracting other planets and trends, but keeping the GP component as part of the "data" being phase-folded. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param params: Dictionary of parameter values (both free and fixed) :type params: dict :param title: Plot title (default: f"Planet {planet_letter} Phase Plot"). Set to None or "" to skip. :type title: str, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "phase_plot.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_posterior_rv(discard_start: int = 0, discard_end: int = 0, thin: int = 1, show_CI: bool = True, title: str | None = 'Posterior predictions (with GP)', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'posterior_rv.png', dpi: int = 100, n_smooth: int = 1000) -> None Plot the posterior GP RV model with uncertainty bands from MCMC samples. Calculates RV model predictions for each MCMC sample, then plots the median with optional 68% CI (16th-84th percentile) uncertainty bands. Shows both the full model (planetary signals + trend + GP) and residuals vs data. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param show_CI: Show 68.3% credible interval band (default: True) :type show_CI: bool, optional :param title: Title for the main RV plot (default: "Posterior predictions (with GP)"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "posterior_rv.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional :param n_smooth: Number of points in smooth time grid for plotting model curves (default: 1000). Reduce for faster plotting, increase for smoother curves. :type n_smooth: int, optional .. py:method:: plot_posterior_phase(planet_letter: str, discard_start: int = 0, discard_end: int = 0, thin: int = 1, show_CI: bool = True, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'posterior_phase.png', dpi: int = 100, n_smooth: int = 50) -> None Plot phase-folded GP RV model with uncertainty bands from MCMC samples. Calculates phase-folded planetary signal with uncertainty bands calculated from MCMC samples. Shows the target planet signal after removing trends and other planets, with the GP component included in the data being plotted. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param show_CI: Show 68.3% credible interval band (default: True) :type show_CI: bool, optional :param title: Title for the main phase plot (default: "Posterior Phase Plot (with GP) - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot to path `fname` (default: False) :type save: bool, optional :param fname: The path to save the plot to (default: "posterior_phase.png") :type fname: str, optional :param dpi: The dpi to save the image at (default: 100) :type dpi: int, optional :param n_smooth: Number of points in smooth time grid for plotting model curves (default: 50). Reduce for faster plotting, increase for smoother curves. :type n_smooth: int, optional .. py:method:: plot_MAP_rv(map_result: scipy.optimize.OptimizeResult, title: str | None = 'MAP RV (with GP)', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'MAP_rv.png', dpi: int = 100) -> None Plot the MAP RV model. Uses the Maximum A Posteriori (MAP) parameter estimates to plot the GP model including both mean model (planets + trend) and GP component. :param map_result: Result from find_map_estimate() :type map_result: scipy.optimize.OptimizeResult :param title: Plot title (default: "MAP RV (with GP)"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "MAP_rv.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_MAP_phase(planet_letter: str, map_result: scipy.optimize.OptimizeResult, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'MAP_phase.png', dpi: int = 100) -> None Plot the MAP phase model. Uses the Maximum A Posteriori (MAP) parameter estimates to plot the phase-folded GP model for a specific planet, including both mean model (planets + trend) and GP component. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param map_result: Result from find_map_estimate() :type map_result: scipy.optimize.OptimizeResult :param title: Plot title (default: f"MAP Phase Plot (with GP) - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "MAP_phase.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_custom_rv(params_hyperparams: dict, title: str | None = 'Custom GP RV Plot', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', xlim: tuple | None = None, ylim: tuple | None = None, res_xlim: tuple | None = None, res_ylim: tuple | None = None, n_smooth: int = 1000, save: bool = False, fname: str = 'custom_rv.png', dpi: int = 100) -> None Plot GP radial velocity data and model using custom parameter and hyperparameter values. Allows plotting with arbitrary parameter and hyperparameter values for exploring parameter space or comparing theoretical models. The GP component will be conditioned on the residuals from the mean model (planets + trend). :param params_hyperparams: Dictionary of parameter and hyperparameter values to use for plotting. Keys should match parameter and hyperparameter names, values should be floats. Must include all required parameters and hyperparameters for the current parameterisation and GP kernel. :type params_hyperparams: dict :param title: Plot title (default: "Custom GP RV Plot"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param xlim: (xmin, xmax) limits for the main RV plot x-axis (default: None, uses data range) :type xlim: tuple or None, optional :param ylim: (ymin, ymax) limits for the main RV plot y-axis (default: None, auto-scaled) :type ylim: tuple or None, optional :param res_xlim: (xmin, xmax) limits for the residuals plot x-axis (default: None, uses data range) :type res_xlim: tuple or None, optional :param res_ylim: (ymin, ymax) limits for the residuals plot y-axis (default: None, symmetric around 0) :type res_ylim: tuple or None, optional :param n_smooth: Number of points in the smooth model curve (default: 1000) :type n_smooth: int, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "custom_rv.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. rubric:: Examples >>> # Plot with custom values (must include all required parameters + hyperparameters) >>> gpfitter.plot_custom_rv({"P_b": 4.25, "K_b": 55.0, "e_b": 0.1, ... "w_b": 1.57, "Tc_b": 2456325.5, ... "g": -10.2, "gd": 0.0, "gdd": 0.0, "jit": 2.0, ... "gp_amp": 15.0, "gp_lambda_e": 50.0, ... "gp_lambda_p": 0.5, "gp_period": 25.0}) .. py:method:: plot_custom_phase(planet_letter: str, params_hyperparams: dict, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'custom_phase.png', dpi: int = 100) -> None Plot GP phase-folded radial velocity data and model using custom parameter and hyperparameter values. Allows plotting phase-folded data with arbitrary parameter and hyperparameter values for exploring parameter space or comparing theoretical models. The GP component will be conditioned on the residuals from the mean model (planets + trend). :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param params_hyperparams: Dictionary of parameter and hyperparameter values to use for plotting. Keys should match parameter and hyperparameter names, values should be floats. Must include all required parameters and hyperparameters for the current parameterisation and GP kernel. :type params_hyperparams: dict :param title: Plot title (default: f"Custom GP Phase Plot - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "custom_phase.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. rubric:: Examples >>> # Plot phase curve with custom values >>> gpfitter.plot_custom_phase("b", {"P_b": 4.25, "K_b": 55.0, "e_b": 0.1, ... "w_b": 1.57, "Tc_b": 2456325.5, ... "g": -10.2, "gd": 0.0, "gdd": 0.0, "jit": 2.0, ... "gp_amp": 15.0, "gp_lambda_e": 50.0, ... "gp_lambda_p": 0.5, "gp_period": 25.0}) .. py:method:: plot_best_sample_rv(discard_start: int = 0, discard_end: int = 0, thin: int = 1, title: str | None = 'Best Sample RV Plot (with GP)', ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Time [days]', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'best_sample_rv.png', dpi: int = 100) -> None Plot radial velocity data and model using parameter and hyperparameter values from the MCMC sample with highest log probability. This is useful for comparing with plot_MAP_rv() to diagnose potential issues with MAP convergence or MCMC mixing. The two plots should be very similar if both MAP and MCMC are working correctly. :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param title: Title for the main RV plot (default: "Best Sample RV Plot (with GP)"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main RV plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Time [days]"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "best_sample_rv.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: plot_best_sample_phase(planet_letter: str, discard_start: int = 0, discard_end: int = 0, thin: int = 1, title: str | None = None, ylabel_main: str | None = 'Radial velocity [m/s]', xlabel: str | None = 'Orbital phase', ylabel_residuals: str | None = 'Residuals [m/s]', save: bool = False, fname: str = 'best_sample_phase.png', dpi: int = 100) -> None Plot phase-folded radial velocity data and model using parameter and hyperparameter values from the MCMC sample with highest log probability. This is useful for comparing with plot_MAP_phase() to diagnose potential issues with MAP convergence or MCMC mixing. The two plots should be very similar if both MAP and MCMC are working correctly. :param planet_letter: Letter identifying the planet to plot (e.g., 'b', 'c', 'd') :type planet_letter: str :param discard_start: Discard the first `discard_start` steps from the start of the chain (default: 0) :type discard_start: int, optional :param discard_end: Discard the last `discard_end` steps from the end of the chain (default: 0) :type discard_end: int, optional :param thin: Use only every `thin` steps from the chain (default: 1) :type thin: int, optional :param title: Title for the main phase plot (default: "Best Sample Phase Plot (with GP) - Planet {planet_letter}"). Set to None or "" to skip. :type title: str or None, optional :param ylabel_main: Y-axis label for main phase plot (default: "Radial velocity [m/s]"). Set to None or "" to skip. :type ylabel_main: str or None, optional :param xlabel: X-axis label for residuals plot (default: "Orbital phase"). Set to None or "" to skip. :type xlabel: str or None, optional :param ylabel_residuals: Y-axis label for residuals plot (default: "Residuals [m/s]"). Set to None or "" to skip. :type ylabel_residuals: str or None, optional :param save: Save the plot (default: False) :type save: bool, optional :param fname: Filename to save (default: "best_sample_phase.png") :type fname: str, optional :param dpi: Resolution for saving (default: 100) :type dpi: int, optional .. py:method:: calculate_rv_planet_from_samples(planet_letter: str, times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = True) -> numpy.ndarray Calculate planetary RV for each MCMC sample. This calculates RV(params_i) for each MCMC sample i, preserving parameter correlations. This differs from using median parameters which may not represent actual samples from the posterior. :param planet_letter: Planet letter (e.g., 'b', 'c') :type planet_letter: str :param times: Time points to calculate RV at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: True) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - RV for each sample :rtype: np.ndarray .. py:method:: calculate_rv_trend_from_samples(times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = True) -> numpy.ndarray Calculate trend RV for each MCMC sample. This calculates RV_trend(params_i) for each MCMC sample i, preserving parameter correlations. This differs from using median parameters which may not represent actual samples from the posterior. :param times: Time points to calculate RV at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: True) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - Trend RV for each sample :rtype: np.ndarray .. py:method:: calculate_rv_gp_from_samples(times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = True) -> numpy.ndarray Calculate GP component for each MCMC sample. This calculates the GP mean at the specified times for each MCMC sample, preserving parameter and hyperparameter correlations from the posterior. The GP is conditioned on residuals from the observed RV data, while predictions are called at the requested `times`. :param times: Time points to calculate GP at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: True) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - GP component for each sample :rtype: np.ndarray .. py:method:: calculate_rv_total_from_samples(times: numpy.ndarray, discard_start: int = 0, discard_end: int = 0, thin: int = 1, progress: bool = True) -> numpy.ndarray Calculate total RV (planets + trend + GP) for each MCMC sample. This calculates RV_total(params_i) for each MCMC sample i, preserving parameter correlations. This differs from using median parameters which may not represent actual samples from the posterior. :param times: Time points to calculate RV at :type times: np.ndarray :param discard_start: Discard first N steps (default: 0) :type discard_start: int, optional :param discard_end: Discard last N steps (default: 0) :type discard_end: int, optional :param thin: Use every Nth sample (default: 1) :type thin: int, optional :param progress: Show progress bar (default: True) :type progress: bool, optional :returns: Shape (n_samples, len(times)) - Total RV for each sample :rtype: np.ndarray .. py:method:: calculate_rv_planet_custom(planet_letter: str, times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate planetary RV for a single set of custom parameters. :param planet_letter: Planet letter to calculate RV for (e.g., 'b', 'c') :type planet_letter: str :param times: Time points to calculate RV at :type times: np.ndarray :param params: Complete parameter dictionary (free + fixed parameters). Can be created using build_params_dict(). :type params: dict[str, float] :returns: Planetary RV values at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = gpfitter.find_map_estimate() >>> params = gpfitter.build_params_dict(map_result.x) >>> planet_rv = gpfitter.calculate_rv_planet_custom('b', times, params) >>> >>> # Using best lnprob sample >>> best_params = gpfitter.get_sample_with_best_lnprob(discard_start=1000) >>> params = gpfitter.build_params_dict(best_params) >>> planet_rv = gpfitter.calculate_rv_planet_custom('b', times, params) .. py:method:: calculate_rv_trend_custom(times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate trend RV for a single set of custom parameters. :param times: Time points to calculate RV at :type times: np.ndarray :param params: Complete parameter dictionary (free + fixed parameters). Can be created using build_params_dict(). :type params: dict[str, float] :returns: Trend RV values at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = gpfitter.find_map_estimate() >>> params = gpfitter.build_params_dict(map_result.x) >>> trend_rv = gpfitter.calculate_rv_trend_custom(times, params) .. py:method:: calculate_rv_gp_custom(times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate GP component for a single set of custom parameters. The GP is conditioned on residuals (observed data - mean RV model) where the mean RV model is the sum of the systemic trend and all planetary signals. :param times: Time points to calculate GP at :type times: np.ndarray :param params: Complete parameter and hyperparameter dictionary. Must include both standard parameters (for trend/planets/jit) and GP hyperparameters (for kernel). Can be created using build_params_dict(). :type params: dict[str, float] :returns: GP RV values at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = gpfitter.find_map_estimate() >>> params = gpfitter.build_params_dict(map_result.x) >>> gp_rv = gpfitter.calculate_rv_gp_custom(times, params) >>> >>> # Using best lnprob sample >>> best_params = gpfitter.get_sample_with_best_lnprob(discard_start=1000) >>> params = gpfitter.build_params_dict(best_params) >>> gp_rv = gpfitter.calculate_rv_gp_custom(times, params) .. py:method:: calculate_rv_total_custom(times: numpy.ndarray, params: dict[str, float]) -> numpy.ndarray Calculate total RV (trend + all planets + GP) for a single set of custom parameters. Useful for calculating RV with specific parameter values (e.g., best lnprob sample, median parameters, or experimental values). :param times: Time points to calculate RV at :type times: np.ndarray :param params: Complete parameter and hyperparameter dictionary. Must include both standard parameters (for trend/planets/jit) and GP hyperparameters (for kernel). Can be created using build_params_dict(). :type params: dict[str, float] :returns: Total RV values (trend + all planets + GP) at the requested times :rtype: np.ndarray .. rubric:: Examples >>> # Using MAP result >>> map_result = gpfitter.find_map_estimate() >>> params = gpfitter.build_params_dict(map_result.x) >>> total_rv = gpfitter.calculate_rv_total_custom(times, params) .. py:class:: GPLogPosterior(planet_letters: list[str], parameterisation: ravest.param.Parameterisation, gp_kernel: ravest.gp.GPKernel, priors: dict[str, Callable[[float], float]], hyperpriors: dict[str, Callable[[float], float]], fixed_params: dict[str, float], fixed_hyperparams: dict[str, float], free_params_names: list[str], free_hyperparams_names: list[str], time: numpy.ndarray, vel: numpy.ndarray, velerr: numpy.ndarray, t0: float, instrument: numpy.ndarray, unique_instruments: list[str]) Log posterior probability for GP MCMC sampling. Combines GP log likelihood and log priors for both parameters and hyperparameters. .. py:attribute:: planet_letters .. py:attribute:: parameterisation .. py:attribute:: gp_kernel .. py:attribute:: priors .. py:attribute:: hyperpriors .. py:attribute:: fixed_params .. py:attribute:: fixed_hyperparams .. py:attribute:: free_params_names .. py:attribute:: free_hyperparams_names .. py:attribute:: time .. py:attribute:: vel .. py:attribute:: velerr .. py:attribute:: t0 .. py:attribute:: instrument .. py:attribute:: unique_instruments .. py:attribute:: gp_log_likelihood .. py:attribute:: log_prior .. py:attribute:: log_hyperprior .. py:method:: _convert_params_for_prior_evaluation(free_params_dict: dict[str, float]) -> Dict[str, float] Convert free parameters for prior evaluation if needed. :param free_params_dict: Free parameters in current parameterisation :type free_params_dict: dict :returns: Parameters with names/values converted for prior evaluation :rtype: dict .. py:method:: log_probability(combined_params_hyperparams: Dict[str, float]) -> float Calculate log posterior probability for given free parameters and hyperparameters. :param combined_params_hyperparams: Combined dictionary of free parameters and hyperparameters :type combined_params_hyperparams: Dict[str, float] :returns: Log posterior probability (log likelihood + log prior + log hyperprior) :rtype: float .. py:method:: _negative_log_probability_for_MAP(combined_free_params_hyperparams_vals: list[float]) -> float For MAP: run __call__ only passing in a list, not dict, of params. Because scipy.optimize.minimise only takes list of values, not a dict, we need to assign the values back to their corresponding keys, and pass that to __call__(). This does not check that the values are in the correct order, it is assumed. As we're dealing with dicts, this hopefully is the case. :param combined_free_params_hyperparams_vals: Combined list of free parameter and free hyperparameter values :type combined_free_params_hyperparams_vals: list .. py:class:: GPLogLikelihood(time: numpy.ndarray, vel: numpy.ndarray, velerr: numpy.ndarray, t0: float, instrument: numpy.ndarray, unique_instruments: list[str], planet_letters: list[str], parameterisation: ravest.param.Parameterisation, gp_kernel: ravest.gp.GPKernel) GP version of Log likelihood calculation for radial velocity data. Calculates log likelihood given RV model parameters and data, and GP hyperparameters. .. py:attribute:: time .. py:attribute:: vel .. py:attribute:: velerr .. py:attribute:: t0 .. py:attribute:: instrument .. py:attribute:: unique_instruments .. py:attribute:: planet_letters .. py:attribute:: parameterisation .. py:attribute:: gp_kernel .. py:attribute:: jax_time .. py:attribute:: jax_vel .. py:attribute:: jax_velerr .. py:attribute:: _instrument_indices .. py:attribute:: _gamma_keys .. py:attribute:: _jitter_keys .. py:attribute:: _velerr_sq .. py:method:: _calculate_mean_model(params: Dict[str, float]) -> jax.numpy.ndarray Calculate the Keplerian RV model (the mean function for the GP). Takes planetary parameters, trend parameters, and per-instrument gamma offsets. :param params: Dictionary of all parameter values :type params: Dict[str, float] :returns: Mean model RV values at observation times :rtype: jnp.ndarray .. py:method:: _compute_gp_log_likelihood(kernel: tinygp.kernels.Kernel, time_array: jax.numpy.ndarray, vel_array: jax.numpy.ndarray, verr_squared_array: jax.numpy.ndarray, mean_model: jax.numpy.ndarray) -> float :staticmethod: JIT-compiled GP log likelihood computation. This is the expensive numerical part that benefits from JIT compilation. .. py:method:: __call__(params: Dict[str, float], hyperparams: Dict[str, float]) -> float Calculate GP log likelihood for given parameters and hyperparameters. :param params: Dictionary of all parameter values :type params: Dict[str, float] :param hyperparams: Dictionary of all hyperparameter values :type hyperparams: Dict[str, float] :returns: Log likelihood value :rtype: float