Instruments¶
All sensor classes live under the hyplan.instruments subpackage and are
re-exported from the top-level hyplan namespace for convenience.
Base class¶
Line scanners¶
- class LineScanner[source]¶
Bases:
SensorA pushbroom or whiskbroom line scanning imager.
Line scanners capture one cross-track line of pixels per frame, building up an image as the aircraft moves along-track.
- Parameters:
name (str) – Sensor name.
fov (float) – Total cross-track field of view in degrees.
across_track_pixels (int) – Number of pixels across the swath.
frame_rate (Quantity) – Frame acquisition rate in Hz.
cross_track_tilt (float) – Cross-track tilt angle in degrees (rotation about the along-track axis). Positive = starboard (right of track), negative = port (left of track). Default 0.0 (nadir-looking).
- swath_offset_angles()[source]¶
Cross-track viewing angles for each swath edge, measured from nadir.
Accounts for
cross_track_tilt(rotation about the along-track axis). Negative = port (left of track), positive = starboard (right of track).- Return type:
- Returns:
Tuple of (port_edge_angle, starboard_edge_angle) in degrees.
Examples
Nadir sensor, 30° half-angle:
(-30.0, 30.0)Same sensor with 10° starboard tilt:(-20.0, 40.0)
- swath_width(altitude_agl)[source]¶
Calculate swath width for a given altitude above ground level (AGL).
Accounts for
cross_track_tilt— when the sensor is tilted off-nadir the swath is asymmetric and its total width changes.- Parameters:
altitude_agl (Quantity) – Altitude above ground level.
- Returns:
Swath width in meters.
- Return type:
Quantity
- ground_sample_distance(altitude_agl, mode='nadir')[source]¶
Calculate the ground sample distance (GSD) for a given altitude above ground level (AGL).
- Parameters:
altitude_agl (Quantity) – Altitude above ground level.
mode (str) – One of
"nadir"(GSD directly below the aircraft),"average"(swath width / pixel count), or"edge"(cross-track GSD of the outermost pixel, exact formh · (tan(θ_edge) − tan(θ_edge − ifov))withθ_edge = fov / 2).
- Raises:
HyPlanValueError – when
modeis not recognized.- Return type:
- altitude_agl_for_ground_sample_distance(gsd, mode='nadir')[source]¶
Calculate the required altitude AGL (Above Ground Level) for a given ground sample distance (GSD).
Inverts
ground_sample_distance()for the samemode, so the two methods round-trip exactly.- Raises:
HyPlanValueError – when
modeis not recognized.- Return type:
- Parameters:
- critical_ground_speed(altitude_agl, along_track_sampling=1.0)[source]¶
Calculate the maximum allowable aircraft ground speed (m/s) to maintain proper along-track sampling.
- Parameters:
altitude_agl (Quantity) – Altitude above ground level in meters.
along_track_sampling (float) – The oversampling factor (default = 1.0).
- Returns:
Maximum allowable ground speed in meters per second.
- Return type:
Quantity
- along_track_pixel_size(aircraft_speed, along_track_sampling=1.0)[source]¶
Calculate the along-track pixel size for a given aircraft speed and along-track sampling factor.
- Parameters:
aircraft_speed (Quantity) – Speed of the aircraft in m/s.
along_track_sampling (float) – Along-track sampling (oversampling) factor (default = 1.0).
- Returns:
Along-track pixel size in meters.
- Return type:
Quantity
- ground_pixel_dimensions(altitude_agl, ground_speed)[source]¶
Cross-track and along-track ground pixel size + aspect ratio.
For a pushbroom line scanner, the cross-track GSD is locked by sensor optics (lens + pixel pitch), while the along-track “pixel” is just
ground_speed × frame_period. The ratio of the two tells you whether your data product has square or rectangular ground pixels at the planned operating point.- Parameters:
- Return type:
- Returns:
A dict with keys
"cross_track"(Quantity, meters),"along_track"(Quantity, meters), and"aspect_ratio"(float).aspect_ratioisalong_track / cross_track(1.0 = square pixels; >1 = elongated along the flight direction).
- class AVIRISClassic¶
Bases:
LineScannerAVIRIS Classic (34.0° FOV, 677 pixels, 12.0 Hz).
- class AVIRISNextGen¶
Bases:
LineScannerAVIRIS Next Gen (36.0° FOV, 600 pixels, 100.0 Hz).
- class AVIRIS3¶
Bases:
LineScannerAVIRIS 3 (39.6° FOV, 1234 pixels, 216.0 Hz).
- class AVIRIS5¶
Bases:
LineScannerAVIRIS 5 (40.2° FOV, 1239 pixels, 148.0 Hz).
- class HyTES¶
Bases:
LineScannerHyTES (50.0° FOV, 512 pixels, 36.0 Hz).
- class PRISM¶
Bases:
LineScannerPRISM (30.7° FOV, 608 pixels, 176.0 Hz).
- class MASTER¶
Bases:
LineScannerMASTER (85.92° FOV, 716 pixels, 25.0 Hz).
- class GLiHT_VNIR¶
Bases:
LineScannerG-LiHT VNIR (Headwall Microhyperspec E) (55.3° FOV, 645 pixels, 75.0 Hz).
- class GLiHT_SIF¶
Bases:
LineScannerG-LiHT SIF (Headwall FIREFLY) (23.5° FOV, 1600 pixels, 37.5 Hz).
- class GCAS_UV_Vis¶
Bases:
LineScannerGCAS UV-Vis Spectrometer (45.0° FOV, 1024 pixels, 12.0 Hz).
- class GCAS_VNIR¶
Bases:
LineScannerGCAS Visible Near-Infrared (VNIR) Spectrometer (70.0° FOV, 1024 pixels, 12.0 Hz).
- class eMAS¶
Bases:
LineScannereMAS (85.92° FOV, 716 pixels, 6.25 Hz).
- class PICARD¶
Bases:
LineScannerPICARD (50.0° FOV, 412 pixels, 100.0 Hz).
LVIS lidar¶
- class LVISLens[source]¶
Bases:
objectLVIS lens option defined by its beam divergence.
divergence_mradis the full-angle beam divergence (the full cone angle, not the half-angle), consistent with the ALS-lidar convention. The footprint diameter is thereforetan(divergence) * altitude.
- class LVIS[source]¶
Bases:
SensorLVIS full-waveform airborne scanning lidar.
Provides the standard Sensor interface (half_angle, swath_width) so that LVIS works with generate_swath_polygon, generate_flight_lines, and other HyPlan tools. The swath_width returned is the geometric maximum; use effective_swath_width to account for contiguous-coverage constraints.
All altitude parameters expect AGL (above ground level).
- Parameters:
rep_rate (
Quantity) – Laser pulse repetition rate (Hz). Default 4000 Hz.lens (
object) – Lens option — LVISLens instance, key from LVIS_LENSES (“narrow”, “medium”, “wide”), or None for wide (default).scan_half_angle_deg (
float) – Half-scan angle in degrees. Controls the geometric maximum swath via2 * altitude * tan(angle). Default ≈5.71° corresponds to max swath = 0.2 * altitude.
- __init__(rep_rate=<Quantity(4000, 'hertz')>, lens=None, scan_half_angle_deg=np.float64(5.710593137499643))[source]¶
- swath_width(altitude_agl)[source]¶
Maximum swath width set by the scanner geometry.
This is the geometric limit: 2 * altitude_agl * tan(half_angle). Equivalent to 0.2 * altitude_agl.
Used by generate_swath_polygon and generate_flight_lines for swath polygon generation and line spacing.
- equivalent_fov(altitude_agl, speed)[source]¶
Equivalent field of view in degrees after contiguous-coverage limits.
When the laser footprint can fill the full scanner swath, this equals the geometric max FOV. When coverage is sampling-limited, the equivalent FOV narrows:
2 * atan(effective_swath / (2 * altitude)).
- footprint_diameter(altitude_agl)[source]¶
Laser footprint diameter on the ground for the configured lens.
footprint = tan(divergence_mrad / 1000) * altitude_agl
- coverage_rate(altitude_agl, speed)[source]¶
Area coverage rate at maximum swath.
coverage_rate = speed * max_swath
- footprint_for_max_swath(altitude_agl, speed)[source]¶
Minimum footprint diameter needed to fill the max swath contiguously.
footprint = sqrt(speed * max_swath / rep_rate)
- effective_swath_width(altitude_agl, speed)[source]¶
Achievable swath width accounting for contiguous coverage.
The effective swath is the minimum of: - the scanner’s max swath (geometric limit), and - footprint^2 * rep_rate / speed (contiguous-coverage limit)
When the footprint is too small relative to the flight speed, shots cannot tile the full max swath without gaps, and the effective swath narrows.
- is_contiguous(altitude_agl, speed)[source]¶
Check whether the current configuration fills the max swath.
Returns True if the footprint is large enough to tile the full scanner swath at the given speed.
- along_track_spacing(speed)[source]¶
Along-track distance between consecutive laser shots.
along_track_spacing = speed / rep_rate
- is_along_track_contiguous(altitude_agl, speed)[source]¶
Check whether consecutive shots overlap along-track.
Returns True if the along-track spacing is less than or equal to the footprint diameter.
- point_density(altitude_agl, speed)[source]¶
Laser shot density within the effective swath.
point_density = rep_rate / (speed * effective_swath)
This is the primary planning metric for LVIS survey design.
- solve_for_speed(target_density, altitude_agl)[source]¶
Compute the maximum aircraft speed for a target point density.
Inverts
point_density = rep_rate / (speed * effective_swath)accounting for the coupling between speed and effective swath.Two regimes apply:
Geometry-limited (
target_density >= 1 / fp^2): slowing down raises the density without bound, so the target is met atspeed = rep_rate / (density * max_swath)and at every slower speed. That closed form is the maximum speed at whichpoint_density >= target_density.Below the sampling-limited floor (
target_density < 1 / fp^2): at high speed the effective swath narrows while the density within it plateaus at1 / fp^2, so the density never drops below the floor at any speed. Every speed meets the target and no maximum speed exists — raisesHyPlanValueError.
- Parameters:
- Return type:
- Returns:
Maximum speed that achieves at least the target density.
- Raises:
HyPlanValueError – If the target density is below the sampling-limited floor 1/fp^2 (achieved at any speed, so no maximum speed exists).
- solve_for_altitude(target_density, speed)[source]¶
Compute the maximum altitude for a target point density.
Inverts the density equation, accounting for the dependence of both footprint and max swath on altitude.
In the geometry-limited regime (where effective swath = max swath):
density = rep_rate / (speed * 2 * altitude * tan(half_angle))
So:
altitude = rep_rate / (speed * density * 2 * tan(half_angle))
- summary(altitude_agl, speed)[source]¶
Compute all LVIS coverage parameters for a given flight configuration.
- footprint_on_terrain(lat, lon, altitude_msl, heading, scan_angle_deg=0.0, dem_file=None)[source]¶
Compute laser footprint on terrain at a single scan position.
Uses
ray_terrain_intersection()to find the ground point, then computes slant range, surface incidence angle, and the resulting footprint ellipse.- Parameters:
lat (
float) – Aircraft latitude (degrees).lon (
float) – Aircraft longitude (degrees).altitude_msl (
float) – Aircraft altitude MSL (meters).heading (
float) – Aircraft heading (degrees true, clockwise from north).scan_angle_deg (
float) – Scan angle from nadir (degrees). Positive = starboard, negative = port. Default 0 (nadir).dem_file (
str|None) – Path to DEM file. Auto-downloaded if None.
- Return type:
- Returns:
Dict with ground position, slant range, incidence angle, footprint ellipse dimensions, and flat-earth comparison.
- effective_swath_on_terrain(lat, lon, altitude_msl, heading, speed, dem_file=None, n_scan_positions=21)[source]¶
Compute effective swath across the scan, accounting for terrain.
Discretises the scan into n_scan_positions angles from port to starboard and evaluates the terrain-aware footprint at each. Returns per-position metrics and the overall effective swath. Each scan position’s share of the rep rate is proportional to its strip width, so local densities and contiguity are independent of the discretization n_scan_positions.
- Parameters:
lat (
float) – Aircraft latitude (degrees).lon (
float) – Aircraft longitude (degrees).altitude_msl (
float) – Aircraft altitude MSL (meters).heading (
float) – Aircraft heading (degrees true).speed (
Quantity) – Aircraft ground speed.dem_file (
str|None) – Path to DEM file. Auto-downloaded if None.n_scan_positions (
int) – Number of scan positions across the swath.
- Return type:
- Returns:
Dict with per-position arrays and aggregate metrics.
- terrain_summary(lat, lon, altitude_msl, heading, speed, dem_file=None)[source]¶
Coverage summary with terrain correction at a specific position.
Combines the flat-earth
summary()output with terrain-aware metrics fromeffective_swath_on_terrain().- Parameters:
lat (
float) – Aircraft latitude (degrees).lon (
float) – Aircraft longitude (degrees).altitude_msl (
float) – Aircraft altitude MSL (meters).heading (
float) – Aircraft heading (degrees true).speed (
Quantity) – Aircraft ground speed.dem_file (
str|None) – Path to DEM file. Auto-downloaded if None.
- Return type:
- Returns:
Dict with all keys from
summary()plus terrain-specific keys prefixed withterrain_.
- LVIS_LENS_NARROW¶
LVIS lens option defined by its beam divergence.
divergence_mradis the full-angle beam divergence (the full cone angle, not the half-angle), consistent with the ALS-lidar convention. The footprint diameter is thereforetan(divergence) * altitude.
- LVIS_LENS_MEDIUM¶
LVIS lens option defined by its beam divergence.
divergence_mradis the full-angle beam divergence (the full cone angle, not the half-angle), consistent with the ALS-lidar convention. The footprint diameter is thereforetan(divergence) * altitude.
- LVIS_LENS_WIDE¶
LVIS lens option defined by its beam divergence.
divergence_mradis the full-angle beam divergence (the full cone angle, not the half-angle), consistent with the ALS-lidar convention. The footprint diameter is thereforetan(divergence) * altitude.
The three pre-configured lens instances are also exposed via the
LVIS_LENSES mapping (keys "narrow", "medium", "wide")
for parameterising tests or campaigns by lens name.
Airborne laser scanners (topographic ALS)¶
Generic ALSLidar class for rotating-mirror
discrete-return topographic lidar (RIEGL VQ-series, Leica TerrainMapper,
Optech Galaxy, Phoenix LiDAR Ranger). Pre-configured reference instance:
RIEGL_VQ_480II (RIEGL VQ-480 II at the
1200 kHz operating point). Worked planning example:
notebooks/als_lidar_planning.ipynb.
- class ALSLidar[source]¶
Bases:
SensorGeneric Airborne Laser Scanner — scanning-mirror discrete-return topographic lidar.
Models rotating-polygon scanners with a fixed-rate pulsed laser sweeping linear scan lines perpendicular to the aircraft track. Conforms to the
hyplan.instruments.ScanningSensorProtocol so instances plug directly intohyplan.swath.generate_swath_polygon()andhyplan.flight_box.box_around_polygon().Parameters¶
- namestr
Instrument display name (e.g.
"RIEGL VQ-480 II").- prfQuantity
Laser pulse repetition rate (Hz).
- scan_rateQuantity
Scan-line rate (Hz) — number of cross-track scan lines per second.
- scan_half_angleQuantity
Half scan angle from nadir (degrees). Total scan FOV =
2 * scan_half_angle.- beam_divergenceQuantity
Full-angle laser beam divergence (radians or mrad).
- wavelengthQuantity
Laser wavelength (nm — informational only).
- max_rangeQuantity
Maximum usable slant range (m) at the reference target reflectivity. This is the radiometric envelope.
- max_range_reflectivityfloat, default 0.6
Target reflectivity (0–1) at which
max_rangeis quoted.- mta_zonesint, default 1
Number of multiple-time-of-arrival processing zones. Defines the timing envelope:
mta_max_unambiguous_range = mta_zones * c / (2 * prf). HyPlan reports the envelope; the actual disambiguation algorithm is the vendor’s job.- scan_geometryScanGeometry, default “rotating_polygon_active_arc”
Scanner kinematic convention — see
ScanGeometry. Determines the angular pulse spacing formula used bycross_track_spacing_at_nadir()andcross_track_spacing_at_angle(). Constructing with"oscillating_mirror"raisesHyPlanValueError.- sourcestr, default “”
Provenance: datasheet citation including URL and retrieval date.
- __init__(name, *, prf, scan_rate, scan_half_angle, beam_divergence, wavelength, max_range, max_range_reflectivity=0.6, mta_zones=1, scan_geometry='rotating_polygon_active_arc', source='')[source]¶
- Parameters:
name (str)
prf (Quantity)
scan_rate (Quantity)
scan_half_angle (Quantity)
beam_divergence (Quantity)
wavelength (Quantity)
max_range (Quantity)
max_range_reflectivity (float)
mta_zones (int)
scan_geometry (Literal['rotating_polygon_active_arc', 'rotating_polygon_full_circle', 'oscillating_mirror'])
source (str)
- swath_offset_angles()[source]¶
Cross-track edge angles
(port, starboard)in degrees.Negative = port (left of track), positive = starboard.
- swath_width(altitude_agl)[source]¶
Total cross-track swath width on flat ground at
altitude_agl.swath = 2 * altitude_agl * tan(scan_half_angle)
- footprint_diameter(altitude_agl, scan_angle=None)[source]¶
Laser spot diameter on flat ground.
At nadir:
footprint = altitude_agl * beam_divergence(small- angle approximation). At off-nadir scan angle θ the ground spot is elliptical. This method returns the along-track (minor) axis =footprint_nadir / cos(θ)— stretched only by the slant-range growth. The along-scan-line (cross-track, major) axis grows faster, asfootprint_nadir / cos²(θ), because the beam also sweeps across the tilted line of sight; that is the convention used byeffective_swath_on_terrain().
- point_density(altitude_agl, groundspeed, *, effective_prf=None)[source]¶
Nominal areal point density over the full swath rectangle.
density_nominal = effective_prf / (groundspeed * swath_width)Semantics (locked): this is the nominal density — total pulses per unit time divided by the nominal swath-rectangle area per unit time. It does not model along-track gaps; if scan lines do not overlap, the actual instantaneously-illuminated ground points concentrate in narrower strips. We deliberately report the nominal value so the formula stays a single closed-form expression suitable for both forward calculation and inverse solving.
For
"rotating_polygon_full_circle"scan geometry only thescan_half_angle / πfraction of pulses reaches the ground swath, so the pulse rate is derated accordingly (consistent withcross_track_spacing_at_nadir()).Pass
effective_prfto overrideself.prf(e.g. for derated MTA operation).Survey planners MUST call
is_along_track_contiguous()separately to verify the configuration produces contiguous ground coverage.
- along_track_spacing(groundspeed)[source]¶
Ground distance between adjacent scan lines.
along_track = groundspeed / scan_ratePurely kinematic — cannot be closed by altering altitude or scan angle. See
is_along_track_contiguous().
- cross_track_spacing_at_nadir(altitude_agl)[source]¶
Distance between adjacent pulses within one scan line at nadir.
For
"rotating_polygon_active_arc":dθ = 2 * scan_half_angle * scan_rate / prf. For"rotating_polygon_full_circle":dθ = 2π * scan_rate / prf.Ground spacing at nadir is then
altitude_agl * dθ.
- cross_track_spacing_at_angle(altitude_agl, scan_angle)[source]¶
Ground pulse spacing at off-nadir scan angle θ.
Two effects combine for a constant-angular-velocity scanner:
Slant range grows by
1 / cos(θ), stretchingaltitude * dθby1 / cos(θ).Projection of the slant-range arc onto the ground adds another
1 / cos(θ).
Net:
spacing(θ) = (altitude_agl * dθ) / cos²(θ).
- coverage_rate(altitude_agl, groundspeed)[source]¶
Nominal swath area covered per unit time (m²/s).
coverage_rate = groundspeed * swath_width(altitude_agl)Geometric coverage rate. Does not derate for along-track gaps — check
is_along_track_contiguous()separately.
- is_along_track_contiguous(altitude_agl, groundspeed)[source]¶
True iff consecutive scan lines on the ground overlap.
along_track_gap = groundspeed / scan_ratenadir_footprint = altitude_agl * beam_divergencecontiguous iffalong_track_gap <= nadir_footprint.Strict planning constraint: if False, the flight line leaves un-imaged strips and no amount of cross-track line overlap will fill them.
- is_cross_track_contiguous(altitude_agl, line_spacing)[source]¶
True iff adjacent flight lines spaced
line_spacingapart produce overlapping swaths on the ground.contiguous := line_spacing <= swath_width(altitude_agl)
- coverage_diagnostic(altitude_agl, groundspeed)[source]¶
Per-dimension coverage breakdown for one flight line.
Returns a dict with keys (all values float or bool):
along_track_gap_m— scan-line ground gapalong_track_footprint_m— nadir laser footprintalong_track_contiguous— boolswath_width_m— geometric swathnadir_density_pts_m2— peak density at nadiredge_density_pts_m2— density at ±scan_half_angleswath_mean_density_pts_m2—point_density()value
This is the diagnostic surface for survey planners. Along- and cross-track coverage are independent and reported separately.
- solve_for_altitude(target_density, groundspeed, *, strict_contiguity=True)[source]¶
Altitude AGL (m) at which nominal density equals
target_densityat the givengroundspeed.Solves the closed-form
altitude = ground_prf / (target_density * groundspeed * 2 * tan(scan_half_angle))whereground_prfis the pulse rate reaching the ground swath (prfderated byscan_half_angle / πfor full-circle scanners, matchingpoint_density()).If
strict_contiguity(default), raisesContiguityErrorwhen the solved altitude would leave un-imaged strips between scan lines.
- solve_for_groundspeed(target_density, altitude_agl, *, strict_contiguity=True)[source]¶
Groundspeed (m/s) at which nominal density equals
target_densityat the givenaltitude_agl. Same contiguity guard assolve_for_altitude().
- required_overlap_percent(altitude_agl, target_density=None, groundspeed=None, *, default_overlap_percent=20.0)[source]¶
Adjacent-line overlap required for contiguous / target-density coverage, expressed as a percent in [0, 100).
Matches HyPlan’s existing overlap convention used by
hyplan.flight_box.box_around_polygon()(0–100 percent).Returns
default_overlap_percent(default 20%) whentarget_densityis not supplied — a small non-zero pad absorbs crab-angle / lateral track-keeping error and matches typical operational practice.When
target_densityandgroundspeedare both supplied, returns the overlap that makes the area-mean combined density equaltarget_density. The formula1 − mean/targetequates the multiplicity-weighted (overlap-counted) density averaged over the swath to the target. Note this is an area-average guarantee, not a worst-case one: single-covered strips between overlap zones remain at the single-pass density (mean), which stays below target — only the doubly-covered overlap zones exceed it. Plan to a minimum-density requirement separately if uniform target coverage is needed.
- mta_max_unambiguous_range()[source]¶
Maximum unambiguous slant range from MTA timing alone (m).
max_unambiguous = mta_zones * c / (2 * prf)Out of scope: vendor-proprietary disambiguation algorithms. HyPlan reports the envelope.
- Return type:
- mta_practical_max_altitude()[source]¶
Practical AGL planning ceiling (m).
= min(mta_max_unambiguous_range, max_range)
The MTA formula gives the timing envelope;
max_rangegives the radiometric envelope. Both must hold. Assumes nadir geometry — off-nadir operation reduces the ceiling further bycos(scan_half_angle); the v1 module leaves that adjustment to the caller.- Return type:
- summary(altitude_agl, groundspeed)[source]¶
Full configuration + coverage summary for an operating point.
- footprint_on_terrain(lat, lon, altitude_msl, heading, scan_angle_deg=0.0, dem_file=None)[source]¶
Laser footprint on terrain at a single scan position.
Uses
hyplan.terrain.ray_terrain_intersection()to find the ground point, then computes slant range, surface incidence angle, and the elliptical footprint on the sloped surface.Footprint ellipse axes:
minor(along the laser axis, perpendicular to the LOS) =tan(beam_divergence) * slant_range.major(along the surface tangent in the laser plane) =minor / cos(incidence)— stretched by the surface incidence angle.
- Parameters:
lat (
float) – Aircraft latitude (degrees).lon (
float) – Aircraft longitude (degrees).altitude_msl (
float) – Aircraft altitude MSL (meters).heading (
float) – Aircraft heading (degrees true, clockwise from north). For the boresight-along-track case, pass the ground track azimuth; for crab-aware planning, pass the aircraft heading (which differs from the track).scan_angle_deg (
float) – Scan angle from nadir (degrees). Positive = starboard, negative = port. Default 0 (nadir).dem_file (
str|None) – Path to DEM file. Auto-downloaded if None.
- Return type:
- Returns:
Dict with ground position, slant range, incidence angle, footprint ellipse dimensions, and flat-earth comparison.
- effective_swath_on_terrain(lat, lon, altitude_msl, heading, groundspeed, dem_file=None, n_scan_positions=51)[source]¶
Cross-track scan over terrain — per-position metrics.
Discretises the scan into
n_scan_positionsangles from port to starboard, ray-traces each to the terrain, and reports per- position slant range, surface incidence, footprint ellipse, cross-track ground spacing, and contiguity.For ALS the contiguity model is two-axis:
along-track:
groundspeed / scan_ratevs nadir footprint diameter (kinematic — same across the scan).cross-track: ground pulse spacing between neighbours vs the along-scan-line footprint axis (which stretches by
1 / cos(incidence)on slopes).
Effective swath = length of the longest contiguous block where BOTH conditions hold.
- terrain_summary(lat, lon, altitude_msl, heading, groundspeed, dem_file=None)[source]¶
Coverage summary at a specific position with terrain correction.
Combines the flat-earth
summary()output with terrain- aware metrics fromeffective_swath_on_terrain()and a nadir footprint fromfootprint_on_terrain(). Keys prefixed withterrain_are the terrain-aware quantities.
- exception ContiguityError[source]¶
Bases:
HyPlanValueErrorRaised by ALS solvers when the requested target density would require a flight configuration that leaves un-imaged strips between consecutive scan lines.
The nominal density formula
density = prf / (groundspeed * swath_width)always has a solution, but the solution may be physically degenerate whengroundspeed / scan_rateexceeds the nadir laser footprint. Solvers raise this error by default; passstrict_contiguity=Falseto receive the nominal-density solution anyway.
- RIEGL_VQ_480II¶
Generic Airborne Laser Scanner — scanning-mirror discrete-return topographic lidar.
Models rotating-polygon scanners with a fixed-rate pulsed laser sweeping linear scan lines perpendicular to the aircraft track. Conforms to the
hyplan.instruments.ScanningSensorProtocol so instances plug directly intohyplan.swath.generate_swath_polygon()andhyplan.flight_box.box_around_polygon().Parameters¶
- namestr
Instrument display name (e.g.
"RIEGL VQ-480 II").- prfQuantity
Laser pulse repetition rate (Hz).
- scan_rateQuantity
Scan-line rate (Hz) — number of cross-track scan lines per second.
- scan_half_angleQuantity
Half scan angle from nadir (degrees). Total scan FOV =
2 * scan_half_angle.- beam_divergenceQuantity
Full-angle laser beam divergence (radians or mrad).
- wavelengthQuantity
Laser wavelength (nm — informational only).
- max_rangeQuantity
Maximum usable slant range (m) at the reference target reflectivity. This is the radiometric envelope.
- max_range_reflectivityfloat, default 0.6
Target reflectivity (0–1) at which
max_rangeis quoted.- mta_zonesint, default 1
Number of multiple-time-of-arrival processing zones. Defines the timing envelope:
mta_max_unambiguous_range = mta_zones * c / (2 * prf). HyPlan reports the envelope; the actual disambiguation algorithm is the vendor’s job.- scan_geometryScanGeometry, default “rotating_polygon_active_arc”
Scanner kinematic convention — see
ScanGeometry. Determines the angular pulse spacing formula used bycross_track_spacing_at_nadir()andcross_track_spacing_at_angle(). Constructing with"oscillating_mirror"raisesHyPlanValueError.- sourcestr, default “”
Provenance: datasheet citation including URL and retrieval date.
Multi-lidar rig (analog to MultiCameraRig)
for systems that fly two or more identical scanning lidars at known
mount orientations. Supports both forward/backward pitch tilt
(multi-angle returns, same swath — NASA G-LiHT pattern) and
left/right roll tilt (wider combined swath). The pre-configured
GLIHT_DUAL_VQ_480I reference instance models
the G-LiHT 2017+ dual VQ-480i configuration.
- class LidarMount[source]¶
Bases:
objectOne unit in a
MultiALSLidarRigwith its mount orientation.Attributes¶
- lidarALSLidar
The sensor instance.
- labelstr
Human-readable name for this unit (e.g. “forward”, “aft”).
- pitch_tilt_degfloat
Pitch tilt about the aircraft’s lateral axis (degrees). Positive = nose-up looking forward along flight direction; negative = looking backward. Pure pitch tilts do not change the cross-track swath — they shift the ground footprint forward/backward by
altitude_agl × tan(pitch_tilt)and create multi-angle returns over the same cross-track ground swath.- roll_tilt_degfloat
Roll tilt about the aircraft’s longitudinal axis (degrees). Positive = starboard, negative = port. Pure roll tilts shift the cross-track scan edges by the same angle, so a port-tilted unit plus a starboard-tilted unit produces a wider combined swath.
- dx, dyQuantity
Lateral and longitudinal physical offsets of the unit’s mount point from the aircraft reference point. Typically small (≤ 1 m) for rigid integrated systems and below the planning precision used by
MultiALSLidarRig.swath_width().
- class MultiALSLidarRig[source]¶
Bases:
SensorRig of multiple
ALSLidarinstances with known mount orientations.Models the two common multi-scanning-lidar integrations:
Pitch-tilted forward/backward (e.g. NASA G-LiHT’s dual VQ-480i): both units image the same cross-track swath from forward and backward oblique angles. Combined cross-track swath = single-unit swath; combined nominal density ≈ sum of unit densities; provides multi-angle returns useful for canopy 3D structure.
Roll-tilted left/right: each unit images a different cross-track band. Combined cross-track swath is the union of the per-unit FOVs (wider than a single unit); density at any given ground point is the single-unit value, except in the overlap zone where the rolls are small enough that adjacent unit FOVs intersect.
Conforms to the
hyplan.instruments.ScanningSensorProtocol so rig instances plug directly intohyplan.swath.generate_swath_polygon()andhyplan.flight_box.box_around_polygon(). The rig’s cross-track edges are the outermost edges across all units (each unit contributes[roll_tilt - half_angle, roll_tilt + half_angle]).- __init__(name, units)[source]¶
- Parameters:
name (str)
units (list[LidarMount])
- Return type:
None
- units: list[LidarMount]¶
- property half_angle: float¶
Magnitude of the larger combined edge angle (degrees).
Used by the ScanningSensor Protocol to size the cross-track ray cast. Equals
max(|port|, |starboard|)of the combined edges.
- swath_offset_angles()[source]¶
Combined cross-track edge angles
(port, starboard)in degrees, from nadir. Negative = port, positive = starboard. Asymmetric roll-tilted rigs are supported (port ≠ -starboard).
- swath_width(altitude_agl)[source]¶
Total combined cross-track swath width on flat ground.
swath = altitude × (tan(starboard_edge) - tan(port_edge))For pure pitch-tilted rigs (all roll_tilt_deg == 0): equals the single-unit swath. For roll-tilted rigs: extended union.
- along_track_offsets(altitude_agl)[source]¶
Along-track ground offset of each unit’s nadir line at altitude.
For unit with pitch tilt θ, nadir ray hits the ground at
altitude_agl × tan(θ)ahead of (or behind) the aircraft position. Returns{label: offset_distance}(positive = forward of aircraft).
- combined_point_density(altitude_agl, groundspeed)[source]¶
Sum of per-unit nominal point densities (pts/m²).
combined = sum(unit.point_density(altitude, speed) for unit in rig)For pitch-only rigs whose units cover the same ground swath, this is the true combined density on every ground point.
For roll-tilted rigs, this is the mean density: total pulses per unit time over the combined swath area. Points in the overlap zone get higher density than this mean, points outside the overlap get lower density — call
unit_point_densities()for the per-unit breakdown.
- unit_point_densities(altitude_agl, groundspeed)[source]¶
Per-unit nominal density at this altitude and groundspeed.
- solve_for_groundspeed(target_density, altitude_agl, *, strict_contiguity=True)[source]¶
Groundspeed (m/s) at which the rig’s combined point density equals
target_densityat the givenaltitude_agl.Inverts
combined_point_density(): each unit contributesprf / (speed × swath), so the combined density across N units is(sum prf_i) / (speed × swath). Solving for speed:speed = (sum prf_i) / (target_density × swath)
For an N-unit pitch-only rig at identical PRF this is N× the per-unit speed returned by
ALSLidar.solve_for_groundspeed()— the dual VQ-480i rig therefore tolerates roughly double the per-unit density-limited speed.Same per-unit contiguity guard as
ALSLidar.solve_for_groundspeed(): any unit whose nadir footprint is smaller than the along-track scan spacing at the solved speed raisesContiguityError(unlessstrict_contiguity=False).- Parameters:
target_density (
Quantity) – Target combined point density (pts/m²).altitude_agl (
Quantity) – Altitude above ground level.strict_contiguity (
bool) – When True (default), raiseContiguityErrorif any unit’s scan lines would not be contiguous at the solved speed.
- Return type:
- Returns:
Ground speed (m/s) achieving the target combined density.
- multi_angle_pairs(min_dir_diff_deg=5.0)[source]¶
Find unit pairs with opposing pitch tilts (forward/backward).
Two units are considered a multi-angle pair if their pitch tilts differ in sign and
|θ_fwd - θ_aft| >= min_dir_diff_deg. Default threshold is 5° — pitch tilts of ±7° (typical for canopy multi-angle configurations) clear it; the tighter QUAKES-I-style ±10°-and-up pairs are obviously detected too. Returns ordered(forward, backward)pairs —forwardis the unit with positive pitch_tilt_deg.Analogous to
MultiCameraRig.stereo_pairs().- Return type:
- Parameters:
min_dir_diff_deg (float)
- coverage_diagnostic(altitude_agl, groundspeed)[source]¶
Per-unit + combined coverage breakdown for the rig.
Returns a dict with:
units— list of per-unitALSLidar.coverage_diagnostic()results, each tagged withlabelandpitch_tilt_deg/roll_tilt_deg.combined_swath_width_m— rig swath width.combined_density_pts_m2— sum of per-unit nominal densities.along_track_offsets_m— per-unit ground offset for pitch tilts.
- GLIHT_DUAL_VQ_480I¶
NASA G-LiHT 2017+ dual VQ-480i scanning lidar rig.
Two identical RIEGL VQ-480i units pitch-tilted ±7° (forward and backward) viewing the same cross-track 60° FOV swath from two oblique along-track angles, providing multi-angle returns for canopy 3D structure and approximately doubled point density.
Source: G-LiHT V2.0/V4.0 User Guide (Wirt 2021, LP DAAC), sec. 2.8 describes the upgrade as ‘Riegl VQ 480i Dual Scanning LiDAR’. The user guide does not publish the tilt angle; ±7° is a representative value used here, parametrically exposed for override. Combined swath and density numbers in the v.2 specs page (387 m at 335 m AGL, ~12 pts/m²) are consistent with forward/backward pitch tilt of the same cross-track scan rather than cross-track FOV extension.
Sampling systems¶
Event-based sampling (single release per drop, drifts to splash through
wind), not a swath geometry. The
DropsondeSystem class and helpers are
documented on the dedicated Dropsondes page.
Profiling lidars¶
Nadir-pointing single-beam atmospheric profilers (no cross-track swath):
ProfilingLidar base class plus three
pre-configured instruments — HSRL2,
HALO, and CPL.
Detailed signatures and references are documented on the dedicated
Profiling Lidars page.
Doppler wind lidar¶
AerosolWindProfiler is a dual-line-of-sight
profiler for vector wind retrieval. Detailed signature and planning
helpers are documented on the dedicated AWP Profiling page.
Radar¶
- class SidelookingRadar[source]¶
Bases:
SensorRepresents a side-looking Synthetic Aperture Radar (SAR).
Models the slant-range geometry where the swath is offset from nadir, defined by near-range and far-range incidence angles. Supports stripmap SAR instruments like UAVSAR.
The swath lies entirely on one side of the flight track (typically left).
- __init__(name, frequency, bandwidth, near_range_angle, far_range_angle, azimuth_resolution, polarization, look_direction='left', peak_power=None, antenna_length=None)[source]¶
- property half_angle: float¶
Effective half-angle for swath calculations.
For a side-looking radar this is the angular extent from the swath center to either edge, i.e. half the angular swath width.
- swath_width(altitude_agl)[source]¶
Ground swath width for a given altitude AGL.
Computed from the difference in ground range at near and far incidence angles.
- ground_range_resolution(altitude_agl, incidence_angle=None)[source]¶
Ground-range resolution at a given incidence angle.
ground_range_res = slant_range_res / sin(incidence_angle)
- ground_sample_distance(altitude_agl)[source]¶
Ground sample distance at near range, center, and far range.
- slant_range(altitude_agl, incidence_angle=None)[source]¶
Slant range distance to target at given incidence angle.
- swath_offset_angles()[source]¶
Return the (port_angle, starboard_angle) for swath polygon generation.
For a left-looking radar, the swath is on the left (port) side. For a right-looking radar, the swath is on the right (starboard) side.
- class UAVSAR_Lband[source]¶
Bases:
SidelookingRadarNASA/JPL UAVSAR L-band fully polarimetric SAR.
Platform: Gulfstream III (C-20A) Typical altitude: ~12,500 m (41,000 ft)
- class UAVSAR_Pband[source]¶
Bases:
SidelookingRadarNASA/JPL UAVSAR P-band SAR (AirMOSS configuration).
Platform: Gulfstream III (C-20A) Typical altitude: ~12,500 m (41,000 ft)
- class UAVSAR_Kaband[source]¶
Bases:
SidelookingRadarNASA/JPL GLISTIN-A Ka-band single-pass cross-track interferometric SAR.
Platform: Gulfstream III (C-20A) Typical altitude: ~12,500 m (41,000 ft)
- class RadarExclusionConflict[source]¶
Bases:
objectA detected conflict between a UAVSAR swath and an FAA L-Band radar exclusion zone.
- Variables:
radar_name – Name of the FAA radar site.
swath_index – Index of the conflicting swath in the input list.
intersection – Shapely geometry of the overlap between the swath and exclusion zone.
exclusion_zone – Shapely Polygon of the full exclusion zone boundary.
- check_lband_radar_exclusions(swath_polygons, geojson=None)[source]¶
Check UAVSAR swath polygons against FAA L-Band radar exclusion zones.
UAVSAR L-Band swaths must remain outside a 10 nautical mile radius of each FAA long-range L-Band radar site. The exclusion zone polygons are pre-computed 10 NMI circles stored in a GeoJSON FeatureCollection.
- Parameters:
swath_polygons (
Polygon|list[Polygon]) – A single Shapely Polygon or a list of Shapely Polygons representing UAVSAR swath footprints (e.g. fromgenerate_swath_polygon()).geojson (
str|dict[Any,Any] |None) –Exclusion zone data. One of:
None— load the bundledhyplan/data/faa_radar_exclusion_zones.geojsonfile.str— path to a GeoJSON FeatureCollection file on disk.dict— an already-parsed GeoJSON FeatureCollection.
- Return type:
- Returns:
List of
RadarExclusionConflict, one for each swath/zone pair that intersects. An empty list means no conflicts.- Raises:
FileNotFoundError – If geojson is
Noneand the bundled data file does not exist, or if a path string is given that does not exist.HyPlanValueError – If the GeoJSON is not a valid FeatureCollection.
Frame camera¶
For nadir survey planning the relevant frame-rate limit is
max_ground_speed_for_overlap()
— the maximum ground speed that maintains a requested forward
overlap at the configured frame rate.
critical_ground_speed() reports
the (typically much tighter, rarely-binding) one-pixel-motion-per-frame
ground speed and is retained for backward compatibility.
- class FrameCamera[source]¶
Bases:
SensorA frame (area-array) camera sensor.
Unlike line scanners, frame cameras capture a full 2D image per frame. The footprint is determined by both horizontal and vertical fields of view.
- Parameters:
name (str) – Sensor name.
sensor_width (Quantity) – Physical sensor width in mm.
sensor_height (Quantity) – Physical sensor height in mm.
focal_length (Quantity) – Lens focal length in mm.
resolution_x (int) – Number of pixels across-track (horizontal).
resolution_y (int) – Number of pixels along-track (vertical).
frame_rate (Quantity) – Frame acquisition rate in Hz.
f_speed (float) – Lens f-number (focal length / aperture diameter).
- __init__(name, sensor_width, sensor_height, focal_length, resolution_x, resolution_y, frame_rate, f_speed, tilt_angle=0.0, tilt_direction=0.0, integration_time=None)[source]¶
- ground_sample_distance(altitude_agl)[source]¶
Calculate the ground sample distance (GSD) for a given altitude AGL.
For nadir cameras, returns
x(across-track) andy(along-track) GSD. For tilted cameras, additionally returnsy_nearandy_farshowing GSD variation across the frame.- Parameters:
altitude_agl (Quantity) – Altitude above ground level in meters.
- Returns:
Ground sample distances in meters.
- Return type:
Dict[str, Quantity]
- altitude_agl_for_ground_sample_distance(gsd_x, gsd_y)[source]¶
Calculate the required altitude AGL for a given ground sample distance (GSD) at nadir.
Each GSD is treated as a not-to-exceed requirement: the returned altitude is the highest at which both axes satisfy their requested GSD (the binding axis is met exactly; the other is finer than requested).
- Parameters:
gsd_x (Quantity) – Desired ground sample distance in meters along the x-axis (across-track).
gsd_y (Quantity) – Desired ground sample distance in meters along the y-axis (along-track).
- Returns:
The required altitude AGL in meters.
- Return type:
Quantity
- footprint_at(altitude_agl)[source]¶
Calculate the footprint dimensions (m) for a given altitude AGL.
For nadir cameras (
tilt_angle == 0), returnswidthandheight. For tilted cameras, additionally returnsheight_nearandheight_far(distances from the principal point to the near/far edges along the tilt axis).
- swath_width(altitude_agl)[source]¶
Across-track swath width at a given altitude AGL.
This is the
widthcomponent offootprint_at(), provided for API compatibility withLineScannerandflight_box.box_around_center_line().
- image_scale(altitude_agl)[source]¶
Image scale denominator (1:N) at a given altitude AGL.
- Parameters:
altitude_agl (
Quantity) – Altitude above ground level.- Returns:
- Return type:
Scale denominator N such that the image scale is 1
- focal_length_for_gsd(altitude_agl, target_gsd)[source]¶
Required focal length for a target GSD at a given altitude.
Useful for zoom lenses where the focal length can be adjusted.
- trigger_distance(altitude_agl, overlap_pct=80.0)[source]¶
Along-track distance between camera exposures from overlap percentage.
- Parameters:
- Return type:
- Returns:
Distance between exposure centers in meters.
- Raises:
HyPlanValueError – when
overlap_pctis outside [0, 100).
- trigger_interval(altitude_agl, ground_speed, overlap_pct=80.0)[source]¶
Time between camera triggers for a given speed and overlap.
- coverage_buffer(altitude_agl, overlap_pct=80.0, n_frames=4)[source]¶
Extra distance beyond AOI boundary to ensure full edge coverage.
Camera triggering should begin this distance before the AOI entry and continue this distance past the AOI exit.
- critical_ground_speed(altitude_agl)[source]¶
Ground speed corresponding to one along-track pixel of motion per frame.
This is a pixel-rate limit (one GSD_y of ground motion per exposure interval), not a survey-overlap planning limit. For most operational frame-camera surveys the binding constraint is the requested forward overlap at the configured frame rate — use
max_ground_speed_for_overlap()for that.
- max_ground_speed_for_overlap(altitude_agl, overlap_pct=80.0)[source]¶
Maximum ground speed that maintains the requested forward overlap.
Uses the along-track footprint and frame rate:
speed_max = trigger_distance(altitude_agl, overlap_pct) * frame_rate
This is the operational frame-rate limit for nadir frame-camera survey planning — distinct from
critical_ground_speed(), which reports one-pixel-per-frame motion (a much tighter, rarely-binding limit).- Parameters:
- Return type:
- Returns:
Maximum allowable ground speed in m/s.
- Raises:
HyPlanValueError – when
overlap_pctis outside [0, 100).
- motion_blur_at(altitude_agl, ground_speed)[source]¶
Along-track motion blur during a single exposure.
Reports the ground distance the platform traverses while the shutter is open (
ground_speed × integration_time) and normalises that length to the along-track GSD so the answer is interpretable in units of “pixels of smear per exposure”.- Parameters:
- Return type:
- Returns:
{"length": Quantity (m), "pixels": float}—lengthis the along-track ground motion during integration;pixelsislength / GSD_y.- Raises:
HyPlanValueError – when
integration_timewas not set on the camera.
- max_ground_speed_for_motion_blur(altitude_agl, max_blur_pixels=1.0)[source]¶
Maximum ground speed at which motion blur stays under a threshold.
The threshold is expressed in along-track GSD units —
max_blur_pixels=1.0means the blur length equals one along-track GSD;0.5is the half-pixel-blur photometry rule of thumb;3.0is a generous bound for feature-detection workflows.- Parameters:
- Return type:
- Returns:
Maximum ground speed in m/s.
- Raises:
HyPlanValueError – when
integration_timewas not set, ormax_blur_pixelsis non-positive.
- base_height_ratio(altitude_agl, overlap_pct=80.0)[source]¶
Base-to-height ratio for stereo photogrammetry.
B/H is the ratio of the baseline (distance between successive exposure centres) to the flying height. Larger values give better vertical accuracy but more occlusion.
- vertical_accuracy(altitude_agl, overlap_pct=80.0, sigma_parallax=0.5)[source]¶
Estimated vertical accuracy from stereo overlap.
Uses the photogrammetric relation
σ_z = (H / B) × σ_p × GSD_ywhereσ_pis the parallax measurement error in pixels.
- range_accuracy(altitude_agl, baseline, sigma_q=None)[source]¶
Stereo range accuracy using the range-error formula.
σ_R = R² × σ_q / Bwhere R is the slant range from the camera to the ground, B is the baseline, and σ_q is the angular measurement uncertainty in radians. This is the model used in Donnellan et al. (2025) for QUAKES-I.- Parameters:
- Return type:
- Returns:
Range accuracy (σ_R) in meters.
- ground_footprint(altitude_agl, cross_track_offset=0.0, *, edge_points=10, lat=None, lon=None, altitude_msl=None, heading=0.0, dem_file=None)[source]¶
Project the sensor perimeter onto the ground as a Shapely Polygon.
Points are distributed along each sensor edge (controlled by edge_points) so the polygon faithfully represents footprint curvature, especially over terrain.
Operates in two modes:
Flat-ground mode (default): When
lat,lon, andaltitude_mslare all None. Returns a 3-D Shapely Polygon with coordinates(x_cross, y_along, 0)in meters, origin at the nadir point.Terrain mode: When
lat,lon, andaltitude_mslare provided. Rays are intersected with the DEM viaray_terrain_intersection(). Returns a 3-D Shapely Polygon with coordinates(lon, lat, elevation). The altitude_agl parameter is ignored in this mode.- Parameters:
altitude_agl (
Quantity) – Altitude above ground level (used in flat mode).cross_track_offset (
float) – Additional cross-track angular offset in degrees (e.g. for cameras in a multi-camera rig).edge_points (
int) – Number of points per sensor edge (default 10). Use 2 for a simple 4-corner quadrilateral.lat (
float|None) – Camera latitude in degrees (terrain mode).lon (
float|None) – Camera longitude in degrees (terrain mode).altitude_msl (
float|None) – Camera altitude MSL in meters (terrain mode).heading (
float) – Aircraft heading in degrees from north (terrain mode).dem_file (
str|None) – Path to DEM file. If None and terrain mode is active, a DEM is downloaded automatically.
- Return type:
- Returns:
A
shapely.geometry.Polygonwith 3-D coordinates.
- footprint_polygon_at(lat, lon, altitude_agl, *, heading=0.0, cross_track_offset=0.0, edge_points=4)[source]¶
Flat-earth ground footprint Polygon at a specified geodetic centre.
Convenience wrapper that returns a 2-D Shapely Polygon in
(lon, lat)coordinates without DEM access — useful for notebooks and survey-plan visualisation where the synthetic flight line shouldn’t depend on terrain data.Internally builds the flat-mode local-meter polygon via
ground_footprint()(which already handles tilt, cross- track offset, and edge densification) and projects each vertex to lat/lon via Vincenty.- Parameters:
lat (
float) – Camera latitude in degrees.lon (
float) – Camera longitude in degrees.altitude_agl (
Quantity) – Altitude above ground level.heading (
float) – Aircraft heading in degrees from north (default 0 = north).cross_track_offset (
float) – Additional cross-track angular offset in degrees (e.g. for cameras in a multi-camera rig).edge_points (
int) – Number of points per sensor edge (default 4 = quadrilateral).
- Return type:
- Returns:
A
shapely.geometry.Polygonwith 2-D(lon, lat)coordinates (no elevation field).
- ground_footprint_corners(*args, **kwargs)[source]¶
Deprecated — use
ground_footprint()instead.
- static footprint_corners(lat, lon, altitude_msl, fov_x, fov_y, dem_file, tilt_angle=0.0, tilt_direction=0.0, heading=0.0)[source]¶
Calculate terrain-intersected footprint corners.
Deprecated since version Use: the instance method
ground_footprint()withlat,lon, andaltitude_mslkeyword arguments instead. It uses the camera’s own FOV and tilt parameters automatically.
- class MultiCameraRig[source]¶
Bases:
SensorA rig of multiple
FrameCamerainstances with known orientations.Each camera carries its own
tilt_angleandtilt_direction. The rig stores an optional angular cross-track offset and a longitudinal mount offset for each camera.- Parameters:
- swath_width(altitude_agl)[source]¶
Combined across-track swath width (union of all cameras).
swath = altitude × (tan(starboard_edge) - tan(port_edge))where the edges are the outermost cross-track view angles across all cameras (mount offset ± half cross-track FOV).
- ground_footprint(altitude_agl, *, edge_points=10, lat=None, lon=None, altitude_msl=None, heading=0.0, dem_file=None)[source]¶
Project each camera’s sensor perimeter onto the ground.
Uses each camera’s tilt geometry and the
cross_track_offsetangular offset stored in the rig layout.
- ground_footprint_corners(*args, **kwargs)[source]¶
Deprecated — use
ground_footprint()instead.
- stereo_pairs()[source]¶
Find camera pairs with opposing tilt directions (~180° apart).
Returns a list of (forward_entry, aft_entry) tuples.
- composite_base_height_ratio(altitude_agl)[source]¶
B/H ratio for each stereo pair.
For convergent stereo,
B/H = tan(θ_fwd) + tan(θ_aft)where θ is the tilt angle of each camera.
- line_spacing(altitude_agl, sidelap_pct=60.0)[source]¶
Flight line spacing from sidelap and combined swath width.
- classmethod quakes_i()[source]¶
Create a QUAKES-I multi-camera rig.
Based on Donnellan et al. (2025), Earth and Space Science. The camera hardware is the same regardless of aircraft platform (Gulfstream V at 12.5 km / 250 m/s, or King Air at 6 km / 125 m/s). The platform choice only affects operational parameters like the altitude passed to
swath_width()etc.- Return type:
- Returns:
A
MultiCameraRigwith 8 cameras (4 forward + 4 aft).
- GLIHT_HRAC¶
A frame (area-array) camera sensor.
Unlike line scanners, frame cameras capture a full 2D image per frame. The footprint is determined by both horizontal and vertical fields of view.
- Parameters:
name (str) – Sensor name.
sensor_width (Quantity) – Physical sensor width in mm.
sensor_height (Quantity) – Physical sensor height in mm.
focal_length (Quantity) – Lens focal length in mm.
resolution_x (int) – Number of pixels across-track (horizontal).
resolution_y (int) – Number of pixels along-track (vertical).
frame_rate (Quantity) – Frame acquisition rate in Hz.
f_speed (float) – Lens f-number (focal length / aperture diameter).
- GLIHT_THERMAL¶
A frame (area-array) camera sensor.
Unlike line scanners, frame cameras capture a full 2D image per frame. The footprint is determined by both horizontal and vertical fields of view.
- Parameters:
name (str) – Sensor name.
sensor_width (Quantity) – Physical sensor width in mm.
sensor_height (Quantity) – Physical sensor height in mm.
focal_length (Quantity) – Lens focal length in mm.
resolution_x (int) – Number of pixels across-track (horizontal).
resolution_y (int) – Number of pixels along-track (vertical).
frame_rate (Quantity) – Frame acquisition rate in Hz.
f_speed (float) – Lens f-number (focal length / aperture diameter).
Factory function¶
- create_sensor(sensor_type)[source]¶
Construct a sensor by registered name.
- Parameters:
sensor_type (
str) – Canonical name or alias registered viaregister_sensor(). Look-up is case- and whitespace-sensitive.- Return type:
- Returns:
A
Sensorinstance. Singleton-backed names return the same shared object on every call; class-backed names return a fresh instance each call.- Raises:
HyPlanValueError – If
sensor_typeis not registered.