Configuration & Validation
Configuration schemas and validation for cruise planning YAML files.
Configuration and validation module for cruise planning.
This module provides configuration schemas and validation for cruise planning YAML files. Import classes directly from submodules for explicit dependencies:
Examples
from cruiseplan.config.activities import PointDefinition, AreaDefinition, LineDefinition from cruiseplan.config.cruise_config import CruiseConfig, LegDefinition, ClusterDefinition from cruiseplan.config.exceptions import ValidationError, BathymetryError, FileError from cruiseplan.config.fields import POINTS_FIELD, LEGS_FIELD, ACTION_FIELD from cruiseplan.config.values import OperationTypeEnum, ActionEnum, StrategyEnum from cruiseplan.config.ports import resolve_port_reference, get_available_ports
cruiseplan.config.activities module
Schema definitions for cruise configuration operations.
Defines Pydantic models that validate and parse YAML configuration data for points, lines, and areas. These are the “schema layer” that ensures your YAML is structured correctly.
Relationship to core/operations.py: - This module: Pydantic models that validate YAML → Python data - core/operations.py: Runtime business objects that do the actual work
Example flow: YAML → PointDefinition (this module) → PointOperation (core)
Also includes base geographic models used throughout the validation system.
- class cruiseplan.config.activities.AreaDefinition(*, name: str, corners: list[GeoPoint], comment: str | None = None, operation_type: AreaOperationTypeEnum | None = AreaOperationTypeEnum.SURVEY, action: ActionEnum | None = None, duration: float | None = None)[source]
Bases:
BaseModelDefinition of an area for survey operations.
Represents a polygonal region for area-based scientific operations such as bathymetric surveys or habitat mapping.
- name
Unique identifier for the area.
- Type:
str
- comment
Human-readable comment or description.
- Type:
Optional[str]
- operation_type
Type of operation for the area (default: “survey”).
- Type:
Optional[AreaOperationTypeEnum]
- action
Specific action for the area operation.
- Type:
Optional[ActionEnum]
- duration
Duration for the area operation in minutes.
- Type:
Optional[float]
- action: ActionEnum | None
- comment: str | None
- duration: float | None
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- name: str
- operation_type: AreaOperationTypeEnum | None
- class cruiseplan.config.activities.FlexibleLocationModel(*, latitude: float | None = None, longitude: float | None = None)[source]
Bases:
BaseModelBase class that allows users to define location in multiple formats.
Supports both explicit latitude/longitude fields and string format (“lat, lon”) in YAML input for user convenience.
- latitude
Latitude in decimal degrees.
- Type:
Optional[float]
- longitude
Longitude in decimal degrees.
- Type:
Optional[float]
- latitude: float | None
- longitude: float | None
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- classmethod unify_coordinates(data: Any) Any[source]
Unify different coordinate input formats.
Handles both explicit lat/lon fields and string position format.
- Parameters:
data (Any) – Input data dictionary to process.
- Returns:
Processed data with latitude and longitude fields.
- Return type:
Any
- Raises:
ValueError – If position string cannot be parsed as “lat, lon”.
- class cruiseplan.config.activities.GeoPoint(*, latitude: float, longitude: float)[source]
Bases:
BaseModelInternal representation of a geographic point.
Represents a latitude/longitude coordinate pair with validation.
- latitude
Latitude in decimal degrees (-90 to 90).
- Type:
float
- longitude
Longitude in decimal degrees (-180 to 360).
- Type:
float
- latitude: float
- longitude: float
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class cruiseplan.config.activities.LineDefinition(*, name: str, route: list[GeoPoint], comment: str | None = None, vessel_speed: float | None = None, operation_type: LineOperationTypeEnum | None = None, action: ActionEnum | None = None, distance_between_stations: float | None = None, max_depth: float | None = None)[source]
Bases:
BaseModelDefinition of a transect route for line operations.
Represents a planned path between geographic points for scientific operations such as ADCP surveys, CTD sections, or towed instruments. Uses oceanographically correct terminology where “transect” refers to the spatial sampling path/route.
- name
Unique identifier for the transect.
- Type:
str
- comment
Human-readable comment or description.
- Type:
Optional[str]
- vessel_speed
Speed for this transect in knots.
- Type:
Optional[float]
- operation_type
Type of operation for scientific transects.
- Type:
Optional[LineOperationTypeEnum]
- action
Specific action for scientific transects.
- Type:
Optional[ActionEnum]
- action: ActionEnum | None
- comment: str | None
- distance_between_stations: float | None
- max_depth: float | None
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- name: str
- operation_type: LineOperationTypeEnum | None
- classmethod parse_route_strings(v)[source]
Parse route strings into GeoPoint objects.
- Parameters:
v (List[Union[str, dict]]) – List of route points as strings or dictionaries.
- Returns:
List of parsed route points.
- Return type:
List[dict]
- vessel_speed: float | None
- class cruiseplan.config.activities.PointDefinition(*, latitude: float | None = None, longitude: float | None = None, name: str, operation_type: OperationTypeEnum | None = None, action: ActionEnum | None = None, operation_depth: float | None = None, water_depth: float | None = None, duration: float | None = None, delay_start: float | None = None, delay_end: float | None = None, comment: str | None = None, equipment: str | None = None, position_string: str | None = None, display_name: str | None = None, timezone: str | None = None)[source]
Bases:
FlexibleLocationModelDefinition of a waypoint location with operation details.
Unified definition for all point operations including CTD stations, moorings, ports, and navigation waypoints. Represents a specific geographic point where operations will be performed.
- name
Unique identifier for the waypoint.
- Type:
str
- operation_type
Type of scientific operation to perform.
- Type:
- action
Specific action for the operation.
- Type:
- operation_depth
Target operation depth (e.g., CTD cast depth) in meters.
- Type:
Optional[float]
- water_depth
Water depth at location (seafloor depth) in meters.
- Type:
Optional[float]
- duration
Manual duration override in minutes.
- Type:
Optional[float]
- delay_start
Time to wait before operation begins in minutes (e.g., for daylight).
- Type:
Optional[float]
- delay_end
Time to wait after operation ends in minutes (e.g., for equipment settling).
- Type:
Optional[float]
- comment
Human-readable comment or description.
- Type:
Optional[str]
- equipment
Equipment required for the operation.
- Type:
Optional[str]
- position_string
Original position string for reference.
- Type:
Optional[str]
- display_name
Human-readable display name (for ports).
- Type:
Optional[str]
- timezone
Timezone identifier (for ports).
- Type:
Optional[str]
- action: ActionEnum | None
- comment: str | None
- delay_end: float | None
- delay_start: float | None
- display_name: str | None
- duration: float | None
- equipment: str | None
- get_ddm_comment() str[source]
Generate DDM (Degree Decimal Minutes) position comment.
- Returns:
Position in DDM format for display.
- Return type:
str
- model_config = {}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- name: str
- classmethod normalize_operation_type(v)[source]
Normalize operation_type for case-insensitive validation.
- operation_depth: float | None
- operation_type: OperationTypeEnum | None
- position_string: str | None
- timezone: str | None
- water_depth: float | None
cruiseplan.config.cruise_config module
Main cruise configuration and schedule organization models.
Defines the root CruiseConfig class and schedule organization models (LegDefinition, ClusterDefinition) that represent the complete cruise configuration file. This is the top-level YAML structure that contains all cruise metadata, global catalog definitions, and schedule organization.
- class cruiseplan.config.cruise_config.ClusterDefinition(*, name: str, description: str | None = None, strategy: StrategyEnum = StrategyEnum.SEQUENTIAL, ordered: bool = True, activities: list[str | dict[str, ~typing.Any]]=<factory>, **extra_data: Any)[source]
Bases:
BaseModelDefinition of a cluster for operation boundary management.
Clusters define boundaries for operation shuffling/reordering during scheduling. Operations within a cluster can be reordered according to the cluster’s strategy, but cannot be mixed with operations from other clusters or the parent leg.
- name
Unique identifier for the cluster.
- Type:
str
- description
Human-readable description of the cluster purpose.
- Type:
Optional[str]
- strategy
Scheduling strategy for the cluster (default: SEQUENTIAL).
- Type:
- ordered
Whether operations should maintain their order (default: True).
- Type:
bool
- activities
Unified list of all activities (stations, transits, areas) in this cluster.
- Type:
List[dict]
- activities: list[str | dict[str, Any]]
- description: str | None
- model_config = {'extra': 'allow'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- name: str
- ordered: bool
- strategy: StrategyEnum
- class cruiseplan.config.cruise_config.CruiseConfig(*, cruise_name: str, description: str | None = None, default_vessel_speed: float = 10.0, default_distance_between_stations: float = 15.0, turnaround_time: float = 30.0, ctd_descent_rate: float = 1.0, ctd_ascent_rate: float = 1.0, day_start_hour: int = 8, day_end_hour: int = 20, start_date: str = '1970-01-01T00:00:00+00:00', start_time: str | None = '08:00', departure_port: str | PointDefinition | None = None, arrival_port: str | PointDefinition | None = None, points: list[PointDefinition] | None = <factory>, lines: list[LineDefinition] | None = <factory>, areas: list[AreaDefinition] | None = <factory>, ports: list[PointDefinition] | None = <factory>, legs: list[LegDefinition] | None = <factory>, **extra_data: Any)[source]
Bases:
BaseModelRoot configuration model for cruise planning.
Contains all the high-level parameters and definitions for a complete oceanographic cruise plan. Represents the top-level YAML structure with cruise metadata, global catalog, and schedule organization.
- cruise_name
Name of the cruise.
- Type:
str
- description
Human-readable description of the cruise.
- Type:
Optional[str]
- default_vessel_speed
Default vessel speed in knots.
- Type:
float
- default_distance_between_stations
Default station spacing in kilometers.
- Type:
float
- turnaround_time
Time required for station turnaround in minutes.
- Type:
float
- ctd_descent_rate
CTD descent rate in meters per second.
- Type:
float
- ctd_ascent_rate
CTD ascent rate in meters per second.
- Type:
float
- day_start_hour
Start hour for daytime operations (0-23).
- Type:
int
- day_end_hour
End hour for daytime operations (0-23).
- Type:
int
- start_date
Cruise start date.
- Type:
str
- start_time
Cruise start time.
- Type:
Optional[str]
- departure_port
Port where the cruise begins.
- Type:
Optional[Union[str, PointDefinition]]
- arrival_port
Port where the cruise ends.
- Type:
Optional[Union[str, PointDefinition]]
- points
Global catalog of point definitions.
- Type:
Optional[List[PointDefinition]]
- lines
Global catalog of line definitions.
- Type:
Optional[List[LineDefinition]]
- areas
Global catalog of area definitions.
- Type:
Optional[List[AreaDefinition]]
- ports
Global catalog of port definitions.
- Type:
Optional[List[WaypointDefinition]]
- legs
List of cruise legs for schedule organization.
- Type:
Optional[List[LegDefinition]]
- areas: list[AreaDefinition] | None
- arrival_port: str | PointDefinition | None
- cruise_name: str
- ctd_ascent_rate: float
- ctd_descent_rate: float
- day_end_hour: int
- day_start_hour: int
- default_distance_between_stations: float
- default_vessel_speed: float
- departure_port: str | PointDefinition | None
- description: str | None
- legs: list[LegDefinition] | None
- lines: list[LineDefinition] | None
- model_config = {'extra': 'allow'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- points: list[PointDefinition] | None
- ports: list[PointDefinition] | None
- start_date: str
- start_time: str | None
- turnaround_time: float
- class cruiseplan.config.cruise_config.LegDefinition(*, name: str, description: str | None = None, departure_port: str | PointDefinition, arrival_port: str | PointDefinition, vessel_speed: float | None = None, distance_between_stations: float | None = None, turnaround_time: float | None = None, first_activity: str | None = None, last_activity: str | None = None, strategy: StrategyEnum | None = None, ordered: bool | None = None, buffer_time: float | None = None, activities: list[str | dict[str, ~typing.Any]] | None=<factory>, clusters: list[ClusterDefinition] | None = <factory>, **extra_data: Any)[source]
Bases:
BaseModelDefinition of a maritime cruise leg (port-to-port segment).
Represents a complete leg of the cruise from departure port to arrival port, containing all operations and clusters that occur during this segment. Maritime legs are always port-to-port with defined departure and arrival points.
- name
Unique identifier for the leg.
- Type:
str
- description
Human-readable description of the leg.
- Type:
Optional[str]
- departure_port
Required departure port for this leg.
- Type:
Union[str, PointDefinition]
- arrival_port
Required arrival port for this leg.
- Type:
Union[str, PointDefinition]
- vessel_speed
Vessel speed for this leg in knots (inheritable from cruise).
- Type:
Optional[float]
- distance_between_stations
Default station spacing for this leg in kilometers (inheritable from cruise).
- Type:
Optional[float]
- turnaround_time
Turnaround time between operations in minutes (inheritable from cruise).
- Type:
Optional[float]
- first_activity
First activity/navigation marker for this leg (routing only, not executed).
- Type:
Optional[str]
- last_activity
Last activity/navigation marker for this leg (routing only, not executed).
- Type:
Optional[str]
- strategy
Default scheduling strategy for the leg.
- Type:
Optional[StrategyEnum]
- ordered
Whether the leg operations should be ordered.
- Type:
Optional[bool]
- buffer_time
Contingency time for entire leg operations in minutes (e.g., weather delays).
- Type:
Optional[float]
- activities
Unified list of all activities (points, lines, areas) in this leg.
- Type:
Optional[List[dict]]
- clusters
List of operation clusters in the leg.
- Type:
Optional[List[ClusterDefinition]]
- activities: list[str | dict[str, Any]] | None
- arrival_port: str | PointDefinition
- buffer_time: float | None
- clusters: list[ClusterDefinition] | None
- departure_port: str | PointDefinition
- description: str | None
- distance_between_stations: float | None
- first_activity: str | None
- last_activity: str | None
- model_config = {'extra': 'allow'}
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- name: str
- ordered: bool | None
- strategy: StrategyEnum | None
- turnaround_time: float | None
- validate_leg_structure()[source]
Validate leg has valid structure and content.
- Returns:
Validated leg definition.
- Return type:
- Raises:
ValueError – If leg structure is invalid.
- vessel_speed: float | None
cruiseplan.config.exceptions module
Custom exception types for CruisePlan.
Provides clean error handling for configuration validation, file operations, and bathymetry processing.
- exception cruiseplan.config.exceptions.BathymetryError[source]
Bases:
ExceptionRaised when bathymetry operations fail.
cruiseplan.config.fields module
YAML field name constants for cruise configuration schema.
Centralized field name constants to enable easy renaming across the codebase. This module focuses on the structural field names (left-hand side of YAML), while cruiseplan.schema.values focuses on field values (right-hand side of YAML).
Note: New field constants need to be added above and in the __all__ list at the bottom.
cruiseplan.config.ports module
Global port configuration system for maritime cruise planning.
This module provides a registry of common maritime ports with their coordinates, timezones, and metadata. Users can reference these ports by standard identifiers (e.g., ‘port_reykjavik’) or override them with custom definitions in their YAML.
Features: - Standard port registry with common research cruise destinations - Timezone information for port operations - Extensible system allowing user-defined port overrides - Support for both string references and PointDefinition objects
- Usage:
# In YAML configuration departure_port: “port_reykjavik” # Reference to global port
# Or override with custom definition departure_port:
name: “Reykjavik_Custom” latitude: 64.1466 longitude: -21.9426 timezone: “GMT+0” comment: “Custom port definition”
- cruiseplan.config.ports.add_custom_port(port_id: str, port_data: dict[str, Any]) None[source]
Add a custom port to the global registry at runtime.
Useful for adding project-specific ports that aren’t in the default registry.
- Parameters:
port_id (str) – Port identifier (should start with ‘port_’).
port_data (dict) – Port data dictionary with required fields (name, latitude, longitude).
- Raises:
ValueError – If port_id doesn’t follow naming convention or required fields are missing.
- cruiseplan.config.ports.get_available_ports() dict[str, str][source]
Get a dictionary of available global ports with comments.
- Returns:
Mapping of port identifiers to comments.
- Return type:
Dict[str, str]
- cruiseplan.config.ports.list_ports_in_region(min_lat: float, max_lat: float, min_lon: float, max_lon: float) dict[str, str][source]
List ports within a geographic bounding box.
- Parameters:
min_lat (float) – Latitude bounds in degrees.
max_lat (float) – Latitude bounds in degrees.
min_lon (float) – Longitude bounds in degrees.
max_lon (float) – Longitude bounds in degrees.
- Returns:
Mapping of port identifiers to names for ports in the region.
- Return type:
Dict[str, str]
- cruiseplan.config.ports.resolve_port_reference(port_ref: str | dict[str, Any] | object, port_catalog: dict[str, Any] | None = None) object[source]
Resolve a port reference to a complete PointDefinition object.
Handles three types of input: 1. String reference to local catalog or global port registry (e.g., ‘port_reykjavik’) 2. Dictionary with port data (user-defined override) 3. Already instantiated PointDefinition object
- Parameters:
port_ref – Port reference to resolve.
port_catalog (dict, optional) – Local port catalog to check first before falling back to global registry. Should be a dict mapping port names to PointDefinition objects or dicts.
- Returns:
Complete port definition object.
- Return type:
- Raises:
ValueError – If string reference is not found in catalog or global registry.
cruiseplan.config.values module
YAML field values and enumeration types for cruise configuration.
This module defines valid values that can appear in YAML configuration fields (right-hand side of YAML), along with their defaults. This complements cruiseplan.schema.fields which defines field names (left-hand side of YAML).
Contains: - Default value constants for YAML fields - Placeholder values for user guidance - Enumeration classes for valid field values
- class cruiseplan.config.values.ActionEnum(*values)[source]
Bases:
str,EnumEnumeration of specific actions for operations.
Defines the specific scientific action to be taken for each operation type.
- ADCP = 'ADCP'
- BATHYMETRY = 'bathymetry'
- CALIBRATION = 'calibration'
- DEFAULT_AREA = 'UPDATE-bathymetry-survey-etc'
- DEFAULT_LINE = 'UPDATE-ADCP-bathymetry-etc'
- DEFAULT_POINT = 'UPDATE-profile-sampling-etc'
- DEMOB = 'demob'
- DEPLOYMENT = 'deployment'
- MICROSTRUCTURE = 'microstructure'
- MOB = 'mob'
- PROFILE = 'profile'
- RECOVERY = 'recovery'
- SAMPLING = 'sampling'
- SECTION = 'section'
- SEISMIC = 'seismic'
- THERMOSALINOGRAPH = 'thermosalinograph'
- TOW_YO = 'tow_yo'
- class cruiseplan.config.values.AreaOperationTypeEnum(*values)[source]
Bases:
str,EnumEnumeration of area operation types.
Defines operations that cover defined geographic areas.
- DEFAULT = 'UPDATE-survey-etc'
- SURVEY = 'survey'
- class cruiseplan.config.values.LineOperationTypeEnum(*values)[source]
Bases:
str,EnumEnumeration of line operation types.
Defines the type of operation performed along a route or transect.
- CTD = 'CTD'
- DEFAULT = 'UPDATE-underway-etc'
- TOWING = 'towing'
- UNDERWAY = 'underway'
- class cruiseplan.config.values.OperationTypeEnum(*values)[source]
Bases:
str,EnumEnumeration of point operation types.
Defines the type of scientific operation to be performed at a station.
- CALIBRATION = 'calibration'
- CTD = 'CTD'
- DEFAULT = 'UPDATE-CTD-mooring-etc'
- MOORING = 'mooring'
- PORT = 'port'
- WATER_SAMPLING = 'water_sampling'
- WAYPOINT = 'waypoint'
- class cruiseplan.config.values.StrategyEnum(*values)[source]
Bases:
str,EnumEnumeration of scheduling strategies for cruise operations.
Defines how operations within a cluster or composite should be executed.
- DAY_NIGHT_SPLIT = 'day_night_split'
- SEQUENTIAL = 'sequential'
- SPATIAL_INTERLEAVED = 'spatial_interleaved'
cruiseplan.config.yaml_io module
Centralized YAML I/O utilities with comment preservation.
This module provides middle-layer YAML file format handling for the cruiseplan package, using ruamel.yaml to preserve comments, formatting, and whitespace during configuration enrichment operations.
I/O Module Architecture: - cruiseplan.utils.io: File system validation, path handling, directory creation (used by this module) - cruiseplan.schema.yaml_io (this module): YAML file format reading/writing with comment preservation - cruiseplan.core.serialization: High-level CruiseInstance object serialization to YAML (uses this module) - cruiseplan.output.*_generator: Specialized output format generators (HTML, LaTeX, CSV, etc.)
Dependencies: Uses cruiseplan.utils.io for file validation. Used by cruiseplan.core.serialization.
See Also: - For file system operations: cruiseplan.utils.io - For converting CruiseInstance objects to YAML: cruiseplan.core.serialization - For generating specific output formats: cruiseplan.output.html_generator, cruiseplan.output.latex_generator, etc.
- exception cruiseplan.config.yaml_io.YAMLIOError[source]
Bases:
ExceptionCustom exception for YAML I/O operations.
- cruiseplan.config.yaml_io.dict_to_yaml_string(data: dict[str, Any], add_comments: bool = True) str[source]
Convert dictionary to YAML string with optional section comments.
- Parameters:
data (dict[str, Any]) – Dictionary to convert to YAML
add_comments (bool, optional) – Whether to add section comments (default: True)
- Returns:
YAML string with optional comments and spacing
- Return type:
str
- cruiseplan.config.yaml_io.dump_yaml_simple(data: dict[str, Any], file_handle: TextIO) None[source]
Dump YAML data to file handle without comment preservation.
This function provides basic YAML dumping for cases like temp files where comment preservation is not needed.
- Args:
data: Dictionary to dump file_handle: Open file handle to write to
- Raises:
YAMLIOError – If dumping fails:
- cruiseplan.config.yaml_io.load_yaml(file_path: str | Path, encoding: str = 'utf-8') dict[str, Any][source]
Load YAML configuration file with comment preservation.
- Args:
file_path: Path to YAML file encoding: File encoding
- Return type:
Parsed YAML content as dictionary
- Raises:
YAMLIOError – If file cannot be loaded or parsed:
- cruiseplan.config.yaml_io.load_yaml_safe(file_path: str | Path) dict[str, Any][source]
Load YAML file using ruamel.yaml safe loading (returns plain dict).
This function provides basic dictionary loading without comment preservation. Returns a plain Python dictionary instead of ruamel.yaml’s CommentedMap. Use load_yaml() for comment-preserving operations.
- Args:
file_path: Path to YAML file
- Return type:
Parsed YAML content as basic dictionary
- Raises:
YAMLIOError – If file cannot be loaded or parsed:
- cruiseplan.config.yaml_io.save_yaml(config: dict[str, Any], file_path: str | Path, backup: bool = False, encoding: str = 'utf-8') None[source]
Save configuration to YAML file with comment preservation.
- Args:
config: Configuration dictionary to save file_path: Output file path backup: Whether to create backup of existing file encoding: File encoding
- Raises:
YAMLIOError – If file cannot be written: