Understanding input and output conditions

Understanding input and output conditions

A useful feature of all CO2SYS software that can nonetheless cause confusion is calculations at “input” and “output” conditions; “conditions” refers to temperature and pressure.

Humphreys et al. (2022), Section 2.3.

Input and output conditions have appeared in all implementations of CO2SYS and they are often troublesome for newcomers. This post aims to demystify them. I will explain what goes on behind the scenes when they are used, giving examples of common use cases, but also showing how they can be avoided altogether.

Terminology: inputs and outputs, arguments and results

First, we need to get our terminology straight.

  • “Conditions” means temperature and pressure (as above).

  • “Input” and “output” refer exclusively to conditions. This can be confusing, because in a coding context, the arguments passed into a function are sometimes called inputs, and the results of the function, outputs. To keep things clear, I will exclusively use “arguments” and “results” for the coding context.

If you can wrap your head around the next sentence, then you’ve got it:

Thus, we provide values at both input and output conditions as arguments to PyCO2SYS and we receive calculations at both input and output conditions as results from the program.

Input vs output

Again, a set of conditions is a set of temperature and pressure values. Input and output conditions are two different sets of temperature and pressure values.

In general, if two core marine carbonate system parameters are known, then we can calculate the others. The core parameters are total alkalinity (TA), dissolved inorganic carbon (DIC), pH, partial pressure or fugacity of CO2 (pCO2 or fCO2), and the components of DIC (aqueous CO2, bicarbonate ion and carbonate ion contents). Of these core parameters, only TA and DIC are conservative with respect to temperature and pressure. This means that if a seawater sample is heated, cooled or (de)pressurised without allowing any gas exchange, its TA and DIC do not change. All other core parameters are non-conservative, because they depend on equilibrium constants, which are functions of temperature and pressure.

Input conditions are the conditions at which the known non-conservative core parameter(s) are known. Output conditions are some other set of conditions at which we want to calculate something, which we don’t always need.

An example: you collect a seawater sample from deep in the ocean with a temperature of 4 °C and hydrostatic pressure of 5000 dbar. In the laboratory, you measure DIC under any arbitrary conditions, and pH at 25 °C and zero hydrostatic pressure. You want to calculate the in situ saturation state of a carbonate mineral (Ω). What are your input and output conditions?

  • Input: 25 °C and 0 dbar, for the non-conservative core parameter pH.
  • Output: 4 °C and 5000 dbar, the in situ conditions.

In the CO2SYS results, there will be two Ω values. The input Ω result tells you what the saturation state was during the measurement in the lab, but the output Ω result tells you its value in situ in the ocean. Here’s the code for PyCO2SYS v1:

import PyCO2SYS as pyco2  # v1

results = pyco2.sys(
    par1=2100,
    par2=8.1,
    par1_type=2,
    par2_type=3,
    temperature=25,
    pressure=0,
    temperature_out=4,
    pressure_out=5000,
)
omega_insitu = results["saturation_calcite_out"]

Which parameters don’t have conditions?

Along with TA and DIC, salinity and total salt contents (internally evaluated: total borate, sulfate and fluoride; user-provided: total silicate, phosphate, ammonia and sulfide) are conservative with respect to temperature and pressure. The same values of all these parameters are used for input- and output-condition calculations and are compatible with the results under all conditions.

How do we go from input to output?

All that happens is that the marine carbonate system is solved twice.

  1. Solve for TA and DIC under input conditions.
  2. Solve from TA and DIC under output conditions.

The input and output condition arguments are just a convenient way for the user to avoid having to manually do two sets of calculations.

Solving “under input conditions” means that all the equilibrium constants are calculated at the input-condition temperature and pressure, and likewise for output conditions. Nothing is fundamentally different about the two steps other than step 2 always having TA and DIC as the known pair and different values for the equilibrium constants.

So the following returns exactly the same as the code above, without using output conditions:

import PyCO2SYS as pyco2  # v1

lab = pyco2.sys(
    par1=2100,
    par2=8.1,
    par1_type=2,
    par2_type=3,
    temperature=25,
    pressure=0,
)
insitu = pyco2.sys(
    par1=lab["alkalinity"],
    par2=lab["dic"],
    par1_type=1,
    par2_type=2,
    temperature=4,
    pressure=5000,
)
omega_insitu = insitu["saturation_calcite"]

TA and DIC known? Output conditions never needed

If TA and DIC are known, we don’t need output conditions. Step 1 above solves for TA and DIC, but they are already known. The temperature and pressure of the TA and DIC measurements don’t matter.

Example: to accompany your earlier DIC and pH values, you also measure TA under any arbitrary conditions. Now, you want to calculate in situ Ω from TA and DIC. What are your input and output conditions?

  • Input: 4 °C and 5000 dbar, the in situ conditions.
  • Output: irrelevant.

In the CO2SYS results, take the input-condition Ω value.

You could use the same input/output combination as in the other example above (with known DIC and pH) and take output Ω instead. But I think it helps develop a deeper understanding of the marine carbonate system to realise the input conditions are irrelevant with that approach; they do not affect the output Ω value. (Try it yourself!)

How does PyCO2SYS differ?

Most CO2SYS implementations calculate all arguments and results under input and output conditions every time they are run.

As it’s fairly common for TA and DIC to be the known pair, PyCO2SYS v1 saves some computation time by not doing any output-condition calculations unless the user explicitly provides output temperature and/or pressure.

In PyCO2SYS v2, output conditions have disappeared altogether. Instead, known parameters are provided under the conditions at which they are known (i.e., input conditions), and results can be calculated under these conditions. There is then an adjust method which creates a second, separate set of results under different conditions. This approach avoids the current situation where one set of results contains two sets of incompatible values. The code for the example above would look like this:

import PyCO2SYS as pyco2  # v2

lab = pyco2.sys(
    dic=2100,
    pH=8.1,
    temperature=25,
    pressure=0,
)
insitu = lab.adjust(
    temperature=4,
    pressure=5000,
)
omega_insitu = insitu["saturation_calcite"]

If both known parameters are non-conservative

If both known core marine carbonate system parameters are non-conservative (i.e., neither TA nor DIC) and they were measured at the same temperature and pressure, then the approach above works fine. However, if they were measured at different temperatures and/or pressures, then to the best of my knowledge the only tool that can currently handle this is QUODcarb (Fennel and Primeau, 2025).