API reference

The public API is a set of verbs on the top-level package:

  • seagliderOG1.read — read a mission’s basestation files into a list of datasets.

  • seagliderOG1.convert — convert that list into one OG1 dataset.

  • seagliderOG1.write — write the OG1 dataset to netCDF.

  • seagliderOG1.report — write the HTML conversion page for a written file.

  • seagliderOG1.enrich — set global attributes on a written file, in place.

  • seagliderOG1.process — load a mission configuration and run read + convert + write (and optionally the page) for one mission.

  • seagliderOG1.process_missions — the same across a root of several missions.

  • seagliderOG1.mission — load and check a mission.yaml (mission.load / mission.check).

plus the exceptions seagliderOG1.MissionError and seagliderOG1.MetadataError, and the supporting modules tools, plotters, vocabularies and contributors.

Modules

  • __init__.py — the public verbs (read, convert, write, report, enrich, process, process_missions), re-exported from the modules below.

  • readers.py — read basestation files from a server or a local directory.

  • _convert.py — convert orchestrates mapping, standardisation, concat and the single post-concat dtype pass; process / process_missions run the pipeline from a configuration. Private: not imported directly.

  • writers.py — write OG1 files and enrich a written file’s globals.

  • mission.py — the mission.yaml schema: load, check.

  • tools.py — user-facing utilities.

  • vocabularies.py — vocabulary and mapping tables (the defaults; see Packaged defaults and your local tables).

  • plotters.py — plotting. contributors.py — contributor/institution record handling.

  • reports/ — the HTML conversion page (report) and the reader behind it.

  • cli/ — the seagliderOG1 command, one module per verb.

  • config/*.yaml — the OG1 mappings and vocabularies (see Packaged defaults and your local tables).

verbs

seagliderOG1.read(raw_dir: str | PathLike[str], dives: tuple[int, int] | None = None, *, repair: bool = False) → list[Dataset][source]

Read a mission directory of basestation files into datasets.

The public form of read_mission(): one directory in, a list of datasets out.

Parameters:
  • raw_dir (str or os.PathLike) – A mission directory holding basestation files (pSSSDDDD*.nc).

  • dives (tuple of (int, int), optional) – First and last dive to read, inclusive. Default is None (every file present).

  • repair (bool, optional) – When True, run repair_files() first (it rewrites files with inconsistent time metadata in the source tree). Default is False.

Returns:

The basestation datasets, ordered by filename.

Return type:

list of xarray.Dataset

seagliderOG1.convert(list_of_datasets: Sequence[Dataset], mission: str | PathLike | Mapping[str, object] | None = None, *, contributors: Sequence[dict] | None = None, institutions: Sequence[dict] | None = None, platform: dict[str, object] | None = None, deployment: dict[str, object] | None = None, deployment_information: dict[str, object] | None = None, global_attributes: dict[str, object] | None = None, sensors: Mapping[str, Mapping[str, object]] | None = None, unit_corrections: Mapping[str, Mapping[str, object]] | None = None, mode: str | None = None, record: dict | None = None) → Dataset[source]

Convert Seaglider basestation datasets to OG1 format.

Maps and standardises each dataset, concatenates them on a shared time axis, sorts by time, and applies platform, deployment and contributor attributes.

Parameters:
  • list_of_datasets (sequence of xarray.Dataset) – A list of xarray datasets in basestation format. The datasets are concatenated and sorted by time, so the input order does not matter: start_date, TRAJECTORY and the output id are seeded from the earliest measurement time and so always agree with time_coverage_start.

  • mission (str or os.PathLike or collections.abc.Mapping, optional) – A mission.yaml path or an already-loaded mapping (from seagliderOG1.mission.load()). Its platform, the three global-attribute sections (merged into deployment), global_attributes, sensors, contributors, institutions and mode are used; the raw_dir / output_dir / dives keys are ignored (convert works on datasets already read). An explicit keyword below overrides the mission value — including an explicit empty mapping (platform={}), which overrides the mission’s block with nothing rather than falling back to it. Default is None.

  • contributors (sequence of dict, optional) – Contributor records (name, role and optional email, orcid) merged with those already on the files. When None, contributors come from the files’ own attributes; no package default is applied. Default is None.

  • institutions (sequence of dict, optional) – Institution records (name, role and optional id) merged with those on the files and resolved against the EDMO registry. Default is None.

  • platform (dict of str to object, optional) – Platform fields from the mission config (PLATFORM_SERIAL_NUMBER, PLATFORM_MODEL, PLATFORM_MAKER, PLATFORM_DEPTH_RATING, GLIDER_FIRMWARE_VERSION, LANDSTATION_VERSION, WMO_IDENTIFIER, platform_model_vocabulary). Config values override file-derived ones. Default is None.

  • deployment (dict of str to object, optional) – The deployment-identity globals from the mission config deployment block (id, program, license, doi, site, …). Written as global attributes; a value for id (derived) or comment (kept from the basestation files when they carry one) overrides it with a warning. Nulls skipped. Default is None.

  • deployment_information (dict of str to object, optional) – The cruise-level deployment position and time from the mission config deployment_information block (DEPLOYMENT_TIME, DEPLOYMENT_LATITUDE, DEPLOYMENT_LONGITUDE). When given they set the OG1 DEPLOYMENT_* variables; otherwise they are derived from the first in-water fix. DEPLOYMENT_TIME after the first data sample warns. Default is None.

  • global_attributes (dict of str to object, optional) – Global attributes written verbatim into the output (nulls skipped). A key that collides with a converter-derived global, or with a key that has a structured home in deployment, raises. Default is None.

  • sensors (collections.abc.Mapping, optional) – Corrections to the basestation sensor records, from the mission config sensors: block: sensor key (a name in the instrument global) to {"serial_number": ..., "calibration_date": ...}. A corrected serial names the SENSOR_* variable; the sensor’s comment records the value it replaced. Default is None.

  • unit_corrections (collections.abc.Mapping, optional) – Per-mission units-label corrections from the mission config unit_corrections: block: basestation variable name to {"from": <label as written or null>, "to": <label to write>}. Applied before unit conversion, in origin terms, and layered over the package corrections (vocabularies.basestation_unit_corrections) so a mission entry wins on a shared key. Use it for a one-off mislabel on this mission; the package file carries the systematic, cross-mission defects. Default is None.

  • mode (str or None, optional) – Data mode, "realtime" or "delayed". Sets the id suffix (R or delayed) and so the output filename, per the OG1 manual, which defines no separate data-mode attribute. Default is None: the mission’s mode if it has one, else "realtime". An explicit value (including "realtime") always wins over the mission’s.

  • record (dict, optional) – When given, filled in place with what the output file cannot record about its own conversion: inputs (one {"path", "bytes", "dive"} per input file) and presence (which dives each variable is present and valid in). Pass it to writers.write(..., record=record) to write it beside the file. Default is None.

Returns:

The concatenated and processed dataset in OG1 format.

Return type:

xarray.Dataset

Raises:
  • MetadataError – If an OG1-mandatory global attribute is absent after all metadata sources are merged (a converter problem: the mandatory set is derived or constant).

  • ValueError – If global_attributes sets a converter-derived or deployment-home key, if deployment has an unknown key, if no datasets are valid, or if mode is not "delayed"/"realtime".

seagliderOG1.write(ds: Dataset, path: str | Path, *, overwrite: bool = False, record: dict | None = None) → Path[source]

Write the dataset to a NetCDF file with lossless compression.

Every non-scalar numeric variable, coordinates included, is written with zlib at level 4 and the shuffle filter. Attributes are checked before anything is written: one netCDF cannot store is refused by name, never converted to text. The input dataset is copied first, so the caller’s dataset is not modified.

Parameters:
  • ds (xr.Dataset) – Dataset to save.

  • path (str or pathlib.Path) – Output NetCDF file path.

  • overwrite (bool, optional) – If True, an existing file will be deleted and replaced. If False, a FileExistsError is raised when the file exists.

  • record (dict, optional) – The conversion record (as filled by convert(record=...)) to write beside the file as <stem>_conversion.json (conversion_path()), bound to it by the dataset’s id and tracking_id; a record already there is replaced. Nothing from it is written into the NetCDF file. Default is None (no record).

Returns:

The path written.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is False.

  • ValueError – If the dataset carries a None-valued attribute.

  • TypeError – If an attribute (global or on a variable) has a type netCDF cannot store, such as a dict or a bool; the message names each one. Nothing is written or removed.

seagliderOG1.report(nc_path: str | PathLike, out: str | PathLike | None = None, *, title: str | None = None, overwrite: bool = False) → Path[source]

Write the HTML conversion page for an OG1 file and return its path.

Parameters:
  • nc_path (str or os.PathLike) – The OG1 netCDF file.

  • out (str or os.PathLike, optional) – Where to write the page. Default is <id>_conversion.html beside the file.

  • title (str or None, optional) – Page title; the file name by default.

  • overwrite (bool, optional) – Replace an existing page. Default is False.

Returns:

The path of the written page.

Return type:

pathlib.Path

Raises:
  • FileNotFoundError – If nc_path does not exist.

  • FileExistsError – If the page exists and overwrite is False.

seagliderOG1.enrich(path: str | Path, *, mission: str | Path | Mapping[str, object] | None = None, deployment: Mapping[str, object] | None = None, global_attributes: Mapping[str, object] | None = None, doi: str | None = None) → Path[source]

Set global attributes on a written OG1 file without converting again.

For metadata that exists only after the file is written — a DOI assigned on publication — or a corrected global-attribute value. Only global attributes change (edited in place; variables are not rewritten). The file gets date_modified set to now, a history line naming the keys, and a new tracking_id; date_created is kept. Every value is checked before the file is opened for writing, so a refused value leaves the file as it was. Replacing a different value already in the file warns with both values. The conversion record beside the file is rebound to the new tracking_id and SHA-256.

Parameters:
  • path (str or pathlib.Path) – The OG1 netCDF file.

  • mission (str or os.PathLike or collections.abc.Mapping, optional) – A mission.yaml path or loaded mapping; only its three global-attribute sections and global_attributes are used (merged into deployment and global_attributes below). The platform: block and other keys are ignored — enrich edits globals only. Default is None.

  • deployment (collections.abc.Mapping, optional) – Deployment-identity globals to set (as in seagliderOG1.convert()); null values are skipped. Overrides the mission’s merged sections. Default is None.

  • global_attributes (collections.abc.Mapping, optional) – global_attributes: keys to set. Overrides the mission’s. Default is None.

  • doi (str, optional) – The DOI, written as the doi global (wins over deployment["doi"]).

Returns:

The enriched file.

Return type:

pathlib.Path

Raises:
  • ValueError – If nothing is given to set; a key is one the converter owns or that belongs in the other block; a value is not text, a number or a date; a key is one enrich writes itself (date_modified, history, tracking_id, draft) or a conversion_* record; or deployment["id"] differs from the file’s id (the file name and the conversion record are bound to it: convert again to change it).

  • FileNotFoundError – If path does not exist.

seagliderOG1.process(mission: str | PathLike | Mapping[str, object], *, raw_dir: str | PathLike | None = None, output_dir: str | PathLike | None = None, dives: tuple[int, int] | None = None, mode: str | None = None, repair: bool | None = None, report: bool = False, report_dir: str | PathLike | None = None, overwrite: bool = False) → Path[source]

Convert one mission from its configuration and write the OG1 file.

Loads and validates mission (a mission.yaml path or a mapping from seagliderOG1.mission.load()), then reads, converts and writes it. The file is <output_dir>/<id>.nc with the conversion record <id>_conversion.json beside it. The keyword arguments override the configuration’s output_dir, dives, mode and report.

Parameters:
  • mission (str or os.PathLike or collections.abc.Mapping) – A mission.yaml path, or a loaded mapping. Its raw_dir must be a single mission directory; a root of SN/DATE missions raises (use process_missions()).

  • raw_dir (str or os.PathLike, optional) – The directory of basestation files to convert; overrides the configuration’s raw_dir (as process --raw-dir does). Default is None.

  • output_dir (str or os.PathLike, optional) – Directory the OG1 file is written to; created if missing. Overrides the configuration’s output_dir. Default is None (use the configuration’s).

  • dives (tuple of (int, int), optional) – First and last dive to convert, inclusive. Overrides the configuration’s dives. Default is None (use the configuration’s, else every dive).

  • mode (str, optional) – Data mode, "realtime" or "delayed"; overrides the configuration’s. Default is None.

  • repair (bool, optional) – Repair basestation time metadata before loading (rewrites the raw_dir tree); overrides the configuration’s repair. Default is None.

  • report (bool, optional) – Also write the HTML conversion page beside the file. ORed with the configuration’s report. Default is False.

  • report_dir (str or os.PathLike, optional) – With report, write the page under <report_dir>/<id>/ instead of beside the file. Default is None.

  • overwrite (bool, optional) – Replace an existing output file (and, with report, the page). Default is False.

Returns:

The path of the written OG1 file.

Return type:

pathlib.Path

Raises:
  • MissionError – If the configuration is invalid, or its raw_dir is a root of SN/DATE missions (use process_missions()).

  • FileExistsError – If the output file or page exists and overwrite is False.

  • MetadataError – As raised by convert().

seagliderOG1.process_missions(mission: str | PathLike | Mapping[str, object], *, select: str | None = None, raw_dir: str | PathLike | None = None, output_dir: str | PathLike | None = None, mode: str | None = None, repair: bool | None = None, report: bool = False, report_dir: str | PathLike | None = None, overwrite: bool = False) → list[Path][source]

Convert every selected mission under a root, from one configuration.

For a mission.yaml whose raw_dir is a root of SN/DATE mission directories: the configuration’s metadata applies to every mission selected. A single range of dives cannot span missions, so there is no dives argument.

Parameters:
  • mission (str or os.PathLike or collections.abc.Mapping) – A mission.yaml path, or a loaded mapping, whose raw_dir is a root of SN/DATE missions.

  • select (str or None, optional) – A glob over each mission’s SN/DATE path; "*/*" selects every mission. Required for a root. Default is None.

  • raw_dir (str or os.PathLike, optional) – The root of SN/DATE missions; overrides the configuration’s raw_dir. Default is None.

  • output_dir (str or os.PathLike, optional) – Directory the OG1 files are written to. Overrides the configuration’s. Default is None.

  • mode (str, optional) – Data mode; overrides the configuration’s. Default is None.

  • repair (bool, optional) – Repair basestation time metadata before loading; overrides the configuration’s repair. Default is None.

  • report (bool, optional) – Also write each HTML conversion page. ORed with the configuration’s report. Default is False.

  • report_dir (str or os.PathLike, optional) – With report, write each page under <report_dir>/<id>/. Default is None.

  • overwrite (bool, optional) – Replace existing output files. Default is False.

