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: esbmtkBase

Element-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

list_species() None[source]

List all species which are predefined for this element.

Return type:

None

Notes

Prints the names of all species associated with this element.

class esbmtk.base_classes.Flux(**kwargs: dict[str, any])[source]

Bases: esbmtkBase

A 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

info(**kwargs) None[source]

Show an overview of the object properties.

Optional arguments are:

Parameters:
  • index – int = 0 this will show data at the given index

  • indent – int = 0 indentation

exception esbmtk.base_classes.FluxError(message)[source]

Bases: Exception

Custom Error Class for flux-related errors.

exception esbmtk.base_classes.ReservoirError(message)[source]

Bases: Exception

Custom Error Class for reservoir-related errors.

exception esbmtk.base_classes.ScaleError(message)[source]

Bases: Exception

Custom Error Class for unit scale-related errors.

class esbmtk.base_classes.Sink(**kwargs)[source]

Bases: SourceSink

Meta 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: SourceSink

Meta 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: esbmtkBase

Meta 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: SpeciesBase

Species 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'
massto(unit)[source]

Convert mass to specified unit.

Parameters:

unit (str | Q_) – Unit to convert to

Returns:

Converted mass

Return type:

Q\_

class esbmtk.base_classes.SpeciesBase(**kwargs)[source]

Bases: esbmtkBase

Base 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.

flux_summary() None[source]

Display all flux names in self.lof.

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:

tuple

Raises:

SpeciesError – If plot_transform_c is not a callable function

info(**kwargs) None[source]

Show an overview of the object properties.

Parameters:

**kwargs (dict) –

Optional arguments:
  • indexint, default=0

    Index to show data at

  • indentint, default=0

    Indentation level for display

Return type:

None

exception esbmtk.base_classes.SpeciesError(message)[source]

Bases: Exception

Custom Error Class for species-related errors.

class esbmtk.base_classes.SpeciesProperties(**kwargs)[source]

Bases: esbmtkBase

Properties 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”

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'
property full_display_name: str

Return the full display name of the species.

Returns:

Formatted display name including element and delta information if applicable

Return type:

str

esbmtk.base_classes.deprecated_keyword(model, message)[source]

Issue a deprecation warning with the provided message.

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: Exception

Custom 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 2 (cs2) 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_pco2(SW) float[source]

Calculate the concentration of pCO2.

esbmtk.carbonate_chemistry.get_zcc(export, zmax, zsat_min, zsat0, ca2, ksp0, AD, kc, co3)[source]

Calculate zcc.

esbmtk.carbonate_chemistry.get_zsat(zsat0, zsat_min, zmax, ca2, co3, ksp0)[source]

Calcualte zsat.

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

Parameters:
  • export_flux (Flux) – CaCO3 export flux from the surface box

  • source_box (Reservoir) – Reservoir instance of the surface box

  • this_box (Reservoir) – Reservoir instance of the deep box

  • kwargs (dict) – dictionary of keyword value pairs

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

Parameters:
  • export_flux (Flux) – CaCO3 export flux from the surface box

  • source_box (Reservoir) – Reservoir instance of the surface box

  • this_box (Reservoir) – Reservoir instance of the deep box

  • next_box – Reservoir instance of the sink box

  • kwargs (dict) – dictionary of keyword value pairs

esbmtk.carbonate_chemistry.phc(m: float) float[source]

Define a plot transform for the reservoir class.

Here we use this to display the H+ concentrations as pH. After import, you can use it with like this in the reservoir definition

plot_transform_c=phc,

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: esbmtkBase

ConnectionProperties 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

Example:

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
   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
)

ConnectionProperties(
          source=OM_Weathering,
          sink=Ocean,
          rate={DIC: f"{OM_w} Tmol/yr" ,
                ALK: f"{0} Tmol/yr"},
          ctype = {DIC: "Fixed",
                   ALK: "Fixed"},
        )
add_connections(**kwargs) None[source]

Add connections to the connection group.

info() None[source]

List all connections in this group.

exception esbmtk.connections.KeywordError(message)[source]

Bases: Exception

Custom Error Class.

exception esbmtk.connections.ScaleFluxError(message)[source]

Bases: Exception

Custom Error Class.

class esbmtk.connections.Species2Species(**kwargs)[source]

