Dive segment¶
Dive segment: one leg of a dive profile.
A DiveSegment is an immutable value — start/end pressure, duration,
gas, and a SegmentKind — with linear pressure interpolation inside
it. Profiles are sequences of segments; models integrate them; planners emit
them. Segments carry no results (tissue states, ceilings): those live in
the Dive layer.
- class diveplan.core.dive_segment.SegmentKind[source]¶
Bases:
objectNamespace of segment-kind enums, grouped by direction of travel.
The three sub-enums (
Descent,Ascent,Constant) categorize a segment for algorithms: planners emitDECO_ASCENTlegs andSTOPholds, gas accounting bills deco kinds at the deco SAC, andGAS_SWITCHmarks the one constant-depth kind allowed a zero duration.Membership in a parent group tests naturally:
segment.kind in SegmentKind.Constant.SegmentKind.Membersis the union of all kinds for annotations, andDESCENT/ASCENT/CONSTANTare the conventional defaults for each group.- class Ascent(*values)[source]¶
Bases:
EnumUpward traverses: planned deco legs vs. forced (direct) ascents.
- class Constant(*values)[source]¶
Bases:
EnumConstant-depth segments: bottom time, deco stops, gas switches.
- static from_name(name)[source]¶
Look up a segment kind by member name, e.g.
"DESCENT","STOP".Member names are unique across the Descent/Ascent/Constant sub-enums, so a bare name is unambiguous. Used by DiveSegment deserialization.
- Raises:
ValueError – If no segment kind has that name.
- Parameters:
name (
str)- Return type:
- class diveplan.core.dive_segment.DiveSegment(start_pressure, end_pressure, duration, gas, *, ascent_kind=Ascent.FORCED_ASCENT, constant_kind=Constant.BOTTOM)[source]¶
Bases:
objectOne leg of a dive profile: pressures, duration, gas, and kind.
Immutable value object (
__slots__+ setattr guards) — profiles copy cheaply because segments never change. Pressure varies linearly between the endpoints; the interpolation helpers (pressure_at_timeand friends) are exact under that assumption. The kind is derived from the pressure direction, refined byascent_kind/constant_kind.- Parameters:
- property absolute_pressure_change: Pressure¶
Magnitude of the pressure change from start to end (always non-negative).
- property pressure_rate: float¶
Signed rate of pressure change in mbar per second.
Positive when descending, negative when ascending, and zero for a constant-depth segment (including a possibly zero-duration gas switch, which would otherwise divide by zero).
- pressure_at_fraction(fraction)[source]¶
Pressure at fraction (0 to 1) into the segment. Linear interpolation.
- time_at_pressure(pressure)[source]¶
Time at which a given pressure is reached. Linear interpolation.
- time_at_fraction(fraction)[source]¶
Time at which a given fraction (0 to 1) is reached. Linear interpolation.
- fraction_at_pressure(pressure)[source]¶
Fraction (0 to 1) at which a given pressure is reached. Linear interpolation.
- split_at_time(t)[source]¶
Split into two segments at time t — useful for injecting a gas switch mid-segment.
- Parameters:
t (
timedelta)- Return type:
- split_at_fraction(fraction)[source]¶
Split into two segments at fraction (0 to 1) — useful for injecting a gas switch mid-segment.
- Parameters:
fraction (
float)- Return type:
- merge_with(other, *, force=False)[source]¶
Merge with another segment if they are continuous (end pressure of self matches start pressure of other). If force=True, merges regardless of continuity (use with caution — may produce unrealistic segments). The resulting segment takes the start pressure of self and end pressure of other, with duration combined. Gas and kind are taken from self if continuous. Ascent and constant kinds are preserved if self is ascent or constant, otherwise default to SegmentKind.ASCENT or SegmentKind.CONSTANT.
Known limitation: the merged segment always keeps
self.gas. Whenforce=Trueis used to merge two segments with different gases (e.g. across a gas discontinuity),other.gasis silently discarded. The caller is responsible for only force-merging segments where dropping the other gas is acceptable.- Parameters:
other (
DiveSegment) – The other segment to merge with.force (
bool) – Whether to merge regardless of continuity. Defaults to False.
- Raises:
ValueError – If segments are not fully continuous and force is False.
- Return type:
- Returns:
The merged dive segment.
- is_pressure_continuous_with(other)[source]¶
End pressure of self matches start pressure of other.
- Parameters:
other (
DiveSegment)- Return type:
- is_gas_continuous_with(other)[source]¶
Same gas on both segments (Nones treated as unknown — not continuous).
- Parameters:
other (
DiveSegment)- Return type:
- is_rate_continuous_with(other)[source]¶
Same pressure rate across the boundary — segments form an unbroken linear traverse.
- Parameters:
other (
DiveSegment)- Return type:
- is_continuous_with(other, *, check_gas=False, check_rate=False)[source]¶
Pressure-continuous by default. Optionally also checks gas and/or rate continuity. All three true = fully continuous (no seam between segments).
- Parameters:
other (
DiveSegment)check_gas (
bool)check_rate (
bool)
- Return type:
- is_fully_continuous_with(other)[source]¶
Convenience — checks pressure, gas, and rate together.
- Parameters:
other (
DiveSegment)- Return type:
- iter_pressures(interval, *, include_end=True)[source]¶
Yield (elapsed, pressure) at each interval through the segment. The start point is always yielded. The end point is yielded if include_end=True and it doesn’t coincide with the last interval tick.
Example
- for t, p in segment.iter_pressures(timedelta(seconds=30)):
tissue_model.update(p, timedelta(seconds=30))
- to_dict()[source]¶
Serialize to a JSON-compatible dict.
Pressures are stored as integer mbar (the ground truth), duration in seconds, and the kind by its member name.
- classmethod from_dict(data)[source]¶
Reconstruct a DiveSegment from
to_dict()output.- Raises:
ValueError – If the stored kind contradicts the pressure geometry (e.g. kind “DESCENT” but start pressure >= end pressure), or the kind name is unknown.
KeyError – If a required field is missing.
- Parameters:
- Return type:
- classmethod from_json(data)[source]¶
Reconstruct a DiveSegment from a JSON string (see
from_dict()).- Parameters:
data (
str)- Return type: