Switching from v1 to v2¶
This explanation is designed as a detailed overview of differences for those who are already familiar with using PyCO2SYS with the pyco2.sys
syntax from v1. New or casual users may find the general instructions for v2 more helpful.
Solving the carbonate system¶
On the surface, v2 looks similar to v1. For example:
import PyCO2SYS as pyco2
# Set up the CO2System
co2s = pyco2.sys(
alkalinity=2250,
pH=8.1,
temperature=12.5,
salinity=32.4,
opt_k_carbonic=10,
)
# Solve for and retrieve a calculated parameter
dic = co2s["dic"]
import PyCO2SYS as pyco2
# Solve the carbonate system
co2s = pyco2.sys(
par1=2250,
par2=8.1,
par1_type=1,
par2_type=2,
temperature=12.5,
salinity=32.4,
opt_k_carbonic=10,
)
# Retrieve a calculated parameter
dic = co2s["dic"]
One set of settings per call¶
The most obvious change above is that the known marine carbonate system parameters alkalinity
and pH
are provided directly as kwargs, instead of using the old approach with par1
, par2
, par1_type
and par2_type
.
This does mean that it's no longer possible to have multiple different parameter types within a single call to pyco2.sys
. Similarly, all settings parameters (anything beginning with opt_
) can no longer be provided as arrays – each call to pyco2.sys
can only have one combination of settings.
However, as before, all other parameters (e.g., alkalinity
, pH
, temperature
and salinity
) can be scalars or NumPy arrays of any shape, as long as they can all be broadcasted together.
Also as before, it's possible to provide no carbonate system parameters, and just calculate equilibrium constants and total salt contents, or one carbonate system parameter, and do whatever calculations are possible with it alone.
When the system is solved¶
In v1.8, the result co2s
was a standard Python dict containing all possible parameters, which were computed at the moment that pyco2.sys
was called. However, in v2.0, co2s
is a CO2System
object, and it contains only the values of kwargs provided as arguments. Other parameters are computed only when the user attempts to retrieve them (e.g., with co2s["dic"]
above).
When a parameter is retrieved, the minimum set of intermediate parameters required to compute it are also calculated and stored in co2s
. These stored values will be used to compute any subsequently requested parameters – they will not be recomputed each time.
Retrieving parameters¶
As mentioned above, parameters can be retrieved (and, if necessary, calculated) as if co2s
were a standard Python dict. However, there is also more flexibility:
Retrieving multiple parameters¶
A list of parameters can be provided with the same syntax as above:
# Solve for / return DIC and fCO2
params = co2s[["dic", "fCO2"]]
# Access the results
dic = params["dic"]
fCO2 = params["fCO2"]
The result params
is a standard dict containing the requested parameters.
The solve
method¶
Parameters can be solved for using solve
:
# Solve for a calculated parameter
co2s.solve("dic", store_steps=1)
This gives the added flexibility of the store_steps
kwarg:
- If
0
, then only the requested parameter is stored. - If
1
(default), then the standard set of intermediate parameters is stored in theco2s
. - If
2
, then all possible intermediate parameters are stored.
Dot notation¶
If a parameter has been calculated, either directly or as an intermediate for another parameter, and its value is stored in the co2s
, it can also be accessed with dot notation:
# Access DIC, if it has been previously calculated
dic = co2s.dic
This will throw an error if the requested parameter is not already available.
Input and output conditions¶
In v1, a second set of temperature and/or pressure conditions could be specified as 'output' conditions with the suffix _out
for their arguments and results. In v2, each CO2System
can only have one set of temperature and pressure conditions. To adjust to a different set of conditions, use the adjust
method:
# Set up the CO2System
co2s = pyco2.sys(
alkalinity=2250,
pH=8.1,
temperature=12.5,
salinity=32.4,
opt_k_carbonic=10,
)
# Convert to different conditions
co2s_adj = co2s.adjust(
temperature=25,
pressure=1000,
store_steps=1,
method_fCO2=1,
opt_which_fCO2_insitu=1,
bh_upsilon=None,
)
# Get fCO2 at the adjusted conditions
fCO2_adj = co2s_adj["fCO2"]
# Solve the carbonate system
co2s = pyco2.sys(
par1=2250,
par2=8.1,
par1_type=1,
par2_type=2,
temperature=12.5,
temperature_out=25,
pressure_out=1000,
salinity=32.4,
opt_k_carbonic=10,
)
# Get fCO2 at the adjusted conditions
fCO2_adj = co2s["fCO2_out"]
The result co2s_adj
is a separate CO2System
at the requested temperature and pressure. If the original co2s
had two known parameters, then both are used to make the adjustment (via DIC and alkalinity). Temperature can also be adjusted with only one known parameter, if its one of pCO2, fCO2, [CO2(aq)] or xCO2. The kwargs method_fCO2
, opt_which_fCO2_insitu
and bh_upsilon
allow for finer control of the one-parameter adjustment (see the v2 general instructions for details).
Uncertainty propagation¶
There are three main differences regarding uncertainty propagation:
-
Uncertainty propagation is carried out by using the
propagate
method in v2.0, instead of by includinguncertainty_into
anduncertainty_from
kwargs in the mainpyco2.sys
call. -
Uncertainty results are stored in nested dicts in
co2s.uncertainty
in v2.0, instead of as additional key-value pairs inco2s
as in v1.8. -
The derivatives used to propagate uncertainties are calculated with automatic differentiation in v2.0, but with forward finite differences in v1.8.
The arguments provided to the propagate
method in v2.0 are exactly the same uncertainty_into
and uncertainty_from
as were provided directly to pyco2.sys
in v1.8.
An example:
# Set up the CO2System
co2s = pyco2.sys(
alkalinity=2250,
pH=8.1,
temperature=12.5,
salinity=32.4,
opt_k_carbonic=10,
)
# Propagate uncertainties
co2s.propagate("dic", {"alkalinity": 2.1, "pH": 0.02})
# Retrieve uncertainties and their components
dic_uncertainty = co2s.uncertainty["dic"]["total"]
dic_uncertainty_from_pH = co2s.uncertainty["dic"]["pH"]
# Solve the carbonate system and propagate uncertainties
co2s = pyco2.sys(
par1=2250,
par2=8.1,
par1_type=1,
par2_type=2,
temperature=12.5,
salinity=32.4,
opt_k_carbonic=10,
uncertainty_into="dic",
uncertainty_from={"par1": 2.1, "par2": 0.02},
)
# Retrieve uncertainties and their components
dic_uncertainty = co2s["u_dic"]
dic_uncertainty_from_pH = co2s["u_dic__pH"]
Settings¶
Before v2, changing opt_k_carbonic
to a different set of carbonic acid dissociation constants could also cause other parameterisations to be switched behind the scenes (for e.g. the borate equilibrium constant and some pressure correction factors). This behaviour was inherited from CO2SYS-MATLAB, but it has been eliminated in PyCO2SYS v2. Instead, every parameterisation that has multiple options is controlled independently with its own setting.
This affects only opt_k_carbonic
values 6
, 7
, and 8
, i.e., the GEOSECS and freshwater cases. All other opt_k_carbonic
options used the set of parameterisations that are now the defaults in v2.