Bases: esbmtkBase

Connect 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 (-)

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”, >>> 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

property delta: float | int

Delta property.

property epsilon: float | int

Epsilon property.

get_species(r1, r2) None[source]

Set the species by r2.

However, if we have backward fluxes the species depends on the r2

info(**kwargs) None[source]

Show an overview of the object properties.

Optional arguments are index :int = 0 this will show data at the given index indent :int = 0 indentation

property rate: float | int

Rate property.

property scale: float | int | Q_

Scale property.

update(**kwargs)[source]

Update connection properties.

This will delete existing processes and fluxes, replace existing key-value pairs in the self.kwargs dict, and then re-initialize the connection.

exception esbmtk.connections.Species2SpeciesError(message)[source]

Bases: Exception

Custom Error Class.

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: Exception

Exception 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: Exception

Exception 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: object

Provides 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: Exception

Exception 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: Exception

Exception 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: Exception

Exception 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: InputParsing

The 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:

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:

bool

Raises:

Examples

>>> obj = SomeClass(name="test", value=10)
>>> obj.validate()  # Returns True if valid, raises exception if not
True

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: Exception

Custom Error Class.

exception esbmtk.extended_classes.CSVReadError(message)[source]

Bases: Exception

Custom Error Class.

class esbmtk.extended_classes.DataField(**kwargs: dict[str, any])[source]

Bases: esbmtkBase

DataField 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)
          y1_legend = Y-Axis Label
          y1_type = "plot", | "scatter"
          y2_data = NDArrayFloat    # optional
          y2_legend = Y-Axis label # optional
          y2_label = Data legend(s) # optional
          y2_type = "plot", | "scatter"
          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: Exception

Custom Error Class.

exception esbmtk.extended_classes.ESBMTKFunctionError(message)[source]

Bases: Exception

Custom Error Class.

class esbmtk.extended_classes.ExternalCode(**kwargs)[source]

Bases: SpeciesNoSet

Implement 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)
create_alialises() None[source]

Register alialises for each vr_datafield.

update_parameter_count()[source]

Update Parameter Count.

class esbmtk.extended_classes.ExternalData(**kwargs: dict[str, str])[source]

Bases: esbmtkBase

Instances 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

plot() None[source]

Plot the data and save a pdf.

Example:

ExternalData.plot()
exception esbmtk.extended_classes.ExternalDataError(message)[source]

Bases: Exception

Custom Error Class.

exception esbmtk.extended_classes.FluxError(message)[source]

Bases: Exception

Custom Error Class.

class esbmtk.extended_classes.GasReservoir(**kwargs)[source]

Bases: SpeciesBase

reservoir 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: Exception

Custom Error Class.

class esbmtk.extended_classes.Reservoir(**kwargs)[source]

Bases: esbmtkBase

Create 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: Exception

Custom Error Class.

class esbmtk.extended_classes.Signal(**kwargs)[source]

Bases: esbmtkBase

Create 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: Exception

Custom Error Class.

class esbmtk.extended_classes.SinkProperties(**kwargs)[source]

Bases: SourceSinkProperties

A wrapper to setup a Sink object.

Example:

SinkProperties(name = "Burial",
     species = [SO42, H2S],
     delta = {"SO4": 10}
     )
class esbmtk.extended_classes.SourceProperties(**kwargs)[source]

Bases: SourceSinkProperties

A wrapper to setup a Source object.

Example:

SourceProperties(name = "weathering",
        species = [SO42, H2S],
        delta = {"SO4": 10}
        )
class esbmtk.extended_classes.SourceSinkProperties(**kwargs)[source]

Bases: esbmtkBase

Create 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

exception esbmtk.extended_classes.SourceSinkPropertiesError(message)[source]

Bases: Exception

Custom Error Class.

class esbmtk.extended_classes.SpeciesNoSet(**kwargs)[source]

Bases: SpeciesBase

class 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: esbmtkBase

A simple container for 1-dimensional data.

Typically used for results obtained by postprocessing.

get_conversion_unit_information()[source]

Return concentrat data in plot units.

class esbmtk.extended_classes.VirtualSpecies(**kwargs)[source]

Bases: Species

A 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: ExternalCode

Alias 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: Exception

