"""
Module with utility functions for plotting data.
"""
import warnings
from string import ascii_lowercase
import numpy as np
from beartype import beartype
from beartype.typing import Dict, List, Optional, Tuple
from species.core import constants
from species.util.model_util import convert_model_name
[docs]
@beartype
def sptype_to_index(
field_range: Tuple[str, str], spec_types: np.ndarray, check_subclass: bool
) -> np.ndarray:
"""
Function for mapping the spectral types of stellar and
substellar objects to indices that corresponds with the
discrete colorbar of a color-magnitude or color-color
diagram.
Parameters
----------
field_range : tuple(str, str)
Range of the discrete colorbar for the field objects. The tuple
should contain the lower and upper value ('early M', 'late M',
'early L', 'late L', 'early T', 'late T', 'early Y). Also
stellar spectral types can be specified.
spec_types : np.ndarray
Array with the spectral types.
check_subclass : bool
Set to ``True`` if the discrete colorbar should distinguish
early and late spectral types with different colors or set
to ``False`` if subclasses should not be distinguished.
Returns
-------
np.ndarray
Array with spectral types mapped to indices. Spectral types
that are not within the range specified with ``field_range``
will be set to NaN.
"""
spt_discrete = np.zeros(spec_types.size)
if check_subclass:
spt_check = [
("early O", "late O"),
("early B", "late B"),
("early A", "late A"),
("early F", "late F"),
("early G", "late G"),
("early K", "late K"),
("early M", "late M"),
("early L", "late L"),
("early T", "late T"),
("early Y", "late Y"),
]
for i, item in enumerate(spec_types):
if isinstance(item, bytes):
# Catch SpT names that were read from FITS files
# and stored as bytes in the HDF5 database
item = item.decode("utf-8")
if item[0:2] in ["O0", "O1", "O2", "O3", "O4"]:
spt_discrete[i] = 0.5
elif item[0:2] in ["O5", "O6", "O7", "O8", "O9"]:
spt_discrete[i] = 1.5
elif item[0:2] in ["B0", "B1", "B2", "B3", "B4"]:
spt_discrete[i] = 2.5
elif item[0:2] in ["B5", "B6", "B7", "B8", "B9"]:
spt_discrete[i] = 3.5
elif item[0:2] in ["A0", "A1", "A2", "A3", "A4"]:
spt_discrete[i] = 4.5
elif item[0:2] in ["A5", "A6", "A7", "A8", "A9"]:
spt_discrete[i] = 5.5
elif item[0:2] in ["F0", "F1", "F2", "F3", "F4"]:
spt_discrete[i] = 6.5
elif item[0:2] in ["F5", "F6", "F7", "F8", "F9"]:
spt_discrete[i] = 7.5
elif item[0:2] in ["G0", "G1", "G2", "G3", "G4"]:
spt_discrete[i] = 8.5
elif item[0:2] in ["G5", "G6", "G7", "G8", "G9"]:
spt_discrete[i] = 9.5
elif item[0:2] in ["K0", "K1", "K2", "K3", "K4"]:
spt_discrete[i] = 10.5
elif item[0:2] in ["K5", "K6", "K7", "K8", "K9"]:
spt_discrete[i] = 11.5
elif item[0:2] in ["M0", "M1", "M2", "M3", "M4"]:
spt_discrete[i] = 12.5
elif item[0:2] in ["M5", "M6", "M7", "M8", "M9"]:
spt_discrete[i] = 13.5
elif item[0:2] in ["L0", "L1", "L2", "L3", "L4"]:
spt_discrete[i] = 14.5
elif item[0:2] in ["L5", "L6", "L7", "L8", "L9"]:
spt_discrete[i] = 15.5
elif item[0:2] in ["T0", "T1", "T2", "T3", "T4"]:
spt_discrete[i] = 16.5
elif item[0:2] in ["T5", "T6", "T7", "T8", "T9"]:
spt_discrete[i] = 17.5
elif "Y" in item:
spt_discrete[i] = 18.5
else:
spt_discrete[i] = np.nan
count = 0
for i, item in enumerate(spt_check):
for j in range(2):
if field_range[0] == item[j]:
spt_discrete -= float(count)
break
count += 1
else:
spt_check = ["O", "B", "A", "F", "G", "K", "M", "L", "T", "Y"]
for i, item in enumerate(spec_types):
if isinstance(item, bytes):
# Catch SpT names that were read from FITS files
# and stored as bytes in the HDF5 database
item = item.decode("utf-8")
if item[0] == "O":
spt_discrete[i] = 0.5
elif item[0] == "B":
spt_discrete[i] = 1.5
elif item[0] == "A":
spt_discrete[i] = 2.5
elif item[0] == "F":
spt_discrete[i] = 3.5
elif item[0] == "G":
spt_discrete[i] = 4.5
elif item[0] == "K":
spt_discrete[i] = 5.5
elif item[0] == "M":
spt_discrete[i] = 6.5
elif item[0] == "L":
spt_discrete[i] = 7.5
elif item[0] == "T":
spt_discrete[i] = 8.5
elif item[0] == "Y":
spt_discrete[i] = 9.5
else:
spt_discrete[i] = np.nan
for i, item in enumerate(spt_check):
if field_range[0] == item:
spt_discrete -= float(i)
break
set_to_nan = spt_discrete < 0.0
spt_discrete[set_to_nan] = np.nan
return spt_discrete
[docs]
@beartype
def update_labels(param: List[str], object_type: str = "planet") -> List[str]:
"""
Function for formatting the model parameters to use them
as labels in the posterior plot.
Parameters
----------
param : list
List with names of the model parameters.
object_type : str
Object type ('planet' or 'star'). With 'planet', the radius
and mass are expressed in Jupiter units. With 'star', the
radius and mass are expressed in solar units.
Returns
-------
list
List with parameter labels for plots.
"""
cloud_species = ["Fe", "MgSiO3", "Al2O3", "Na2S", "KCl"]
cloud_labels = ["Fe", r"MgSiO_{3}", r"Al_{2}O_{3}", r"Na_{2}S", "KCl"]
abund_species = [
"CO_all_iso",
"CO_all_iso_HITEMP",
"H2O",
"H2O_HITEMP",
"H2O_main_iso",
"CH4",
"CH4_main_iso",
"NH3",
"NH3_main_iso",
"CO2",
"CO2_main_iso",
"H2S",
"H2S_main_iso",
"Na",
"Na_allard",
"Na_burrows",
"Na_lor_cur",
"K",
"K_allard",
"K_burrows",
"K_lor_cur",
"PH3",
"PH3_main_iso",
"VO",
"VO_Plez",
"TiO",
"TiO_all_Exomol",
"TiO_all_iso_Plez",
"FeH",
"FeH_main_iso",
"MgSiO3(c)",
"Fe(c)",
"Al2O3(c)",
"Na2S(c)",
"KCL(c)",
]
abund_labels = [
"CO",
"CO",
"H_{2}O",
"H_{2}O",
"H_{2}O",
"CH_{4}",
"CH_{4}",
"NH_{3}",
"NH_{3}",
"CO_{2}",
"CO_{2}",
"H_{2}S",
"H_{2}S",
"Na",
"Na",
"Na",
"Na",
"K",
"K",
"K",
"K",
"PH_{3}",
"PH_{3}",
"VO",
"VO",
"TiO",
"TiO",
"TiO",
"FeH",
"FeH",
"MgSiO_{3}",
"Fe",
"Al_{2}O_{3}",
"Na_{2}S",
"KCl",
]
if "teff" in param:
index = param.index("teff")
param[index] = r"$T_\mathrm{eff}$ (K)"
for i in range(100):
if f"disk_teff_{i}" in param:
index = param.index(f"disk_teff_{i}")
param[index] = r"$T_\mathrm{disk,}$" + rf"$_\mathrm{{{i+1}}}$ (K)"
else:
break
if "logg" in param:
index = param.index("logg")
param[index] = r"$\log\,g$"
if "logg_0" in param:
index = param.index("logg_0")
param[index] = r"$\log\,g_\mathrm{1}$"
if "logg_1" in param:
index = param.index("logg_1")
param[index] = r"$\log\,g_\mathrm{2}$"
if "metallicity" in param:
index = param.index("metallicity")
param[index] = "[Fe/H]"
if "feh" in param:
index = param.index("feh")
param[index] = "[Fe/H]"
if "feh_0" in param:
index = param.index("feh_0")
param[index] = r"[Fe/H]$_\mathrm{1}$"
if "feh_1" in param:
index = param.index("feh_1")
param[index] = r"[Fe/H]$_\mathrm{2}$"
if "fsed" in param:
index = param.index("fsed")
param[index] = r"$f_\mathrm{sed}$"
if "fsed_0" in param:
index = param.index("fsed_0")
param[index] = r"$f_\mathrm{sed,1}$"
if "fsed_1" in param:
index = param.index("fsed_1")
param[index] = r"$f_\mathrm{sed,2}$"
if "vsini" in param:
index = param.index("vsini")
param[index] = r"$v\,\sin\,i$ (km s$^{-1}$)"
if "vsini_0" in param:
index = param.index("vsini_0")
param[index] = r"$v\,\sin\,i_\mathrm{1}$ (km s$^{-1}$)"
if "vsini_1" in param:
index = param.index("vsini_1")
param[index] = r"$v\,\sin\,i_\mathrm{2}$ (km s$^{-1}$)"
if "rad_vel" in param:
index = param.index("rad_vel")
param[index] = r"$v_\mathrm{r}$ (km s$^{-1}$)"
if "rad_vel_0" in param:
index = param.index("rad_vel_0")
param[index] = r"$v_\mathrm{r,1}$ (km s$^{-1}$)"
if "rad_vel_1" in param:
index = param.index("rad_vel_1")
param[index] = r"$v_\mathrm{r,2}$ (km s$^{-1}$)"
if "log_lum_0" in param:
index = param.index("log_lum_0")
param[index] = r"$\log\,L_\mathrm{1}/L_\mathrm{\odot}$"
if "log_lum_1" in param:
index = param.index("log_lum_1")
param[index] = r"$\log\,L_\mathrm{2}/L_\mathrm{\odot}$"
if "f_clouds" in param:
index = param.index("f_clouds")
param[index] = r"$w_\mathrm{clouds}$"
if "c_o_ratio" in param:
index = param.index("c_o_ratio")
param[index] = r"C/O"
if "radius" in param:
index = param.index("radius")
if object_type == "planet":
param[index] = r"$R_\mathrm{p}$ ($R_\mathrm{J}$)"
elif object_type == "star":
param[index] = r"$R_\ast$ ($R_\mathrm{\odot}$)"
if "distance" in param:
index = param.index("distance")
param[index] = "$d$ (pc)"
if "parallax" in param:
index = param.index("parallax")
param[index] = r"$\varpi$ (mas)"
if "parallax_0" in param:
index = param.index("parallax_0")
param[index] = r"$\varpi_\mathrm{1}$ (mas)"
if "parallax_1" in param:
index = param.index("parallax_1")
param[index] = r"$\varpi_\mathrm{2}$ (mas)"
if "mass" in param:
index = param.index("mass")
if object_type == "planet":
param[index] = r"$M$ ($M_\mathrm{J}$)"
elif object_type == "star":
param[index] = r"$M_\ast$ ($M_\mathrm{\odot}$)"
if "mass_0" in param:
index = param.index("mass_0")
if object_type == "planet":
param[index] = r"$M_\mathrm{1}$ ($M_\mathrm{J}$)"
elif object_type == "star":
param[index] = r"$M_\mathrm{1}$ ($M_\mathrm{\odot}$)"
if "mass_1" in param:
index = param.index("mass_1")
if object_type == "planet":
param[index] = r"$M_\mathrm{2}$ ($M_\mathrm{J}$)"
elif object_type == "star":
param[index] = r"$M_\mathrm{2}$ ($M_\mathrm{\odot}$)"
# for i, item in enumerate(ascii_lowercase[1:]):
# if f"mass_{i}" in param:
# index = param.index(f"mass_{i}")
# param[index] = rf"$M_\mathrm{{{item}}}$ ($M_\mathrm{{J}}$)"
# else:
# break
if "log_mass" in param:
index = param.index("log_mass")
if object_type == "planet":
param[index] = r"$\log\,M/M_\mathrm{J}$"
elif object_type == "star":
param[index] = r"$\log\,M_\ast/M_\mathrm{\odot}$"
if "log_mass_0" in param:
index = param.index("log_mass_0")
if object_type == "planet":
param[index] = r"$\log\,M_\mathrm{1}/M_\mathrm{J}$"
elif object_type == "star":
param[index] = r"$\log\,M_\mathrm{1}/M_\mathrm{\odot}$"
if "log_mass_1" in param:
index = param.index("log_mass_1")
if object_type == "planet":
param[index] = r"$\log\,M_\mathrm{2}/M_\mathrm{J}$"
elif object_type == "star":
param[index] = r"$\log\,M_\mathrm{2}/M_\mathrm{\odot}$"
if "mass_ratio" in param:
index = param.index("mass_ratio")
param[index] = r"$q$"
if "age" in param:
index = param.index("age")
param[index] = "Age (Myr)"
# if "mass_1" in param:
# index = param.index("mass_1")
# param[index] = r"$M_\mathrm{b}$ ($M_\mathrm{J}$)"
#
# if "mass_2" in param:
# index = param.index("mass_2")
# param[index] = r"$M_\mathrm{c}$ ($M_\mathrm{J}$)"
if "s_init" in param:
index = param.index("s_init")
param[index] = r"$S_\mathrm{i}$ ($k_\mathrm{B}/\mathrm{baryon}$)"
# if "s_init_1" in param:
# index = param.index("s_init_1")
# param[index] = r"$S_\mathrm{i,b}$ ($k_\mathrm{B}/\mathrm{baryon}$)"
#
# if "s_init_2" in param:
# index = param.index("s_init_2")
# param[index] = r"$S_\mathrm{i,c}$ ($k_\mathrm{B}/\mathrm{baryon}$)"
if "dfrac_1" in param:
index = param.index("dfrac_1")
param[index] = r"$\log\,D_\mathrm{i,b}$"
if "dfrac_2" in param:
index = param.index("dfrac_2")
param[index] = r"$\log\,D_\mathrm{i,c}$"
if "y_frac" in param:
index = param.index("y_frac")
param[index] = r"$Y$"
if "yfrac_1" in param:
index = param.index("yfrac_1")
param[index] = r"$Y_\mathrm{b}$"
if "yfrac_2" in param:
index = param.index("yfrac_2")
param[index] = r"$Y_\mathrm{c}$"
if "mcore_1" in param:
index = param.index("mcore_1")
param[index] = r"$M_\mathrm{core,b}$ ($M_\mathrm{E}$)"
if "mcore_2" in param:
index = param.index("mcore_2")
param[index] = r"$M_\mathrm{core,c}$ ($M_\mathrm{E}$)"
for i, item in enumerate(ascii_lowercase[1:]):
if f"s_init_{i}" in param:
index = param.index(f"s_i_{i}")
param[index] = (
rf"$S_\mathrm{{i,{item}}}$ ($k_\mathrm{{B}}/\mathrm{{baryon}}$)"
)
for i, item in enumerate(ascii_lowercase[1:]):
if f"teff_evol_{i}" in param:
index = param.index(f"teff_evol_{i}")
param[index] = rf"$T_\mathrm{{eff,{item}}}$ (K)"
else:
break
for i, item in enumerate(ascii_lowercase[1:]):
if f"radius_evol_{i}" in param:
index = param.index(f"radius_evol_{i}")
param[index] = rf"$R_\mathrm{{{item}}}$ ($R_\mathrm{{J}}$)"
else:
break
for i, item in enumerate(ascii_lowercase[1:]):
if f"logg_evol_{i}" in param:
index = param.index(f"logg_evol_{i}")
param[index] = rf"$\log\,g_\mathrm{{{item}}}$"
else:
break
for i, item in enumerate(ascii_lowercase[1:]):
if f"inflate_lbol{i}" in param:
index = param.index(f"inflate_lbol{i}")
param[index] = rf"$\sigma_{{L,{{{item}}}}}$ (dex)"
else:
break
for i, item in enumerate(ascii_lowercase[1:]):
if f"inflate_mass{i}" in param:
index = param.index(f"inflate_mass{i}")
param[index] = rf"$\sigma_{{M,{{{item}}}}}$ ($M_\mathrm{{J}}$)"
else:
break
if "luminosity" in param:
index = param.index("luminosity")
if object_type == "planet":
param[index] = r"$\log\,L/L_\mathrm{\odot}$"
elif object_type == "star":
param[index] = r"$\log\,L_\ast/L_\mathrm{\odot}$"
if "luminosity_ratio" in param:
index = param.index("luminosity_ratio")
param[index] = r"$\log\,L_\mathrm{1}/L_\mathrm{2}$"
if "luminosity_disk_planet" in param:
index = param.index("luminosity_disk_planet")
if object_type == "planet":
param[index] = r"$L_\mathrm{disk}/L_\mathrm{atm}$"
elif object_type == "star":
param[index] = r"$L_\mathrm{disk}/L_\ast$"
if "log_lum" in param:
index = param.index("log_lum")
if object_type == "planet":
param[index] = r"$\log\,L/L_\mathrm{\odot}$"
elif object_type == "star":
param[index] = r"$\log\,L_\ast/L_\mathrm{\odot}$"
if "log_lum_atm" in param:
index = param.index("log_lum_atm")
if object_type == "planet":
param[index] = r"$\log\,L_\mathrm{p}/L_\mathrm{\odot}$"
elif object_type == "star":
param[index] = r"$\log\,L_\ast/L_\mathrm{\odot}$"
if "log_lum_disk" in param:
index = param.index("log_lum_disk")
param[index] = r"$\log\,L_\mathrm{disk}/L_\mathrm{\odot}$"
if "lognorm_radius" in param:
index = param.index("lognorm_radius")
param[index] = r"$\log\,r_\mathrm{g}$"
if "lognorm_sigma" in param:
index = param.index("lognorm_sigma")
param[index] = r"$\sigma_\mathrm{g}$"
if "lognorm_ext" in param:
index = param.index("lognorm_ext")
param[index] = r"$A_V$"
if "powerlaw_min" in param:
index = param.index("powerlaw_min")
param[index] = r"$\log\,a_\mathrm{min}/\mathrm{µm}$"
if "powerlaw_max" in param:
index = param.index("powerlaw_max")
param[index] = r"$\log\,a_\mathrm{max}/\mathrm{µm}$"
if "powerlaw_exp" in param:
index = param.index("powerlaw_exp")
param[index] = r"$\beta$"
if "powerlaw_ext" in param:
index = param.index("powerlaw_ext")
param[index] = r"$A_V$"
if "ism_ext" in param:
index = param.index("ism_ext")
param[index] = r"$A_V$"
if "ism_ext_0" in param:
index = param.index("ism_ext_0")
param[index] = r"$A_{V,\mathrm{1}}$"
if "ism_ext_1" in param:
index = param.index("ism_ext_1")
param[index] = r"$A_{V,\mathrm{2}}$"
if "ism_red" in param:
index = param.index("ism_red")
param[index] = r"$R_V$"
if "ext_av" in param:
index = param.index("ext_av")
param[index] = r"$A_V$"
if "ext_av_0" in param:
index = param.index("ext_av_0")
param[index] = r"$A_{V,\mathrm{1}}$"
if "ext_av_1" in param:
index = param.index("ext_av_1")
param[index] = r"$A_{V,\mathrm{2}}$"
if "ext_rv" in param:
index = param.index("ext_rv")
param[index] = r"$R_V$"
for item in param:
if item.startswith("phot_ext_"):
index = param.index(item)
filter_name = item[9:].split("/")[1]
param[index] = rf"$A_\mathrm{{{filter_name}}}$"
break
if "tint" in param:
index = param.index("tint")
param[index] = r"$T_\mathrm{int}$ (K)"
for i in range(15):
if f"t{i}" in param:
index = param.index(f"t{i}")
param[index] = rf"$T_\mathrm{{{i}}}$ (K)"
if "alpha" in param:
index = param.index("alpha")
param[index] = r"$\alpha$"
if "log_sigma_alpha" in param:
index = param.index("log_sigma_alpha")
param[index] = r"$\log\,\sigma_\alpha$"
if "log_delta" in param:
index = param.index("log_delta")
param[index] = r"$\log\,\delta$"
if "T_bottom" in param:
index = param.index("T_bottom")
param[index] = r"$T_\mathrm{bot}$ (K)"
num_layer = 6 # could make a variable in the future
for i in range(num_layer):
if f"PTslope_{num_layer - i}" in param:
index = param.index(f"PTslope_{num_layer - i}")
param[index] = rf"dlnT/dlnP$_{i}$ "
if "log_p_quench" in param:
index = param.index("log_p_quench")
param[index] = r"$\log\,P_\mathrm{quench}$"
if "sigma_lnorm" in param:
index = param.index("sigma_lnorm")
param[index] = r"$\sigma_\mathrm{g}$"
if "log_kzz" in param:
index = param.index("log_kzz")
param[index] = r"$\log\,K_\mathrm{zz}$"
if "kzz" in param:
# Backward compatibility
index = param.index("kzz")
param[index] = r"$\log\,K_\mathrm{zz}$"
if "log_co_iso" in param:
index = param.index("log_co_iso")
param[index] = r"$\log\,^{12}\mathrm{CO}/^{13}\mathrm{CO}$"
print(cloud_species)
for item in param:
if item[-9:] == "_fraction":
from petitRADTRANS.chemistry.utils import simplify_species_list
index = param.index(item)
cloud_simple = simplify_species_list([item[:-9]])[0]
param[index] = rf"$\log\,\tilde{{\mathrm{{X}}}}_\mathrm{{{cloud_simple}}}$"
if item[-4:] == "_tau":
from petitRADTRANS.chemistry.utils import simplify_species_list
index = param.index(item)
cloud_simple = simplify_species_list([item[:-4]])[0]
param[index] = rf"$\bar{{\tau}}_\mathrm{{{cloud_simple}}}$"
if item[:11] == "log_p_base_":
from petitRADTRANS.chemistry.utils import simplify_species_list
index = param.index(item)
cloud_simple = simplify_species_list([item[11:-3]])[0]
param[index] = rf"$\log\,P_\mathrm{{{cloud_simple}}}$"
if item[:5] == "fsed_":
from petitRADTRANS.chemistry.utils import simplify_species_list
index = param.index(item)
cloud_simple = simplify_species_list([item[5:-3]])[0]
param[index] = rf"fsed$_\mathrm{{{cloud_simple}}}$"
for i, item_i in enumerate(cloud_species):
for j, item_j in enumerate(cloud_species):
if f"{item_i.lower()}_{item_j.lower()}_ratio" in param:
index = param.index(f"{item_i.lower()}_{item_j.lower()}_ratio")
param[index] = (
rf"$\log\,\tilde{{\mathrm{{X}}}}"
rf"_\mathrm{{{cloud_labels[i]}}}/"
rf"\mathrm{{\tilde{{X}}}}_\mathrm{{{cloud_labels[j]}}}$"
)
for i, item in enumerate(abund_species):
if item in param:
index = param.index(item)
param[index] = rf"$\log\,\mathrm{{{abund_labels[i]}}}$"
for i, item in enumerate(param):
if item[0:8] == "scaling_":
item_name = item[8:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
if item_name.find("/") > 0:
item_name = item_name[item_name.find("/") + 1 :]
param[i] = rf"$a_\mathrm{{{item_name}}}$"
elif item[0:6] == "error_":
item_name = item[6:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
if item_name.find("/") > 0:
item_name = item_name[item_name.find("/") + 1 :]
param[i] = rf"$b_\mathrm{{{item_name}}}$"
elif item[0:10] == "log_error_":
item_name = item[10:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
if item_name.find("/") > 0:
item_name = item_name[item_name.find("/") + 1 :]
param[i] = rf"$\log\,b_\mathrm{{{item_name}}}$"
elif item[0:7] == "radvel_":
item_name = item[7:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
param[i] = rf"$v_\mathrm{{r,{item_name}}}$ (km s$^{{-1}}$)"
elif item[0:8] == "rad_vel_":
item_name = item[8:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
param[i] = rf"$v_\mathrm{{r,{item_name}}}$ (km s$^{{-1}}$)"
elif item[0:6] == "vsini_":
item_name = item[6:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
param[i] = rf"$v\,\sin\,i_\mathrm{{{item_name}}}$ (km s$^{-1}$)"
elif item[0:11] == "wavelength_":
item_name = item[11:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
param[i] = rf"$c_\mathrm{{{item_name}}}$ (nm)"
elif item[:6] == "error_":
item_name = item[6:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
if item_name.find("/") > 0:
item_name = item_name[item_name.find("/") + 1 :]
param[i] = rf"$b_\mathrm{{{item_name}}}$"
elif item[:10] == "log_error_":
item_name = item[10:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
if item_name.find("/") > 0:
item_name = item_name[item_name.find("/") + 1 :]
param[i] = rf"$\log\,b_\mathrm{{{item_name}}}$"
elif item[0:9] == "corr_len_":
item_name = item[9:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
param[i] = rf"$\log\,\ell_\mathrm{{{item_name}}}$"
elif item[0:9] == "corr_amp_":
item_name = item[9:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
param[i] = rf"$f_\mathrm{{{item_name}}}$"
elif item[0:6] == "ratio_":
item_name = item[6:]
if item_name.find("\\_") == -1 and item_name.find("_") > 0:
item_name = item_name.replace("_", "\\_")
item_name = item_name.split("/")[1]
param[i] = rf"$r_\mathrm{{{item_name}}}$"
if "c_h_ratio" in param:
index = param.index("c_h_ratio")
param[index] = r"[C/H]"
if "o_h_ratio" in param:
index = param.index("o_h_ratio")
param[index] = r"[O/H]"
for i in range(100):
if f"teff_{i}" in param:
index = param.index(f"teff_{i}")
param[index] = rf"$T_\mathrm{{eff,{i+1}}}$ (K)"
else:
break
for i in range(100):
if f"radius_{i}" in param:
index = param.index(f"radius_{i}")
if object_type == "planet":
param[index] = rf"$R_\mathrm{{{i+1}}}$ ($R_\mathrm{{J}}$)"
elif object_type == "star":
param[index] = rf"$R_\mathrm{{{i+1}}}$ ($R_\mathrm{{\odot}}$)"
else:
break
for i in range(100):
if f"luminosity_{i}" in param:
index = param.index(f"luminosity_{i}")
param[index] = rf"$\log\,L_\mathregular{{{i+1}}}/L_\mathregular{{\odot}}$"
else:
break
if "disk_teff" in param:
index = param.index("disk_teff")
param[index] = r"$T_\mathrm{disk}$ (K)"
for i in range(100):
if f"disk_teff_{i}" in param:
index = param.index(f"disk_teff_{i}")
param[index] = r"$T_\mathrm{disk,}$" + rf"$_\mathrm{{{i+1}}}$ (K)"
else:
break
if "disk_radius" in param:
index = param.index("disk_radius")
if object_type == "planet":
param[index] = r"$R_\mathrm{disk}$ ($R_\mathrm{J}$)"
elif object_type == "star":
param[index] = r"$R_\mathrm{disk}$ (au)"
for i in range(100):
if f"disk_radius_{i}" in param:
index = param.index(f"disk_radius_{i}")
if object_type == "planet":
param[index] = (
r"$R_\mathrm{disk,}$" + rf"$_{{{i+1}}}$ ($R_\mathrm{{J}}$)"
)
elif object_type == "star":
param[index] = r"$R_\mathrm{disk,}$" + rf"$_\mathrm{{{i+1}}}$ (au)"
else:
break
if "radius_bb" in param:
index = param.index("radius_bb")
if object_type == "planet":
param[index] = r"$R_\mathrm{bb}$ ($R_\mathrm{J}$)"
elif object_type == "star":
param[index] = r"$R_\mathrm{bb}$ (au)"
for i in range(100):
if f"radius_bb_{i}" in param:
index = param.index(f"radius_bb_{i}")
if object_type == "planet":
param[index] = r"$R_\mathrm{bb,}$" + rf"$_{{{i+1}}}$ ($R_\mathrm{{J}}$)"
elif object_type == "star":
param[index] = r"$R_\mathrm{bb,}$" + rf"$_\mathrm{{{i+1}}}$ (au)"
else:
break
if "log_powerlaw_a" in param:
index = param.index("log_powerlaw_a")
param[index] = r"$a_\mathrm{powerlaw}$"
if "log_powerlaw_b" in param:
index = param.index("log_powerlaw_b")
param[index] = r"$b_\mathrm{powerlaw}$"
if "log_powerlaw_c" in param:
index = param.index("log_powerlaw_c")
param[index] = r"$c_\mathrm{powerlaw}$"
if "pt_smooth" in param:
index = param.index("pt_smooth")
param[index] = r"$\sigma_\mathrm{P-T}$"
if "abund_smooth" in param:
index = param.index("abund_smooth")
param[index] = r"$\sigma_\mathrm{abund}$"
if "log_prob" in param:
index = param.index("log_prob")
param[index] = r"$\log\,\mathcal{L}$"
if "ln_prob" in param:
index = param.index("ln_prob")
param[index] = r"$\ln\,\mathcal{L}$"
if "log_tau_cloud" in param:
index = param.index("log_tau_cloud")
param[index] = r"$\log\,\tau_\mathrm{cloud}$"
if "veil_a" in param:
index = param.index("veil_a")
param[index] = r"$a_\mathrm{veil}$"
if "veil_b" in param:
index = param.index("veil_b")
param[index] = r"$b_\mathrm{veil}$"
if "veil_ref" in param:
index = param.index("veil_ref")
param[index] = r"$F_\mathrm{ref, veil}$"
if "gauss_amplitude" in param:
index = param.index("gauss_amplitude")
param[index] = r"$a$ (W m$^{-2}$ µm$^{-1}$)"
if "gauss_mean" in param:
index = param.index("gauss_mean")
param[index] = r"$\lambda$ (nm)"
if "gauss_sigma" in param:
index = param.index("gauss_sigma")
param[index] = r"$\sigma$ (nm)"
if "gauss_amplitude_2" in param:
index = param.index("gauss_amplitude_2")
param[index] = r"$a_2$ (W m$^{-2}$ µm$^{-1}$)"
if "gauss_mean_2" in param:
index = param.index("gauss_mean_2")
param[index] = r"$\lambda_2$ (nm)"
if "gauss_sigma_2" in param:
index = param.index("gauss_sigma_2")
param[index] = r"$\sigma_2$ (nm)"
if "gauss_fwhm" in param:
index = param.index("gauss_fwhm")
param[index] = r"FWHM (km s$^{-1}$)"
if "line_flux" in param:
index = param.index("line_flux")
param[index] = r"$F_\mathrm{line}$ (W m$^{-2}$)"
if "line_luminosity" in param:
index = param.index("line_luminosity")
param[index] = r"$L_\mathrm{line}$ ($L_\mathrm{\odot}$)"
if "log_line_lum" in param:
index = param.index("log_line_lum")
param[index] = r"$\log\,L_\mathrm{line}/L_\mathrm{\odot}$"
if "log_acc_lum" in param:
index = param.index("log_acc_lum")
param[index] = r"$\log\,L_\mathrm{acc}/L_\mathrm{\odot}$"
if "line_eq_width" in param:
index = param.index("line_eq_width")
param[index] = r"EW ($\mathrm{\AA}$)"
if "line_vrad" in param:
index = param.index("line_vrad")
param[index] = r"$v_\mathrm{r}$ (km s$^{-1}$)"
if "log_kappa_0" in param:
index = param.index("log_kappa_0")
param[index] = r"$\log\,\kappa_0$"
if "log_kappa_abs" in param:
index = param.index("log_kappa_abs")
param[index] = r"$\log\,\kappa_\mathrm{abs}$"
if "log_kappa_sca" in param:
index = param.index("log_kappa_sca")
param[index] = r"$\log\,\kappa_\mathrm{sca}$"
if "opa_index" in param:
index = param.index("opa_index")
param[index] = r"$\xi$"
if "opa_abs_index" in param:
index = param.index("opa_abs_index")
param[index] = r"$\xi_\mathrm{abs}$"
if "opa_sca_index" in param:
index = param.index("opa_sca_index")
param[index] = r"$\xi_\mathrm{sca}$"
if "log_p_base" in param:
index = param.index("log_p_base")
param[index] = r"$\log\,P_\mathrm{cloud}$"
if "albedo" in param:
index = param.index("albedo")
param[index] = r"$\omega$"
if "opa_knee" in param:
index = param.index("opa_knee")
param[index] = r"$\lambda_\mathrm{R}$ (µm)"
if "lambda_ray" in param:
index = param.index("lambda_ray")
param[index] = r"$\lambda_\mathrm{R}$ (µm)"
if "mix_length" in param:
index = param.index("mix_length")
param[index] = r"$\ell_\mathrm{m}$ ($H_\mathrm{p}$)"
if "spec_weight" in param:
index = param.index("spec_weight")
param[index] = r"w$_\mathrm{spec}$"
if "log_beta_r" in param:
index = param.index("log_beta_r")
param[index] = r"$\log\,\beta_\mathrm{r}$"
if "log_gamma_r" in param:
index = param.index("log_gamma_r")
param[index] = r"$\log\,\gamma_\mathrm{r}$"
if "gamma_r" in param:
index = param.index("gamma_r")
param[index] = r"$\gamma_\mathrm{r}$"
if "log_kappa_gray" in param:
index = param.index("log_kappa_gray")
param[index] = r"$\log\,\kappa_\mathrm{gray}$"
if "log_cloud_top" in param:
index = param.index("log_cloud_top")
param[index] = r"$\log\,P_\mathrm{top}$"
if "flux_scaling" in param:
index = param.index("flux_scaling")
param[index] = r"$a_\mathrm{flux}$"
if "log_flux_scaling" in param:
index = param.index("log_flux_scaling")
param[index] = r"$\log\,a_\mathrm{flux}$"
if "flux_offset" in param:
index = param.index("flux_offset")
param[index] = r"$b_\mathrm{flux}$ (W m$^{-2}$ µm$^{-1}$)"
return param
[docs]
@beartype
def quantity_unit(
param: List[str], object_type: str
) -> Tuple[List[str], List[Optional[str]], List[str]]:
"""
Function for creating lists with quantities, units,
and labels for the fitted parameter.
Parameters
----------
param : list
List with parameter names.
object_type : str
Object type (``'planet'`` or ``'star'``).
Returns
-------
list
List with the quantities.
list
List with the units.
list
List with the parameter labels for plots.
"""
quantity = []
unit = []
label = []
for item in param:
item_split = item.split("_")
if item == "teff":
quantity.append("teff")
unit.append("K")
label.append(r"$T_\mathrm{eff}$")
elif item == "logg":
quantity.append("logg")
unit.append(None)
label.append(r"$\log g$")
elif item == "metallicity":
quantity.append("metallicity")
unit.append(None)
label.append("[Fe/H]")
elif item == "feh":
quantity.append("feh")
unit.append(None)
label.append("[Fe/H]")
elif item == "fsed":
quantity.append("fsed")
unit.append(None)
label.append(r"$f_\mathrm{sed}$")
elif item == "c_o_ratio":
quantity.append("c_o_ratio")
unit.append(None)
label.append("C/O")
elif item == "log_kzz":
quantity.append("log_kzz")
unit.append(None)
label.append(r"$\log\,K_\mathrm{zz}$")
elif item == "ad_index":
quantity.append("ad_index")
unit.append(None)
label.append(r"$\gamma_\mathrm{ad}$")
elif item == "log_co_iso":
quantity.append("log_co_iso")
unit.append(None)
label.append(r"$\log\,^{12}\mathrm{CO}/^{13}\mathrm{CO}$")
elif item == "radius":
quantity.append("radius")
if object_type == "planet":
unit.append(r"$R_\mathrm{J}$")
label.append(r"$R_\mathrm{p}$")
elif object_type == "star":
unit.append(r"$R_\mathrm{\odot}$")
label.append(r"$R_\ast$")
elif len(item_split) > 1 and item_split[-1].isdigit():
param_index = int(item_split[-1])
if item_split[0] == "teff":
quantity.append(f"teff_{param_index}")
unit.append("K")
label.append(rf"$T_\mathrm{{eff,{param_index+1}}}$")
elif item_split[0] == "logg":
quantity.append(f"logg_{param_index}")
unit.append(None)
label.append(rf"$\log g_\mathrm{{{param_index+1}}}$")
elif item_split[0] == "feh":
quantity.append(f"feh_{param_index}")
unit.append(None)
label.append(rf"[Fe/H]$_\mathrm{{{param_index+1}}}$")
elif item_split[0] == "fsed":
quantity.append(f"fsed_{param_index}")
unit.append(None)
label.append(rf"$f_\mathrm{{sed,{param_index+1}}}$")
elif item_split[0] == "radius":
quantity.append(f"radius_{param_index}")
if object_type == "planet":
unit.append(r"$R_\mathrm{J}$")
elif object_type == "star":
unit.append(r"$R_\mathrm{\odot}$")
label.append(rf"$R_\mathrm{{{param_index+1}}}$")
elif item[:7] == "ism_ext":
quantity.append(f"ism_ext_{param_index}")
unit.append(None)
label.append(r"$A_{V,}$" + rf"$_\mathrm{{{param_index+1}}}$")
elif item[:6] == "ext_av":
quantity.append(f"ext_av_{param_index}")
unit.append(None)
label.append(r"$A_{V,}$" + rf"$_\mathrm{{{param_index+1}}}$")
elif item_split[0] == "disk" and item_split[1] == "teff":
quantity.append(f"disk_teff_{param_index}")
unit.append("K")
label.append(r"$T_\mathrm{disk,}$" + rf"$_\mathrm{{{param_index+1}}}$")
elif item_split[0] == "disk" and item_split[1] == "radius":
quantity.append(f"disk_radius_{param_index}")
if object_type == "planet":
unit.append(r"$R_\mathrm{J}$")
elif object_type == "star":
unit.append("au")
label.append(r"$R_\mathrm{disk,}$" + rf"$_\mathrm{{{param_index+1}}}$")
elif item == "distance":
quantity.append("distance")
unit.append("pc")
label.append(r"$d$")
elif item == "parallax":
quantity.append("parallax")
unit.append("mas")
label.append(r"$\varpi$")
elif item == "mass":
quantity.append("mass")
if object_type == "planet":
unit.append(r"$M_\mathrm{J}$")
label.append(r"$M$")
elif object_type == "star":
unit.append(r"$M_\mathrm{\odot}$")
label.append(r"$M_\ast$")
elif item == "luminosity":
quantity.append("luminosity")
if object_type == "planet":
unit.append(None)
label.append(r"$\log\,L_\mathrm{p}/L_\mathrm{\odot}$")
elif object_type == "star":
unit.append(None)
label.append(r"$\log\,L_\ast/L_\mathrm{\odot}$")
elif item == "log_lum":
quantity.append("log_lum")
if object_type == "planet":
unit.append(None)
label.append(r"$\log\,L/L_\mathrm{\odot}$")
elif object_type == "star":
unit.append(None)
label.append(r"$\log\,L/L_\mathrm{\odot}$")
elif item == "log_lum_atm":
quantity.append("log_lum_atm")
if object_type == "planet":
unit.append(None)
label.append(r"$\log\,L_\mathrm{p}/L_\mathrm{\odot}$")
elif object_type == "star":
unit.append(None)
label.append(r"$\log\,L_\ast/L_\mathrm{\odot}$")
elif item == "log_lum_disk":
quantity.append("log_lum_disk")
unit.append(None)
label.append(r"$\log\,L_\mathrm{disk}/L_\mathrm{\odot}$")
elif item == "ism_ext":
quantity.append("ism_ext")
unit.append(None)
label.append(r"$A_V$")
elif item == "ext_av":
quantity.append("ext_av")
unit.append(None)
label.append(r"$A_V$")
elif item == "lognorm_ext":
quantity.append("lognorm_ext")
unit.append(None)
label.append(r"$A_V$")
elif item == "powerlaw_ext":
quantity.append("powerlaw_ext")
unit.append(None)
label.append(r"$A_V$")
elif item.startswith("phot_ext_"):
quantity.append(item)
unit.append(None)
filter_name = item[9:].split("/")[1]
label.append(rf"$A_\mathrm{{{filter_name}}}$")
elif item == "pt_smooth":
quantity.append("pt_smooth")
unit.append(None)
label.append(r"$\sigma_\mathrm{P-T}$")
elif item == "abund_smooth":
quantity.append("abund_smooth")
unit.append(None)
label.append(r"$\sigma_\mathrm{abund}$")
elif item == "disk_teff":
quantity.append("disk_teff")
unit.append("K")
label.append(r"$T_\mathrm{disk}$")
elif item == "disk_radius":
quantity.append("disk_radius")
if object_type == "planet":
unit.append(r"$R_\mathrm{J}$")
elif object_type == "star":
unit.append("au")
label.append(r"$R_\mathrm{disk}$")
elif item == "flux_scaling":
quantity.append("flux_scaling")
unit.append(None)
label.append(r"$a_\mathrm{flux}$")
elif item == "log_flux_scaling":
quantity.append("log_flux_scaling")
unit.append(None)
label.append(r"$\log\,a_\mathrm{flux}$")
elif item == "flux_offset":
quantity.append("flux_offset")
unit.append(r"W m$^{-2}$ µm$^{-1}$")
label.append(r"$b_\mathrm{flux}$")
elif item == "rad_vel":
quantity.append("rad_vel")
unit.append(r"km s$^{-1}$")
label.append(r"$v_\mathrm{r}$")
elif item == "vsini":
quantity.append("vsini")
unit.append(r"km s$^{-1}$")
label.append(r"$v\,\sin\,i$")
return quantity, unit, label
[docs]
@beartype
def field_bounds_ticks(
field_range: Tuple[str, str],
check_subclass: bool,
) -> Tuple[np.ndarray, np.ndarray, List[str]]:
"""
Function for converting the specified field range into boundaries
and labels for the discrete colorbar that is plotted with a
color-magnitude or color-color diagram.
Parameters
----------
field_range : tuple(str, str)
Range of the discrete colorbar for the field objects. The tuple
should contain the lower and upper value ('early M', 'late M',
'early L', 'late L', 'early T', 'late T', 'early Y). Also
stellar spectral types can be specified.
check_subclass : bool
Set to ``True`` if the discrete colorbar should distinguish
early and late spectral types with different colors or set
to ``False`` if subclasses should not be distinguished.
Returns
-------
np.ndarray
Array with the boundaries for the discrete colorbar.
np.ndarray
Array with the midpoints for the discrete colorbar.
list(str)
List with the tick labels for the discrete colorbar.
"""
if check_subclass:
spectral_ranges = [
"O0-O4",
"O5-O9",
"B0-B4",
"B5-B9",
"A0-A4",
"A5-A9",
"F0-F4",
"F5-F9",
"G0-G4",
"G5-G9",
"K0-K4",
"K5-K9",
"M0-M4",
"M5-M9",
"L0-L4",
"L5-L9",
"T0-T4",
"T5-T9",
"Y1-Y2",
]
if field_range[0] == "early O":
index_start = 0
elif field_range[0] == "late O":
index_start = 1
elif field_range[0] == "early B":
index_start = 2
elif field_range[0] == "late B":
index_start = 3
elif field_range[0] == "early A":
index_start = 4
elif field_range[0] == "late A":
index_start = 5
elif field_range[0] == "early F":
index_start = 6
elif field_range[0] == "late F":
index_start = 7
elif field_range[0] == "early G":
index_start = 8
elif field_range[0] == "late G":
index_start = 9
elif field_range[0] == "early K":
index_start = 10
elif field_range[0] == "late K":
index_start = 11
elif field_range[0] == "early M":
index_start = 12
elif field_range[0] == "late M":
index_start = 13
elif field_range[0] == "early L":
index_start = 14
elif field_range[0] == "late L":
index_start = 15
elif field_range[0] == "early T":
index_start = 16
elif field_range[0] == "late T":
index_start = 17
elif field_range[0] == "early Y":
index_start = 18
if field_range[1] == "early O":
index_end = 1
elif field_range[1] == "late O":
index_end = 2
elif field_range[1] == "early B":
index_end = 3
elif field_range[1] == "late B":
index_end = 4
elif field_range[1] == "early A":
index_end = 5
elif field_range[1] == "late A":
index_end = 6
elif field_range[1] == "early F":
index_end = 7
elif field_range[1] == "late F":
index_end = 8
elif field_range[1] == "early G":
index_end = 9
elif field_range[1] == "late G":
index_end = 10
elif field_range[1] == "early K":
index_end = 11
elif field_range[1] == "late K":
index_end = 12
elif field_range[1] == "early M":
index_end = 13
elif field_range[1] == "late M":
index_end = 14
elif field_range[1] == "early L":
index_end = 15
elif field_range[1] == "late L":
index_end = 16
elif field_range[1] == "early T":
index_end = 17
elif field_range[1] == "late T":
index_end = 18
elif field_range[1] == "early Y":
index_end = 19
else:
spectral_ranges = ["O", "B", "A", "F", "G", "K", "M", "L", "T", "Y"]
if field_range[0] == "O":
index_start = 0
elif field_range[0] == "B":
index_start = 1
elif field_range[0] == "A":
index_start = 2
elif field_range[0] == "F":
index_start = 3
elif field_range[0] == "G":
index_start = 4
elif field_range[0] == "K":
index_start = 5
elif field_range[0] == "M":
index_start = 6
elif field_range[0] == "L":
index_start = 7
elif field_range[0] == "T":
index_start = 8
elif field_range[0] == "Y":
index_start = 9
if field_range[1] == "O":
index_end = 1
elif field_range[1] == "B":
index_end = 2
elif field_range[1] == "A":
index_end = 3
elif field_range[1] == "F":
index_end = 4
elif field_range[1] == "G":
index_end = 5
elif field_range[1] == "K":
index_end = 6
elif field_range[1] == "M":
index_end = 7
elif field_range[1] == "L":
index_end = 8
elif field_range[1] == "T":
index_end = 9
elif field_range[1] == "Y":
index_end = 10
index_range = index_end - index_start + 1
bounds = np.linspace(index_start, index_end, index_range)
ticks = np.linspace(index_start + 0.5, index_end - 0.5, index_range - 1)
labels = spectral_ranges[index_start:index_end]
ticks -= bounds[0]
bounds -= bounds[0]
return bounds, ticks, labels
[docs]
@beartype
def remove_color_duplicates(
object_names: List[str], empirical_names: np.ndarray
) -> List[int]:
""" "
Function for deselecting young/low-gravity objects that will
already be plotted individually as directly imaged objects.
Parameters
----------
object_names : list(str)
List with names of directly imaged planets and brown dwarfs.
empirical_names : np.ndarray
Array with names of young/low-gravity objects.
Returns
-------
list
List with selected indices of the young/low-gravity objects.
"""
indices = []
for i, item in enumerate(empirical_names):
if item == "beta_Pic_b" and "beta Pic b" in object_names:
continue
if item == "HR8799b" and "HR 8799 b" in object_names:
continue
if item == "HR8799c" and "HR 8799 c" in object_names:
continue
if item == "HR8799d" and "HR 8799 d" in object_names:
continue
if item == "HR8799e" and "HR 8799 e" in object_names:
continue
if item == "kappa_And_B" and "kappa And b" in object_names:
continue
if item == "HD1160B" and "HD 1160 B" in object_names:
continue
indices.append(i)
return indices
[docs]
@beartype
def create_model_label(
model_param: Dict[str, float],
object_type: str,
model_name: str,
inc_model_name: bool,
leg_param: List[str],
param_fmt: Dict[str, str],
) -> str:
""" "
Function for creating a label that includes the parameters of a
model spectrum. The label is used in the legend of a SED plot.
Parameters
----------
model_param : dict
Dictionary with model parameters.
model_name : str
Name of the atmospheric model.
inc_model_name : bool
Include the model name in the label.
object_type : str
Object type ('planet' or 'star') that determines if
Jupiter or solar units are used.
leg_param : list(str)
List with the parameters to include. Apart from atmospheric
parameters (e.g. 'teff', 'logg', 'radius') also parameters
such as 'mass' and 'luminosity' can be included. The default
atmospheric parameters are included in the legend if the
argument is an empty list.
param_fmt : dict(str, str)
Dictionary with formats that will be used for the model
parameter. The parameters are included in the ``legend``
when plotting the model spectra. Default formats are
used if the argument of ``param_fmt`` is set to ``None``.
Returns
-------
str
Text label that includes the selected parameter names,
the model values, and the parameter units.
"""
# data_file = Path(__file__).parents[1].resolve() / "data/model_data/model_data.json"
# with open(data_file, "r", encoding="utf-8") as json_file:
# model_data = json.load(json_file)
# model_list = list(model_data.keys())
# Do not include these parameters by default in the legend
not_default = ["distance", "parallax", "mass", "luminosity"]
# Do not include log_lum because log_lum_atm is already include
# except when the model spectrum is a blackbody from ReadPlanck
if model_name != "planck":
not_default.append("log_lum")
# Use the model parameters if leg_param is empty
if len(leg_param) == 0:
leg_param = list(model_param.keys())
for param_item in not_default:
if param_item in leg_param:
# Do not include the not_default parameters
leg_param.remove(param_item)
# Remove parameters from the model_param dictionary
# if they are not included in the leg_param list
del_keys = []
for param_item in model_param.keys():
if param_item not in leg_param:
del_keys.append(param_item)
for param_item in del_keys:
del model_param[param_item]
# Get parameters keys, units, and labels
par_key, par_unit, par_label = quantity_unit(
param=list(model_param.keys()), object_type=object_type
)
# Initiate an empty label that will be returned
label = ""
# newline = False
# Optionally include the model name into the label
if model_name is not None and inc_model_name:
label += convert_model_name(model_name)
if len(par_key) > 0:
label += ": "
for param_item in leg_param:
if param_item in par_key:
param_idx = par_key.index(param_item)
else:
continue
if param_item[:4] == "teff":
value = f"{model_param[param_item]:{param_fmt['teff']}}"
elif param_item[:9] == "disk_teff":
value = f"{model_param[param_item]:{param_fmt['disk_teff']}}"
elif param_item[:4] == "logg":
value = f"{model_param[param_item]:{param_fmt['logg']}}"
elif param_item[:3] == "feh":
value = f"{model_param[param_item]:{param_fmt['feh']}}"
elif param_item[:4] == "fsed":
value = f"{model_param[param_item]:{param_fmt['fsed']}}"
elif param_item[:7] == "ism_ext":
value = f"{model_param[param_item]:{param_fmt['ism_ext']}}"
elif param_item[:6] == "ext_av":
value = f"{model_param[param_item]:{param_fmt['ext_av']}}"
elif param_item[:6] == "radius":
if object_type == "planet":
value = f"{model_param[param_item]:{param_fmt['radius']}}"
elif object_type == "star":
value = f"{model_param[param_item]*constants.R_JUP/constants.R_SUN:{param_fmt['radius']}}"
elif param_item[:11] == "disk_radius":
if object_type == "planet":
value = f"{model_param[param_item]:{param_fmt['disk_radius']}}"
elif object_type == "star":
radius_au = model_param[param_item] * constants.R_JUP / constants.AU
value = f"{radius_au:{param_fmt['disk_radius']}}"
elif param_item == "mass":
if object_type == "planet":
value = f"{model_param[param_item]:{param_fmt['mass']}}"
elif object_type == "star":
value = f"{model_param[param_item]*constants.M_JUP/constants.M_SUN:{param_fmt['mass']}}"
elif param_item == "luminosity":
value = f"{np.log10(model_param[param_item]):{param_fmt['luminosity']}}"
elif param_item == "log_lum":
value = f"{model_param[param_item]:{param_fmt['log_lum']}}"
elif param_item == "log_lum_atm":
value = f"{model_param[param_item]:{param_fmt['log_lum_atm']}}"
elif param_item == "log_lum_disk":
value = f"{model_param[param_item]:{param_fmt['log_lum_disk']}}"
elif param_item in param_fmt:
value = f"{model_param[param_item]:{param_fmt[param_item]}}"
elif param_item not in param_fmt:
warnings.warn(
f"The '{param_item}' parameter is not "
"found in the dictionary of 'param_fmt'."
)
value = f"{model_param[param_item]:.2f}"
else:
continue
# if len(label) > 80 and newline == False:
# label += '\n'
# newline = True
if par_unit[param_idx] is None:
if len(label) > 0 and label[-2] != ":":
label += ", "
label += f"{par_label[param_idx]} = {value}"
else:
if len(label) > 0 and label[-2] != ":":
label += ", "
label += f"{par_label[param_idx]} = {value} {par_unit[param_idx]}"
return label