exocomp module

Created on Fri Jun 6 14:04:20 2025

@author: jlothringer

class exocomp.Abund(bulk_abunds=None, species_abunds=None, bulk_errs=None, species_errs=None, species_type='VMR', solar='Asplund09', retrieval=None, save_plots=False, plotname='exocomp')[source]

Bases: object

Top-level class for abundance calculations.

Parameters:
  • species_abunds (dict) – (Optional) Input/output for bulk_abundance calculations. Of form {species:VMR} (e.g., {‘H2O’:1e-3})

  • species_errs (dict) – (Optional) Input/output for bulk_abundance calculations. Of form {species:VMR_err} for symmetric errors (e.g., {‘H2O’:1e-4}), {species:[VMR_low,VMR_high]} for asymetric error bars, or {species:[VMR_0,VMR_1,…]} for posteriors.

  • solar (str) – (Optional) Which set of solar abundances to use. Default is Lodders25. Possible options listed in self.possible_solars.

  • retrieval (str) – (Optional) Which retrieval code was used to produce metallicity and C/O constraints. This is used to choose the correct conversion calculation. Defines self.mh_type, self.co_type, and self.solar. Not all retrieval codes are included and you may need a different set up, so you can just define self.mh_type, self.co_type, and self.solar yourself.

Returns:

  • bulk_abunds (dict) – Where output of fits to species abundances or conversion to different solar compositions is placed. Will be of the format {‘O’:8.0} for an O/H ratio of 1e8 parts per trillion (i.e., H = 1e12).

  • bulk_errs (dict) – (Optional) Where output of fits to species abundances or conversion to different solar compositions is placed. Of form {species:bulk_errs} for symmetric errors (e.g., {‘O/H’:0.5}), {species:[abund_low,abund_high]} for asymetric error bars, or {species:[abund_0,abund_1,…]} for posteriors.

possible_solars
Type:

list possible solar compositions

define_stellar[source]
Type:

define host star composition to use instead of solar

VMR_to_MMR[source]
Type:

convert a dict of volume mixing ratios to mass fraction

MMR_to_VMR[source]
Type:

convert a dict of mass fractions to volume mixing ratios

convert_bulk_abundance[source]
Type:

given bulk abundance properties, calculate elemental abundances

convert_solar[source]
Type:

convert self.bulk_abundances to another definition of solar

convert_species_abunds[source]
Type:

given species abundances, calculate bulk abundances

count_metallicity[source]
Type:

add up species abundances to infer bulk abundances

predict_abund[source]
Type:

given bulk abundance properties, calculate species abundances

init_ec[source]
Type:

utility function to initialize easyCHEM with proper solar abundances

import_masses[source]

(e.g., conversion between VMR and MMR)

Type:

read in molecular masses for MMW calculation

species_type : VMR or MMR solar_abundances : elemental abundances for given self.solar solar_abundances_orig : solar abundances first defined in class definition possible_solars : list of possible solar compositions best_fit_mh : best-fit metallicity from convert_species_abunds best_fit_co : best-fit C/O from convert_species_abunds best_fit_refvol : best-fit ref/vol from convert_species_abunds best_fit_abund : best-fit species abundances from convert_species_abunds Asplund09 : elemental abundance definitions from Asplund, M., et al. (2009). ARA&A, 47, 481 Asplund21 : elemental abundance definitions from Asplund, M., et al. (2021). A&A, 653, A141 Asplund05 : elemental abundance definitions from Asplund, M., et al. (2005). Lodders10 : elemental abundance definitions from Lodders, K. (2010). Astro and Space Sci. Pro. Lodders20 : elemental abundance definitions from Lodders, K. (2020). Space Sci. Rev., 216, 44 Lodders25 : elemental abundance definitions from Lodders, K. et al. (2025). Space Sci. Rev., 221, 2 Caffau11 : elemental abundance definitions from Caffau, E. (2011). Solar Physics, 268, 2

Examples

Setting up for a bulk abundance calculation with symmetric errors g = Abund(species_abunds={‘H2O’:-2.96,’CH4’:-9.05,’CO2’:-5.81,’K’:-8.07,’Na’:-9.31},

species_errs={‘H2O’:0.31,’CH4’:2.1,’CO2’:1.31,’K’:0.58,’Na’:1.77})