Custom Error Class for Flux lookup errors.

class esbmtk.model.Model(**kwargs: dict[str, any])[source]

Bases: esbmtkBase

Earth 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

See https://doi.org/10.5194/gmd-15-15-2022.

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.

clear()[source]

Delete all model objects.

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.

list_allbool, default=False

If True, print all connection attributes including internal ones.

Returns:

This method prints to stdout but doesn’t return a value.

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:
  • **kwargs (dict) – Optional keyword arguments.

  • indent (int, default=0) – Number of spaces to use for indentation in the output.

  • index (int, default=0) – Index to use when showing data samples (if applicable).

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:
  • directory (str, default="state") – Directory where state files will be saved. Will be created if it doesn’t exist and deleted if it already exists.

  • prefix (str, default="state") – Prefix to add to all saved filenames.

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: Exception

Custom Error Class for Model-related errors.

exception esbmtk.model.SolverError(message)[source]

Bases: Exception

Custom Error Class for solver-related errors.

esbmtk.model.deprecated_keyword(model, message)[source]

Issue a deprecation warning with the provided message.

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: Exception

Custom 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(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_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 species.

Based on previously calculated Hplus, TA, and DIC concentrations.

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

Parameters:

rg – A reservoirgroup object with initialized carbonate system

esbmtk.post_processing.carbonate_system_2_pp(bn: Reservoir | list, export_fluxes: float | list, zsat_min: float = 200, zmax: float = 10000) None[source]

Calculate the fraction of carbonate that is dissolved.

Parameters:
  • rg – Reservoir, e.g., M.D_b

  • export – export flux in mol/year

  • zsat_min – depth of mixed layer

  • zmax – depth of lookup table

This function then saves the data as

M.box_name.Hplus M.box_name.CO3 M.box_name.CO2aq M.box_name.pH M.box_name.zsat # top of lysocline M.box_name.zcc # bottom of lysocline M.box_name.zsnow # snow line M.box_name.Fburial # The CaCO3 burial flux (Export - dissolution) M.box_name.Fdiss # The CaCO3 dissolution flux

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.post_processing.carbonate_system_3_pp(bn: Reservoir | list, export_fluxes: float | list, zsat_min: float = 200, zmax: float = 10000) None[source]

Calculate the fraction of carbonate that is dissolved.

Parameters:
  • rg – Reservoir, e.g., M.D_b

  • export – export flux in mol/year

  • zsat_min – depth of mixed layer

  • zmax – depth of lookup table

This function then saves the data as

M.box_name.Hplus M.box_name.CO3 M.box_name.CO2aq M.box_name.pH M.box_name.zsat # top of lysocline M.box_name.zcc # bottom of lysocline M.box_name.zsnow # snow line M.box_name.Fburial # The CaCO3 burial flux (Export - dissolution) M.box_name.Fdiss # The CaCO3 dissolution flux

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.post_processing.gas_exchange_fluxes(liquid_reservoir: Species, gas_reservoir: GasReservoir, pv: str)[source]

Calculate gas exchange fluxes for a given reservoir.

Parameters:
  • liquid_reservoir – Species handle

  • gas_reservoir – Species handle

  • pv – piston velocity as string e.g., “4.8 m/d”

Returns:

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:
  • gas_c (float | tuple) – gas concentration in atmosphere

  • liquid_c (float | tuple) – reference species in liquid phase, e.g., DIC

  • gas_aq (float) – dissolved gas concentration, e.g., CO2aq

  • p (tuple) – parameters, see init_gas_exchange

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:
  • c_pco2 (float | list[float]) – current pCO2 concentration as absolute concentration, e.g. 280 ppm = 0.00028

  • p (tuple) – a tuple with the following entries: pco2_0 = reference pCO2 area_fraction = fraction of total surface area ex = exponent used in the equation f0 = flux at the reference value

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.processes.weathering_ref_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 the data is a tuple.

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.earth_radius(lat: float) float[source]

Get earth radius as function of latitude.

Parameters:

lat (float) – latitude in degrees

Returns:

radius of earth in meters

Return type:

float

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.

Parameters:
  • lat (float) – latitude in degrees

  • size (float) – size of the rectangular area in degrees

Returns:

area in square meters

Return type:

float

class esbmtk.sealevel.hypsometry(**kwargs)[source]

Bases: esbmtkBase

Calculate hypsometric data.

Depth interval between -6000 to 1000 meter (relative to sealevel)

Invoke as:

hyspometry(name=”hyp”)

area(elevation: int) float[source]

Calculate the ocean area at a given depth.

Parameters:

elevation (int) – Elevation datum in meters

Returns:

area in m^2

Return type:

float

area_dz(upper: float, lower: float) float[source]

Calculate the area between two elevation datums.

Parameters:
  • u (float) – upper elevation datum in meters (relative to sealevel)

  • l (float) – lower elevation datum relative to sealevel

Returns:

area in m^2

Return type:

float

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:
  • FileNotFoundError

  • The file structure must follow this scheme

  • Elevation[m], Cumsum

  • -11000, 0

show_data()[source]

Provide a diagnostic graph showing the hypsometric data.

volume(upper: float, lower: float) float[source]

Calculate the area between two elevation datums.

Parameters:
  • u (float) – upper elevation datum in meters (relative to sealevel)

  • l (float) – lower elevation datum relative to sealevel

Returns:

volume in m^3

Return type:

float

Raises:

ValueError – if elevation datums are outside the defined interval

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: esbmtkBase

Provide 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

o2_solubility_constant() None[source]

Calculate the solubility of CO2 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)

