Source code for taurex.data.profiles.chemistry.gas.twolayergas

from .gas import Gas
from taurex.util import movingaverage, molecule_texlabel
import numpy as np


[docs]class TwoLayerGas(Gas): """ Two layer gas profile. A gas profile with two different mixing layers at the surface of the planet and top of the atmosphere seperated at a defined pressure point and smoothened. Parameters ----------- molecule_name : str Name of molecule mix_ratio_surface : float Mixing ratio of the molecule on the planet surface mix_ratio_top : float Mixing ratio of the molecule at the top of the atmosphere mix_ratio_P : float Boundary Pressure point between the two layers mix_ratio_smoothing : float , optional smoothing window """ def __init__(self, molecule_name='CH4', mix_ratio_surface=1e-4, mix_ratio_top=1e-8, mix_ratio_P=1e3, mix_ratio_smoothing=10): super().__init__(self.__class__.__name__, molecule_name=molecule_name) self._mix_surface = mix_ratio_surface self._mix_top = mix_ratio_top self._mix_ratio_pressure = mix_ratio_P self._mix_ratio_smoothing = mix_ratio_smoothing self._mix_profile = None self.add_surface_param() self.add_top_param() self.add_P_param() @property def mixProfile(self): """ Returns ------- mix: :obj:`array` Mix ratio for molecule at each layer """ return self._mix_profile @property def mixRatioSurface(self): """Abundance on the planets surface""" return self._mix_surface @property def mixRatioTop(self): """Abundance on the top of atmosphere""" return self._mix_top @property def mixRatioPressure(self): return self._mix_ratio_pressure @property def mixRatioSmoothing(self): return self._mix_ratio_smoothing @mixRatioSurface.setter def mixRatioSurface(self, value): self._mix_surface = value @mixRatioTop.setter def mixRatioTop(self, value): self._mix_top = value @mixRatioPressure.setter def mixRatioPressure(self, value): self._mix_pressure = value @mixRatioSmoothing.setter def mixRatioSmoothing(self, value): self._mix_smoothing = value
[docs] def add_surface_param(self): """ Generates surface fitting parameters. Has the form ''Moleculename_surface' """ param_name = self.molecule param_tex = molecule_texlabel(param_name) param_surface = '{}_surface'.format(param_name) param_surf_tex = '{}_surface'.format(param_tex) def read_surf(self): return self._mix_surface def write_surf(self, value): self._mix_surface = value fget_surf = read_surf fset_surf = write_surf bounds = [1.0e-12, 0.1] default_fit = False self.add_fittable_param(param_surface, param_surf_tex, fget_surf, fset_surf, 'log', default_fit, bounds)
[docs] def add_top_param(self): """ Generates TOA fitting parameters. Has the form: 'Moleculename_top' """ param_name = self.molecule param_tex = molecule_texlabel(param_name) param_top = '{}_top'.format(param_name) param_top_tex = '{}_top'.format(param_tex) def read_top(self): return self._mix_top def write_top(self, value): self._mix_top = value fget_top = read_top fset_top = write_top bounds = [1.0e-12, 0.1] default_fit = False self.add_fittable_param(param_top, param_top_tex, fget_top, fset_top, 'log', default_fit, bounds)
[docs] def add_P_param(self): """ Generates pressure fitting parameter. Has the form 'Moleculename_P' """ mol_name = self.molecule mol_tex = molecule_texlabel(mol_name) param_P = '{}_P'.format(mol_name) param_P_tex = '{}_P'.format(mol_tex) def read_P(self): return self._mix_ratio_pressure def write_P(self, value): self._mix_ratio_pressure = value fget_P = read_P fset_P = write_P bounds = [1.0e-12, 0.1] default_fit = False self.add_fittable_param(param_P, param_P_tex, fget_P, fset_P, 'log', default_fit, bounds)
[docs] def initialize_profile(self, nlayers=None, temperature_profile=None, pressure_profile=None, altitude_profile=None): self._mix_profile = np.zeros(nlayers) smooth_window = self._mix_ratio_smoothing P_layer = np.abs(pressure_profile - self._mix_ratio_pressure).argmin() start_layer = max(int(P_layer-smooth_window/2), 0) end_layer = min(int(P_layer+smooth_window/2), nlayers-1) Pnodes = [pressure_profile[0], pressure_profile[start_layer], pressure_profile[end_layer], pressure_profile[-1]] Cnodes = [self.mixRatioSurface, self.mixRatioSurface, self.mixRatioTop, self.mixRatioTop] chemprofile = 10**np.interp((np.log(pressure_profile[::-1])), np.log(Pnodes[::-1]), np.log10(Cnodes[::-1])) wsize = nlayers * (smooth_window / 100.0) if (wsize % 2 == 0): wsize += 1 C_smooth = 10**movingaverage(np.log10(chemprofile), int(wsize)) border = np.int((len(chemprofile) - len(C_smooth)) / 2) self._mix_profile = chemprofile[::-1] self._mix_profile[border:-border] = C_smooth[::-1]
[docs] def write(self, output): gas_entry = super().write(output) gas_entry.write_scalar('mix_ratio_top', self.mixRatioTop) gas_entry.write_scalar('mix_ratio_surface', self.mixRatioSurface) gas_entry.write_scalar('mix_ratio_P', self.mixRatioPressure) gas_entry.write_scalar('mix_ratio_smoothing', self.mixRatioSmoothing) return gas_entry
[docs] @classmethod def input_keywords(self): return ['twolayer', '2layer', ]
BIBTEX_ENTRIES = [ """ @misc{changeat2019complex, title={Towards a more complex description of chemical profiles in exoplanets retrievals: A 2-layer parameterisation}, author={Quentin Changeat and Billy Edwards and Ingo Waldmann and Giovanna Tinetti}, year={2019}, eprint={1903.11180}, archivePrefix={arXiv}, primaryClass={astro-ph.EP} } """, ]