Setting up for a bulk abundance calculation with posteriors g = Abund(species_abunds={‘H2O’:-2.96,’CH4’:-9.05,’CO2’:-5.81,’K’:-8.07,’Na’:-9.31},

species_errs={‘H2O’:np.random.normal(-2.96,0.31,100),’CH4’:np.random.normal(-9.05,2.1,100),

‘CO2’:np.random.normal(-5.81,1.31,100), ‘K’:np.random.normal(-8.07,0.58,100),’Na’:np.random.normal(-9.31,1.77,100)})

__init__(bulk_abunds=None, species_abunds=None, bulk_errs=None, species_errs=None, species_type='VMR', solar='Asplund09', retrieval=None, save_plots=False, plotname='exocomp')[source]
define_stellar(abund_dict)[source]
VMR_to_MMR(vmr_dict, mmw=2.3, replace_abunds=False)[source]
MMR_to_VMR(mmr_dict, mmw=2.3, replace_abunds=False)[source]
count_metallicity(rv=False)[source]
convert_bulk_abundance(mh, co, rv=0.0, mh_err=0.0, co_err=0.0, rv_err=0.0, solar=None)[source]

Convert bulk abundance parameters to elemental abundances with error propagation.

This method transforms fundamental stellar/planetary parameters (metallicity, C/O ratio, and refractory enhancement) into individual elemental abundances relative to hydrogen. It supports both symmetric/asymmetric error propagation and posterior sampling for uncertainty quantification.

Parameters:
  • mh (float or array-like) – Metallicity [M/H] in dex. Can be a single value or array for posterior sampling.

  • co (float or array-like) –

    Carbon-to-oxygen ratio. Interpretation depends on co_type attribute:

    • ’O/H’: C/O ratio, oxygen abundance adjusted

    • ’C/H’: C/O ratio, carbon abundance adjusted

    • ’MH_Preserve’: C/O ratio, preserves total C+O abundance

  • rv (float or array-like, optional) – Refractory enhancement factor in dex for elements heavier than oxygen. Default is 0.0 (no enhancement).

  • mh_err (float, list, or array-like, optional) –

    Uncertainty in metallicity. Can be:

    • Single float: symmetric error

    • 2-element list: [lower, upper] asymmetric errors

    • Array: posterior samples

    Default is 0.0.

  • co_err (float, list, or array-like, optional) – Uncertainty in C/O ratio, same format as mh_err. Default is 0.0.

  • rv_err (float, list, or array-like, optional) – Uncertainty in refractory enhancement, same format as mh_err. Default is 0.0.

  • solar (str, optional) – Solar abundance reference to use. If provided, overrides current solar abundance. Supported values: ‘Lodders25’, ‘Asplund09’, ‘Asplund05’, ‘Asplund21’, ‘Lodders20’, ‘Lodders10’, ‘Caffau11’. Default uses current self.solar.

Returns:

  • bulk_dict (dict) – Dictionary of elemental abundances in the format log10(X/H) + 12, where keys are element symbols and values are abundances.

  • err_dict (dict) – Dictionary of abundance uncertainties with same keys as bulk_dict.

    • For symmetric/asymmetric errors: contains propagated uncertainties

    • For posterior sampling: contains arrays of posterior abundance samples

Notes

The method requires the following class attributes to be set:

  • mh_type: Metallicity parameterization type

  • co_type: C/O ratio treatment (‘O/H’, ‘C/H’, or ‘MH_Preserve’)

  • solar: Solar abundance reference (if solar parameter not provided)

The method automatically detects whether inputs represent:

  1. Single values with errors: Standard error propagation using Gaussian approximation

  2. Posterior samples: Full posterior propagation through the abundance calculation

For elements heavier than oxygen (Z > 8), the refractory enhancement rv is applied as an additional multiplicative factor in dex space.

Examples

>>> # Single value with symmetric errors
>>> bulk_dict, err_dict = obj.convert_bulk_abundance(
...     mh=0.1, co=0.55, rv=0.2, mh_err=0.05, co_err=0.03, rv_err=0.1
... )
>>> # Asymmetric errors
>>> bulk_dict, err_dict = obj.convert_bulk_abundance(
...     mh=0.1, co=0.55, mh_err=[-0.03, 0.07], co_err=[-0.02, 0.04]
... )
>>> # Posterior sampling
>>> import numpy as np
>>> mh_samples = np.random.normal(0.1, 0.05, 1000)
>>> co_samples = np.random.normal(0.55, 0.03, 1000)
>>> bulk_dict, err_dict = obj.convert_bulk_abundance(
...     mh=0.1, co=0.55, mh_err=mh_samples, co_err=co_samples
... )

See also

init_ec

Initialize elemental composition object

References

Solar abundance compilations used depend on the solar parameter choice.

convert_solar(convert_to)[source]

Convert existing bulk abundances to a different solar abundance reference.

This method transforms previously calculated elemental abundances from one solar abundance scale to another while preserving the relative abundances. The conversion accounts for differences between solar abundance compilations by applying appropriate offset corrections to maintain consistency in the abundance ratios.

Parameters:

convert_to (str) –

Target solar abundance reference scale. Supported values:

  • ’Lodders25’: Lodders (2025) solar photospheric abundances

  • ’Asplund09’: Asplund et al. (2009) solar photospheric abundances

  • ’Asplund21’: Asplund et al. (2021) solar photospheric abundances

  • ’Lodders20’: Lodders (2020) solar photospheric abundances

  • ’Lodders10’: Lodders (2010) solar photospheric abundances

Returns:

Method modifies class attributes (self.bulk_abunds and sel.fsolar_abundances) in-place and prints status messages.

Return type:

None

Notes

This method modifies the following class attributes:

  • solar_abundances: Updated to the new solar abundance reference

  • bulk_abunds: Element abundances converted to the new solar scale

  • solar_abundances_orig: Changes at the end

The conversion preserves the physical meaning of abundance ratios by applying the transformation:

\[[X/H]_{new} = [X/H]_{old} - ([X/H]_{solar,new} - [X/H]_{solar,old})\]

where the solar abundance difference accounts for systematic offsets between different solar abundance compilations.

Behavior when no bulk abundances exist:

If bulk_abunds is None (no previous abundance calculation), the method only updates the solar abundance reference without performing any conversions.

Workflow Integration:

This method is typically used after convert_bulk_abundance() when you want to compare results using different solar abundance scales or when literature values use a different solar reference than your initial calculation.

Examples

>>> # After calculating abundances with one solar reference
>>> obj.convert_bulk_abundance(mh=0.1, co=0.55, solar='Asplund09')
>>>
>>> # Convert to a different solar abundance scale
>>> obj.convert_solar('Lodders25')
Changed solar abunds to Lodders25
>>> # If no bulk abundances calculated yet
>>> obj.convert_solar('Asplund21')
Changed solar abunds to Asplund21
No bulk abundances to convert...
>>> # Invalid solar reference
>>> obj.convert_solar('InvalidRef')
Input solar not recognized

See also

convert_bulk_abundance

Calculate initial elemental abundances

References

Solar abundance scales and their systematic differences are discussed in:

  • Asplund, M., et al. (2009). ARA&A, 47, 481

  • Asplund, M., et al. (2021). A&A, 653, A141

  • Lodders, K. (2010). Astrophys. Space Sci., 334, 1

  • Lodders, K. (2020). Space Sci. Rev., 216, 44

solar_ratio_calc()[source]
init_ec()[source]

Function to initialize easyCHEM with the elemental abundances from the present definition of solar.

Returns:

exo – easyCHEM object

Return type:

obj

predict_abund(mh, co, T, P, species=['H2O', 'CO', 'CO2'], verbose=True, mode='VMR', adjust_C=True)[source]

Predict molecular abundances from bulk parameters and atmospheric conditions.

Calculates equilibrium molecular abundances for specified species given metallicity, C/O ratio, temperature, and pressure. Uses the definition of solar in self.solar!

Parameters:
  • mh (float) – Metallicity [M/H] in dex.

  • co (float) – Carbon-to-oxygen ratio.

  • T (float) – Temperature in Kelvin.

  • P (float) – Pressure in bar.

  • species (list of str, optional) – Molecular species to calculate. Default is [‘H2O’,’CO’,’CO2’].

  • verbose (bool, optional) – Print abundances to console. Default is True.

  • mode ({'VMR', 'MMR'}, optional) – Return volume mixing ratios (‘VMR’) or mass mixing ratios (‘MMR’). Default is ‘VMR’.

  • adjust_C (bool, optional) – If True, adjust carbon abundance to match C/O ratio. If False, adjust oxygen abundance. Default is True.

Returns:

