Source code for arve.planets.injection_recovery

import numpy as np

from typing import Literal

[docs] class injection_recovery:
[docs] def injection_recovery( self, xy_arr : np.ndarray | None = None , p_arr : np.ndarray | None = None , xy_map : list[float] | None = None , map_dim : list[float] | None = [10,10] , x_var : Literal["P", "a"] = "P" , y_var : Literal["K", "m"] = "K" , scale : Literal["linear", "log"] = "linear", P_lim : float = 0.1 , oversamp : float = 3 , fap : float = 0.01 , N_max : int = 10 , ) -> None: """Injection-recovery test of specific injected values, 2D map or both. Parameters ---------- xy_arr : np.ndarray | None, optional 2D array with injected values in the format [x_arr, y_arr], by default None p_arr : np.ndarray | None, optional 1D array with injected phases, by default None xy_map : list[float] | None, optional array with 2D map bounds in the format [x_min, x_max, y_min, y_max], by default None map_dim : list[float] | None, optional map dimensions in the format [x_dim, y_dim] (only used if xy_map is provided), by default [10,10] x_var : Literal["P", "a"], optional x variable, either period "P" in days or semi-major axis "a" in AUs, by default "P" y_var : Literal["K", "m"], optional y variable, either RV semi-amplitude "K" in km/s or planet mass "m" in Earth masses, by default "K" scale : Literal["linear", "log"], optional scale of injected values, either "linear" or "log", by default "linear" P_lim : float, optional fraction of injected periods within which the recovered periods can differ to count as recoveries, by default 0.1 oversamp : float, optional oversamling factor of the periodogram frequency grid, by default 3 fap : float, optional false-alarm probability (FAP) level, by default 0.01 N_max : int, optional maximum number of fitted Keplerians, by default 10 Returns ------- None None """ # read star mass M = self.arve.star.stellar_parameters["M"] # read periodograms and keplerians periodograms = self.periodograms keplerians = self.keplerians # include array and include map include_arr = xy_arr is not None include_map = xy_map is not None # if injected array is provided if include_arr: # input x and y arrays x_arr, y_arr = xy_arr x_arr = np.array(x_arr) y_arr = np.array(y_arr) # convert to P and K if x_var == "P": P_arr = x_arr P_err = P_arr*P_lim if x_var == "a": a_arr = x_arr P_arr = 365.25*a_arr**(3/2)*M**(-1/2) P_err = P_arr*P_lim if y_var == "K": K_arr = y_arr if y_var == "m": m_arr = y_arr K_arr = 8.95e-5*(P_arr/365.25)**(-1/3)*M**(-2/3)*m_arr # recovery array recovery_arr = self.recovery_test(P_arr, K_arr, p_arr, P_err=P_err, oversamp=oversamp, fap=fap, N_max=N_max) # else set arrays to None else: x_arr = None y_arr = None recovery_arr = None # if injected map is provided if include_map: # input x and y arrays x_min, x_max, y_min, y_max = xy_map x_dim, y_dim = map_dim if scale == "linear": x_map = np.linspace(x_min, x_max, x_dim) y_map = np.linspace(y_min, y_max, y_dim) if scale == "log": x_map = np.logspace(np.log10(x_min), np.log10(x_max), x_dim) y_map = np.logspace(np.log10(y_min), np.log10(y_max), y_dim) # convert to P and K if x_var == "P": P_map = x_map P_err = P_map*P_lim if x_var == "a": a_map = x_map P_map = 365.25*a_map**(3/2)*M**(-1/2) P_err = P_map*P_lim if y_var == "K": K_map = y_map if y_var == "m": m_map = y_map K_map = 8.95e-5*(P_map/365.25)**(-1/3)*M**(-2/3)*m_map # recovery map recovery_map = np.zeros((len(P_map),len(K_map))) for i in range(len(P_map)): for j in range(len(K_map)): recovery_map[i,j] = self.recovery_test(np.array([P_map[i]]), np.array([K_map[j]]), P_err=np.array([P_err[i]]), oversamp=oversamp, fap=fap, N_max=N_max)[0] # else set arrays to None else: x_map = None y_map = None recovery_map = None # save self.recoveries = { "x_var" : x_var , "y_var" : y_var , "x_arr" : x_arr , "y_arr" : y_arr , "x_map" : x_map , "y_map" : y_map , "recovery_arr": recovery_arr, "recovery_map": recovery_map, "scale" : scale } # re-set periodograms and Keplerians self.periodograms = periodograms self.keplerians = keplerians return None