Returns:

One path per selected mission, in selection order.

Return type:

list of pathlib.Path

Raises:
  • MissionError – If the configuration is invalid.

  • ValueError – If select matches no mission, or is omitted for a root.

mission

Mission-configuration schema, loader and validator.

The mission configuration (mission.yaml) lives outside the installed package so that platform, contributor and global-attribute metadata belong to the user rather than to seagliderOG1. This module holds the known keys, the validation checks, and the two public entry points a caller needs:

  • load() reads a mission.yaml (or an already-loaded mapping), validates it, resolves raw_dir / output_dir relative to the file, and returns the configuration with the file’s own keys (the three global-attribute sections left unmerged).

  • check() returns the list of validation issues without raising, for the validate verb to print.

It is the single place that parses a mission configuration. The commented template that init writes, and the printing of issues, stay in the CLI (cli/_mission.py), which imports the schema tables from here.

Kept import-light on purpose (module-level imports are the standard library and yaml only); readers, vocabularies and contributors are imported inside the functions that need them, so building the CLI parser and --help do not pull in xarray or the packaged-YAML reads.

class seagliderOG1.mission.ValidationIssue(level: str, message: str, key: str | None)[source]

A single problem found in a mission configuration.

Parameters:
  • level (str) – Severity, either "ERROR" or "WARNING".

  • message (str) – Human-readable description of the problem.

  • key (str or None) – The configuration key the problem relates to, or None if general.

key: str | None

Alias for field number 2

level: str

Alias for field number 0

message: str

Alias for field number 1

seagliderOG1.mission.check(path: str | PathLike, *, strict: bool = False, raw_dir_override: str | None = None) → list[ValidationIssue][source]

Validate a mission configuration file, returning its issues without raising.

Parameters:
  • path (str or os.PathLike) – Path to the mission.yaml file.

  • strict (bool, optional) – When True, also require every dive in the dives range to be present. Default is False.

  • raw_dir_override (str or None, optional) – A command-line --raw-dir that replaces the config’s raw_dir for validation, so an override is checked rather than the stale config value.

Returns:

All problems found, ERROR and WARNING; empty when the config is valid.

Return type:

list of ValidationIssue

seagliderOG1.mission.global_rows() → list[dict[str, str]][source]

Return one row per OG1 global the package knows a tier or a config home for.

Every name in vocabularies.REQUIRED_GLOBALS, in tier order, followed by the global-section keys with no OG1 tier (license, acknowledgment), marked optional. The single source for the global-section template comments, the validate highly-desirable check and list globals.

Returns:

Rows with keys name, tier, source (derived / constant / config), set_in (the mission.yaml block, or “”) and note (what an override does, or “”).

Return type:

list of dict of str to str

seagliderOG1.mission.load(config: str | PathLike | Mapping[str, object]) → dict[source]