show() None[source]

Printout constants.

Units are mol/kg or mol**2/kg for doubly charged ions

update_parameters(**kwargs: dict) None[source]

Update values if necessary.

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.species_definitions.Sulfur(model)[source]

Element property definitions.

Parameters:

model (Model) – Model instance

esbmtk.species_definitions.misc_variables(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: Exception

Custom 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:
  • quantity (str | quantity | float | int) – e.g., “12 m/s”, or 12,

  • unit (str) – desired unit for keyword, e.g., “m/s”

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_reservoirs()[source]

Raise Error on use.

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.debug(func)[source]

Print the function signature and return value.

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 isotopeb

esbmtk.utility_functions.get_longest_dict_entry(d: dict) int[source]

Get length of each item in the connection dict.

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:
  • k (str) – with the initial flux name, e.g., M_F_A_db_DIC

  • M (Model) – Model handle

Returns:

Species2Species, SpeciesProperties

Return type:

tuple

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:
  • M (Model) – Model handle

  • box_dict (dict) – dictionary with reservoir parameters

Returns:

list of all Species objects in box_dict

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

Parameters:

c (float) – H+ concentration

Returns:

pH value

Return type:

float

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.

Parameters:
  • ec (ExternalCode object)

  • model_object (Species | Reservoir) – instance to register with

  • dict_key (str) – E.g., “M.A_db.DIC”

  • dict_value (str) – id value, e.g., “db_cs2”

Returns:

list of Flux instances

Return type:

list

esbmtk.utility_functions.register_new_reservoir(r, sp, v)[source]

Register a new reservoir.

esbmtk.utility_functions.register_return_values(ef: ExternalFunction, rg) None[source]

Register the return values of an external function instance.

Parameters:
  • ec (ExternalFunction) – ExternalFunction Instance

  • rg (Reservoir | Species) – The Resevoir or Reservoirgroup the external function is associated with

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.

Parameters:
  • M (Model) – Model handle

  • lib_name (str) – name of python file that contains the function

  • func_name (str | list) – Name of one or more user supplied function(s)

esbmtk.utility_functions.reverse_key(key: str) str[source]

Reverse a connection key e.g., sb2db@POM becomes db2sb@POM.

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.utility_functions.summarize_results(M: Model)[source]

Summarize all model results.

At t_max into a hirarchical dictionary, where values are accessed in the following way:

results[basin_name][level_name][species_name]

e.g., result[“A”][“sb”][“O2”]

esbmtk.utility_functions.warn_if_non_numeric(df)[source]

Warn about non numeric data in dataframe.

Checks all columns in the DataFrame for non-numeric values. Prints warnings with the row indices and offending values for each column.

Parameters:

df (pd.DataFrame) – The DataFrame to check.

esbmtk.version module

Get esbmtk version information.

This is in a dedicated file to avoid circular imports during initialization

esbmtk.version.get_version()[source]

Retrieve Version Data