Dropsondes¶
Warning
Experimental module (v1.9). The public API of
hyplan.instruments.dropsondes is provisional and may change in
subsequent releases as it is validated against operational use. Pin
the HyPlan version if you depend on the current surface; track release
notes for breaking changes.
Event-based sampling — each release is a single (lat, lon, alt, time)
event, not a swath. The science footprint is the slant column from
release to splash, drifting through the ambient wind. HyPlan’s
dropsondes are first-class objects: DropsondeRelease (event),
DropsondeTrajectory (simulated descent), and DropsondePlan
(collection). All three are frozen with identity equality;
DropsondePlan.simulate() is functional — it returns a new plan,
leaving the original pre-sim plan intact.
The DropsondeSystem class extends
Sensor for naming / registry uniformity
but does not implement the ScanningSensor protocol — dropsondes
have no swath. The pre-configured
AVAPS_NRD41 reference is the standard
NCAR-EOL Vaisala NRD41 sonde used in hurricane and airborne campaigns.
Reference instances are shared singletons — to customise a
parameter, build a new DropsondeSystem(...) rather than mutating
the reference.
Worked planning example:
notebooks/dropsonde_objects.ipynb.
Core objects¶
- class DropsondeRelease[source]¶
Bases:
objectA planned single-sonde release event.
All gating QC flags are tri-state (
True/False/None);qc_release_okaggregates them.qc_splash_in_target_polygonis not a gate — it is a post-simulation diagnostic populated byDropsondePlan.simulate().Equality/hashing is identity-based (
eq=False): two releases with structurally identical fields are still distinct objects. Userelease_idas the explicit join key when set-like semantics are needed.- sensor: DropsondeSystem = <hyplan.instruments.dropsondes.sensor.DropsondeSystem object>¶
- source: FlightLine | Pattern | Hashable | None = None¶
- property qc_release_ok: bool | None¶
Tri-state aggregate over the gating flags only.
Rule (locked):
any known gate is
False→Falseall gates are
True→Trueotherwise (at least one
None, noneFalse) →None
qc_splash_in_target_polygonis intentionally not part of this aggregate.
- classmethod from_waypoint(wp, *, sensor=<hyplan.instruments.dropsondes.sensor.DropsondeSystem object>, release_time=None, release_id=0, **kwargs)[source]¶
Build a release from a
Waypoint(defensively copied).- Return type:
- Parameters:
wp (Waypoint)
sensor (DropsondeSystem)
release_time (datetime | None)
release_id (int)
kwargs (Any)
- to_record()[source]¶
One-row dict for manifest export.
Columns are stable (used by
DropsondePlan.to_manifest_gdf()).
- with_qc(*, qc_min_alt_ok=<dataclasses._MISSING_TYPE object>, qc_aircraft_envelope_ok=<dataclasses._MISSING_TYPE object>, qc_segment_allowed=<dataclasses._MISSING_TYPE object>, qc_splash_in_target_polygon=<dataclasses._MISSING_TYPE object>)[source]¶
Return a copy of self with one or more QC flags replaced.
- __init__(waypoint, sensor=<hyplan.instruments.dropsondes.sensor.DropsondeSystem object>, aircraft=None, release_time=None, aircraft_velocity_mps=None, source=None, source_id=None, source_pattern_id=None, source_segment_type=None, qc_min_alt_ok=None, qc_aircraft_envelope_ok=None, qc_segment_allowed=None, qc_splash_in_target_polygon=None, release_id=0)¶
- Parameters:
waypoint (Waypoint)
sensor (DropsondeSystem)
aircraft (Aircraft | None)
release_time (datetime | None)
source (FlightLine | Pattern | Hashable | None)
source_id (Hashable | None)
source_pattern_id (str | None)
source_segment_type (str | None)
qc_min_alt_ok (bool | None)
qc_aircraft_envelope_ok (bool | None)
qc_segment_allowed (bool | None)
qc_splash_in_target_polygon (bool | None)
release_id (int)
- Return type:
None
- class DropsondeTrajectory[source]¶
Bases:
objectA single simulated descent — the kernel output plus splash diagnostics.
- release: DropsondeRelease¶
- track: GeoDataFrame¶
- __init__(release, track, splash_waypoint, time_to_surface, drift_distance, drift_bearing_deg, ensemble_member=0, qc_terminated_at_ground=True, qc_max_steps_exceeded=False, qc_dem_gap_count=0)¶
- class DropsondePlan[source]¶
Bases:
objectA collection of planned dropsonde releases (and optionally their simulations).
Frozen;
simulate()is functional and returns a new plan. Equality/hashing are identity-based (eq=False) — embeddedWaypoint/Aircraft/FlightPlanTrack/GeoDataFrameobjects make structural equality either expensive or wrong.- releases: tuple[DropsondeRelease, ...] = ()¶
- trajectories: tuple[DropsondeTrajectory, ...] = ()¶
- flight_track: FlightPlanTrack | None = None¶
- classmethod from_flight_plan(plan, *, sensor=<hyplan.instruments.dropsondes.sensor.DropsondeSystem object>, aircraft=None, takeoff_time, spacing=None, spacing_time=None, segment_types=('flight_line', 'transit'), min_release_altitude=None, surface_elevation_msl=None, target_polygon=None, dem_file=None, terrain_aware=False)[source]¶
Build a plan from a
compute_flight_planGeoDataFrame.Set
flight_trackon the returned plan so the inverse targeting solver can iterate the aircraft trajectory later.- Return type:
- Parameters:
plan (GeoDataFrame | FlightPlanTrack)
sensor (DropsondeSystem)
aircraft (Aircraft | None)
takeoff_time (datetime)
spacing (Quantity | None)
spacing_time (Quantity | None)
min_release_altitude (Quantity | None)
surface_elevation_msl (Quantity | None)
target_polygon (Polygon | None)
dem_file (str | None)
terrain_aware (bool)
- classmethod from_pattern(pattern, *, sensor=<hyplan.instruments.dropsondes.sensor.DropsondeSystem object>, aircraft=None, takeoff_time=None, spacing=None, spacing_time=None, start_elapsed=<Quantity(0, 'second')>)[source]¶
Build a plan from a line-based
Pattern.Spacing resets per line; line-to-line transit is NOT modelled in this release. For authoritative multi-line timing use
from_flight_plan(compute_flight_plan(...)).Emits a
UserWarningwhen the pattern has more than one line andtakeoff_timeis supplied, because the first release on every line carries the same timestamp (takeoff_time + start_elapsed) — physically impossible, just a hazard of geometry-only timing.For
is_waypoint_basedpatterns returns an empty plan and emits aUserWarning.- Return type:
- Parameters:
- simulate(*, wind_field, n_ensemble=0, wind_perturbation_sigma=<Quantity(1.5, 'meter / second')>, fall_rate_perturbation_pct=5.0, dem_file=None, terrain_aware=False, surface_elevation_msl=None, dt=<Quantity(1, 'second')>, rng_seed=None)[source]¶
Forward-simulate all non-skipped releases. Returns a new plan.
- to_manifest_gdf()[source]¶
Manifest GeoDataFrame — one row per planned release.
- Return type:
GeoDataFrame
- trajectories_gdf()[source]¶
Concatenated per-step trajectory GeoDataFrame for all releases × members.
- Return type:
GeoDataFrame
- plot(*, ax=None, show_traces=True, show_ellipses=True, sigma_scale=2.0)[source]¶
Simple map overlay: track, releases, traces, splash means.
- __init__(releases=(), trajectories=(), flight_track=None, target_polygon=None)¶
- Parameters:
releases (tuple[DropsondeRelease, ...])
trajectories (tuple[DropsondeTrajectory, ...])
flight_track (FlightPlanTrack | None)
target_polygon (Polygon | None)
- Return type:
None
Sensor¶
- class DropsondeSystem[source]¶
Bases:
SensorGeneric ballistic-parachute dropsonde with configurable descent model.
Parameters¶
- namestr
Display name (e.g.
"Vaisala NRD41").- descent_rate_modelCallable[[Quantity], Quantity]
Function mapping altitude MSL → terminal fall speed (positive downward). Default:
terminal_velocity_nrd41().- min_release_altitudeQuantity
Minimum height AGL at which the chute can deploy reliably (default 300 m).
- deployment_timeQuantity
Time from canister exit to stable terminal-velocity descent (default 5 s).
- nominal_massQuantity
Sonde mass; informational only (default 0.39 kg for NRD41).
- sourcestr
Provenance string (URL + retrieval date for the datasheet).
- AVAPS_NRD41¶
Generic ballistic-parachute dropsonde with configurable descent model.
Parameters¶
- namestr
Display name (e.g.
"Vaisala NRD41").- descent_rate_modelCallable[[Quantity], Quantity]
Function mapping altitude MSL → terminal fall speed (positive downward). Default:
terminal_velocity_nrd41().- min_release_altitudeQuantity
Minimum height AGL at which the chute can deploy reliably (default 300 m).
- deployment_timeQuantity
Time from canister exit to stable terminal-velocity descent (default 5 s).
- nominal_massQuantity
Sonde mass; informational only (default 0.39 kg for NRD41).
- sourcestr
Provenance string (URL + retrieval date for the datasheet).
- RD94¶
Generic ballistic-parachute dropsonde with configurable descent model.
Parameters¶
- namestr
Display name (e.g.
"Vaisala NRD41").- descent_rate_modelCallable[[Quantity], Quantity]
Function mapping altitude MSL → terminal fall speed (positive downward). Default:
terminal_velocity_nrd41().- min_release_altitudeQuantity
Minimum height AGL at which the chute can deploy reliably (default 300 m).
- deployment_timeQuantity
Time from canister exit to stable terminal-velocity descent (default 5 s).
- nominal_massQuantity
Sonde mass; informational only (default 0.39 kg for NRD41).
- sourcestr
Provenance string (URL + retrieval date for the datasheet).
- AXCTD¶
Generic ballistic-parachute dropsonde with configurable descent model.
Parameters¶
- namestr
Display name (e.g.
"Vaisala NRD41").- descent_rate_modelCallable[[Quantity], Quantity]
Function mapping altitude MSL → terminal fall speed (positive downward). Default:
terminal_velocity_nrd41().- min_release_altitudeQuantity
Minimum height AGL at which the chute can deploy reliably (default 300 m).
- deployment_timeQuantity
Time from canister exit to stable terminal-velocity descent (default 5 s).
- nominal_massQuantity
Sonde mass; informational only (default 0.39 kg for NRD41).
- sourcestr
Provenance string (URL + retrieval date for the datasheet).
- terminal_velocity_nrd41(altitude_msl)[source]¶
Vaisala NRD41 / RD94 terminal fall velocity, positive downward.
Linearly interpolates between published Vaisala values (~11 m/s at sea level, rising to ~22 m/s at 13 km MSL). Outside the tabulated range the curve clamps to the nearest endpoint.
- terminal_velocity_sippican_axctd(altitude_msl)[source]¶
Air-phase terminal fall velocity for a Lockheed-Martin Sippican AXCTD.
Approximate planning model from public product literature: ~10 m/s at the surface rising to ~13-14 m/s at the upper end of operational release altitudes. The water-phase descent through the ocean column is not modelled —
DropsondeSystemterminates the trajectory at splash.
Simulation¶
- simulate_release(release, *, wind_field, dem_file=None, terrain_aware=False, surface_elevation_msl=None, dt=<Quantity(1, 'second')>, u_bias_mps=0.0, v_bias_mps=0.0, fall_rate_scale=1.0, ensemble_member=0)[source]¶
Forward-simulate a
DropsondeReleasethroughwind_field.Wraps
simulate_descent_trajectory(). All inputs except the integration kwargs come fromrelease. Returns aDropsondeTrajectorywhosereleasefield is the same object passed in.
- simulate_descent_trajectory(release_lat, release_lon, release_altitude_msl, release_time_utc, *, sensor, wind_field, dem_file=None, terrain_aware=False, surface_elevation_msl=None, dt=<Quantity(1, 'second')>, method='rk4', max_steps=3600, release_id=0, ensemble_member=0, u_bias_mps=0.0, v_bias_mps=0.0, fall_rate_scale=1.0, aircraft_velocity_mps=None)[source]¶
RK4 integrator for a single dropsonde descent.
Integrates:
dlat/dt = v_n / R_earth dlon/dt = v_e / (R_earth * cos(lat)) dz/dt = -w_f(z)
with per-step wind sampling at the current trajectory point, a deployment-transient that decays linearly from the aircraft velocity to the local wind over
sensor.deployment_time, and per-ensemble (u_bias, v_bias) additive offsets.Termination, in order: terrain (
terrain_aware=True),surface_elevation_msl, sea level, ormax_steps.Returns the per-step GeoDataFrame with
terminated_at_ground/max_steps_exceeded/dem_gap_countattached asattrs.- Return type:
GeoDataFrame- Parameters:
release_lat (float)
release_lon (float)
release_altitude_msl (Quantity)
release_time_utc (datetime)
sensor (DropsondeSystem)
wind_field (WindField)
dem_file (str | None)
terrain_aware (bool)
surface_elevation_msl (Quantity | None)
dt (Quantity)
method (Literal['rk4', 'euler'])
max_steps (int)
release_id (int)
ensemble_member (int)
u_bias_mps (float)
v_bias_mps (float)
fall_rate_scale (float)
Planning helpers¶
- releases_along_flight_line(flight_line, *, sensor=<hyplan.instruments.dropsondes.sensor.DropsondeSystem object>, aircraft=None, takeoff_time=None, start_elapsed=<Quantity(0, 'second')>, groundspeed=None, spacing=None, spacing_time=None, min_release_altitude=None, surface_elevation_msl=None, first_release_id=0)[source]¶
Spaced
DropsondeReleaseevents along aFlightLine.Heading comes from
flight_line.az12; altitude is the line’s single altitude. Spacing follows the same stricter-wins rule asDropsondePlan.from_flight_plan().- Return type:
- Parameters:
flight_line (FlightLine)
sensor (DropsondeSystem)
aircraft (Aircraft | None)
takeoff_time (_dt.datetime | None)
start_elapsed (Quantity)
groundspeed (Quantity | None)
spacing (Quantity | None)
spacing_time (Quantity | None)
min_release_altitude (Quantity | None)
surface_elevation_msl (Quantity | None)
first_release_id (int)
Inverse targeting¶
- class DropsondeReleaseSolution[source]¶
Bases:
objectResult of an inverse targeting solve.
- release: DropsondeRelease¶
- trajectory: DropsondeTrajectory¶
- __init__(target, release, trajectory, miss_distance, feasible, reason=None)¶
- Parameters:
target (Waypoint)
release (DropsondeRelease)
trajectory (DropsondeTrajectory)
miss_distance (Quantity)
feasible (bool)
reason (str | None)
- Return type:
None
- solve_release_for_target(target, flight_plan, *, takeoff_time, sensor=<hyplan.instruments.dropsondes.sensor.DropsondeSystem object>, wind_field, aircraft=None, search_window=None, segment_types=('flight_line', 'transit'), coarse_step=<Quantity(10, 'second')>, tolerance=<Quantity(100, 'meter')>, max_iter=30)[source]¶
Find the release time along
flight_planwhose splash hitstarget.Coarse scan + golden-section refine. Returns a solution whose
feasibleflag isTrueonly when the miss distance is withintolerance.- Return type:
- Parameters:
target (Waypoint)
flight_plan (FlightPlanTrack | DropsondePlan)
takeoff_time (datetime)
sensor (DropsondeSystem)
wind_field (WindField)
aircraft (Aircraft | None)
coarse_step (Quantity)
tolerance (Quantity)
max_iter (int)
Flight-plan adapter¶
- class FlightPlanTrack[source]¶
Bases:
objectTyped view of a computed flight plan, with a trajectory sampler.
- __init__(segments)[source]¶
- Parameters:
segments (list[PlannedSegment])
- Return type:
None
- classmethod from_compute_flight_plan(plan)[source]¶
Validate + normalise a
compute_flight_planGeoDataFrame.- Return type:
- Parameters:
plan (GeoDataFrame)
- filter(segment_types)[source]¶
Return a track with only the given segment types, preserving cumulative timing.
- Return type:
- Parameters:
- sample_at_elapsed(elapsed)[source]¶
Aircraft state at the given elapsed time after takeoff.
- Return type:
- Parameters:
- iter_samples(*, step=<Quantity(1, 'second')>, segment_types=None)[source]¶
Iterate samples at uniform elapsed-time spacing.
Samples that fall inside a segment whose type is not in
segment_types(when provided) are skipped. This is what the inverse-targeting solver uses to enumerate feasible release times.
- class PlannedSegment[source]¶
Bases:
objectOne row of a computed flight plan, normalised to SI units.
- geometry: LineString¶
- __init__(index, geometry, segment_type, start_altitude_m, end_altitude_m, duration_s, start_elapsed_s, end_elapsed_s, planned_track_deg, wind_corrected_heading_deg, groundspeed_mps, segment_name, _length_m=0.0)¶
- Parameters:
index (Hashable)
geometry (LineString)
segment_type (str)
start_altitude_m (float)
end_altitude_m (float)
duration_s (float)
start_elapsed_s (float)
end_elapsed_s (float)
planned_track_deg (float | None)
wind_corrected_heading_deg (float | None)
groundspeed_mps (float | None)
segment_name (str | None)
_length_m (float)
- Return type:
None
GeoDataFrame exports¶
DropsondePlan exposes three GeoDataFrame views — manifest (one row
per planned release), trajectories (one row per integration step), and
summary (per-release diagnostics with splash ellipse) — via
to_manifest_gdf(), trajectories_gdf(), and summary(). See the
worked notebook for the column schemas in context.
- summarize_trajectories(trajectories, *, target_polygon=None)[source]¶
Per-release splash diagnostics + (when supplied) polygon-hit fraction.
- Return type:
DataFrame- Parameters:
trajectories (Iterable[DropsondeTrajectory])
target_polygon (Polygon | None)