Dictionary with species names as keys and log10 abundances as values.

Return type:

dict

Examples

>>> # Predict H2O, CO, CO2 abundances
>>> abunds = obj.predict_abund(mh=0.0, co=0.55, T=1500, P=1.0)
H2O: -3.2
CO: -3.8
CO2: -7.1
>>> # Custom species list, silent mode
>>> abunds = obj.predict_abund(mh=0.5, co=0.8, T=2000, P=10.0,
...                          species=['CH4', 'NH3'], verbose=False)
convert_species_abunds(T, P, adjust_C=True, plot_it=True, posterior_samples=100, fit_refvol=False)[source]

Fit bulk atmospheric parameters to observed molecular abundances.

Performs inverse retrieval to determine metallicity [M/H], C/O ratio, and optionally refractory enhancement from observed molecular species abundances using thermochemical equilibrium modeling. Supports both error propagation and full posterior sampling.

IMPORTANT: This assumes chemical equilibrium, of course! Results can be very sensitive to the assumed T and P. And atmospheres are not necessarily in equilibrium. Interpret these results with care.

Parameters:
  • T (float) – Atmospheric temperature in Kelvin for which the species abundances are representative.

  • P (float) – Atmospheric pressure in bar for which the species abundances are representative.

  • adjust_C (bool, optional) – Carbon adjustment method for C/O ratio. If True, adjust carbon abundance; if False, adjust oxygen abundance. If string ‘Neither’ conserve [M/H]. Default is True.

  • plot_it (bool, optional) – Generate diagnostic plots showing fit results and parameter distributions. Default is True.

  • posterior_samples (int, optional) – Number of posterior samples to use when species_errs contains posteriors. Default is 100.

  • fit_refvol (bool, optional) – Include refractory enhancement (R/V) as a free parameter in the fit. Default is False.

Returns:

  • popt (list) – Best-fit parameters [M/H, C/O] or [M/H, C/O, R/V] if fit_refvol=True.

  • pcov (array-like or list) – Parameter covariance matrix (for error-based fitting) or list of posterior samples (for posterior-based fitting).

  • best_fit (array) – Model predictions for molecular abundances at best-fit parameters.

Notes

This method requires the following class attributes to be set:

  • species_abunds: Dictionary of observed molecular abundances

  • species_errs: Uncertainties (symmetric, asymmetric, or posteriors)

Fitting Methods:

  1. Symmetric errors: Uses scipy.optimize.curve_fit with Gaussian likelihood

  2. Asymmetric errors: Uses scipy.optimize.fmin with custom chi-squared

  3. Posterior samples: Fits each sample individually, returns percentiles

Parameter Bounds:

  • Metallicity: -2.0 < [M/H] < 3.0

  • C/O ratio: 0.0 < C/O < 2.0

  • Model returns -1000 for abundances outside these bounds

The method updates several class attributes:

  • best_fit_mh, best_fit_co: Best-fit bulk parameters

  • best_fit_refvol: Best-fit refractory enhancement (if fitted)

  • best_fit_abund: Dictionary of best-fit molecular abundances

  • bulk_abunds: Updated elemental abundances from best-fit parameters

  • fits: Posterior samples (for posterior-based fitting)

Examples

>>> # Basic fitting with symmetric errors
>>> obj.species_abunds = {'H2O': -3.2, 'CO': -3.8, 'CO2': -7.1}
>>> obj.species_errs = {'H2O': 0.1, 'CO': 0.15, 'CO2': 0.3}
>>> popt, pcov, fit = obj.convert_species_abunds(T=1500, P=1.0)
>>> # Include refractory enhancement
>>> popt, pcov, fit = obj.convert_species_abunds(T=1500, P=1.0, fit_refvol=True)
>>> # Posterior sampling (when species_errs contains arrays)
>>> popt, pcov, fit = obj.convert_species_abunds(T=1500, P=1.0,
...                                             posterior_samples=500)
Raises:
  • AttributeError – If species_abunds is not defined in the class instance.

  • ValueError – If optimization fails to converge or input data is inconsistent.

See also

predict_abund

Forward modeling of molecular abundances

convert_bulk_abundance

Convert bulk parameters to elemental abundances

Lodders25()[source]
Asplund09()[source]
Lodders20()[source]
Asplund21()[source]
Lodders10()[source]
Caffau11()[source]
import_masses()[source]
define_molecules()[source]