Migration Guide: v2 to v3#
Version 3.0.0 is a major release that changes the core data model of the toolkit and reorganizes several modules. This guide describes the changes that affect existing code and explains how to update it.
The most significant change is that the toolkit now uses xarray.Dataset
as its primary data structure in place of the InstrumentData class and
pandas.DataFrame. Most other changes are renames or module moves, and
the previous names are retained as deprecated aliases wherever practical so
that existing code continues to run while emitting deprecation warnings.
Summary of changes#
Python 3.11 or later is required.
matplotlibandplotlyare no longer core dependencies. Install theplotsextra to usevisualizationandutils.plot.xarray.DatasetreplacesInstrumentDataandpandas.DataFrameas the data structure returned by the file reading functions and consumed byprocessingandvisualization.instrument_data.cnv_to_instrument_datais replaced byinstrument_data.read_cnv_file, which reads Fathom.cnvfiles by default.The
InstrumentDataandMeasurementSeriesclasses have been removed.Instrument-specific hex reading functions are renamed to lower snake_case.
HexDataTypesis replaced byHEX_TYPE_*string constants.EOS-80 functions have moved from
eos80_processingto a neweos80_conversionmodule or to theseawaterlibrary.buoyancyandbuoyancy_frequencyhave moved fromprocessingtoconversionand now return NumPy arrays.convert_pressurenow returns psia by default, andconvert_conductivitytakes aninstrument_typeparameter in place ofscalar.loop_edit_depthandloop_edit_pressureare replaced byloop_edit, which returns flags instead of a cast array.splitnow labels casts with acast_typecoordinate instead of returning a list of DataFrames.SBE 911plus status bits are now decoded from the least significant bit.
The
ChartDataclass has been removed fromvisualization; charting functions now take anxarray.Datasetdirectly.Several parameters that took enums now take plain strings.
Several parameters with unit suffixes have been renamed.
Constants have been consolidated into a new
constantsmodule.Several deprecated v2 aliases and parameters have been removed.
Dependencies and the example notebook layout have changed.
Installation and dependencies#
Version 3 requires Python 3.11 or later. Support for Python 3.9 and 3.10 has been removed, and Python 3.13 and 3.14 are supported.
Version 3 adds xarray and seawater as core dependencies and removes
matplotlib and plotly. Core dependencies now specify minimum versions
that were released at most 2 years ago. The optional dependency groups have been
reorganized. The dev extra has been replaced with more focused groups:
plots: required byvisualizationandutils.plot.notebooks: dependencies for running the example notebooks.docs: dependencies for building the documentation.
Development dependencies are now only available through the dev
dependency group.
Installing the base package is unchanged:
py -m pip install seabirdscientific
Optional dependencies can be included with square brackets:
py -m pip install seabirdscientific[docs,notebooks,plots]
The data model: xarray.Dataset#
In v2, .cnv files were read into an InstrumentData object that held a
dictionary of MeasurementSeries objects and exposed a
pandas.DataFrame, and .hex files were read into a pandas.DataFrame.
In v3, both are read directly into an xarray.Dataset. Each measurand is a
variable in the dataset along the scan dimension, and metadata such as the
sample interval and start time are stored as dataset attributes.
v2:
import seabirdscientific.instrument_data as si
data = si.cnv_to_instrument_data("example.cnv")
temperature = data.measurements["tv290C"].values
df = data.to_dataframe()
v3:
import seabirdscientific.instrument_data as si
dataset = si.read_cnv_file("example.cnv", software="seasoft")
temperature = dataset["tv290C"].values
df = dataset.to_dataframe()
Variable metadata is available on each DataArray through its attrs
dictionary, and file-level metadata is available on the dataset:
dataset["tv290C"].attrs["long_name"] # e.g. "Temperature"
dataset["tv290C"].attrs["units"] # e.g. "ITS-90, deg C"
dataset["tv290C"].attrs["sbs_name"] # the original Sea-Bird name
dataset.attrs["file_name"]
dataset.attrs["sample_interval"]
dataset.attrs["start_time"]
Duplicate variable names in a .cnv file are disambiguated by appending an
index. For example, a second depSM column becomes depSM_1. The
original name is preserved in the sbs_name attribute.
instrument_data#
read_cnv_file#
cnv_to_instrument_data has been replaced by read_cnv_file, which
returns an xarray.Dataset. read_cnv_file takes a software
parameter that selects the file format: "fathom" (default) or
"seasoft". Files created by SBE Data Processing (SeaSoft) must be read
with software="seasoft".
cnv_to_instrument_data remains as a wrapper for
read_cnv_file(filepath, "seasoft") and emits a DeprecationWarning.
# v2
data = si.cnv_to_instrument_data(filepath)
# v3
fathom_dataset = si.read_cnv_file(filepath)
seasoft_dataset = si.read_cnv_file(filepath, software="seasoft")
When reading a SeaSoft file, a scan column in the file is stored as
scan_count because scan is used as the dataset dimension. When reading
a Fathom file, a scan column replaces the values of the scan
coordinate.
The start_time attribute is an ISO 8601 string instead of a datetime.
read_hex_file#
read_hex_file keeps the same name and parameters but now returns an
xarray.Dataset instead of a pandas.DataFrame. Each hex data type is a
variable in the returned dataset. The enabled_sensors parameter no longer
has a default and must be provided. A file with no data returns an empty
dataset instead of an empty DataFrame.
dataset = si.read_hex_file(filepath, instrument_type, enabled_sensors)
temperature_counts = dataset["temperature"].values
Removed classes and functions#
The InstrumentData and MeasurementSeries classes have been removed.
Code that referenced these types should be updated to work with
xarray.Dataset and xarray.DataArray instead.
fix_exponents has been removed. The .cnv readers handle exponent
formatting internally.
Renamed hex reading functions#
The instrument-specific hex reading functions have been renamed from mixed
case to lower snake_case and no longer specify a format. The old names remain
as deprecated aliases that forward to the new functions and emit a
DeprecationWarning.
v2 name |
v3 name |
|---|---|
|
|
|
|
|
|
|
|
|
|
The deprecated hex parameter has been removed from read_hex and the
hex reading functions. Use hex_segment instead.
SBE 911plus status bits#
read_sbe911plus_data now decodes the status nibble from the least
significant bit: bit 0 is pump status, bit 1 is bottom contact, bit 2 is
confirm, and bit 3 is modem.
pHyre and pHyreCAT#
InstrumentType.pHyre and InstrumentType.pHyreCAT have been added, with
a new read_phyre_data function. read_hex_file and read_hex support
both instruments. New HEX_TYPE_PH_TEMPERATURE_EXTERNAL and
HEX_TYPE_PH_TEMPERATURE_INTERNAL constants identify their reference
temperatures.
Hex data types and lengths#
The HexDataTypes enum is deprecated, and accessing any member emits a
DeprecationWarning. Use the module-level HEX_TYPE_* string constants
instead. The values are unchanged.
# v2
dataset[si.HexDataTypes.temperature.value]
# v3
dataset[si.HEX_TYPE_TEMPERATURE]
The HEX_LENGTH dictionary has been removed and replaced with
HEX_LEN_* constants, for example HEX_LEN_TEMPERATURE and
HEX_LEN_DATE_TIME.
cal_coefficients#
PressureDigiquartzCoefficients:AD590MandAD590Bhave been renamed toad590mandad590b. Newslope(default 1) andoffset(default 0, dbar) fields have been added.TemperatureCoefficientsandPressureCoefficientshave a newoffsetfield (default 0).PHSeaFETInternalCoefficientsis now a dataclass.kdf0andkdf2are required, and the deprecatedk0,k2,int_k0, andint_k2parameters have been removed.PHSeaFETExternalCoefficientsis now a dataclass. The deprecatedext_k0andext_k2parameters have been removed, andk2_poly_orderandfp_poly_orderare now the last fields. Code that constructs this class with positional arguments must be updated; keyword arguments are recommended.
conversion and eos80_conversion#
The individual convert_* functions still accept and return NumPy arrays.
The following changes affect existing code.
Pressure#
convert_pressure: the defaultunitsis now"psia"instead of"psig". Passunits="psig"to keep the v2 behavior. The coefficientoffsetis applied in dbar.convert_pressure_digiquartz:units="psia"now returns absolute pressure. In v2 it returned gauge pressure."psig"is now supported. The coefficientslopeandoffsetare applied in dbar. The temperature compensation average now uses a trailing 30 second window with edge padding, which can produce small numerical differences.
Conductivity#
convert_conductivity now takes a required instrument_type parameter
in place of scalar. The SBE 911plus scaling is applied automatically, and
the wbotc term is not applied for the SBE 16plus, SBE 19plus, and
SBE 911plus. A new units parameter selects "S/m" (default),
"mS/cm", or "uS/cm".
# v2
c.convert_conductivity(counts, temperature, pressure, coefs, scalar=0.1)
# v3
c.convert_conductivity(
counts, temperature, pressure, coefs, si.InstrumentType.SBE911Plus
)
SeaFET pH#
convert_internal_seafet_ph and convert_external_seafet_ph no longer
provide defaults for the data and coefficient parameters, and the deprecated
ph_counts parameter has been removed. Use raw_ph with
ph_units="counts".
Other parameter changes#
The following parameters are new and default to the v2 behavior:
convert_sbe43_oxygenandconvert_sbe63_oxygen:unitsselects the output units (default"ml/l").convert_sbe63_oxygenalso takes an optionalexternal_temperature.depth_from_pressure:water_typeselects"salt"(default) or"fresh".convert_altimeter:unitsselects"m"(default) or"ft".
EOS-80 functions#
The EOS-80 functions in eos80_processing are deprecated. Density and
potential temperature are now provided by the seawater library, and the
remaining functions have moved to eos80_conversion.
# v2
import seabirdscientific.eos80_processing as se
rho = se.density(salinity, temperature, pressure)
# v3
import seawater
rho = seawater.dens(salinity, temperature, pressure)
Note that the deprecated eos80_processing.density now returns density
minus 1000 kg/m^3 (sigma). In v2 it returned full density.
eos80_conversion.bouyancy_frequency and the deprecated
eos80_processing.bouyancy_frequency now use the seawater library and
the sigma convention used by SBE Data Processing. Results differ from v2.
buoyancy moved to conversion and was split#
The buoyancy and bouyancy_frequency functions have moved from
processing to conversion, and bouyancy_frequency has been renamed
to buoyancy_frequency. The versions in processing remain as
deprecated wrappers.
conversion.buoyancy only uses TEOS-10 equations. The EOS-80 calculation
is now eos80_conversion.buoyancy_eos80. Passing
use_modern_formula=False to conversion.buoyancy emits a
DeprecationWarning and returns arrays filled with the flag value.
# v2
import seabirdscientific.processing as p
result = p.buoyancy(..., use_modern_formula=True)
result = p.buoyancy(..., use_modern_formula=False)
# v3
# TEOS-10
import seabirdscientific.conversion as c
n2, n, e, e_scaled = c.buoyancy(...)
# EOS-80
import seabirdscientific.eos80_conversion as ec
n2, n, e, e_scaled = ec.buoyancy_eos80(...)
In v2, buoyancy returned a pandas.DataFrame with the columns N2,
N, E, and E10^-8. In v3, both functions return a tuple of four
NumPy arrays in the same order. Where N^2 is negative, N is now the negative
square root of the absolute value to match SeaSoft. In v2 it was NaN.
New functions#
The following functions are new in v3:
conversion:convert_temperature_units,convert_pressure_units,convert_conductivity_units,convert_oxygen_units,convert_oxygen_to_umol_per_l,derive_descent_rate,derive_acceleration,derive_oxygen_saturation_gg,derive_oxygen_saturation_w, andderive_nitrogen_saturation.eos80_conversion:derive_potential_temperature_anomaly,derive_thermosteric_anomaly,derive_sound_velocity,derive_specific_conductance,derive_average_sound_velocity, andderive_gpa.
contour#
The parameters of contour_from_t_s_p and contour_from_t_c_p have been
renamed. The old names remain as deprecated keyword arguments.
v2 name |
v3 name |
|---|---|
|
|
|
|
|
|
|
|
A new reference_pressure parameter (default 0) sets the reference
pressure for potential density. Samples with salinity below min_salinity
are now set to NaN instead of being removed, so the output arrays have the
same length as the input arrays.
The density grid now spans the data with a fixed margin of 1 g/kg absolute salinity and 1 deg C conservative temperature, with a step of 0.1 on both axes. In v2 the margin was a percentage of the minimum and maximum values, and the temperature step was 1 deg C. The salinity grid does not extend below 0.
processing#
bin_average#
bin_average previously accepted and returned a pandas.DataFrame. It
now accepts and returns an xarray.Dataset. The input must have a scan
dimension, such as the dataset returned by read_cnv_file or
read_hex_file. The output uses a bin_number dimension and keeps the
input dataset attributes. It now raises a ValueError is CastType is invalid.
dataset = si.read_cnv_file(filepath, software="seasoft")
binned = p.bin_average(dataset, "prdM", bin_size=1)
loop_edit#
loop_edit_depth and loop_edit_pressure are deprecated and replaced by
loop_edit. loop_edit takes depth by default, or pressure with
units="pressure" and a latitude. Most parameters now have defaults.
The return value has changed. In v2, the functions modified the flag
array in place and returned a cast array (-1 for downcast, 1 for upcast, 0
otherwise). In v3, loop_edit returns a new flag array and does not modify
the input.
# v2
p.loop_edit_pressure(pressure, latitude, flag, interval, MinVelocityType.FIXED, ...)
dataset["flag"] = flag
# v3
dataset["flag"] = p.loop_edit(
pressure, flag, interval, "fixed", ..., latitude=latitude, units="pressure"
)
The use_deck_pressure_offset option now adds the first depth value to the
minimum and maximum soak depths. In v2 it was subtracted.
split and cast selection#
split now takes an xarray.Dataset and returns a copy with a
cast_type coordinate that labels each scan as "downcast",
"upcast", or None. In v2 it returned a list of DataFrames. The
control_name and split_mode parameters have been renamed to
control_variable and cast_type. New min_value and drop
parameters have been added. Set drop=True to remove unlabeled scans.
# v2
downcast, upcast = p.split(df, "prdM", CastType.BOTH)
# v3
ds = p.split(dataset, "prdM", CastType.BOTH)
downcast = ds.where(ds["cast_type"] == "downcast", drop=True)
upcast = ds.where(ds["cast_type"] == "upcast", drop=True)
get_downcast and get_upcast have been removed. Use split, or the
new find_downcast and find_upcast functions, which return the start
and end indices of a cast from depth and flag arrays. A new trim function
trims a DataFrame to a range of a control variable.
The CastType enum values are now strings ("both", "downcast",
"upcast", ""), and CastType.NA has been renamed to
CastType.NONE. bin_average raises a ValueError for an invalid
cast_type.
String literals replace enums#
Several parameters that previously took enum values now take string literals.
The enums are deprecated and emit a DeprecationWarning when passed.
loop_edit: themin_velocity_typeparameter now takes"fixed"or"percent"instead ofMinVelocityType.FIXEDorMinVelocityType.PERCENT.window_filter: thewindow_typeparameter now takes one of"boxcar","cosine","gaussian","median", or"triangle"instead of aWindowFilterTypeenum value.
# v2
p.window_filter(data, flags, WindowFilterType.BOXCAR, width, interval)
# v3
p.window_filter(data, flags, "boxcar", width, interval)
window_filter#
window_filter now increments an even window_width by one so that the
window has a center point.
wild_edit#
wild_edit now passes each block’s slice of flags to the flagging step.
In v2 the full flag array was passed for every block, so existing flags were
not aligned with the data in each block. Results can differ from v2 when the
input contains flagged values.
cell_thermal_mass#
The temperature_C and conductivity_Sm parameters have been renamed to
temperature and conductivity. The old names remain as deprecated
keyword arguments. amplitude, time_constant, and sample_interval
now default to 1.
Removed aliases#
The deprecated v2 aliases min_velocity_mask, mean_speed_percent_mask,
flag_by_minima_maxima, and flag_data have been removed. These were
internal functions and have no public replacement.
visualization#
The ChartData class has been removed. Charting functions now take an
xarray.Dataset directly in place of a ChartData object.
# v2
config = vis.ChartConfig(...)
chart_data = vis.ChartData(source, config)
figure = vis.plot_xy_chart(chart_data, config)
# v3
config = vis.ChartConfig(...)
dataset = si.read_cnv_file(filepath, software="seasoft")
figure = vis.plot_xy_chart(dataset, config)
The ChartConfig constructor keeps the same parameters, but x_names,
y_names, and z_names are no longer normalized with
interpret_sbs_variable. They must match variable names in the dataset. For
example, a tv290C variable must be referenced as tv290C, not
t090C. When titles are not provided, they default to the variable title
from interpret_sbs_variable (for example "Temperature") instead of the
variable name.
create_single_plot, create_subplots, and create_overlay now take
xarray.Dataset objects for x and y. create_single_plot now
builds the figure with plotly.graph_objects instead of plotly.express.
visualization requires the plots extra.
parse_instrument_data now accepts an xarray.Dataset in addition to
the v2 source types and returns an xarray.Dataset. select_subset now
operates on and returns an xarray.Dataset. When called with an empty name
list it returns a variable named "Scan Count" instead of
"Sample Count", and it raises a KeyError for names not in the
dataset.
interpret_sbs_variable#
Variable definitions are now loaded from resources/sbs_variables.json.
interpret_sbs_variable returns a dictionary with the additional keys
aliases, title, and info. Unit strings no longer include the
calibration standard or sensor information, which is now in info. For
example, t090C has units "deg C" and info ["ITS-90"]. In v2 the
units were "ITS-90, deg C".
utils#
plot imports matplotlib when called and requires the plots extra.
get_tolerance takes an optional flag_value parameter (default
-9.99e-29).
constants#
Numeric constants that were previously defined within individual modules are
now consolidated in a new constants module (for example
KELVIN_OFFSET_0C, ITS90_TO_IPTS68, FLAG_VALUE, and
COUNTS_TO_VOLTS). Constants such as conversion.KELVIN_OFFSET_0C are no
longer available from their original modules. Import them from constants
instead.
Example notebooks and data#
The example notebooks and example data have moved from the documentation
directory to a new notebooks directory. If you referenced these files by
path, update the paths accordingly.
Deprecation reference#
The following names still work in v3 but emit a DeprecationWarning and
should be updated:
Deprecated |
Replacement |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The following have been removed with no compatibility alias:
instrument_data.InstrumentDatainstrument_data.MeasurementSeriesinstrument_data.fix_exponentsinstrument_data.HEX_LENGTHThe
hexparameter ofinstrument_data.read_hexand the hex reading functionsprocessing.get_downcastandprocessing.get_upcastprocessing.min_velocity_mask,processing.mean_speed_percent_mask,processing.flag_by_minima_maxima, andprocessing.flag_dataprocessing.CastType.NA(renamed toCastType.NONE)The
scalarparameter ofconversion.convert_conductivityThe
ph_countsparameter ofconversion.convert_internal_seafet_phandconversion.convert_external_seafet_phThe
AD590MandAD590Bfields ofcal_coefficients.PressureDigiquartzCoefficients(renamed toad590mandad590b)The
k0,k2,int_k0, andint_k2parameters ofcal_coefficients.PHSeaFETInternalCoefficientsThe
ext_k0andext_k2parameters ofcal_coefficients.PHSeaFETExternalCoefficientsConstants defined in
conversion(moved toconstants)visualization.ChartData