Source code for ForMoSA.transform.apply_effects

import numpy as np

import ForMoSA.utils.spec as us
from ForMoSA.core.errors import ForMoSAError
from ForMoSA.core.enums import VsiniFunction
from ForMoSA.transform.observed import ObservedModel
from ForMoSA.observation.observation_base import Observation

[docs] class ApplyPhysicsEffects: ''' Apply physics effects to a model given parameters. Notes ----- Authors: Allan Denis ''' @staticmethod def _apply_rv(observed_model: ObservedModel, rv_value: float) -> ObservedModel: ''' Apply radial velocity transformation. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel rv_value : float RV value Returns ------- observed_model : ObservedModel Instance of class ObservedModel Doppler shifted Notes ----- Authors: Allan Denis ''' observed_model.wave, observed_model.flux, observed_model.res = us.doppler_fct(observed_model.wave, observed_model.flux, observed_model.res, rv_value) return observed_model @staticmethod def _apply_vsini(observed_model: ObservedModel, vsini_value: float, ld_value: float, vsini_function: VsiniFunction) -> ObservedModel: ''' Apply v.sini transformation. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel vsini_value : float v.sini value ld_value : float limbd darkening value vsini_function : VsiniFunction Function used for the v.sini Returns ------- observed_model : ObservedModel Instance of class ObservedModel rotationally broadened Notes ----- Authors: Allan Denis ''' observed_model.flux, observed_model.res = us.vsini_fct(observed_model.wave, observed_model.flux, observed_model.res, ld_value, vsini_value, vsini_function.value) return observed_model @staticmethod def _apply_reddening(observed_model: ObservedModel, av_value: float) -> np.ndarray: ''' Apply redening transformation. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel av_value : float Extinction value Returns ------- observed_model : ObservedModel Instance of class ObservedModel redenned Notes ----- Authors: Allan Denis ''' observed_model.flux = us.reddening_fct(observed_model.wave, observed_model.flux, av_value) return observed_model @staticmethod def _apply_cpd(observed_model: ObservedModel, bb_T_value: float, bb_R_value: float, d_value: float) -> np.ndarray: ''' Apply CPD effect. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel bb_T_value : float Black body temperature value bb_R_value : float Black body radius value d_value : float Distance value Returns ------- (ObservedModel): Instance of class ObservedModel with a CPD effect Notes ----- Authors: Allan Denis ''' observed_model.flux = us.bb_cpd_fct(observed_model.wave, observed_model.flux, d_value, bb_T_value, bb_R_value) return observed_model @staticmethod def _apply_scaling(observed_model: ObservedModel, r_value: float, d_value: float) -> np.ndarray: ''' Apply scaling. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel r_value : float Radius value d_value : float Distance value Returns ------- flux_transformed : np.ndarray Scaled model Notes ----- Authors: Allan Denis ''' observed_model.flux, ck = us.calc_ck(observed_model.flux, [], [], r_value, d_value) observed_model.scaling = 'physical' return observed_model
[docs] class ApplyObservationEffects: @staticmethod def _apply_resolution_decreasing(observed_model: ObservedModel, obs: Observation) -> ObservedModel: ''' Apply resolution decreasing. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel to transform obs : Observation Observation Returns ------- (ObservedModel): Instance of class ObservedModel degraded in resolution Notes ----- Authors: Allan Denis ''' if obs.res.all() == 0: return observed_model if len(observed_model.wave) != len(obs.wave): flux = us.resolution_decreasing(observed_model.wave, observed_model.flux, observed_model.res, obs.wave, obs.res) return ObservedModel(obs.wave, flux, obs.res) return observed_model @staticmethod def _apply_scaling(observed_model: ObservedModel, obs: Observation, bounds: tuple[float, float] = (-float('inf'), float('inf'))) -> ObservedModel: ''' Apply analytical scaling between a model and observations. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel to transform obs : Observation Observation bounds : tuple[float, float] Bounds for the Least Squares Returns ------- (ObservedModel): Instance of class ObservedModel scaled to the data Notes ----- Authors: Allan Denis ''' if observed_model.scaling == 'analytic': observed_model.flux, ck = us.calc_ck(observed_model.flux, obs.flux, obs.err, 0, 0, analytic='yes', bounds = bounds) return observed_model @staticmethod def _hc_modeling(observed_model: ObservedModel, obs: Observation, bounds: tuple[float, float] = (-float('inf'), float('inf'))) -> ObservedModel: ''' High-contrast modeling: solve flux_obs = sum_i coeffs_i * components_i where components_0 is model and components_i (i >= 1) is stellar speckles or systematics. Parameters ---------- observed_model : ObservedModel Instance of class ObservedModel to transform obs : Observation Observation bounds : tuple[float, float] Bounds for the least squares Returns ------- (ObservedModel): Instance of class ObservedModel high-contrast modelled Notes ----- Authors: Allan Denis ''' # ================================= # Initial checks # ================================= if not obs.hc_mode: raise ForMoSAError('Your observation needs to be in high-contrast mode in order to be able to use high-contrast modeling' ) # ================================= # Consistency between model and obs # ================================= wave_cont, res_cont = obs.wave_cont, obs.res_cont wave, res = obs.wave, obs.res if len(wave) != len(observed_model.wave): raise ForMoSAError(f'Wrong length for model wavelength: {len(observed_model.wave)}. Expected the same length as the observations: {len(wave)}' ) observed_model.flux_cont = us.continuum_estimate(wave, observed_model.flux * obs.transm, res, wave_cont, res_cont) # ================================= # Build components for linear fit # ================================= components, fixed_coeffs, bounds, labels = us.build_linear_components( observed_model.flux, transm=obs.transm, flx_cont_obs=obs.flux_cont, flx_cont_mod=observed_model.flux_cont, star_flx_obs=obs.star_flux, star_flx_cont_obs=obs.star_flux_cont, system_obs=obs.system, analytic='yes', bounds=bounds ) # ================================= # Solve linear model # ================================= result = us.fit_linear_model( components=components, flx_obs=obs.flux, err_obs=obs.err, bounds=bounds, fixed_coeffs=fixed_coeffs ) observed_model.flux, observed_model.component = result['reconstructed'][0], np.sum(result['reconstructed'][1: len(components)], axis= 0) return observed_model