esbmtk package
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Submodules
esbmtk.base_classes module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- class esbmtk.base_classes.ElementProperties(**kwargs)[source]
Bases:
esbmtkBaseElement-specific properties for models.
Each model can have one or more elements. This class defines the properties specific to elements, such as name, mass unit, and isotope information.
- Parameters:
name (str) – The element name, e.g., “S”
model (Model) – The model handle
mass_unit (str | Q_) – Base mass unit, e.g., “mol”
li_label (str, optional) – Label of light isotope, e.g., “$^{32}$S”
hi_label (str, optional) – Label of heavy isotope, e.g., “$^{34}$S”
d_label (str, optional) – Label for delta value, e.g., r”$delta^{34}$S”
d_scale (str, optional) – Isotope scale, e.g., “VCDT”
r (float | int, optional) – Isotopic abundance ratio for element, defaults to 1
reference (str, optional) – Reference for isotope values, e.g., URL or citation
register (str | Model, optional) – Where to register this element, defaults to model
parent (str | Model, optional) – Parent object (usually model), defaults to model
full_name (str, optional) – Full name of the element
Examples
>>> ElementProperties( ... name="S", ... model=Test_model, ... mass_unit="mol", ... li_label="$^{32}$S", ... hi_label="$^{34}$S", ... d_label=r"$\delta^{34}$S", ... d_scale="VCDT", ... r=0.044162589, ... reference="https link or citation" ... )
- add_species(species: SpeciesProperties) None[source]
Add a species to this element’s species list.
- Parameters:
species (SpeciesProperties) – Species to add to this element
- Return type:
None
- class esbmtk.base_classes.Flux(**kwargs: dict[str, any])[source]
Bases:
esbmtkBaseA class which defines a flux object.
Flux objects contain information which links them to an species, describe things like the mass and time unit, and store data of the total flux rate at any given time step. Similarly, they store the flux of the light and heavy isotope flux, as well as the delta of the flux. This is typically handled through the Species2Species object. If you set it up manually
Example:
Flux = (name = "Name" # optional, defaults to _F species = species_handle, delta = any number, rate = "12 mol/s" # must be a string display_precision = number, optional, inherited from Model
)
You can access the flux data as
Name.m # mass
Name.d # delta
Name.c # same as Name.m since flux has no concentration
- exception esbmtk.base_classes.FluxError(message)[source]
Bases:
ExceptionCustom Error Class for flux-related errors.
- exception esbmtk.base_classes.ReservoirError(message)[source]
Bases:
ExceptionCustom Error Class for reservoir-related errors.
- exception esbmtk.base_classes.ScaleError(message)[source]
Bases:
ExceptionCustom Error Class for unit scale-related errors.
- class esbmtk.base_classes.Sink(**kwargs)[source]
Bases:
SourceSinkMeta class to setup a Source/Sink objects.
These are not actual reservoirs, but we stil need to have them as objects Example:
Sink(name = "Pyrite", species = SO4, display_precision = number, optional, inherited from Model delta = number or str. optional defaults to "None" register = Model handle )
- class esbmtk.base_classes.Source(**kwargs)[source]
Bases:
SourceSinkMeta class to setup a Source/Sink objects.
These are not actual reservoirs, but we stil need to have them as objects Example:
Ssource(name = "weathering", species = SO4, display_precision = number, optional, inherited from Model delta = number or str. optional defaults to "None" register = Model handle )
- class esbmtk.base_classes.SourceSink(**kwargs)[source]
Bases:
esbmtkBaseMeta class to setup a Source/Sink objects.
These are not actual reservoirs, but we stil need to have them as objects Example:
Sink(name = "Pyrite", species = SO4, display_precision = number, optional, inherited from Model delta = number or str. optional defaults to "None" register = Model handle )
- property delta
Delta Setter.
- class esbmtk.base_classes.Species(**kwargs)[source]
Bases:
SpeciesBaseSpecies implementation for chemical species in a model.
This class provides a concrete implementation of SpeciesBase for chemical species with properties like mass, concentration, and isotope information.
- Parameters:
name (str) – Name of the reservoir
species (SpeciesProperties) – Handle to the species properties
delta (float | int | str, optional) – Initial delta value for isotope calculation
concentration (str | Q_ | float, optional) – Species concentration (must provide either this or mass)
mass (str | Q_, optional) – Species mass (must provide either this or concentration)
volume (str | Q_, optional) – Reservoir volume (must provide either this or geometry)
geometry (list | dict | str, optional) – Geometry parameters for volume calculation
plot (str, optional) – Whether to plot this species, defaults to “yes”
plot_transform_c (callable, optional) – Function to transform concentration for plotting
legend_left (str, optional) – Custom label for left y-axis
display_precision (float | int, optional) – Decimal places for display, defaults to 0.01
register (any, optional) – Where to register this species
isotopes (bool, optional) – Whether to use isotope values
seawater_parameters (dict | str, optional) – Parameters for seawater calculations
Examples
>>> Species( ... name="foo", ... species=S, ... delta=20, ... concentration="1 mmol/liter", ... volume="1E5 liter", ... )
Notes
You must provide either mass or concentration, and either volume or geometry. For geometry, you can provide a list [upper_depth, lower_depth, total_area] or a dictionary with “area” and “volume” keys.
- DEFAULT_RTYPE = 'regular'
- class esbmtk.base_classes.SpeciesBase(**kwargs)[source]
Bases:
esbmtkBaseBase class for all Species objects.
This class provides common functionality for all species-related classes, including data handling, visualization, and state management.
Notes
This is an abstract base class that should not be instantiated directly. Use the derived classes like Species instead.
- get_conversion_unit_information() tuple[source]
Extract unit and scaling information.
This method provides the unit information and a scaling factor that maps from model units to display units.
- Returns:
Tuple containing (unit name, scaling factor)
- Return type:
- Raises:
SpeciesError – If plot_transform_c is not a callable function
- exception esbmtk.base_classes.SpeciesError(message)[source]
Bases:
ExceptionCustom Error Class for species-related errors.
- class esbmtk.base_classes.SpeciesProperties(**kwargs)[source]
Bases:
esbmtkBaseProperties class for chemical species in a model.
This class defines the properties specific to chemical species, such as their name, display format, and relationship to elements.
- Parameters:
name (str) – Name of the species, e.g., “SO4”
element (ElementProperties) – Handle to the element this species belongs to
display_as (str, optional) – How to display the species, defaults to name if not provided
m_weight (int | float | str, optional) – Molecular weight, defaults to 0
register (Model | ElementProperties | Species | GasReservoir, optional) – Where to register this species, defaults to element
parent (Model | ElementProperties | Species | GasReservoir, optional) – Parent object, defaults to register value
flux_only (bool, optional) – Whether this species only exists in fluxes, not reservoirs, defaults to False
logdata (bool, optional) – Whether to log data for this species, defaults to False
scale_to (str, optional) – Unit to scale to for display, defaults to “mmol”
stype (str, optional) – Species type, defaults to “concentration”, can also be length|particulate
species (The species_list returned by the initialize_reservoirs function does not contain)
concentration (that are not of type)
Examples
>>> SpeciesProperties( ... name="SO4", ... element=S, ... )
Notes
When a species is created, it’s automatically registered with its element.
- DEFAULT_SCALE_TO = 'mmol'
- DEFAULT_STYPE = 'concentration'
esbmtk.carbonate_chemistry module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020-2021 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.carbonate_chemistry.CarbonateSystem2Error(message)[source]
Bases:
ExceptionCustom Error Class for Model-related errors.
- esbmtk.carbonate_chemistry.add_carbonate_system_1(rgs: list)[source]
Create a new carbonate system virtual reservoir.
For each reservoir in rgs. Note that rgs must be a list of reservoir groups.
- Required keywords:
rgs: tp.List = [] of Reservoir Group objects
These new virtual reservoirs are registered to their respective Species as ‘cs’.
The respective data fields are available as rgs.r.cs.xxx where xxx stands for a given key key in the vr_datafields dictionary (i.e., H, CA, etc.)
- esbmtk.carbonate_chemistry.add_carbonate_system_2(**kwargs) None[source]
Create a new carbonate system virtual reservoir.
which will compute carbon species, saturation, compensation, and snowline depth, and compute the associated carbonate burial fluxes
- Required keywords:
source_box: tp.List of Reservoir objects in the surface layer this_box: tp.List of Reservoir objects in the deep layer carbonate_export_fluxes: tp.List of flux objects which must match the list of Reservoir objects. zsat_min = depth of the upper boundary of the deep box z0 = upper depth limit for carbonate burial calculations typically zsat_min
Optional Parameters:
zsat = initial saturation depth (m) zcc = initial carbon compensation depth (m) zsnow = initial snowline depth (m) zsat0 = characteristic depth (m) Ksp0 = solubility product of calcite at air-water interface (mol^2/kg^2) kc = heterogeneous rate constant/mass transfer coefficient for calcite dissolution (kg m^-2 yr^-1) Ca2 = calcium ion concentration (mol/kg) pc = characteristic pressure (atm) pg = seawater density multiplied by gravity due to acceleration (atm/m) I = dissolvable CaCO3 inventory co3 = CO3 concentration (mol/kg) Ksp = solubility product of calcite at in situ sea water conditions (mol^2/kg^2)
- esbmtk.carbonate_chemistry.add_carbonate_system_3(**kwargs) None[source]
Create a new carbonate system virtual reservoir.
This function initializes carbonate system 3 (cs3) for each specified deep box. It computes saturation, compensation, and snowline depth, and the associated carbonate burial fluxes.
- Required keywords:
r_sb / source_box: list of surface Reservoirs r_db / this_box: list of deep Reservoirs r_nb / next_box: list of sink Reservoirs carbonate_export_fluxes: list of CaCO3 export Flux objects z0: depth (m) for burial calculations
- Optional (defaulted) keywords:
zsat, zcc, zsnow, zsat0, Ksp0, kc, alpha, pg, pc, I_caco3, zmax, Ksp
- esbmtk.carbonate_chemistry.carbonate_system_1(dic, ta, hplus_0, co2aq_0, p) tuple[source]
Return the H+ and carbonate alkalinity concentrations.
- Parameters:
dic – float with the dic concentration
ta – float with the ta concentration
hplus_0 – float with the H+ concentration
co2aq_0 – float with the [CO2]aq concentration
p – tuple with the parameter list
- Returns:
dCdt_Hplus, dCdt_co2aq
LIMITATIONS: - Assumes all concentrations are in mol/kg - Assumes your Model is in mol/kg ! Otherwise, DIC and TA updating will not be correct.
Calculations are based off equations from: Boudreau et al., 2010, https://doi.org/10.1029/2009GB003654 Follows, 2006, doi:10.1016/j.ocemod.2005.05.004
- esbmtk.carbonate_chemistry.carbonate_system_2(CaCO3_export: float, dic_t_db: float | tuple, ta_db: float, dic_t_sb: float | tuple, hplus_0: float, zsnow: float, p: tuple) tuple[source]
Return the fraction of the carbonate rain that is dissolved.
This functions returns:
DIC_burial, DIC_burial_l, Hplus, zsnow
LIMITATIONS: - Assumes all concentrations are in mol/kg - Assumes your Model is in mol/kg
Calculations are based off equations from: Boudreau et al., 2010, https://doi.org/10.1029/2009GB003654
- esbmtk.carbonate_chemistry.carbonate_system_3(CaCO3_export: float, dic_t_db: float | tuple, ta_db: float, dic_t_sb: float | tuple, hplus_0: float, zsnow: float, p: tuple) tuple[source]
Return the fraction of the carbonate rain that is dissolved.
This functions returns:
DIC_burial, DIC_burial_l, Hplus, zsnow
LIMITATIONS: - Assumes all concentrations are in mol/kg - Assumes your Model is in mol/kg
Calculations are based off equations from: Boudreau et al., 2010, https://doi.org/10.1029/2009GB003654
- esbmtk.carbonate_chemistry.get_hplus(dic, ta, h0, boron, K1, K1K2, KW, KB) float[source]
Calculate H+ concentration based on a previous estimate.
[H+]. After Follows et al. 2006, doi:10.1016/j.ocemod.2005.05.004
- Parameters:
dic – DIC in mol/kg
ta – TA in mol/kg
h0 – initial guess for H+ mol/kg
boron – boron concentration
K1 – Ksp1
K1K2 – Ksp1 * Ksp2
KW – K_water
KB – K_boron
- Returns H:
new H+ concentration in mol/kg
- esbmtk.carbonate_chemistry.get_zcc(export, zmax, zsat_min, zsat0, ca2, ksp0, AD, kc, co3)[source]
Calculate zcc.
- esbmtk.carbonate_chemistry.init_carbonate_system_1(rg: Reservoir)[source]
Create a new carbonate system virtual reservoir.
for each reservoir in rgs. Note that rgs must be a list of reservoir groups.
- Required keywords:
rgs: tp.List = [] of Reservoir Group objects
These new virtual reservoirs are registered to their respective Species as ‘cs’.
The respective data fields are available as rgs.r.cs.xxx where xxx stands for a given key key in the vr_datafields dictionary (i.e., H, CA, etc.)
- esbmtk.carbonate_chemistry.init_carbonate_system_2(export_flux: Flux, source_box: Reservoir, this_box: Reservoir, kwargs: dict)[source]
Initialize a carbonate system 2 instance.
Note that the current implmentation assumes that the export flux is the total export flux over surface area of the mixed layer, i.e., the sediment area between z0 and zmax
- esbmtk.carbonate_chemistry.init_carbonate_system_3(export_flux: Flux, source_box: Reservoir, this_box: Reservoir, next_box: Reservoir, kwargs: dict)[source]
Initialize a carbonate system 3 instance.
Note that the current implmentation assumes that the export flux into this_box is the total export flux over surface area of the mixed layer, i.e., the sediment area between z0 and zmax
esbmtk.carbonate_system_4 module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020-2021 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.carbonate_system_4.CarbonateSystem2Error(message)[source]
Bases:
ExceptionCustom Error Class for Model-related errors.
- esbmtk.carbonate_system_4.add_carbonate_system_4(**kwargs) None[source]
Create a new carbonate system virtual reservoir.
This function initializes carbonate system 4 for the specified set of boxes. It computes saturation, compensation, and snowline depth, and the associated carbonate burial fluxes.
- Parameters:
this_box (list[ Reservoir]) – list of intermediate Reservoirs
burial_box (list[Reservoir]) – Burial reservoirs receiving permanently buried CaCO3.
r_bb (list[Reservoir]) – Burial reservoirs receiving permanently buried CaCO3.
carbonate_export_fluxes (list[Flux]) – list of CaCO3 export Flux objects from the surface reservoir.
z0 (float) – Depth of surface ocean box.
zint (float) – Depth of the intermediate ocean box.
parameters (Optional (defaulted)) – zsat, zcc, zsnow, zsat0, Ksp0, kc, alpha, pg, pc, I_caco3, zmax, Ksp
- Return type:
None
- esbmtk.carbonate_system_4.carbonate_system_4(CaCO3_export: float, dic_t_db: float | tuple, ta_db: float, dic_t_ib: float | tuple, ta_ib, dic_t_sb: float | tuple, hplus_db_0: float, hplus_ib_0: float, zsnow: float, p: tuple) tuple[source]
Compute carbonate burial and dissolution fluxes for a three vertical layer ocean.
This routine represents carbonate sediment dynamics for a system consisting of surface, intermediate, and deep ocean reservoirs coupled to a sediment reservoir. Carbonate dissolution, burial, snowline evolution, and alkalinity feedbacks are calculated following Boudreau et al. (2010).
- Parameters:
CaCO3_export (float) – Export flux of CaCO₃ from the surface ocean.
dic_t_db (float or tuple) – Deep-box DIC concentration. If isotopes are enabled, a tuple containing total and isotope-specific values.
ta_db (float) – Deep-box total alkalinity.
dic_t_ib (float or tuple) – Intermediate-box DIC concentration.
ta_ib (float) – Intermediate-box total alkalinity.
hplus_db_0 (float) – Deep-box hydrogen ion concentration from the previous timestep.
hplus_ib_0 (float) – Intermediate-box hydrogen ion concentration from the previous timestep.
zsnow (float) – Snowline depth from the previous timestep.
p (tuple) –
Collection of constant model parameters and lookup tables:
seawater chemistry constants
carbonate-system parameters
area lookup table
area-per-depth lookup table
carbonate saturation lookup table
- Returns:
Tuple containing:
Intermediate-box DIC dissolution flux
Intermediate-box TA dissolution flux
Deep-box hydrogen ion rate of change
Snowline migration rate
Deep-box DIC dissolution flux
Deep-box TA dissolution flux
Burial DIC flux
Burial TA flux
- Return type:
Notes
Assumptions:
All concentrations are expressed in mol kg⁻¹.
Carbonate chemistry follows the approximation of Follows et al. (2006).
Sediment dissolution and burial follow Boudreau et al. (2010).
References
Boudreau, Bernard P., Jack J. Middelburg, Andreas F. Hofmann, and Filip J. R. Meysman. 2010. “Ongoing Transients in Carbonate Compensation.” Global Biogeochemical Cycles 24 (4). https://doi.org/10.1029/2009GB003654.
- esbmtk.carbonate_system_4.get_hplus(dic, ta, h0, boron, K1, K1K2, KW, KB) float[source]
Calculate H+ concentration based on a previous estimate.
[H+]. After Follows et al. 2006, doi:10.1016/j.ocemod.2005.05.004
- Parameters:
dic – DIC in mol/kg
ta – TA in mol/kg
h0 – initial guess for H+ mol/kg
boron – boron concentration
K1 – Ksp1
K1K2 – Ksp1 * Ksp2
KW – K_water
KB – K_boron
- Returns H:
new H+ concentration in mol/kg
- esbmtk.carbonate_system_4.get_zcc(export, zmax, zsat_min, zsat0, ca2, ksp0, AD, kc, co3)[source]
Calculate zcc.
- esbmtk.carbonate_system_4.init_carbonate_system_4(export_flux: Flux, source_box: Reservoir, this_box: Reservoir, next_box: Reservoir, burial_box: Reservoir, kwargs: dict)[source]
Initialize a carbonate_system_4 external-code instance.
Creates and registers an
ExternalCodeobject that evaluates carbonate dissolution, burial, and snowline dynamics for a coupled intermediate-deep ocean system.- Parameters:
export_flux (Flux) – CaCO₃ export flux from the surface reservoir.
source_box (Reservoir) – Surface-ocean reservoir supplying exported carbonate.
this_box (Reservoir) – Intermediate-ocean reservoir receiving dissolved carbonate.
next_box (Reservoir) – Deep-ocean reservoir receiving dissolved carbonate and storing snowline state variables.
burial_box (Reservoir) – Sediment reservoir receiving permanently buried carbonate.
kwargs (dict) – Carbonate-system configuration parameters.
- Returns:
Configured Carbonate System 4 external-code instance.
- Return type:
Notes
The implementation assumes that the export flux represents total CaCO₃ export over the sediment area bounded by
z0andzmax.
esbmtk.connections module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- class esbmtk.connections.ConnectionProperties(**kwargs)[source]
Bases:
esbmtkBaseConnectionProperties Class.
Connect reservoir/sink/source groups when at least one of the arguments is a reservoirs_group object. This method will create regular connections for each matching species.
Use the connection.update() method to fine tune connections after creation
ConnectionProperties signature:
ConnectionProperties( source = upstream reservoir / upstream reservoir group sink = downstrean reservoir / downstream reservoirs_group delta = defaults to zero and has to be set manually epsilon = defaults to zero and has to be set manually rate = shared between all connections ref_reservoirs = shared between all connections scale = int/float scaling factor, see below ref_flux = shared between all connections species = list, optional, if present, only these species will be connected ctype = needs to be set for all connections. Use "Fixed" unless you require a specific connection type pl = [list] process list. optional, shared between all connections id = optional identifier, passed on to individual connection plot = "yes/no" # defaults to yes, shared between all connections )
Note: that the scale keyword will only affect the flux rate, it will not! affec the flux + signal. Use the scale keyword in the signal class to scale the signal data.
Example:
ConnectionProperties( source=OM_Weathering, sink=Ocean, rate={DIC: f"{OM_w} Tmol/yr" , ALK: f"{0} Tmol/yr"}, ctype = {DIC: "Fixed", ALK: "Fixed"}, )
- class esbmtk.connections.Species2Species(**kwargs)[source]
Bases:
esbmtkBaseConnect two reservoir species to each other.
This module creates the connecting flux and creates a connector object which stores all connection properties.
For simple connections, the type flux type is derived implcitly from the specified parameters. For complex connections, the flux type must be set explicitly. See the examples below:
- Parameters:
source (-)
sink (-)
rate (-)
delta (-)
ref_reservoirs (-)
epsilon (-)
id (-) – automatic name creation
signal (-)
ctype (-)
bypass (-)
scale (-)
Note: that the scale keyword will only affect the flux rate, it will not! affec the flux + signal. Use the scale keyword in the signal class to scale the signal data.
The connection name is derived automatically, and can be queried with M.connection_summary()
Connection Types:
Connecting two reservoirs with a fixed rate: >>> Species2Species( # deep box to sediment >>> ctype=”fixed”, # or “regular” >>> source=M.L_b.PO4, >>> sink=M.Fb.PO4, >>> scale=”108 Gmol/year”, >>> id=”shelf_burial”, >>> )
Connecting two reservoirs with a concentration dependent flux: >>> Species2Species( # Surface to deep box >>> source=M.L_b.PO4, >>> sink=M.D_b.PO4, >>> ctype=”scale_with_concentration”, >>> scale=M.L_b.PO4.volume >>> / M.tau >>> * M.L_b.swc.density >>> / 1000, # concentration * volume = mass * 1/tau >>> id=”po4_productivity”, >>> )
Connecting two reservoirs using another flux as reference. Note presently, you cannot chain flux references! You can use a reference flux multiple times, but it is not possible to reference f1 for f2, and then reference f2 for f3. The reference flux can either be given as a flux object, e.g., as returned from a flux lookup:
M.flux_summary(filter_by=”po4_productivity”, return_list=True)[0]
or simply as the id string:
“po4_productivity”
>>> Species2Species( # deep box to sediment >>> source=M.D_b.PO4, >>> sink=M.Fb.PO4, >>> ctype="scale_with_flux", >>> ref_flux=""po4_productivity", >>> # increase p_burial >>> scale=(1 - M.remin_eff), # burial of ~1% P >>> id="burial", >>> )
Useful methods in this class
info() will provide a short description of the connection objects.
list_processes() which will list all the processes which are associated with this connection.
update() which allows you to update connection properties after the connection has been created
- get_species(r1, r2) None[source]
Set the species by r2.
However, if we have backward fluxes the species depends on the r2
esbmtk.esbmtk_base module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.esbmtk_base.FluxSpecificationError(message)[source]
Bases:
ExceptionException raised for errors in flux specifications.
- Parameters:
message (str) – Explanation of the error
Examples
>>> raise FluxSpecificationError("Unknown flux units")
- exception esbmtk.esbmtk_base.InputError(message)[source]
Bases:
ExceptionException raised for errors in the input parameters.
- Parameters:
message (str) – Explanation of the error
Examples
>>> raise InputError("Value must be positive")
- class esbmtk.esbmtk_base.InputParsing[source]
Bases:
objectProvides various routines to parse and process keyword arguments.
All derived classes need to declare the allowed keyword arguments, their default values and the type in the following format:
defaults = {“key”: [value, (allowed instances)]}
The recommended sequence is to first set default values via __register_variable_names__() and then update with provided values using __update_dict_entries__(defaults, kwargs).
Notes
This class is not meant to be instantiated directly.
- exception esbmtk.esbmtk_base.KeywordError(message)[source]
Bases:
ExceptionException raised for errors in keyword arguments.
- Parameters:
message (str) – Explanation of the error
Examples
>>> raise KeywordError("Invalid keyword 'xyz'")
- exception esbmtk.esbmtk_base.MissingKeywordError(message)[source]
Bases:
ExceptionException raised when a required keyword argument is missing.
- Parameters:
message (str) – Explanation of the error
Examples
>>> raise MissingKeywordError("'name' is a mandatory keyword")
- exception esbmtk.esbmtk_base.SpeciesPropertiesMolweightError(message)[source]
Bases:
ExceptionException raised when molecular weight is missing or invalid.
- Parameters:
message (str) – Explanation of the error
Examples
>>> raise SpeciesPropertiesMolweightError("Missing molecular weight for C")
- class esbmtk.esbmtk_base.esbmtkBase[source]
Bases:
InputParsingThe esbmtk base class template.
This class handles keyword arguments, name registration and other common tasks.
Examples
# Define required keywords in lrk list self.lrk: tp.List = ["name"] # Define allowed type per keyword in defaults dict self.defaults: dict[str, list[any, tuple]] = { "name": ["None", (str)], "model": ["None", (str, Model)], "salinity": [35, (int, float)], # int or float } # Parse and register all keywords with the instance self.__initialize_keyword_variables__(kwargs) # Register the instance self.__register_with_parent__()
- ensure_q(arg)[source]
Ensure that a given input argument is a quantity object.
- Parameters:
arg (str, Quantity, or numeric) – The argument to convert to a Quantity
- Returns:
The input argument as a Quantity object
- Return type:
Quantity
- Raises:
InputError – If the argument is None, empty, or cannot be converted to a Quantity
Examples
>>> self.ensure_q("10 kg") <Quantity(10, 'kilogram')> >>> self.ensure_q(existing_quantity) <Quantity(existing_quantity)>
- help() None[source]
Show all keywords, their default values and allowed types.
Prints information about all available keywords and highlights which ones are mandatory.
- Return type:
None
Examples
>>> obj.help()
- info(**kwargs) None[source]
Show an overview of the object properties.
- Parameters:
**kwargs (dict, optional)
arguments (Additional keyword)
----------------------------
indent (*) – Number of spaces for indentation
- Return type:
None
Examples
obj.info(indent=2)
- set_flux(mass: str, time: str, substance: SpeciesProperties)[source]
Convert a flux rate to model units (kg/s or mol/s).
- Parameters:
mass (str) – Mass value with units, e.g., “12 Tmol” or “500 kg”
time (str) – Time unit, e.g., “year”, “day”, “s”
substance (SpeciesProperties) – Species properties object containing molecular weight information
- Returns:
Flux rate in model units (mol/time or g/time)
- Return type:
Quantity
- Raises:
InputError – If input parameters are None, empty, or of incorrect type
FluxSpecificationError – If unit conversion cannot be performed
SpeciesPropertiesMolweightError – If substance has no molecular weight defined
Examples
>>> M.set_flux("12 Tmol", "year", M.C) <Quantity(12, 'teramol / year')>
Notes
If model mass units are in mol, no mass unit conversion will be made. If model mass units are in kg, the flux will be converted accordingly.
- validate() bool[source]
Validate the object state after initialization.
This method performs comprehensive validation of the object’s attributes to ensure they are in a consistent and valid state.
- Returns:
True if the object is valid
- Return type:
- Raises:
ValueError – If the object fails validation
AttributeError – If required attributes are missing
Examples
>>> obj = SomeClass(name="test", value=10) >>> obj.validate() # Returns True if valid, raises exception if not True
esbmtk.excel_connection_functions module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020-2021 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- esbmtk.excel_connection_functions.create_gas_exchange_connections(model, basin_list, species, piston_velocity, scale, delta=None)[source]
Create gas exchange connection objects.
- Parameters:
model (Model) – ESBMTK model instance.
basin_list (list) – List of basins participating in gas exchange.
species (SpeciesProperties) – Gas species being exchanged.
piston_velocity (str or Quantity) – Gas transfer velocity.
scale (float, optional) – Scaling factor.
delta (float or str, optional) – Isotopic composition of the flux.
- Return type:
None
- esbmtk.excel_connection_functions.create_gas_exchange_connections_from_excel(M, excel_file: str, sheet_name: str = 'gas_exchange')[source]
Create gas exchange connections from an Excel worksheet.
- Parameters:
- Return type:
None
Notes
- Required columns::
species basins piston_velocity
- Optional columns::
scale delta
Example Excel sheet:
species | basins | piston_velocity | scale CO2 | A_sb, I_sb, P_sb, H_sb | 4.8 | 1.0 O2 | A_sb, I_sb, P_sb, H_sb | 4.8 | 1.0
- esbmtk.excel_connection_functions.create_gas_reservoirs_from_excel(M, excel_file: str, sheet_name: str = 'gas_reservoirs')[source]
Create atmospheric reservoirs from an Excel worksheet.
- Parameters:
- Returns:
Dictionary mapping reservoir names to the created
GasReservoirobjects.- Return type:
- Raises:
ValueError – If no
SpeciesPropertiesobjects are found in the model.ValueError – If a referenced species does not exist.
ValueError – If
species_ppmis missing.
Notes
- Required columns::
name species species_ppm
- Optional columns::
delta reservoir_mass plot
Numeric values supplied in the
species_ppmcolumn are automatically interpreted as ppm and converted to strings of the form"<value> ppm".Examples
Excel sheet:
name | species | species_ppm | delta ----------|---------|-------------|------ CO2_At | CO2 | 420 | 0 O2_At | O2 | 209000 | 0
- esbmtk.excel_connection_functions.create_reservoirs_from_excel(M, excel_file: str, sheet_name: str = 'reservoirs', species_units: dict | None = None, default_temperature: float | None = None, default_salinity: float | None = None, default_pressure: float | None = None)[source]
Create ESBMTK reservoirs, sources, and sinks from an Excel worksheet.
This function reads a spreadsheet describing model boxes, converts each row into a dictionary key, and then calls
initialize_reservoirs()to create the corresponding ESBMTK objects.Reservoir rows must contain geometry information and may contain any number of species concentration columns. Species columns are detected automatically by matching spreadsheet column names to
SpeciesPropertiesobjects registered in the model.- Parameters:
Example
Create a dict like this:
{ "DIC": "umol/kg", "TA": "umol/kg", "PO4": "umol/kg", }
Species not listed default to
"umol/kg".- Returns:
List of objects returned by
initialize_reservoirs().- Return type:
- Parameters:
- Raises:
ValueError – If no SpeciesProperties objects are found in the model.
Notes
Minimal required spreadsheet columns:
"name" "type"
Reservoir rows additionally require:
"z_top" "z_bottom" "area_percentage"
Optional columns (for reservoirs):
"temperature" "pressure" "salinity"
Any additional column whose name matches a SpeciesProperties object registered in the model is interpreted as a species concentration.
- esbmtk.excel_connection_functions.create_transport_matrix_from_excel(M, excel_file: str, species_list, sheet_name: str = 'transport_matrix', connection_type: str = 'scale_with_concentration')[source]
Construct transport connections for a model from an Excel sheet.
The function reads an Excel file defining transport connections between reservoirs, and registers them in the model.
- Parameters:
M (object) – Model object.
excel_file (str) – Path to an Excel file defining the transport matrix.
species_list (list of SpeciesProperties) – List of species associated with each transport connection.
sheet_name (str, optional) – Name of the Excel worksheet containing the transport matrix. Default is “transport_matrix”.
connection_type (str, optional) – Type identifier for the connection. Default is “scale_with_concentration”.
- Returns:
Dictionary of constructed connections. Keys are connection names of the form
"{source}_to_{sink}@{flux_id}"and values are dicts containing:- tystr
Connection type.
- scfloat or Quantity
Scaling factor (evaluated expression or parsed quantity).
- splist
Species list.
- Return type:
Notes
- Excel required columns format:
source : str
sink : str
flux_id : str
sc : str
Connections with
flux_id == "mix_up"automatically generate a corresponding reverse connection namedmix_downunless that connection already exists in the spreadsheet.Example Excel table:
source | sink | flux_id | sc -------|------|------------|---------------- H_sb | A_db | thermohaline | thc A_db | A_ib | thermohaline | ta * thc A_ib | A_sb | mix_up | 21 Sverdrup
esbmtk.extended_classes module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.extended_classes.CSVDataError(message)[source]
Bases:
ExceptionCustom Error Class.
- exception esbmtk.extended_classes.CSVReadError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.DataField(**kwargs: dict[str, any])[source]
Bases:
esbmtkBaseDataField Class.
Datafields can be used to plot data which is computed after the model finishes in the overview plot windows. Therefore, datafields will plot in the same window as the reservoir they are associated with. Datafields must share the same x-axis is the model, and can have up to two y axis.
Example:
DataField(name = "Name" register = Model handle, x1_data = ["None", (np.ndarray, list)], defaults to model time y1_data = NDArrayFloat or list of arrays y1_label = Data label(s) [list | string] y1_legend = Y-Axis Label y1_type = "plot", | "scatter" y1_style = "dashed" # [list | string] y2_data = NDArrayFloat # optional [list | string] y2_legend = Y-Axis label # optional [list | string] y2_label = Data legend(s) # optional [list | string] y2_type = "plot", | "scatter" [list | string] y2_style = "dashed" [list | string] common_y_scale = "no", #optional, default "no" display_precision = number, optional, inherited from Model )
All y1 and y2 keywords can be either a single value or a list of values. Note that Datafield data is not mapped to model units. Care must be taken that the data units match the model units.
The instance provides the following data
Name.x = X-axis = model X-axis Name.y1_data Name.y1_label Name.y1_legend
Similarly for y2
You can specify more than one data set, and be explicit about color and linestyle choices.
Example:
DataField( name="df_pH", x1_data=[M.time, M.time, M.time, M.ef_hplus_l.x, M.ef_hplus_h.x, M.ef_hplus_d.x], y1_data=[ -np.log10(M.L_b.Hplus.c), -np.log10(M.H_b.Hplus.c), -np.log10(M.D_b.Hplus.c), -np.log10(M.ef_hplus_l.y), -np.log10(M.ef_hplus_h.y), -np.log10(M.ef_hplus_d.y), ], y1_label="Low latitude, High latitude, Deep box, d_L, d_H, d_D".split( ", "), y1_color="C0 C1 C2 C0 C1 C2".split(" "), y1_style="solid solid solid dotted dotted dotted".split( " "), y1_legend="pH", register=M, )
- exception esbmtk.extended_classes.DataFieldError(message)[source]
Bases:
ExceptionCustom Error Class.
- exception esbmtk.extended_classes.ESBMTKFunctionError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.ExternalCode(**kwargs)[source]
Bases:
SpeciesNoSetImplement user-provided functions.
The data inside an ExternalCode instance will only change in response to a user-provided function but will otherwise remain unaffected. That is, it is up to the user-provided function to manage changes in response to external fluxes.
An ExternalCode instance is declared in the following way:
ExternalCode( name="cs", # instance name species=M.CO2, # must be Speciesproperties instance vr_datafields={ # the vr_datafields contain any data that is referenced inside the "Hplus": self.swc.hplus, # function, rather than passed as an argument, and all data "Beta": 0.0 # that is explicitly referenced by the model }, function=calc_carbonates, # function reference, see below fname="function name as string", function_input_data="DIC TA", # Note that parameters must be individual float values function_params=(float), return_values={ # list of return values, these must be known species definitions "Hplus": rg.swc.hplus, "zsnow": float(abs(kwargs["zsnow"])), }, register=rh # reservoir_handle to register with )
The dictionary keys of vr_datafields will be used to create alias names which c an be used to access the respective variables. See the online documentation: https://esbmtk.readthedocs.io/
In the default configuration, ExternalCode instances are computed after all regular connections have been established. However, sometimes, a connection may depend on a computed value. In this case set the optional parameter ftype to “in_sequence”
- append(**kwargs) None[source]
Update GenericFunction parameters.
After the VirtualSpecies has been initialized. This is most useful when parameters have to reference other virtual reservoirs which do not yet exist, e.g., when two virtual reservoirs have a circular reference.
Example:
VR.update(a1=new_parameter, a2=new_parameter)
- class esbmtk.extended_classes.ExternalData(**kwargs: dict[str, str])[source]
Bases:
esbmtkBaseInstances of this class hold external X/Y data.
which can be associated with a reservoir.
Example:
ExternalData(name = "Name" filename = "filename", legend = "label", legend_z = "label", offset = "0 yrs", reservoir = reservoir_handle, scale = scaling factor, optional display_precision = number, optional, inherited from Model convert_to = optional, see below y_as_z = False, plot_as_line = False, plot_args = {}, e.g., {"alpha": 0.5} )
The data must exist as CSV file, where the first column contains the X-values, and the second column contains the Y-values.
The x-values must be time and specify the time units in the header between square brackets They will be mapped into the model time units.
The y-values can be any data, but the user must take care that they match the model units defined in the model instance. So your data file mujst look like this
Time [years], Data [units], Data [units] 1, 12, -12 2, 13, 12
By convention, the secon column should contain the same type of data as the reservoir (i.e., a concentration), whereas the third column contain isotope delta values. In cases were there is no concentration data, set y_as_z = True, and the second column will be printed on the right side of the plot. This will only work for reservoirs that have isotope data though!
The column headers are only used for the time or concentration data conversion, and are ignored by the default plotting methods, but they are available as self.xh,yh
The convert_to keyword can be used to force a specific conversion. The default is to convert into the model concentration units.
Note that the instance name will be a combination of the name specified in the name field, and the name of the reservoir the data is associated with.
The plot_args keyword allows to pass arbitrary plot arguments
- - name.plot()
- Data:
name.x
name.y
name.df = dataframe as read from csv file
- exception esbmtk.extended_classes.ExternalDataError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.GasReservoir(**kwargs)[source]
Bases:
SpeciesBasereservoir specific information similar to the Species class.
Example:
Species(name = "foo", # Name of reservoir species = CO2, # SpeciesProperties handle # initial delta - optional (defaults to 0) delta = 20, reservoir_mass = quantity # total mass of all gases defaults to 1.78E20 mol species_ppm = number # concentration in ppm plot = "yes"/"no", defaults to yes plot_transform_c = a function reference, optional (see below) legend_left = str, optional, useful for plot transform display_precision = number, optional, inherited from Model register = optional, use to register with Reservoir Group isotopes = True/False otherwise use Model.m_type )
Accesing Species Data:
You can access the reservoir data as:
Name.m # species mass
Name.l # mass of light isotope
Name.d # species delta (only avaible after M.get_delta_values()
Name.c # partial pressure
Name.v # total gas mass
Useful methods include:
Name.write_data() # save data to file
Name.info() # info Species
- exception esbmtk.extended_classes.GasReservoirError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.Reservoir(**kwargs)[source]
Bases:
esbmtkBaseCreate a group of reservoirs.
which share a common volume, and potentially connections. E.g., if we have twoy reservoir groups with the same reservoirs, and we connect them with a flux, this flux will apply to all reservoirs in this group.
A typical examples might be ocean water which comprises several species. A reservoir group like ShallowOcean will then contain sub-reservoirs like DIC in the form of ShallowOcean.DIC
Example:
Reservoir(name = "ShallowOcean", # Name of reservoir group volume/geometry = "1E5 l", # see below delta = {DIC:0, TA:0, PO4:0] # dict of delta values mass/concentration = {DIC:"1 unit", TA: "1 unit"} plot = {DIC:"yes", TA:"yes"} defaults to yes isotopes = {DIC: True/False} see Species class for details seawater_parameters = dict, optional, see below register= model handle, required )
- Notes: The subreservoirs are derived from the keys in the concentration or mass
dictionary. Toward this end, the keys must be valid species handles and – not species names – !
Connecting two reservoir groups requires that the names in both group match, or that you specify a dictionary which delineates the matching.
Most parameters are passed on to the Species class. See the reservoir class documentation for details
The geometry keyword specifies the upper depth interval, the lower depth interval, and the fraction of the total ocean area inhabited by the reservoir
If the geometry parameter is supplied, the following instance variables will be computed:
self.volume: in model units (usually liter)
self.area: surface area in m^2 at the upper bounding surface
self.sed_area: area of seafloor which is intercepted by this box.
self.area_fraction: area of seafloor which is intercepted by this relative to the total ocean floor area
seawater_parameters:
If this optional parameter is specified, a SeaWaterConstants instance will be registered for this Species as Species.swc See the SeaWaterConstants class for details how to specify the parameters, e.g.:
seawater_parameters = {"temperature": 2, "pressure": 240, "salinity" : 35, },
- exception esbmtk.extended_classes.ReservoirError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.Signal(**kwargs)[source]
Bases:
esbmtkBaseCreate a signal.
which is described by its startime (relative to the model time), it’s size (as mass) and duration, or as duration and magnitude. Furthermore, we can presribe the signal shape (square, pyramid, bell, file )and whether the signal will repeat. You can also specify whether the event will affect the delta value. Alternatively, signal can be read from a CSV file. The file needs to specify Time [unit], Flux [unit/time unit], delta value
The delta value column is optional.The units must be of similar dimensions as the model dimensions (e.g., mol/l or mol/kg). Data will be automatically interpolated.
Example:
Signal(name = "Name", species = SpeciesProperties handle, start = "0 yrs", # optional duration = "0 yrs", # reverse_time: [False, (bool)], # optional delta = 0, # optional stype = "addition" # or multiplication/epsilon_only shape = "square/pyramid/bell/filename" mass/magnitude/filename # give one offset = '0 yrs', # scale = 1, optional, # offset = option # reservoir = r-handle # optional, see below source = s-handle optional, see below display_precision = number, optional, inherited from Model register, )
Signals are cumulative, i.e., complex signals ar created by adding one signal to another (i.e., Snew = S1 + S2)
The optional scaling argument will only affect the y-column data of external data files
Signals are registered with a flux during flux creation, i.e., they are passed on the process list when calling the connector object.
if the filename argument is used, you can provide a filename which contains the data to be used in csv format. The data will be interpolated to the model domain, and added to the already existing data. The external data need to be in the following format
Time, Rate, delta value 0, 10, 12
i.e., the first row needs to be a header line
All time data in the csv file will be treated as realative time (i.e., the start time will be mapped to zero). The reverse keyword can be used to invert a signal that is read from a csv file.
Last but not least, you can provide an optional reservoir name. In this case, the signal will create a source as (signal_name_source) and the connection to the specified reservoir. If you build a complex signal do this as the last step. If you additionally provide a source name the connection will be made between the provided source (this can be useful if you use source groups).
This class has the following methods
Signal.repeat() Signal.plot() Signal.info()
The signal class provides the following data fields
- self.data.m which contains the interpolated signal
also available as self.m
- self.data.l which contain the interpolated isotope
data in the form of the light isotope also availavle as self.l If no isotope data is given, it is 0
- self.ed is the object reference for the externaldata
instance in cases wher data is read from a csv file
Isotopes: Delta values are always additive, regardless of signal type. The epsilon_only type ignores are flux values (the column must be present though), and applies the delta value to a given flux. This setting is most useful to dynamically control the fractionation factor of an output flux.
- repeat(start, stop, offset, times) None[source]
Create a new signal by repeating an existing signal.
Example:
new_signal = signal.repeat(start, # start time of signal slice to be repeated stop, # end time of signal slice to be repeated offset, # offset between repetitions times, # number of time to repeat the slice )
- signal_data
self.__map_signal__() returns a Flux object, so we need to remove this from the list of model Fluxes, with self.mo.lof.remove(self.data) since we do not use is as a Flux. Probably better to just create a vector object instead. FIXME sometime
- exception esbmtk.extended_classes.SignalError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.SinkProperties(**kwargs)[source]
Bases:
SourceSinkPropertiesA wrapper to setup a Sink object.
Example:
SinkProperties(name = "Burial", species = [SO42, H2S], delta = {"SO4": 10} )
- class esbmtk.extended_classes.SourceProperties(**kwargs)[source]
Bases:
SourceSinkPropertiesA wrapper to setup a Source object.
Example:
SourceProperties(name = "weathering", species = [SO42, H2S], delta = {"SO4": 10} )
- class esbmtk.extended_classes.SourceSinkProperties(**kwargs)[source]
Bases:
esbmtkBaseCreate Source/Sink Groups.
These are not actual reservoirs, but we stil need to have them as objects Example:
SinkProperties(name = "Pyrite", species = [SO42, H2S], )
where the first argument is a string, and the second is a reservoir handle
- loc: set[Species2Species]
- exception esbmtk.extended_classes.SourceSinkPropertiesError(message)[source]
Bases:
ExceptionCustom Error Class.
- class esbmtk.extended_classes.SpeciesNoSet(**kwargs)[source]
Bases:
SpeciesBaseclass that makes no assumptions about the type of data.
I.e., all data will be left alone. The original class will calculate delta and concentration from mass an d and h and l. Since we want to use this class without a priory knowledge of how the reservoir arrays are being used we overwrite the data generated during initialization with the values provided in the keywords
- class esbmtk.extended_classes.VectorData(**kwargs: dict[str, any])[source]
Bases:
esbmtkBaseA simple container for 1-dimensional data.
Typically used for results obtained by postprocessing.
- class esbmtk.extended_classes.VirtualSpecies(**kwargs)[source]
Bases:
SpeciesA virtual reservoir.
Unlike regular reservoirs, the mass of a virtual reservoir depends entirely on the return value of a function.
Example:
VirtualSpecies(name="foo", volume="10 liter", concentration="1 mmol", species= , function=bar, a1 to a3 = to 3optional function arguments, display_precision = number, optional, inherited from Model, )
The concentration argument will be used to initialize the reservoir and to determine the display units.
The function definition follows the GenericFunction class. which takes a generic function and up to 6 optional function arguments, and will replace the mass value(s) of the given reservoirs with whatever the function calculates. This is particularly useful e.g., to calculate the pH of a given reservoir as function of e.g., Alkalinity and DIC.
The function must return a list of numbers which correspond to the data which describe a reservoir i.e., mass, light isotope, heavy isotope, delta, and concentration
In order to use this function we need first declare a function we plan to use with the generic function process. This function needs to follow this template:
def my_func(i, a1, a2, a3) -> tuple: # # i = index of the current max_timestep # a1 to a3 = optional function parameter. These must be present, # even if your function will not use it See above for details # calc some stuff and return it as # where m= mass, and l & h are the respective return [m, l, h, d, c] # isotopes. d denotes the delta value and # c the concentration # Use dummy value as necessary.
This class provides an update method to resolve cases where e.g., two virtual reservoirs have a circular reference. See the documentation of update().
- update(**kwargs) None[source]
Update GenericFunction parameters.
After the VirtualSpecies has been initialized. This is most useful when parameters have to reference other virtual reservoirs which do not yet exist, e.g., when two virtual reservoirs have a circular reference.
Example:
VR.update(a1=new_parameter, a2=new_parameter)
- class esbmtk.extended_classes.VirtualSpeciesNoSet(**kwargs)[source]
Bases:
ExternalCodeAlias to ensure backwards compatibility.
esbmtk.initialize_unit_registry module
Initialize a common unit registry.
esbmtk.model module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.model.FluxNameError(message)[source]
Bases:
ExceptionCustom Error Class for Flux lookup errors.
- class esbmtk.model.Model(**kwargs: dict[str, any])[source]
Bases:
esbmtkBaseEarth Science Box Model Toolkit (ESBMTK) Model class.
This class represents the main model framework for creating and running Earth science box models. It handles initialization of model parameters, management of reservoirs, fluxes, and species, and provides methods for running simulations and visualizing results.
The user-facing methods of the model class are:
Model_Name.info() - Display model information
Model_Name.save_data() - Save model data to files
Model_Name.plot([sb.DIC, sb.TA]) - Plot specified objects
Model_Name.save_state() - Save current model state
Model_Name.read_state() - Initialize with a previous model state
Model_Name.run() - Run the model simulation
Model_Name.list_species() - List all defined species
Model_Name.flux_summary() - Display flux information
Model_Name.connection_summary() - Display connection information
- Parameters:
**kwargs (dict) – A dictionary with key-value pairs for model configuration.
Examples
>>> esbmtkModel( ... name="Test_Model", # required ... stop="10000 yrs", # end time ... max_timestep="1 yr", # maximum time step ... element=["Carbon", "Sulfur"] ... )
Important Parameters
- namestr
The model name, e.g., “M”.
- mass_unitstr
Base mass unit for the model, default is “mol”.
- volume_unitstr
Volume unit for the model, default is “liter”.
- elementlist or str
One or more species names to include in the model.
- max_timestepstr
Limit automatic step size increase (time resolution of the model). Optional, defaults to model duration/100.
- m_typestr
Controls isotope calculation for the entire model. Options: “Not set” (default, isotopes calculated only for reservoirs with isotope keyword), “mass_only”, or “both” (overrides reservoir settings).
- offsetstr
Offset the time axis by the specified amount when plotting data. For display purposes only, does not affect model calculations.
- display_precisionfloat
Affects on-screen display of data and sets cutoff for graphical output.
- opt_k_carbonicint
- opt_pH_scaleint
pH scale setting: total=1, free=3.
- debug: bool
output debug information
- debug_equations_file: bool
write a debug version of the equations file.
- connection_summary(**kwargs) None[source]
Display a summary of model connections.
Prints information about all connections in the model or a filtered subset. For each connection, shows source and target, plus additional attributes if requested.
- Parameters:
**kwargs (dict) –
Optional keyword arguments:
- filter_bystr, default=None
If provided, only show connections containing this substring in their name.
- return_list: bool, default=False
Return connection objects as list
- Returns:
This method prints to stdout but doesn’t return a value unless return_as_list is True
- Return type:
None
Examples
>>> model.connection_summary() # Show all connections
>>> model.connection_summary(filter_by="DIC") # Show only DIC connections
>>> model.connection_summary(list_all=True) # Show all connection details
- flux_summary(**kwargs: dict) list | None[source]
Display or return a filtered summary of model fluxes.
Creates a report of fluxes in the model, filtered by name patterns. Can either print the results to the console or return them as a list.
- Parameters:
**kwargs (dict) –
Optional keyword arguments:
- filter_bystr, default=””
Filter fluxes by name or partial name. Multiple words separated by spaces act as additional conditions - all words must appear in the flux name.
- excludestr, default=””
Exclude any fluxes whose names contain this string.
- return_listbool, default=False
If True, return a list of flux objects instead of printing to console.
- Returns:
If return_list=True, returns a list of flux objects matching the filters. If return_list=False, returns None (results are printed to console).
- Return type:
list or None
- Raises:
ModelError – If the deprecated “filter” parameter is used instead of “filter_by”.
Examples
# Display all fluxes containing “PO4” in their name >>> model.flux_summary(filter_by=”PO4”)
# Get a list of fluxes containing both “POP” and “A_sb” in their names >>> fluxes = model.flux_summary(filter_by=”POP A_sb”, return_list=True)
# Display fluxes containing “PO4” but not “H_sb” >>> model.flux_summary(filter_by=”PO4”, exclude=”H_sb”)
- get_delta_values() None[source]
Calculate reservoir masses and isotope delta values.
Updates the mass (m) and delta (d) values for all reservoirs in the model that have isotopes enabled. For each reservoir, the mass is calculated from concentration and volume, and the delta value is calculated using the get_delta_h function.
- Parameters:
None
- Returns:
The method modifies reservoir objects in place.
- Return type:
None
- info(**kwargs) None[source]
Display an overview of the model properties.
Prints information about the model instance including defined elements and their associated species.
- Parameters:
- Returns:
This method prints to stdout but doesn’t return a value.
- Return type:
None
- list_species() None[source]
Display all elements and species defined in the model.
Prints a hierarchical list of all elements in the model and their associated species properties. This provides a quick overview of the chemical species available in the model simulation.
- Parameters:
None
- Returns:
This method prints to stdout but doesn’t return a value.
- Return type:
None
Examples
>>> model.list_species() Currently defined elements and their species: Carbon Defined SpeciesProperties: DIC CO2 HCO3 CO3 Sulfur Defined SpeciesProperties: SO4 H2S
- plot(pl: list = None, **kwargs) tuple[source]
Plot model objects and save results to a file.
Creates a figure with subplots for each provided model object and renders their data using the object’s __plot__ method.
- Parameters:
pl (list or object, default=None) – A list of ESBMTK instances (e.g., reservoirs) to plot. If a single object is provided, it will be converted to a list. If None, an empty list will be used.
**kwargs (dict) –
Optional plotting parameters:
- fnstr, default=”{model_name}.pdf”
Filename to save the plot.
- titlestr, default=None
Title for the plot window.
- no_showbool, default=False
If True, don’t display or save the figure; instead return the plt, fig, and axes handles for manual customization.
- reverse_timebool, default=False
If True, reverse the time axis and adjust tick labels.
- blockingbool, default=True
If True, block execution until plot window is closed.
- Returns:
If no_show=True, returns (plt, fig, axes), otherwise None.
- Return type:
tuple or None
Examples
Basic usage:
>>> M.plot([sb.PO4, sb.DIC], fn='test.pdf')
Advanced usage with customization:
>>> from esbmtk import data_summaries >>> species_names = [M.DIC, M.TA, M.pH, M.CO3, M.zcc, M.zsat, M.zsnow, M.PO4] >>> box_names = [M.L_b, M.H_b, M.D_b] >>> pl = data_summaries(M, species_names, box_names, M.L_b.DIC) >>> pl += [M.CO2_At] >>> plt, fig, axs = M.plot( >>> pl, >>> fn="steady_state.pdf", >>> title="ESBMTK Preindustrial Steady State", >>> no_show=True, >>> )
- post_process_data(results) None[source]
Process solver results and update model data structures.
Takes the raw numerical results from the ODE solver and maps them back into the appropriate ESBMTK data structures (reservoirs, signals, fluxes). Also performs post-processing operations like interpolating signals, calculating derived quantities, and checking for pH stability.
- Parameters:
results (scipy.integrate._ivp.ivp.OdeResult) – The results object returned by the ODE solver, containing solution time points (t) and state variables (y)
- Returns:
The method updates model data structures in-place
- Return type:
None
Notes
The processing order is important: 1. Interpolate signals and external data to match solver time points 2. Map state variables to reservoir concentrations and masses 3. Update time vector and flux data 4. Perform specialized checks (pH stability) and calculations (carbonate chemistry)
- read_data(directory: str = './data') None[source]
Read model results from CSV files.
Loads previously saved model data from CSV files in the specified directory. Updates the model’s internal state with the loaded data.
- Parameters:
directory (str, default="./data") – Directory containing the saved model data files.
- Return type:
None
- read_state(directory='state')[source]
Initialize the model with the result of a previous.
For this to work, you will first need to issue a save_state command at then end of a model run. This will create the necessary data files to initialize a subsequent model run.
- run(**kwargs) None[source]
Run the model simulation.
Executes the model simulation by solving the system of ordinary differential equations (ODEs) that describe the model dynamics.
- Parameters:
**kwargs (dict) –
Optional keyword arguments to control the simulation:
- solverstr, default=”ode”
The solver type to use. Currently only “ode” is supported.
- methodstr, default=”BDF”
The integration method for the ODE solver. Options include “BDF” and “LSODA”.
- stypestr, default=”solve_ivp”
The solver function to use. Currently only “solve_ivp” is supported.
- Returns:
Results are stored in the model instance.
- Return type:
None
- Raises:
ModelError – If an unsupported solver type is specified.
SolverError – If the solver fails to find a solution.
Notes
After running, performance metrics (CPU time, memory usage) are printed.
- save_data(directory: str = './data') None[source]
Save all model results to CSV files.
Creates a directory (or recreates if it exists) and saves the full time series of all model components to separate CSV files. Each reservoir, signal, and vector data object will have its own CSV file.
- Parameters:
directory (str, default="./data") – Directory where data files will be saved. Will be created if it doesn’t exist and deleted if it already exists.
- Return type:
None
- Raises:
FileExistsError – If the directory exists and cannot be deleted.
- save_state(directory: str = 'state', prefix: str = 'state') None[source]
Save the current model state to files.
Saves only the last time step of each reservoir to files in the specified directory. This is similar to save_data() but focuses on capturing the current state rather than the full time series.
- Parameters:
- Return type:
None
- Raises:
FileExistsError – If the directory exists and cannot be deleted.
- sub_sample_data() None[source]
Reduce data resolution by subsampling time series data.
If the number of time points exceeds the desired number of data points, this method reduces the data resolution by taking every nth point (where n is the stride). This affects the time array and all data in reservoirs, virtual reservoirs, and fluxes.
The method is mainly used to reduce memory usage and file sizes when saving model output.
- Parameters:
None
- Returns:
The method modifies model data in place.
- Return type:
None
Notes
Subsampling only occurs if the stride is greater than 1. The time series boundaries (first two and last two points) are excluded from subsampling to avoid boundary effects.
- test_d_pH(reservoir_group: Species, time_vector: NDArrayFloat) None[source]
Test for large changes in pH between time steps.
Checks if the pH change between consecutive time steps exceeds 0.01 units, which could indicate numerical instability or unrealistic model behavior. Warnings are issued for any time steps where the threshold is exceeded.
- Parameters:
reservoir_group (Species) – The reservoir group containing a Hplus species to be checked
time_vector (NDArrayFloat) – Time vector as returned by the solver
- Returns:
Issues warnings if large pH changes are detected
- Return type:
None
Notes
This is a crude test since the solver interpolates between integration steps, so it may not catch all problems. It only identifies pH changes that exceed 0.01 units between the specific time points in the solution.
The pH is calculated as -log10([H+]), where [H+] is the hydrogen ion concentration.
- exception esbmtk.model.ModelError(message)[source]
Bases:
ExceptionCustom Error Class for Model-related errors.
esbmtk.ode_backend_2 module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.ode_backend_2.SourceIsotopeError(message)[source]
Bases:
ExceptionCustom Error Class.
- esbmtk.ode_backend_2.build_eqs_matrix(M: Model) tuple[NDArrayFloat, NDArrayFloat][source]
Build the coefficient matrix CM and Flux vector f.
So that we can solve dC_dt = C dot flux_values
- esbmtk.ode_backend_2.check_signal_2(rhs: str, rhs_l: str, c: Species2Species, icl: dict)[source]
Test if connection is affected by a signal.
- Parameters:
ex – equation string
c – connection object
icl – dict of reservoirs that have actual fluxes
- Returns:
(modified) equation string
- esbmtk.ode_backend_2.get_flux(flux: Flux, M: Model, R: list[float], icl: dict) tuple[str, str, list][source]
Create formula expressions that calculates the flux F.
Return the equation expression as string
- Parameters:
flux – The flux object for which we create the equation
M – The current model object
R – The list of initial conditions for each reservoir
icl – dict of reservoirs that have actual fluxes
- Returns:
A tuple where the first string is the equation for the total flux, and the second string is the equation for the flux of the light isotope
- esbmtk.ode_backend_2.get_ic(r: Species, icl: dict, isotopes=False) str[source]
Get initial condition in a reservoir.
If the reservoir is icl, return index expression into R.c. If the reservoir is not in the index, return the Species concentration a t=0
In both cases return these a string
If isotopes == True, return the pointer to the light isotope concentration
- Parameters:
r – A reservoir handle
icl – icl = dict[Species, list[int, int]] where reservoir indicates the reservoir handle, and the list contains the index into the reservoir data. list[0] = concentration list[1] concentration of the light isotope.
- Raises:
ValueError – get_ic: can’t find {r.full_name} in list of initial conditions
- Returns:
the string s which is the full_name of the reservoir concentration or isotope concentration
- esbmtk.ode_backend_2.get_initial_conditions(M: Model, rtol: float, atol_d: float = 1e-07) tuple[dict[str, float], dict, list, list, NDArrayFloat][source]
Get list of initial conditions.
This list needs to match the number of equations.
- Parameters:
Model – The model handle
rtol – relative tolerance for BDF solver.
atol_d – default value for atol if c = 0
- Returns:
lic = dict of initial conditions
- Returns:
icl = dict[Species, list[int, int]] where reservoir indicates the reservoir handle, and the list contains the index into the reservoir data. list[0] = concentration list[1] concentration of the light isotope.
- Returns:
cpl = list of reservoirs that use function to evaluate reservoir data
- Returns:
ipl = list of static reservoirs that serve as input
- Returns:
rtol = array of tolerence values for ode solver
We need to consider 3 types of reservoirs:
1) Species that change as a result of physical fluxes i.e. r.lof > 0. These require a flux statements and a reservoir equation.
2) Species that do not have active fluxes but are computed as a tracer, i.e.. HCO3. These only require a reservoir equation
3) Species that do not change but are used as input. Those should not happen in a well formed model, but we cannot exclude the possibility. In this case, there is no flux equation, and we state that dR/dt = 0
get_ic() will look up the index position of the reservoir_handle on icl, and then use this index to retrieve the correspinding value in R
Isotopes are handled by adding a second entry
- esbmtk.ode_backend_2.get_regular_flux_eq(flux: Flux, c: Species2Species, icl: dict, ind2, ind3, CM: NDArrayFloat, toc: tuple) tuple[str, str, list][source]
Create a string containing the equation for a regular connection.
Regular = fixed rate
- Parameters:
flux – flux instance
c – connection object
icl – dict of reservoirs that have actual fluxes
ind2 – indent 2 times
ind3 – indent 3 times
- Returns:
two strings, where the first describes the equation for the total flux, and the second describes the rate for the light isotope
- esbmtk.ode_backend_2.get_scale_with_concentration_eq(flux: Flux, c: Species2Species, cfn: str, icl: dict, ind2: str, ind3: str, CM: NDArrayFloat, toc: tuple) tuple[str, str, list][source]
Create equation string for flux.
The flux will scale with the concentration in the upstream reservoir
Example: M1_ConnGrp_D_b_to_L_b_TA_thc__F = M1.ConnGrp_D_b_to_L_b.TA_thc.scale * R[5]
- Parameters:
flux – Flux object
c – connection instance
cfn – full name of the connection instance
icl – dict[Species, list[int, int]] where reservoir indicates the reservoir handle, and the list contains the index into the reservoir data. list[0] = concentration list[1] concentration of the light isotope.
- Returns:
two strings with the respective equations for the change in the total reservoir concentration and the concentration of the light isotope
- esbmtk.ode_backend_2.get_scale_with_flux_eq(flux: Flux, c: Species2Species, cfn: str, icl: dict, ind2: str, ind3: str, CM: NDArrayFloat, toc: tuple)[source]
Equation defining a flux.
The flux will scale relative to the magnitude of another flux. If isotopes are used, use the isotope ratio of the upstream reservoir.
- Parameters:
flux – Flux object
c – connection instance
cfn – full name of the connection instance
icl – dict[Species, list[int, int]] where reservoir indicates the reservoir handle, and the list contains the index into the reservoir data. list[0] = concentration list[1] concentration of the light isotope.
- Returns:
two strings with the respective equations for the change in the total reservoir concentration and the concentration of the light isotope
- esbmtk.ode_backend_2.isotopes_regular_flux(flux_m: str, c: Species2Species, icl: dict, ind3: str, ind2: str, CM: NDArrayFloat, toc: NDArrayFloat, flux: Flux) str[source]
Test if the connection involves any isotope effects.
- Parameters:
f_m – string with the flux name
c – connection object
icl – dict of reservoirs that have actual fluxes
ind2 – indent 2 times
ind3 – indent 3 times
:returns equation string
We calculate the isotope signal as follows: If delta is given given the isotopic ratio of the flux leaving/extering a reservoir is independent of the source. So we can calculate light isotope flux without signal as
flux_l = flux_m * 1000 / (r * (flux_d + 1000) + 1000)
and the contribution from the signal
as
signal_l = signal_m * 1000 / (r * (signal_d + 1000) + 1000)
and the actual flux_l as a combbination of the two.
If epsilon (alpha) is given we calculate the flux without signal as
flux_l = flux_m * source_l / (flux_a * source_c + source_l - flux_a * source_l)
We use the same equation to calculate the signal flux, but replace it with the signal_a.
If flux mass equals source concentration, this is a scale with concentration connection, and f_l = s_l * scale where scale is part of the constants on the equations matrix. Otherwise, the flux isotope ratio is similar to the source isotope ratio: fl = fm * sl/sc * scale. Note that scale is dropped in the below equations since it is moved to the equations matrix.
FIXME: move constants in the matrix?
- esbmtk.ode_backend_2.isotopes_scale_concentration(f_m: str, c: Species2Species, icl: dict, ind3: str, ind2: str, CM: NDArrayFloat, toc: NDArrayFloat, flux: Flux) str[source]
Test if the connection involves any isotope effects.
- Parameters:
f_m – string with the flux name
c – connection object
icl – dict of reservoirs that have actual fluxes
ind2 – indent 2 times
ind3 – indent 3 times
- Returns equation string:
- esbmtk.ode_backend_2.isotopes_scale_flux(f_m: str, c: Species2Species, icl: dict, ind3: str, ind2: str, CM: NDArrayFloat, toc: NDArrayFloat, flux: Flux) str[source]
Test if the connection involves any isotope effects.
- Parameters:
f_m – string with the flux name
c – connection object
icl – dict of reservoirs that have actual fluxes
ind2 – indent 2 times
ind3 – indent 3 times
- Returns equation string:
- esbmtk.ode_backend_2.parse_esbmtk_input_data_types(d: any, r: Species, ind: str, icl: dict) str[source]
Parse esbmtk data types.
That are provided as arguments to external function objects, and convert them into a suitable string format that can be used in the ode equation file
- esbmtk.ode_backend_2.write_ef(eqs, ef: Species | ExternalFunction, icl: dict, rel: str, ind2: str, ind3: str, gpt: tuple) str[source]
Write external function call code.
- Parameters:
eqs – equation file handle
ef – external_function handle
icl – dict of reservoirs that have actual fluxes
rel – string with reservoir names returned by setup_ode
ind2 – indent 2 times
ind3 – indent 3 times
gpt – tuple with global paramaters
- Returns:
rel: modied string of reservoir names
- esbmtk.ode_backend_2.write_equations_3(M: Model, R: list[float], icl: dict, cpl: list, ipl: list, eqs_fn: str) str[source]
Write file that contains the ode-equations for the Model.
- Parameters:
Model – Model handle
R – tp.List of floats with the initial conditions for each reservoir
icl – dict of reservoirs that have actual fluxes
cpl – tp.List of reservoirs that have no fluxes but are computed based on other reservoirs
ipl – tp.List of reservoir that do not change in concentration
fn – str, filename
Returns: equationfile name
esbmtk.post_processing module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- esbmtk.post_processing.carbonate_system_1_pp(box_names: SpeciesGroup) None[source]
Calculate carbonate system diagnostic variables from DIC and H⁺.
Computes bicarbonate concentration (HCO3⁻), carbonate concentration (CO_3^2-), pH, and calcite saturation state (Ω) from previously calculated DIC and H⁺ concentrations.
- Parameters:
box_names (SpeciesGroup or list[SpeciesGroup]) –
Reservoir group(s) containing initialized carbonate system variables. Each reservoir must contain at minimum:
DICHplusswc(seawater chemistry constants)
- Returns:
Results are stored as
VectorDataobjects attached to each reservoir group.- Return type:
None
Notes
The following variables are created:
HCO3: bicarbonate concentrationCO3: carbonate concentrationpH: pH on the total scaleOmega: calcite saturation stateConcentrations must be expressed as mol kg⁻¹.
The model state variables must be stored as mol kg⁻¹.
References
Boudreau et al. (2010), https://doi.org/10.1029/2009GB003654
Follows et al. (2006), https://doi.org/10.1016/j.ocemod.2005.05.004
- esbmtk.post_processing.carbonate_system_2_pp(bn: Reservoir | list, export_fluxes: float | list, zsat_min: float = 200, zmax: float = 10000) None[source]
Carbonate chemistry post-processing diagnostics for CS2.
Computes carbonate concentration, CO2aq concentration, pH, lysocline depth, carbonate compensation depth, dissolution flux, and burial flux from model DIC and H⁺ concentrations.
- Parameters:
bn (Reservoir or list[Reservoir]) – Reservoir(s) for post-processing.
export_fluxes (float or array-like or list) – CaCO₃ export flux supplied to each reservoir. Scalar values are expanded to a full time series.
zsat_min (float, default=200) – Minimum saturation depth (m).
zmax (float, default=10000) – Maximum depth represented by the carbonate lookup tables (m).
- Returns:
None – Results are written as
VectorDataobjects attached to each reservoir.Creates
——-
CO3 – Carbonate ion concentration.
CO2aq – Dissolved aqueous CO₂ concentration.
pH – pH on the total scale.
zsat – Saturation horizon depth (m).
zcc – Carbonate compensation depth (m).
Fdiss – Carbonate dissolution flux (mol yr⁻¹).
Fburial – Carbonate burial flux (mol yr⁻¹).
CaCO3_export – Export flux used in the calculation (mol yr⁻¹).
Assumptions
———–
- Concentrations are expressed in mol kg⁻¹.
- Model state variables are stored in mol kg⁻¹.
- Lookup tables defining seafloor area and saturation carbonate – concentrations have already been initialized.
References
Boudreau et al. (2010), https://doi.org/10.1029/2009GB003654
Follows et al. (2006), https://doi.org/10.1016/j.ocemod.2005.05.004
- esbmtk.post_processing.carbonate_system_3_pp(bn: Reservoir | list, export_fluxes: float | list, zsat_min: float = 200, zmax: float = 10000) None[source]
Carbonate chemistry post-processing diagnostics for CS3.
Computes carbonate concentration, CO2aq concentration, pH, lysocline depth, carbonate compensation depth, dissolution flux, and burial flux from model DIC and H⁺ concentrations.
- Parameters:
bn (Reservoir or list[Reservoir]) – Reservoir(s) for post-processing.
export_fluxes (float or array-like or list) – CaCO₃ export flux supplied to each reservoir. Scalar values are expanded to a full time series.
zsat_min (float, default=200) – Minimum saturation depth (m).
zmax (float, default=10000) – Maximum depth represented by the carbonate lookup tables (m).
- Returns:
None – Results are written as
VectorDataobjects attached to each reservoir.Creates
——-
CO3 – Carbonate ion concentration.
CO2aq – Dissolved aqueous CO₂ concentration.
pH – pH on the total scale.
zsat – Saturation horizon depth (m).
zcc – Carbonate compensation depth (m).
Fdiss – Carbonate dissolution flux (mol yr⁻¹).
Fburial – Carbonate burial flux (mol yr⁻¹).
CaCO3_export – Export flux used in the calculation (mol yr⁻¹).
Assumptions
———–
- Concentrations are expressed in mol kg⁻¹.
- Model state variables are stored in mol kg⁻¹.
- Lookup tables defining seafloor area and saturation carbonate – concentrations have already been initialized.
References
Boudreau et al. (2010), https://doi.org/10.1029/2009GB003654
Follows et al. (2006), https://doi.org/10.1016/j.ocemod.2005.05.004
- esbmtk.post_processing.carbonate_system_4_pp(bn: Reservoir | list, export_fluxes: float | list, zsat_min: float = 200, zmax: float = 10000) None[source]
Carbonate chemistry post-processing diagnostics for CS4.
Computes carbonate concentration, CO2aq concentration, pH, lysocline depth, carbonate compensation depth, dissolution flux, and burial flux from model DIC and H⁺ concentrations.
- Parameters:
bn (Reservoir or list[Reservoir]) – Reservoir(s) for post-processing.
export_fluxes (float or array-like or list) – CaCO₃ export flux supplied to each reservoir. Scalar values are expanded to a full time series.
zsat_min (float, default=200) – Minimum saturation depth (m).
zmax (float, default=10000) – Maximum depth represented by the carbonate lookup tables (m).
- Returns:
None – Results are written as
VectorDataobjects attached to each reservoir.Creates
——-
CO3 – Carbonate ion concentration.
CO2aq – Dissolved aqueous CO₂ concentration.
pH – pH on the total scale.
zsat – Saturation horizon depth (m).
zcc – Carbonate compensation depth (m).
Fdiss – Carbonate dissolution flux (mol yr⁻¹).
Fburial – Carbonate burial flux (mol yr⁻¹).
CaCO3_export – Export flux used in the calculation (mol yr⁻¹).
Notes
This is intended only for deep boxes. Surface and intermediate boxes should be post-processed with
carbonate_system_1_pp.Assumptions
Concentrations are expressed in mol kg⁻¹.
Model state variables are stored in mol kg⁻¹.
Lookup tables defining seafloor area and saturation carbonate concentrations have already been initialized.
References
Boudreau et al. (2010), https://doi.org/10.1029/2009GB003654
Follows et al. (2006), https://doi.org/10.1016/j.ocemod.2005.05.004
- esbmtk.post_processing.gas_exchange_fluxes(liquid_reservoir: Species, gas_reservoir: GasReservoir, pv: str)[source]
Calculate air-sea gas exchange fluxes.
Computes bidirectional gas exchange between a dissolved species in an ocean reservoir and its atmospheric reservoir using a piston velocity formula.
- Parameters:
liquid_reservoir (Species) – Reservoir species participating in gas exchange. Species that are currently supported are O2 and CO2.
gas_reservoir (GasReservoir) – Atmospheric reservoir coupled to the liquid reservoir.
pv (str or Quantity) – Piston velocity. E.g.:
"4.8 m/d"
- Returns:
Gas exchange flux time series returned by
esbmtk.gas_exchange.- Return type:
ndarray
- Raises:
ValueError – If
pvcannot be interpreted as a quantity.ValueError – If the liquid species is not
DICorO2.
esbmtk.processes module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright(C), 2020-2021 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- esbmtk.processes.gas_exchange(gas_c: float | tuple, liquid_c: float | tuple, gas_aq_c: float, p: tuple) float | tuple[source]
Calculate the gas exchange flux across the air sea interface.
including isotope effects.
- Parameters:
- Returns:
float | tuple – gas flux across the air/sea interface
Note that the sink delta is co2aq as returned by the carbonate VR
this equation is for mmol but esbmtk uses mol, so we need to
multiply by 1E3
The Total flux across interface dpends on the difference in either
concentration or pressure the atmospheric pressure is known, as gas_c, and
we can calculate the equilibrium pressure that corresponds to the dissolved
gas in the water as [CO2]aq/beta.
Conversely, we can convert the the pCO2 into the amount of dissolved CO2 =
pCO2 * beta
The h/c ratio in HCO3 estimated via h/c in DIC. Zeebe writes C12/C13 ratio
but that does not work. the C13/C ratio results however in -8 permil
offset, which is closer to observations
- esbmtk.processes.init_gas_exchange(c: Species2Species)[source]
Create ExternalCode instance for gas exchange reactions.
- Parameters:
c (Species2Species) – connection instance
- esbmtk.processes.init_weathering(c: Species2Species, pco2: float, pco2_0: float | str | Q_, area_fraction: float, ex: float, f0: float | str | Q_)[source]
Create a new external code instance.
- Parameters:
c – Species2Species
pco2 – float current pco2
pco2_0 – float reference pco2
ex – exponent
- Area_fraction:
float area/total area
- F0:
flux at pco2_0
- esbmtk.processes.weathering_isotopes(c_pco2: float | list[float], source_data: float | list[float], p: tuple) float | tuple[source]
Calculate weathering as a function of pCO2.
This is the same function as weathering_no_isotopes, but assumes that we weather a species (e.g., carbonate) that requires fluxes for both isotopes. data is a tuple.
- esbmtk.processes.weathering_isotopes_alpha(c_pco2: float | list[float], source_data: float | list[float], p: tuple) float | tuple[source]
Calculate weathering as a function of pCO2.
This is the same function as weathering_no_isotopes, but assumes that we weather a species (e.g., carbonate) that requires fluxes for both isotopes. data is a tuple. s_c = source mass s_l = source mass of light isotope
- esbmtk.processes.weathering_isotopes_delta(c_pco2: float | list[float], source_data: float | list[float], p: tuple) float | tuple[source]
Calculate weathering as a function of pCO2.
This is the same function as weathering_no_isotopes, but assumes that we weather a species (e.g., carbonate) that requires fluxes for both isotopes. data is a tuple.
- esbmtk.processes.weathering_no_isotopes(c_pco2: float | list[float], source_data: float | list[float], p: tuple) float | tuple[source]
Calculate weathering as a function of pCO2.
- Parameters:
- Returns:
float – a float value for the weathering flux
Explanation
———–
If the model uses isotopes, the function expects the concentration
values for the total mass and the light isotope as a list, and
will simiraly return the flux as a list of total flux and flux of
the light isotope.
The flux itself is calculated as – F_w = area_fraction * f0 * (pco2/pco2_0)**ex
esbmtk.sealevel module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- esbmtk.sealevel.get_box_geometry_parameters(box) None[source]
Calculate box volume and area from the data in box.
- Parameters:
box – list or dict with the geometry parameters
- Fraction:
0 to 1 to specify a fractional part (i.e., Atlantic)
If box is a list the first entry is the upper depth datum, the second entry is the lower depth datum, and the third entry is the fraction of ocean area. E.g., to specify the upper 200 meters of the entire ocean, you would write:
geometry=[0, -200, 1]
the corresponding ocean volume will then be calculated by the calc_volume method in this case the following instance variables will also be set:
self.volume in model units (usually liter)
self.are:a surface area in m^2 at the upper bounding surface
self.sed_area: area of seafloor which is intercepted by this box.
self.area_fraction: area of seafloor which is intercepted by this relative to the total ocean floor area
It is also possible to specify volume and area explicitly. In this case provide a dictionary like this:
box = {"area": "1e14 m**2", # surface area in m**2 "volume": "3e16 m**3", # box volume in m**3 "ta": "4e16 m**2", # reference area }
- esbmtk.sealevel.grid_area(lat: float, size: float) float[source]
Calculate the area of a rectangular area of size = 1 deg.
At a given lat-long position.
- class esbmtk.sealevel.hypsometry(**kwargs)[source]
Bases:
esbmtkBaseCalculate hypsometric data.
Depth interval between -6000 to 1000 meter (relative to sealevel)
- Invoke as:
hyspometry(name=”hyp”)
- area_dz(upper: float, lower: float) float[source]
Calculate the area between two elevation datums.
- Parameters:
- Returns:
area in m^2
- Return type:
- Raises:
ValueError – if elevation datums are outside the defined interval
- get_lookup_table_area() ndarray[tuple[Any, ...], dtype[float64]][source]
Return the area values between 0 and max_depth as 1-D array.
- get_lookup_table_area_dz() ndarray[tuple[Any, ...], dtype[float64]][source]
Return the are_dz values between 0 and max_depth as 1-D array.
- read_data(fn: str) None[source]
Read the hypsometry data from a pickle file.
If the pickle file is missing, create it from the csv data save the hypsometry data as a numpy array with elevation, area, and area_dz in self.hypdata
- Parameters:
fn (str) – file name to read from
- Raises:
The file structure must follow this scheme –
Elevation[m], Cumsum –
-11000, 0 –
- esbmtk.sealevel.process_slice(start: int, end: int, lat: ndarray[tuple[Any, ...], dtype[float64]], grid: ndarray[tuple[Any, ...], dtype[float64]], dz: int, elevation_minimum: float, elevation_maximum: float, elevations: ndarray[tuple[Any, ...], dtype[float64]], dx: float) ndarray[tuple[Any, ...], dtype[float64]][source]
Take grid area in to account when calculating the elevation count.
As earth is elliptical, the grid area for same latitude and longitude gap is different, the function adjust the weight for each slice and return the weighted elevation count array for each slice.
- Parameters:
start (int) – start index of the slice
end (int) – end index of the slice
lat (NDArrayFloat) – latitude array
grid (NDArrayFloat) – grid of elevation data
dz (int) – elevation interval
elevation_minimum (int) – minimum elevation in the grid
elevation_maximum (int) – maximum elevation in the grid
elevations (NDArrayFloat) – elevation array
dx (float) – grid resolution in degrees
- Returns:
elevation count array for each latitudinal slice
- Return type:
NDArrayFloat
- esbmtk.sealevel.slice_count(start: int, end: int, weight: ndarray[tuple[Any, ...], dtype[float64]], grid: ndarray[tuple[Any, ...], dtype[float64]], elevation_minimum: float, elevation_maximum: float, elevations: ndarray[tuple[Any, ...], dtype[float64]], dz: int) ndarray[tuple[Any, ...], dtype[float64]][source]
Generate elevation count array for each latitudinal slice.
Summarizing the count of elevation values in each elevation interval in current slice.
- Parameters:
start (int) – start index of the slice
end (int) – end index of the slice
weight (NDArrayFloat) – weight array for each latitudinal slice
grid (NDArrayFloat) – grid of all the data about to be sliced
elevation_minimum (int) – minimum elevation
elevation_maximum (int) – maximum elevation
elevations (NDArrayFloat) – elevation array
dz (int) – elevation interval
- Returns:
elevation count array for each latitudinal slice
- Return type:
NDArrayFloat
esbmtk.seawater module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright(C), 2020-2021 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- class esbmtk.seawater.SeawaterConstants(**kwargs: dict[str, str])[source]
Bases:
esbmtkBaseProvide basic seawater properties as a function of T, P and Salinity.
Since we cannot know if TA and DIC have already been specified, creating the instance uses standard seawater composition. Updating/Setting TA & DIC does not recalculate these values after initialization, unless you explicitly call the update_parameters() method.
Example:
Seawater(name="SW", register=M # model handle temperature = optional in C, defaults to 25, salinity = optional in psu, defaults to 35, pressure = optional, defaults to 0 bars = 1atm, pH = 8.1, # optional )
Results are always in mol/kg
Acess the values “dic”, “ta”, “ca”, “co2”, “hco3”, “co3”, “boron”, “boh4”, “boh3”, “oh”, “ca2”, “so4”,”hplus”, as SW.co3 etc.
This method also provides “K0”, “K1”, “K2”, “KW”, “KB”, “Ksp”, “Ksp0”, “KS”, “KF” and their corresponding pK values, as well as the density for the given (P/T/S conditions)
useful methods:
SW.show() will list values
After initialization this class provides access to each value the following way
instance_name.variable_name
Since this class is just a frontend to PyCO2SYS, it is easy to add parameters that are supported in PyCO2SYS. See the update_parameter() method.
- calc_solubility_term(S, T, A1, A2, A3, A4, B1, B2, B3) float[source]
Calculate solubility of given gas species.
- co2_solubility_constant() None[source]
Calculate the solubility of CO2 at a given temperature and salinity.
The value for K0 is taken from pyCO2sys which is in mol/kg-SW/atm esbmtk uses mol/(t atm). pyCO2sys follows Weiss, R. F., Marine Chemistry 2:203-215, 1974.
- get_density(S, TC, P) float[source]
Calculate density as function of T, P, S.
- Parameters:
S – salinity in PSU
TC – temp in C
P – pressure in bar
- Returns rho:
in kg/m**3
- n2_solubility_constant() None[source]
Calculate the solubility of N2 at a given temperature and salinity.
Coefficients after Sarmiento and Gruber 2006 which includes corrections for non ideal gas behavior
Parameters Ai & Bi from Tab 3.2.2 in Sarmiento and Gruber 2006
The result is in mol/(l atm)
- o2_solubility_constant() None[source]
Calculate the solubility of O2 at a given temperature and salinity.
Coefficients after Sarmiento and Gruber 2006 which includes corrections for non ideal gas behavior
Parameters Ai & Bi from Tab 3.2.2 in Sarmiento and Gruber 2006
The result is in mol/(l atm)
- water_vapor_partial_pressure() None[source]
Calculate the water vapor partial pressure at sealevel (1 atm).
As a function of temperature and salinity. Eq. Weiss and Price 1980 doi:10.1016/0304-4203(80)90024-9
Since we assume that we only use this expression at sealevel, we drop the pressure term
The result is in p/1atm (i.e., a percentage)
esbmtk.species_definitions module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright(C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- esbmtk.species_definitions.Boron(model)[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
- esbmtk.species_definitions.Calcium(model)[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
- esbmtk.species_definitions.Carbon(model)[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
- esbmtk.species_definitions.Hydrogen(model)[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
- esbmtk.species_definitions.Nitrogen(model)[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
- esbmtk.species_definitions.Oxygen(model) None[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
- esbmtk.species_definitions.Phosphor(model)[source]
Element property definitions.
- Parameters:
model (Model) – Model instance
esbmtk.utility_functions module
esbmtk: A general purpose Earth Science box model toolkit.
Copyright (C), 2020 Ulrich G. Wortmann
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
- exception esbmtk.utility_functions.ScaleError(message)[source]
Bases:
ExceptionCustom Error Class.
- esbmtk.utility_functions.add_to(my_list, e)[source]
Add element e to list l, but check if the entry already exist.
If so, throw exception. Otherwise add
- esbmtk.utility_functions.build_concentration_dicts(cd: dict, bg: dict) dict[source]
Build a dict which can be used by create_reservoirs.
- Parameters:
bg – dict where the box_names are dict keys.
cd – dictionary
with the following format:
cd = { # species: [concentration, isotopes] PO4: [Q_("2.1 * umol/liter"), False], DIC: [Q_("2.1 mmol/liter"), False], }
This function returns a new dict in the following format
# box_names: [concentrations, isotopes] d= {“bn”: [{PO4: .., DIC: ..},{PO4:False, DIC:False}]}
- esbmtk.utility_functions.build_ct_dict(d: dict, p: dict) dict[source]
Build a connection dictionary.
From a dict containing connection keys, and a dict containing connection properties. This is most useful for connections which a characterized by a fixed rate but apply to many species. E.g., mixing fluxes in a complex model etc.
- esbmtk.utility_functions.calc_volumes(bg: dict, M: any, h: any) list[source]
Calculate volume contained in a given depth interval.
bg is a dictionary in the following format:
bg={ "hb": (0.1, 0, 200), "sb": (0.9, 0, 200), }
where the key must be a valid box name, the first entry of the list denoted the areal extent in percent, the second number is upper depth limit, and last number is the lower depth limit.
M must be a model handle h is the hypsometry handle
The function returns a list with the corresponding volumes
- esbmtk.utility_functions.check_for_NaN(a: ndarray[tuple[Any, ...], dtype[float64]]) bool[source]
Test if a contains NaN values.
- esbmtk.utility_functions.check_for_quantity(quantity, unit)[source]
Check if keyword is quantity or string an convert as necessary.
If input is a string, convert string into a quantity
If input is a quantity, do nothing
if input is a number, convert to default quantity
- Parameters:
- Returns:
Returns a Quantity
- Return type:
Q\_
- Raises:
ValueError – if keywword is neither number, str or quantity
- esbmtk.utility_functions.convert_to_lists(d: dict, my_list: int) dict[source]
Expand mixed dict entries.
(i.e. list and single value) such that they are all lists of equal length
- esbmtk.utility_functions.create_bulk_connections(ct: dict, M: Model, mt: int = '1:1') dict[source]
Create connections from a dictionary.
The dict can have the following format:
mt = mapping type. See below for explanation
# na: names, tuple or str. If lists, all list elements share the same properties # sp: species list or species # ty: type, str # ra: rate, Quantity # sc: scale, Number # re: reference, optional # al: epsilon, optional # de: delta, optional # bp: bypass, see scale_with_flux # si: signal # mx: True, optional defaults to False. If set, it will create forward and backward fluxes (i.e. mixing)
There are 6 different cases how to specify connections
- Case 1 One connection, one set of parameters
ct1 = {“sb2hb”: {“ty”: “scale”, ‘ra’….}}
- Case 2 One connection, one set of instructions, one subset with multiple parameters
This will be expanded to create connections for each species ct2 = {“sb2hb”: {“ty”: “scale”, “sp”: [“a”, “b”]}}
- Case 3 One connection complete set of multiple characters. Similar to case 2,
but now all parameters are given explicitly ct3 = {“sb2hb”: {“ty”: [“scale”, “scale”], “sp”: [“a”, “b”]}}
- Case 4 Multiple connections, one set of parameters. This will create
identical connection for “sb2hb” and “ib2db” ct4 = {(“sb2hb”, “ib2db”): {“ty”: “scale”, ‘ra’: …}}
- Case 5 Multiple connections, one subset of multiple set of parameters. This wil
- create a connection for species ‘a’ in sb2hb and with species ‘b’ in ib2db
ct5 = {(“sb2hb”, “ib2db”): {“ty”: “scale”, “sp”: [“a”, “b”]}}
- Case 6 Multiple connections, complete set of parameters of multiple parameters
Same as case 5, but now all parameters are specified explicitly ct6 = {(“sb2hb”, “ib2db”): {“ty”: [“scale”, “scale”], “sp”: [“a”, “b”]}}
The default interpretation for cases 5 and 6 is that each list entry corresponds to connection. However, sometimes we want to create multiple connections for multiple entries. In this case provide the mt=’1:N’ parameter which will create a connection for each species in each connection group. See the below example.
It is easy to shoot yourself in the foot. It is best to try the above first with some simple examples, e.g.,
from esbmtk import expand_dict ct2 = {“sb2hb”: {“ty”: “scale”, “sp”: [“a”, “b”]}}
It is best to use the show_dict function to verify that your input dictionary produces the correct results!
- esbmtk.utility_functions.create_connection(n: str, p: dict, M: Model) None[source]
Create a connection group.
It is assumed that all rates are in liter/year or mol per year. This may not be what you want or need.
- Parameters:
n – a connection key. if the mix flag is given interpreted as mixing a connection between sb and db and thus create connections in both directions
p – a dictionary holding the connection properties
M – the model handle
- esbmtk.utility_functions.create_connections_from_flux_list(model: Model, flux_list: list, target_id: str, species: SpeciesProperties, scale: float, **kwargs: dict) None[source]
Create Species2Species connections from an existing list of flux objects.
This function constructs coupling relationships between reservoir species based on a list of reference fluxes. It interprets flux naming conventions to infer source/sink reservoirs unless explicitly overridden.
- Parameters:
model (Model) – The ESBMTK model instance containing reservoir groups.
flux_list (list) – List of flux objects used as references for constructing connections. Each flux is expected to have at least an
idattribute following a naming convention such asA_sb_2_A_ib_POP_ex.target_id (str) – Identifier used to label the resulting connection group.
species (SpeciesProperties) – Species object defining which tracer is being coupled (e.g. DIC, PO4).
scale (int or float) – Scaling factor applied to the reference flux when constructing the Species2Species coupling.
source (str, optional) –
Source selection mode or explicit source name.
Options: - “auto” (default): infer source from flux name - “from_sink”: infer source from sink portion of flux name - str: explicit model attribute name for source reservoir group
sink (str or ReservoirGroup, optional) –
Sink selection mode or explicit sink identifier.
Options: - “auto” (default): infer sink from flux name - str: explicit sink reservoir group name
delta (float, optional) – Isotopic fractionation passed to Species2Species.
epsilon (float, optional) – Additional isotopic or parameter modifier passed to Species2Species.
- Returns:
The function modifies the model by adding connection objects.
- Return type:
None
- esbmtk.utility_functions.create_weathering_fluxes(model: Model, species: SpeciesProperties, area_dict: dict, ref_flux_name: str, scale: float, delta: float | None = None, alpha: float | None = None, **kwargs: dict) None[source]
Create Species2Species connections representing weathering fluxes.
This function generates coupling terms between a crustal or atmospheric source reservoir and basin sink reservoirs, scaled by basin area and a reference flux.
- Parameters:
model (Model) – ESBMTK model instance containing reservoirs and flux definitions.
species (SpeciesProperties) – Species being transported (e.g. DIC, alkalinity).
area_dict (dict) – Dictionary mapping basin names to their surface areas.
ref_flux_name (str) – Name of the reference flux used.
scale (int or float) – Scaling factor applied to all basin weathering fluxes.
delta (float, optional) – Optional isotopic fractionation parameter passed to Species2Species.
alpha (float, optional) – Optional isotopic fractionation parameter passed to Species2Species.
source (str, optional) –
Source reservoir selection mode.
Options: - “crust” (default): use crustal reservoir (Fw.<species>) - “atmosphere”: use atmospheric reservoir (e.g., CO2_At for DIC)
- Returns:
The function modifies the model by adding connection objects.
- Return type:
None
Notes
Weathering fluxes are constructed per basin.
Source selection currently supports crust and atmosphere only.
Examples
>>> create_weathering_fluxes(model, DIC, areas, "weathering_silicate", 1.0)
- esbmtk.utility_functions.data_summaries(M: Model, species_names: list, box_names: list, register_with='None') list[source]
Group results by species and Reservoirs.
- Parameters:
M – model instance
species_names – tp.List of species instances
box_names – tp.List of Reservoir instances
register_with – defaults to M
- Returns pl:
a list of datafield instances to be plotted
Note: because pl is a list, you need to expand it before using it in the plot method. Either use
M.plot(pl)
or M.plot([*pl])
If you call a plot with many subfigures, use pl like this:
M.plot([o1, o2, *pl])
- esbmtk.utility_functions.dict_alternatives(d: dict, e: str, a: str) any[source]
Use dictionary =d=, an expression =e=, and an alternative expression =a=.
Returns the value associated with either =a= or =e= in the dictionary =d=.
- Parameters:
d – A dictionary.
e – The first expression to check.
a – The alternative expression to check.
- Returns r:
The value associated with either =a= or =e= in the dictionary =d=.
- Raises:
ValueError – If neither =a= nor =e= are found in the dictionary.
- esbmtk.utility_functions.expand_dict(d: dict, mt: str = '1:1') int[source]
Determine dict structure.
in case we have mutiple connections with mutiple species, the default action is to map connections to species (t = ‘1:1’). If you rather want to create mutiple connections (one for each species) in each connection set t = ‘1:N’
- esbmtk.utility_functions.find_matching_fluxes(my_list: list, filter_by: str, exclude: str) list[source]
Loop over all reservoirs in my_list.
And extract the names of all fluxes which match the filter string. Return the list of names (not objects!)
- esbmtk.utility_functions.find_matching_strings(s: str, fl: list[str]) bool[source]
Test if all elements of fl occur in s.
Return True if yes,otherwise False
- esbmtk.utility_functions.fractionate_with_epsilon(epsilon: float, source_c: float, source_l: float, sink_c: float) float[source]
Calculate how a given epsilon would affect the downstream isotoe ratio.
- esbmtk.utility_functions.gen_dict_entries(M: Model, **kwargs)[source]
Find all fluxes that contain the reference string.
Create a new Species2Species instance that connects the flux matching ref_id, with a flux matching target_id. The function will a tuple containig the new connection keys that can be used by the create bulk_connection() function. The second return value is a list containing the reference fluxes.
The optional inverse parameter, can be used where in cases where the flux direction needs to be reversed, i.e., the returned key will not read sb_to_dbPOM, but db_to_sb@POM
- Parameters:
M – Model or list
kwargs – keyword dictionary, known keys are ref_id, and raget_id, inverse
- Return f_list:
tp.List of fluxes that match ref_id
- Return k_tuples:
tuple of connection keys
- esbmtk.utility_functions.get_connection_keys(f_list: set, ref_id: str, target_id: str, inverse: bool, exclude: str) list[str][source]
Extract connection keys from set of flux names.
Replace ref_id with target_id so that the key can be used in create_bulk_connnections()
- Parameters:
f_list – a set with flux objects
ref_id – string with the reference id
target_id – string with the target_id
inverse – Bool, optional, defaults to false
- Return cnc_l:
a list of connection keys (str)
The optional inverse parameter, can be used where in cases where the flux direction needs to be reversed, i.e., the returned key will not read sb2db@POM, but db2s@POM
- esbmtk.utility_functions.get_delta(li: ndarray[tuple[Any, ...], dtype[float64]], h: ndarray[tuple[Any, ...], dtype[float64]], r: float) ndarray[tuple[Any, ...], dtype[float64]][source]
Calculate the delta from the mass of light and heavy isotope.
- Parameters:
l – light isotope mass/concentration
h – heavy isotope mass/concentration
r – reference ratio
:return : delta
- esbmtk.utility_functions.get_delta_from_concentration(c, li, r)[source]
Calculate the delta from the mass of light and heavy isotope.
- Parameters:
c – total mass/concentration
l – light isotope mass/concentration
r – reference ratio
- esbmtk.utility_functions.get_delta_h(R) float[source]
Calculate the delta of a flux or reservoir.
- Parameters:
R – Species or Flux handle
returns d as vector of delta values R.c = total concentration R.l = concentration of the light isotope
- esbmtk.utility_functions.get_imass(m: float, d: float, r: float) [<class 'float'>, <class 'float'>][source]
Calculate the isotope masses from bulk mass and delta value.
Arguments are m = mass, d= delta value, r = abundance ratio species
- esbmtk.utility_functions.get_l_mass(m: float, d: float, r: float) float[source]
Get mass of light isotope.
- Parameters:
m – mass or concentration
d – delta value
r – isotopic reference ratio
return mass or concentration of the light isotope
- esbmtk.utility_functions.get_longest_dict_entry(d: dict) int[source]
Get length of each item in the connection dict.
- esbmtk.utility_functions.get_matrix_coefficients(flux_name: str, CM: ndarray[tuple[Any, ...], dtype[float64]], F: ndarray[tuple[Any, ...], dtype[float64]], F_names: list[str], R_names: list[str], *, include_zeros: bool = False, atol: float = 0.0) list[tuple[str, float]][source]
Return reservoir rows affected by a given flux (and their CM coefficients).
A flux corresponds to one column in CM. Reservoirs correspond to rows in CM. This function finds the column index for flux_name in F_names, then returns (reservoir_name, CM[row, col]) for each reservoir row where that coefficient is non-zero (or all rows if include_zeros=True).
- Parameters:
flux_name – Name as stored in F_names (e.g., entries produced by f.full_name).
CM – Coefficient matrix with shape (n_reservoir_rows, n_fluxes).
F – Flux value vector with shape (n_fluxes,). (Not required for coefficients, but kept to match your provided signature and for sanity checks.)
F_names – Flux names aligned with flux indices (columns of CM, entries of F).
R_names – Reservoir row names aligned with row indices of CM.
include_zeros – If True, return all reservoirs with their coefficient (including 0.0). If False, only return reservoirs with non-zero coefficients.
atol – Absolute tolerance for treating very small coefficients as zero.
- Returns:
List of (reservoir_name, coefficient) tuples.
- Return type:
- esbmtk.utility_functions.get_name_only(o: any) any[source]
Test if item is an esbmtk type.
If yes, extract the name
- esbmtk.utility_functions.get_new_ratio_from_alpha(ref_mass: float, ref_l: float, a: float) [<class 'float'>, <class 'float'>][source]
Calculate the effect of the istope fractionation factor alpha.
For the ratio between the mass of the light isotope devided by the total mass
Note that alpha needs to be given as fractional value, i.e., 1.07 rather than 70 (i.e., (alpha-1) * 1000
- esbmtk.utility_functions.get_object_from_list(name: str, my_list: list) any[source]
Match a name to a list of objects.
Return the object
- esbmtk.utility_functions.get_object_handle(res: list, M: Model)[source]
Test if the key is a global reservoir handle.
Or exists in the model namespace
- Parameters:
res – tp.List of strings, or reservoir handles
M – Model handle
- esbmtk.utility_functions.get_plot_layout(obj)[source]
Select a row, column layout.
Based on the number of objects to display. The expected argument is a reservoir object which contains the list of fluxes in the reservoir
- esbmtk.utility_functions.get_reservoir_reference(k: str, M: Model) tuple[source]
Get SpeciesProperties and Species handles.
- Parameters:
- Returns:
Species2Species, SpeciesProperties
- Return type:
- Raises:
ValueError – If reservoir_name is not of type ConnectionProperties or Species2Species
- esbmtk.utility_functions.get_simple_list(my_list: list) list[source]
Return a list.
Which only has the full name rather than all the object properties
- esbmtk.utility_functions.get_string_between_brackets(s: str) str[source]
Parse string and extract substring between square brackets.
- esbmtk.utility_functions.get_sub_key(d: dict, i: int) dict[source]
Take a dict which has where the value is a list.
Return the key with the n-th value of that list
- esbmtk.utility_functions.initialize_reservoirs(M: Model, box_dict: dict)[source]
Initialize one or more reservoirs.
Based on the data in box_dict (see the example below).
- Parameters:
- Returns:
list of all Species objects in box_dict that are != particular
- Return type:
tp.List
- Raises:
ValueError – If there are no Species objects in the dictionary
Example:
box_parameters = { # name: [[ud, ld ap], T, P, S] # Atlantic Ocean "M.A_sb": { "g": [0, -100, A_ap], "T": 20, "P": 5, "S": 34.7, "c": {M.PO4: "2.1 mmol/kg", M.DIC: "2.21 mmol/kg", M.TA: "2.31 mmol/kg", } species_list = initialize_reservoirs(M, box_parameters)
Note: the first entry in the box_parameters dict must be a regular reservoir, not a Source or Sink.
- esbmtk.utility_functions.is_name_in_list(n: str, my_list: list) bool[source]
Test if an object name is part of the object list.
- esbmtk.utility_functions.list_fluxes(self, name, i) None[source]
Echo all fluxes in the reservoir to the screen.
- esbmtk.utility_functions.make_dict(keys: list, values: list) dict[source]
Create a dictionary from a list and value, or from two lists.
- esbmtk.utility_functions.map_units(obj: any, v: any, *args) float[source]
Parse v to see if it is a string.
If yes, map to quantity. parse v to see if it is a quantity, if yes, map to model units and extract magnitude, assign mangitude to return value if not, assign value to return value
- Parameters:
obj – connection object
v – input string/number/quantity
- Args:
tp.List of model base units
- Returns:
number
- Raises:
ScaleError – if input cannot be mapped to a model unit
- esbmtk.utility_functions.phc(c: float) float[source]
Calculate concentration as pH.
c can be a number or numpy array
- esbmtk.utility_functions.plot_geometry(noo: int)[source]
Define plot geometry based on number of objects to plot.
- esbmtk.utility_functions.register_new_flux(ec, model_object, dict_key, dict_value) list[source]
Register a new flux object with a Species2Species instance.
- esbmtk.utility_functions.register_return_values(ef: ExternalFunction, rg) None[source]
Register the return values of an external function instance.
- Parameters:
- Raises:
ValueError – If the return value type is undefined
Check the return values of external function instances, –
and create the necessary reservoirs, fluxes, or connections –
if they are missing. –
These fluxes are not associated with a connection Object –
so we register the source/sink relationship with the –
reservoir they belong to. –
This fails for GasReservoir since they can have a 1:many –
relatioship. The below is a terrible hack, it would be –
better to express this with several connection –
objects, rather than overloading the source attribute of the –
GasReservoir class. –
- esbmtk.utility_functions.register_user_function(M: Model, lib_name: str, func_name: str | list) None[source]
Register user supplied library and function with the model.
- esbmtk.utility_functions.reverse_tick_labels_factory(max_tick_value)[source]
Reverse the label of the x-axis ticks but not the data.
Usage:
From matplotlib.ticker import FuncFormatter ax.xaxis.set_major_formatter(FuncFormatter(reverse_tick_labels_factory(x_max)))
where xmax = max value on the x-axis
- esbmtk.utility_functions.rmtree(f) None[source]
Delete file or files if file is directory.
- Parameters:
f – pathlib path object
- esbmtk.utility_functions.set_y_limits(ax: Axes, obj: any) None[source]
Prevent the display or arbitrarily small differences.
- esbmtk.utility_functions.show_dict(d: dict, mt: str = '1:1') None[source]
Show dict entries in an organized manner.
- esbmtk.utility_functions.sort_by_type(my_list: list, t: list, m: str) list[source]
Divide a list by type into new lists.
This function will return a list and it is up to the calling code to unpack the list
l is list with various object types t is a list which contains the object types used for sorting m is a string for the error function
- esbmtk.utility_functions.split_key(k: str, M: any) any | any | str[source]
Split the string k with letters _to_.
Test if optional id string is present
esbmtk.version module
Get esbmtk version information.
This is in a dedicated file to avoid circular imports during initialization