Load and validate a mission configuration, returning it with resolved paths.

Parameters:

config (str or os.PathLike or Mapping) – A path to a mission.yaml file, or an already-loaded mapping.

Returns:

The configuration with the file’s own keys (the three global-attribute sections left unmerged; config_version and local_config kept, so the returned mapping round-trips back through load()), raw_dir and output_dir resolved to absolute paths.

Return type:

dict

Raises:

MissionError – If the configuration has one or more validation errors, or (for a mapping) a relative raw_dir / output_dir with no base directory to resolve against.

seagliderOG1.mission.platform_rows() → list[dict[str, str]][source]

Return one row per platform: key, in template order.

Read from vocabularies.PLATFORM_FIELDS (requirement, basestation source) plus the two _vocabulary keys, which are attributes on PLATFORM_MODEL / PLATFORM_MAKER. The single source for the platform: template comments and list platform.

Returns:

Rows with keys key, requirement (required / optional), destination (variable or attribute on <VARIABLE>), from_file (the basestation global init --raw-dir reads, or “”) and hint.

Return type:

list of dict of str to str

seagliderOG1.mission.select_missions(root: str | PathLike, select: str | None = None) → list[source]

Return the missions under root to convert.

Parameters:
  • root (str or os.PathLike) – A basestation directory: a single mission directory (p*.nc inside) or a root of SN/DATE mission directories.

  • select (str or None, optional) – For a root, a glob over each mission’s SN/DATE path (*/* selects every mission). Ignored for a single mission directory; required for a root.

Returns:

The selected missions, as returned by readers.discover_missions.

Return type:

list

Raises:

ValueError – If select is given for a single mission directory, if a root is given with no select, or if select matches no mission under the root.

vocabularies

Vocabularies and mappings for OG1 format conversion.

This module defines the vocabulary mappings, unit conversions, and attribute configurations used to convert Seaglider basestation files to OG1 format. It loads YAML configuration files and defines various dictionaries used throughout the conversion process.

Key Components:

  • Variable name mappings from basestation to OG1 format

  • Unit conversion factors and formatting rules

  • Global attribute definitions and ordering

  • Variables to include/exclude during conversion

  • Dimension renaming mappings

Configuration Files:

  • OG1_variable_names.yaml: Variable name mappings

  • OG1_unit_corrections.yaml: Basestation units labels that are wrong for the values

  • OG1_sensor_names.yaml: Sensor keys to OG1_sensor_attributes.yaml titles

  • OG1_variable_attributes.yaml: Variable attribute vocabularies

  • OG1_sensor_attributes.yaml: Sensor attribute definitions

  • OG1_global_attributes.yaml: Global attribute configurations

Notes

This module is primarily data-driven and loads most configuration from YAML files in the config/ directory. The YAML-based approach allows easy modification of OG1 format requirements without code changes.

class seagliderOG1.vocabularies.PlatformField(source: str | None, formatter: Callable[[object], str] | None, required: bool, kind: str)[source]

How one OG1 platform field is sourced and written.

Parameters:
  • source (str or None) – Basestation global attribute the value derives from, or None when the field is config-only (no file fallback).

  • formatter (callable or None) – Applied to the file value before use; None when there is no file source.

  • required (bool) – When True, a null in the mission config is a validate ERROR rather than a silent default written into the output.

  • kind (str) – How to_og1 writes an unset field: "serial" names the output and raises when absent, "string" warns and writes "UNK", "numeric" is omitted, "optional_string" is omitted silently (an optional platform variable the user may leave null).

formatter: Callable[[object], str] | None

Alias for field number 1

kind: str

Alias for field number 3

required: bool

Alias for field number 2

source: str | None

Alias for field number 0

seagliderOG1.vocabularies.platform_from_file(attrs: dict) → dict[source]

Derive OG1 platform fields from a basestation file’s global attributes.

Parameters:

attrs (dict) – The first basestation file’s global attributes.

Returns:

The OG1 platform fields derivable from the file (only those whose source attribute is present).

Return type:

dict

contributors

Contributor and institution attributes for OG1, as comma-aligned lists.

OG1 records contributors as parallel comma-separated attributes — contributor_name, contributor_email, contributor_id, contributor_role and contributor_role_vocabulary — one slot per person, empty slots preserved so the lists stay aligned (three people with one email give "a@x, , c@z"). Institutions are a separate parallel set (contributing_institutions and its _role, _vocabulary and _role_vocabulary).

This module parses those attributes into records and formats records back, without dropping interior empties, deduping within a field, or rewriting commas inside a value. One role per slot: a person with two roles is listed twice.

seagliderOG1.contributors.canonical_orcid(value: object) → str[source]

Return an ORCID as a full https://orcid.org/… URL, or "" when absent.

Parameters:

value (object) – A bare ORCID, a full ORCID URL, or None/empty.

Returns:

The normalised URL; an existing http value is kept; empty stays "".

Return type:

str

seagliderOG1.contributors.canonical_role(role: str) → str | None[source]

Return the preferred W08 label for a role.

Parameters:

role (str) – The role label as given (any case), a known spelling variant, or empty.

Returns:

The preferred W08 label; "" for an empty (role-less) value; None when the role is not a W08 term or attested alias (caller decides whether that is a config error or a file-derived passthrough).

Return type:

str or None

seagliderOG1.contributors.consolidate(records: Sequence[Mapping]) → list[dict[str, str]][source]

Merge records on (normalised name, role), filling empty fields.

Same person/institution with the same role from two sources becomes one slot, its empty email/id filled from the duplicate. Two different roles stay two slots. A role-less record merges into a same-name record that has a role (in either order); a role is never invented and two roles are never combined.

Parameters:

records (sequence of Mapping) – Records with at least name and role.

Returns:

Consolidated records, order preserved by first appearance.

Return type:

list of dict of str to str

seagliderOG1.contributors.enrich_institutions(institutions: Sequence[Mapping]) → list[dict[str, str]][source]

Resolve institution names against the EDMO registry.

A name (whitespace-collapsed) matched in the registry is written as the registry standard_name with the EDMO URL; a config id wins over the registry. An unmatched name is written as given (a comma replaced by a space, with a warning) and no EDMO id (also warned); nothing is invented.

Parameters:

institutions (sequence of Mapping) – Records with name, role and optional id.

Returns:

Records with name, role and id resolved for formatting.

Return type:

list of dict of str to str

seagliderOG1.contributors.format_contributors(people: Sequence[Mapping]) → dict[str, str][source]

Format person records into the five aligned contributor_* attributes.

Parameters:

people (sequence of Mapping) – Records with name, email, role and either id or orcid; an explicit role_vocabulary overrides the role-derived one.

Returns:

The five contributor_* attributes, each a ", "-joined aligned list. Empty when people is empty.

Return type:

dict of str to str

seagliderOG1.contributors.format_institutions(institutions: Sequence[Mapping]) → dict[str, str][source]

Format institution records into the four contributing_institutions* attrs.

Parameters:

institutions (sequence of Mapping) – Records with name, role and id.

Returns:

The four aligned contributing_institutions* attributes; empty when institutions is empty.

Return type:

dict of str to str

seagliderOG1.contributors.institution_registry() → dict[str, dict][source]

Read the EDMO institution registry, keyed by EDMO code.

Cached: the registry is a read-only package data file, so the YAML is parsed once per process even when every mission in a run resolves institutions.

Returns:

EDMO code -> registry entry (standard_name, name_variants, …).

Return type:

dict of str to dict

seagliderOG1.contributors.load_institution_registry() → dict[str, tuple[str, str]][source]

Build a name lookup from the EDMO institution registry.

Returns:

Maps each normalised standard name and name variant to its (standard_name, id_url).

Return type:

dict of str to (str, str)

seagliderOG1.contributors.parse_contributors(attrs: Mapping) → list[dict[str, str]][source]

Parse creator_* then contributor_* attributes into person records.

Parameters:

attrs (Mapping) – A dataset’s global attributes.

Returns:

Records with name, email, id, role and role_vocabulary, creators first.

Return type:

list of dict of str to str

seagliderOG1.contributors.parse_institutions(attrs: Mapping) → list[dict[str, str]][source]

Parse contributing_institutions* attributes into institution records.

Parameters:

attrs (Mapping) – A dataset’s global attributes.

Returns:

Records with name, role and id.

Return type:

list of dict of str to str

seagliderOG1.contributors.role_vocabulary(role: str) → str[source]

Return the W08 term URI for a contributor or institution role.

Parameters:

role (str) – The role label (any case) or a known spelling variant.

Returns:

The term URI from vocabularies.ROLE_VOCABULARY; "" for an empty or unrecognised role (an unrecognised role is never given a URL).

Return type:

str

seagliderOG1.contributors.split_aligned(value: object) → list[str][source]

Split a comma-separated OG1 attribute into stripped parts, keeping empties.

Parameters:

value (object) – The attribute value (string, or None/empty for an absent attribute).

Returns:

One stripped element per comma-separated slot; [] when absent. Interior and trailing empties are preserved ("a, , c" becomes ["a", "", "c"]).

Return type:

list of str

readers

Readers module for Seaglider basestation files.

This module provides functions to read Seaglider basestation NetCDF files from either online sources or local directories. It does not manipulate the data, only loads it into xarray datasets.

seagliderOG1.readers.discover_missions(source: str | PathLike[str]) → list[Mission][source]

Discover Seaglider missions under a directory.

A directory holding basestation files (pSSSDDDD*.nc) directly is one mission. A directory whose second-level SN/DATE subdirectories hold such files is a root: one mission per SN/DATE directory. Discovery is the same rule the CLI and notebooks share.

Parameters:

source (str or os.PathLike) – A mission directory, or a root of SN/DATE mission directories.

Returns:

One entry per mission, sorted by path. Empty when nothing is found.

Return type:

list of Mission

Raises:

ValueError – If source is not an existing directory.

seagliderOG1.readers.load_sample_basestation(file_path: str = '/home/runner/work/seagliderOG1/seagliderOG1/seagliderOG1/data/sg271/p2710001.nc') → Dataset[source]

Open a bundled sample Seaglider basestation file.

The sample is the sg271 Drygalski Trough mission (PycnMix), three dives shipped inside the package, so it loads from an installed package as well as a source checkout.

Parameters:

file_path (str, optional) – Path to the sample basestation file to load. Default is the bundled sg271 dive 1 file (seagliderOG1/data/sg271/p2710001.nc).

Returns:

The requested sample dataset loaded from disk.

Return type:

xarray.Dataset

Raises:

KeyError – If the requested dataset file does not exist.

seagliderOG1.readers.read(raw_dir: str | PathLike[str], dives: tuple[int, int] | None = None, *, repair: bool = False) → list[Dataset][source]

Read a mission directory of basestation files into datasets.

The public form of read_mission(): one directory in, a list of datasets out.

Parameters:
  • raw_dir (str or os.PathLike) – A mission directory holding basestation files (pSSSDDDD*.nc).

  • dives (tuple of (int, int), optional) – First and last dive to read, inclusive. Default is None (every file present).

  • repair (bool, optional) – When True, run repair_files() first (it rewrites files with inconsistent time metadata in the source tree). Default is False.

Returns:

The basestation datasets, ordered by filename.

Return type:

list of xarray.Dataset

seagliderOG1.readers.read_file(source: str | PathLike[str]) → Dataset[source]

Load the first (alphabetically) basestation file from a source.

Useful for quick examination of data structure and metadata from a Seaglider mission without loading all files.

Parameters:

source (str or os.PathLike) – URL or local directory path containing NetCDF files.

Returns:

The first basestation dataset.

Return type:

xarray.Dataset

seagliderOG1.readers.read_mission(source: str | PathLike[str], start_profile: int | None = None, end_profile: int | None = None, *, repair: bool = False) → list[Dataset][source]

Load multiple Seaglider basestation files with optional profile filtering.

Main function for loading Seaglider data from either online repositories or local directories. Supports filtering by dive/profile number range.

Parameters:
  • source (str or os.PathLike) – Directory path containing Seaglider NetCDF files.

  • start_profile (int, optional) – Minimum profile number to load.

  • end_profile (int, optional) – Maximum profile number to load.

  • repair (bool, optional) – When True, run repair_files() first (it rewrites files with inconsistent time metadata in the source tree). Default False: the source tree is never modified unless explicitly asked.

Returns:

List of loaded basestation datasets, ordered by filename.

Return type:

list of xarray.Dataset

seagliderOG1.readers.repair_files(source: str | PathLike[str], start_profile: int | None = None, end_profile: int | None = None) → None[source]

Scan NetCDF files and repair inconsistent time metadata only when needed.

Parameters:
  • source (str or os.PathLike) – Directory path containing NetCDF files to scan and repair.

  • start_profile (int, optional) – Minimum profile number to include (inclusive).

  • end_profile (int, optional) – Maximum profile number to include (inclusive).

Return type:

None

seagliderOG1.readers.sample_mission_dir() → Path[source]

Return the packaged sample mission directory.

The directory holds the bundled sg271 sample — three dives of the Drygalski Trough PycnMix mission — and its mission.yaml, shipped inside the installed package.

Returns:

The seagliderOG1/data/sg271 directory.

Return type:

pathlib.Path

seagliderOG1.readers.validate_filename(filename: str) → bool[source]

Validate if filename matches expected Seaglider basestation patterns.

Validates against two expected patterns: 1. p1234567.nc (7 digits after ‘p’) 2. p0420100_20100903.nc (7 digits, underscore, 8 digits)

Also validates that both glider serial number and profile number are positive.

Parameters:

filename (str) – The filename to validate.

Returns:

True if filename matches expected pattern and has valid numbers.

Return type:

bool

plotters

Plotting and visualization functions for Seaglider data.

This module provides functions for plotting and inspecting Seaglider datasets, including variable summaries, attribute displays, and depth profile visualizations.

seagliderOG1.plotters.plot_ctd_depth_vs_time(ds: Dataset, start_traj: int | None = None, end_traj: int | None = None, ax: Axes | None = None) → tuple[Figure, Axes][source]

Plot CTD depth vs time with GPS fix highlighting.

Creates a depth time series plot with special highlighting of points where GPS latitude data is available (non-NaN), useful for identifying surface intervals.

Parameters:
  • ds (xarray.Dataset) – The input dataset containing ‘ctd_time’, ‘ctd_depth’, and ‘gps_lat’ variables.

  • start_traj (int, optional) – The starting trajectory number to filter the data. If None, no filtering applied.

  • end_traj (int, optional) – The ending trajectory number to filter the data. If None, no filtering applied.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. A new figure and axes are created when None.

Returns:

The figure and axes drawn on.

Return type:

tuple of (matplotlib.figure.Figure, matplotlib.axes.Axes)

Notes

  • Plots CTD depth as black dots for all data points.

  • Overlays red circles at points where GPS latitude is non-NaN.

  • Inverts y-axis to show depth increasing downward.

  • Filters data by trajectory range if specified.

seagliderOG1.plotters.plot_depth_colored(data: DataFrame | Dataset, color_by: str | None = None, start_dive: int | None = None, end_dive: int | None = None, ax: Axes | None = None) → tuple[Figure, Axes][source]

Plot depth as a function of time with optional coloring and dive filtering.

Creates a depth time series plot with optional color coding by another variable and filtering by dive number range.

Parameters:
  • data (pandas.DataFrame or xarray.Dataset) – The input data containing depth, time, and dive number variables. Should contain ‘ctd_depth’/’DEPTH’, ‘ctd_time’/’TIME’, and dive number variables.

  • color_by (str, optional) – The variable name to color the plot by. If None, uses a simple line plot.

  • start_dive (int, optional) – The starting dive number to filter the data. If None, no filtering applied.

  • end_dive (int, optional) – The ending dive number to filter the data. If None, no filtering applied.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. A new figure and axes are created when None.

Returns:

The figure and axes drawn on.

Return type:

tuple of (matplotlib.figure.Figure, matplotlib.axes.Axes)

Notes

  • Accepts dive number variables: ‘dive_number’, ‘divenum’, or ‘dive_num’.

  • Uses scatter plot with colorbar when color_by is specified.

  • Inverts y-axis and formats time axis similar to plot_profile_depth.

Raises:
  • TypeError – If input data is not a pandas DataFrame or xarray Dataset.

  • ValueError – If no valid dive number variable is found in the dataset.

seagliderOG1.plotters.plot_profile_depth(data: DataFrame | Dataset, ax: Axes | None = None) → tuple[Figure, Axes][source]

Plot profile depth as a function of time.

Creates a time series plot of depth data with automatic point reduction for large datasets and proper axis formatting.

Parameters:
  • data (pandas.DataFrame or xarray.Dataset) – The input data containing depth and time variables. Should contain either ‘ctd_depth’/’ctd_time’ or ‘DEPTH’/’TIME’ variables.

  • ax (matplotlib.axes.Axes, optional) – Axes to draw on. A new figure and axes are created when None.

Returns:

The figure and axes drawn on.

Return type:

tuple of (matplotlib.figure.Figure, matplotlib.axes.Axes)

Notes

  • Automatically reduces the total number of points to less than 100,000 for performance.

  • Inverts y-axis to show depth increasing downward.

  • Formats x-axis with month-day labels and adds year information.

  • Sets tight y-axis limits to the exact finite data minimum and maximum.

Raises:
  • TypeError – If input data is not a pandas DataFrame or xarray Dataset.

  • KeyError – If required time or depth variables are not found in the dataset.

seagliderOG1.plotters.show_attributes(data: object, *args: object, **kwargs: object) → object

show_attributes; a path argument is deprecated (open it yourself), removed in 0.3.0.

seagliderOG1.plotters.show_contents(data: object, *args: object, **kwargs: object) → object

show_contents; a path argument is deprecated (open it yourself), removed in 0.3.0.

seagliderOG1.plotters.show_variables(data: object, *args: object, **kwargs: object) → object

show_variables; a path argument is deprecated (open it yourself), removed in 0.3.0.

seagliderOG1.plotters.show_variables_by_dimension(data: object, *args: object, **kwargs: object) → object

show_variables_by_dimension; a path argument is deprecated (open it yourself), removed in 0.3.0.

writers

Write OG1 datasets to compressed NetCDF files, and edit a written file’s globals.

seagliderOG1.writers.conversion_path(path: str | Path, suffix: str) → Path[source]

Return a conversion output beside an OG1 file: <stem>_conversion<suffix>.

The one place the names of the conversion record (.json) and the conversion page (.html) are built.

Parameters:
  • path (str or pathlib.Path) – The OG1 netCDF file.

  • suffix (str) – ".json" for the sidecar, ".html" for the page.

Returns:

The path, in the same directory as path.

Return type:

pathlib.Path

seagliderOG1.writers.enrich(path: str | Path, *, mission: str | Path | Mapping[str, object] | None = None, deployment: Mapping[str, object] | None = None, global_attributes: Mapping[str, object] | None = None, doi: str | None = None) → Path[source]

Set global attributes on a written OG1 file without converting again.

For metadata that exists only after the file is written — a DOI assigned on publication — or a corrected global-attribute value. Only global attributes change (edited in place; variables are not rewritten). The file gets date_modified set to now, a history line naming the keys, and a new tracking_id; date_created is kept. Every value is checked before the file is opened for writing, so a refused value leaves the file as it was. Replacing a different value already in the file warns with both values. The conversion record beside the file is rebound to the new tracking_id and SHA-256.

Parameters:
  • path (str or pathlib.Path) – The OG1 netCDF file.

  • mission (str or os.PathLike or collections.abc.Mapping, optional) – A mission.yaml path or loaded mapping; only its three global-attribute sections and global_attributes are used (merged into deployment and global_attributes below). The platform: block and other keys are ignored — enrich edits globals only. Default is None.

  • deployment (collections.abc.Mapping, optional) – Deployment-identity globals to set (as in seagliderOG1.convert()); null values are skipped. Overrides the mission’s merged sections. Default is None.

  • global_attributes (collections.abc.Mapping, optional) – global_attributes: keys to set. Overrides the mission’s. Default is None.

  • doi (str, optional) – The DOI, written as the doi global (wins over deployment["doi"]).

Returns:

The enriched file.

Return type:

pathlib.Path

Raises:
  • ValueError – If nothing is given to set; a key is one the converter owns or that belongs in the other block; a value is not text, a number or a date; a key is one enrich writes itself (date_modified, history, tracking_id, draft) or a conversion_* record; or deployment["id"] differs from the file’s id (the file name and the conversion record are bound to it: convert again to change it).

  • FileNotFoundError – If path does not exist.

seagliderOG1.writers.file_sha256(path: str | Path) → str[source]

Return the SHA-256 hex digest of a file’s bytes.

Parameters:

path (str or pathlib.Path) – The file to hash.

Returns:

The 64-character hex digest.

Return type:

str

seagliderOG1.writers.proposal_path(path: str | Path) → Path[source]

Return the proposed mission config beside a draft file: <stem>_mission.yaml.

Written by the draft verb; named here, beside conversion_path(), so the verb and the converter’s existence check agree. Not a _conversion name: it is a config for the next run, not a record of this one.

Parameters:

path (str or pathlib.Path) – The draft netCDF file.

Returns:

The path, in the same directory as path.

Return type:

pathlib.Path

seagliderOG1.writers.record_attribute_sources(attrs: MutableMapping[str, object], names: Iterable[str], category: str) → None[source]

Move global names into one category of the conversion_attribute_sources record.

For a global written after the conversion built the source record (tracking_id here, and draft and enrich’s keys), so the record still names every global exactly once. Does nothing when attrs carries no such record.

Parameters:
  • attrs (collections.abc.MutableMapping) – Global attributes holding the source record as JSON; modified in place.

  • names (collections.abc.Iterable of str) – The globals to record.

  • category (str) – The category they now belong to (e.g. "derived", "enriched").

seagliderOG1.writers.write(ds: Dataset, path: str | Path, *, overwrite: bool = False, record: dict | None = None) → Path[source]

Write the dataset to a NetCDF file with lossless compression.

Every non-scalar numeric variable, coordinates included, is written with zlib at level 4 and the shuffle filter. Attributes are checked before anything is written: one netCDF cannot store is refused by name, never converted to text. The input dataset is copied first, so the caller’s dataset is not modified.

Parameters:
  • ds (xr.Dataset) – Dataset to save.

  • path (str or pathlib.Path) – Output NetCDF file path.

  • overwrite (bool, optional) – If True, an existing file will be deleted and replaced. If False, a FileExistsError is raised when the file exists.

  • record (dict, optional) – The conversion record (as filled by convert(record=...)) to write beside the file as <stem>_conversion.json (conversion_path()), bound to it by the dataset’s id and tracking_id; a record already there is replaced. Nothing from it is written into the NetCDF file. Default is None (no record).

Returns:

The path written.

Return type:

pathlib.Path

Raises:
  • FileExistsError – If path exists and overwrite is False.

  • ValueError – If the dataset carries a None-valued attribute.

  • TypeError – If an attribute (global or on a variable) has a type netCDF cannot store, such as a dict or a bool; the message names each one. Nothing is written or removed.

seagliderOG1.writers.write_record(path: str | Path, attrs: dict, contents: dict) → Path[source]

Write the conversion record <stem>_conversion.json beside an OG1 file.

The record is bound to the file’s current version by its id and tracking_id plus the SHA-256 of its bytes, so a reader can tell the record belongs to this file and that the file has not changed since. A checksum cannot live inside the file it covers, so it lives beside it.

Parameters:
  • path (str or pathlib.Path) – The OG1 netCDF file, already written.

  • attrs (dict) – Its global attributes (id, tracking_id, date_created).

  • contents (dict) – The record body (inputs, presence, …); its binding keys, if any, are replaced.

Returns:

The path of the record file.

Return type:

pathlib.Path

tools

User-facing utilities for Seaglider-to-OG1 conversion.

Sensor metadata extraction, variable-name mapping, QC-flag conversion, dtype coercion, profile and phase numbering, time encoding, and dataset merging.

seagliderOG1.tools.add_depth(ds: Dataset) → Dataset[source]

Calculate the depth (Z position) of the glider using the gsw library to convert pressure to depth.

Parameters:

ds – The input dataset containing ‘PRES’, ‘LATITUDE’, and ‘LONGITUDE’ variables.

Returns:

The dataset with an additional ‘DEPTH’ variable.

Return type:

xarray.Dataset

seagliderOG1.tools.add_dive_number(ds: Dataset, dive_number: int | None = None) → Dataset[source]

Add dive number as a variable to the dataset. Assumes present in the basestation attributes.

Parameters:
  • ds – The dataset to which the dive number will be added.

  • dive_number – The dive number to add. If None, extracts from dataset attributes.

  • optional – The dive number to add. If None, extracts from dataset attributes.

Returns:

The dataset with the dive number added.

Return type:

xarray.Dataset

seagliderOG1.tools.add_phase(ds: Dataset) → Dataset[source]

Add ‘PHASE’ and ‘PHASE_QC’ variables indicating the phase of each measurement.

The phase is determined from the pressure readings (‘PRES’) for each unique dive number (‘dive_num’).

Parameters:

ds (xarray.Dataset) – The input dataset containing ‘dive_num’ and ‘PRES’ variables.

Returns:

The dataset with additional ‘PHASE’ and ‘PHASE_QC’ variables, where:

  • ’PHASE’ indicates the phase of each measurement:
    • Phase 2 up to and including the maximum pressure point.

    • Phase 1 after the maximum pressure point.

  • ’PHASE_QC’ is an additional variable with no QC applied.

Return type:

xarray.Dataset

Notes

In this formulation, we are only separating into dives and climbs based on when the glider is at the maximum depth. Future work needs to separate out the other phases and generate a PHASE_QC: https://github.com/OceanGlidersCommunity/OG-format-user-manual/blob/main/vocabularyCollection/phase.md

seagliderOG1.tools.add_profile_number(ds: Dataset, ds1: Dataset) → Dataset[source]

Assign profile numbers to measurements based on dive phases (down/up casts).

This function separates each dive into two profiles: descent (down cast) and ascent (up cast) phases. The dive is split at the maximum pressure point, with the descent phase getting the dive number and ascent getting dive + 0.5. Profile numbers are then calculated as 2 * DIVE_NUMBER - 1.

Parameters:
  • ds – The dataset to add profile numbers to.

  • ds1 – Dataset containing dive number information in attributes.

Returns:

Dataset with ‘DIVE_NUMBER’ and ‘PROFILE_NUMBER’ variables added.

Return type:

xarray.Dataset

Notes

  • Requires pressure variable (PRES)

seagliderOG1.tools.convert_qc_flags(dsa: Dataset, qc_name: str) → Dataset[source]

Convert QC flag variables to proper integer format and update attributes.

This function converts QC flag variables from string format to int8, handles NaN values appropriately, removes QC_ prefixes from flag meanings, and adds proper metadata including long_name and standard_name.

Parameters:
  • dsa – The dataset containing QC flag variables.

  • qc_name – The name of the QC flag variable to process.

Returns:

Dataset with converted QC flag variable and updated attributes.

Return type:

xarray.Dataset

Notes

Must be called after the main variable has been assigned its OG1 long_name.

seagliderOG1.tools.encode_times_og1(ds: Dataset) → Dataset[source]

Encode time variables according to OG1 format specifications.

Parameters:

ds – Dataset containing time variables to encode.

Returns:

Dataset with OG1-formatted time variables.

Return type:

xarray.Dataset

seagliderOG1.tools.split_by_unique_dims(ds: Dataset) → dict[source]

Split an xarray dataset into datasets grouped by each variable’s dimension set.

Parameters:

ds – The input xarray dataset containing various variables.

Returns:

A dictionary mapping dimension tuples to datasets, each with variables sharing the same set of dimensions.

Return type:

dict