Instruments

All sensor classes live under the hyplan.instruments subpackage and are re-exported from the top-level hyplan namespace for convenience.

Base class

class Sensor[source]

Bases: object

Base class to represent a generic sensor.

Parameters:

name (str) – Human-readable name identifying the sensor.

__init__(name)[source]
Parameters:

name (str)

Line scanners

class LineScanner[source]

Bases: Sensor

A 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).

__init__(name, fov, across_track_pixels, frame_rate, cross_track_tilt=0.0)[source]
Parameters:
property ifov: float

Calculate the cross-track Instantaneous Field of View (IFOV) in degrees.

property half_angle: float

Calculate and return the half angle in degrees.

property frame_period: Quantity

Calculate and return the frame period in seconds.

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:

tuple

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).

Return type:

Quantity

Parameters:
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).

Return type:

Quantity

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 oversampling rate.

Parameters:
  • aircraft_speed (Quantity) – Speed of the aircraft in m/s.

  • oversampling_rate (float) – Oversampling factor (default = 1.0).

  • along_track_sampling (float)

Returns:

Along-track pixel size in meters.

Return type:

Quantity

class AVIRISClassic

Bases: LineScanner

AVIRIS Classic (34.0° FOV, 677 pixels, 12.0 Hz).

__init__()
class AVIRISNextGen

Bases: LineScanner

AVIRIS Next Gen (36.0° FOV, 600 pixels, 100.0 Hz).

__init__()
class AVIRIS3

Bases: LineScanner

AVIRIS 3 (39.6° FOV, 1234 pixels, 216.0 Hz).

__init__()
class AVIRIS5

Bases: LineScanner

AVIRIS 5 (40.2° FOV, 1239 pixels, 148.0 Hz).

__init__()
class HyTES

Bases: LineScanner

HyTES (50.0° FOV, 512 pixels, 36.0 Hz).

__init__()
class PRISM

Bases: LineScanner

PRISM (30.7° FOV, 608 pixels, 176.0 Hz).

__init__()
class MASTER

Bases: LineScanner

MASTER (85.92° FOV, 716 pixels, 25.0 Hz).

__init__()
class GLiHT_VNIR

Bases: LineScanner

G-LiHT VNIR (64.0° FOV, 1600 pixels, 250.0 Hz).

__init__()
class GLiHT_Thermal

Bases: LineScanner

G-LiHT Thermal (42.6° FOV, 640 pixels, 50.0 Hz).

__init__()
class GLiHT_SIF

Bases: LineScanner

G-LiHT SIF (23.5° FOV, 1600 pixels, 37.6 Hz).

__init__()
class GCAS_UV_Vis

Bases: LineScanner

GCAS UV-Vis Spectrometer (45.0° FOV, 1024 pixels, 12.0 Hz).

__init__()
class GCAS_VNIR

Bases: LineScanner

GCAS Visible Near-Infrared (VNIR) Spectrometer (70.0° FOV, 1024 pixels, 12.0 Hz).

__init__()
class eMAS

Bases: LineScanner

eMAS (85.92° FOV, 716 pixels, 6.25 Hz).

__init__()
class PICARD

Bases: LineScanner

PICARD (50.0° FOV, 412 pixels, 100.0 Hz).

__init__()

LVIS lidar

class LVISLens[source]

Bases: object

LVIS lens option defined by its beam divergence.

name: str
divergence_mrad: float
footprint_diameter(altitude_agl)[source]

Footprint diameter on the ground for a given altitude AGL.

Parameters:

altitude_agl (Quantity) – Flight altitude above ground level.

Return type:

Quantity

Returns:

Footprint diameter in meters.

__init__(name, divergence_mrad)
Parameters:
Return type:

None

class LVIS[source]

Bases: Sensor

LVIS 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 via 2 * 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]
Parameters:
property half_angle: float

Half-scan angle in degrees (default ≈5.71 deg).

swath_offset_angles()[source]

Cross-track viewing angles for each swath edge (nadir-looking).

Return type:

tuple

Returns:

Tuple of (port_edge_angle, starboard_edge_angle) in degrees.

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.

Parameters:

altitude_agl (Quantity) – Flight altitude above ground level.

Return type:

Quantity

Returns:

Maximum swath width in meters.

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)).

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • speed (Quantity) – Aircraft ground speed.

Return type:

float

Returns:

Equivalent FOV in degrees.

footprint_diameter(altitude_agl)[source]

Laser footprint diameter on the ground for the configured lens.

footprint = tan(divergence_mrad / 1000) * altitude_agl

Parameters:

altitude_agl (Quantity) – Flight altitude above ground level.

Return type:

Quantity

Returns:

Footprint diameter in meters.

coverage_rate(altitude_agl, speed)[source]

Area coverage rate at maximum swath.

coverage_rate = speed * max_swath

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • speed (Quantity) – Aircraft ground speed.

Return type:

Quantity

Returns:

Coverage rate in m^2/s.

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)

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • speed (Quantity) – Aircraft ground speed.

Return type:

Quantity

Returns:

Required footprint diameter in meters.

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.

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • speed (Quantity) – Aircraft ground speed.

Return type:

Quantity

Returns:

Effective swath width in meters.

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.

Return type:

bool

Parameters:
along_track_spacing(speed)[source]

Along-track distance between consecutive laser shots.

along_track_spacing = speed / rep_rate

Parameters:

speed (Quantity) – Aircraft ground speed.

Return type:

Quantity

Returns:

Shot spacing in meters.

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.

Return type:

bool

Parameters:
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.

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • speed (Quantity) – Aircraft ground speed.

Return type:

Quantity

Returns:

Point density in shots per square meter (1/m^2).

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 (effective swath = max swath): density = rep_rate / (speed * max_swath), so speed = rep_rate / (density * max_swath).

  • Sampling-limited (effective swath < max swath): density = 1 / fp^2, independent of speed. In this regime the density is always at least the target (since 1/fp^2 >= target_density), so faster speeds are feasible — the effective swath narrows but density within it stays constant.

The returned speed is the maximum speed at which point_density >= target_density.

Parameters:
  • target_density (Quantity) – Desired point density (1/m^2).

  • altitude_agl (Quantity) – Flight altitude above ground level.

Return type:

Quantity

Returns:

Maximum speed that achieves at least the target density.

Raises:

HyPlanValueError – If the target density exceeds 1/fp^2 (impossible at this altitude/lens regardless of speed).

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))

Parameters:
  • target_density (Quantity) – Desired point density (1/m^2).

  • speed (Quantity) – Aircraft ground speed.

Return type:

Quantity

Returns:

Maximum altitude AGL in meters.

summary(altitude_agl, speed)[source]

Compute all LVIS coverage parameters for a given flight configuration.

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • speed (Quantity) – Aircraft ground speed.

Return type:

dict

Returns:

Dictionary with all computed parameters.

print_summary(altitude_agl, speed)[source]

Print a formatted summary of LVIS coverage parameters.

Return type:

None

Parameters:
compare_lenses(altitude_agl, speed)[source]

Print a comparison table across all standard lenses.

Return type:

None

Parameters:
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 (Optional[str]) – Path to DEM file. Auto-downloaded if None.

Return type:

dict

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.

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 (Optional[str]) – Path to DEM file. Auto-downloaded if None.

  • n_scan_positions (int) – Number of scan positions across the swath.

Return type:

dict

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 from effective_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 (Optional[str]) – Path to DEM file. Auto-downloaded if None.

Return type:

dict

Returns:

Dict with all keys from summary() plus terrain-specific keys prefixed with terrain_.

LVIS_LENS_NARROW

LVIS lens option defined by its beam divergence.

LVIS_LENS_MEDIUM

LVIS lens option defined by its beam divergence.

LVIS_LENS_WIDE

LVIS lens option defined by its beam divergence.

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.

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: Sensor

Represents 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]
Parameters:
property wavelength: Quantity

Radar wavelength derived from frequency.

property range_resolution: Quantity

c / (2 * B).

Type:

Slant-range resolution from bandwidth

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.

property swath_center_angle: float

Incidence angle at swath center (degrees from nadir).

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.

Parameters:

altitude_agl (Quantity) – Flight altitude above ground level.

Return type:

Quantity

Returns:

Swath width in meters.

near_range_ground_distance(altitude_agl)[source]

Ground distance from nadir to near edge of swath.

Return type:

Quantity

Parameters:

altitude_agl (Quantity)

far_range_ground_distance(altitude_agl)[source]

Ground distance from nadir to far edge of swath.

Return type:

Quantity

Parameters:

altitude_agl (Quantity)

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)

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • incidence_angle (float | None) – Incidence angle in degrees. Defaults to swath center.

Return type:

Quantity

Returns:

Ground-range resolution in meters.

ground_sample_distance(altitude_agl)[source]

Ground sample distance at near range, center, and far range.

Parameters:

altitude_agl (Quantity) – Flight altitude above ground level.

Return type:

dict

Returns:

Dict with ‘near_range’, ‘center’, ‘far_range’ ground-range resolutions and ‘azimuth’ resolution.

slant_range(altitude_agl, incidence_angle=None)[source]

Slant range distance to target at given incidence angle.

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • incidence_angle (float | None) – Incidence angle in degrees. Defaults to swath center.

Return type:

Quantity

Returns:

Slant range in meters.

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.

Return type:

tuple

Returns:

Tuple of (near_side_angle, far_side_angle) where the sign convention matches swath.py: port = left of track, starboard = right of track.

interferometric_line_spacing(altitude_agl, overlap_fraction=0.0)[source]

Compute the required spacing between parallel flight lines for interferometric or mosaicking coverage.

Parameters:
  • altitude_agl (Quantity) – Flight altitude above ground level.

  • overlap_fraction (float) – Fraction of swath overlap (0.0 = edge-to-edge, 0.5 = 50% overlap). For InSAR mosaics, typically 0.1-0.2.

Return type:

Quantity

Returns:

Line spacing in meters (center-to-center).

class UAVSAR_Lband[source]

Bases: SidelookingRadar

NASA/JPL UAVSAR L-band fully polarimetric SAR.

Platform: Gulfstream III (C-20A) Typical altitude: ~12,500 m (41,000 ft)

__init__()[source]
class UAVSAR_Pband[source]

Bases: SidelookingRadar

NASA/JPL UAVSAR P-band SAR (AirMOSS configuration).

Platform: Gulfstream III (C-20A) Typical altitude: ~12,500 m (41,000 ft)

__init__()[source]
class UAVSAR_Kaband[source]

Bases: SidelookingRadar

NASA/JPL GLISTIN-A Ka-band single-pass cross-track interferometric SAR.

Platform: Gulfstream III (C-20A) Typical altitude: ~12,500 m (41,000 ft)

__init__()[source]
class RadarExclusionConflict[source]

Bases: object

A 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.

radar_name: str
swath_index: int
intersection: object
exclusion_zone: Polygon
__init__(radar_name, swath_index, intersection, exclusion_zone)
Parameters:
Return type:

None

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 (Union[Polygon, List[Polygon]]) – A single Shapely Polygon or a list of Shapely Polygons representing UAVSAR swath footprints (e.g. from generate_swath_polygon()).

  • geojson (Union[str, dict, None]) –

    Exclusion zone data. One of:

    • None — load the bundled hyplan/data/faa_lband_radar_exclusion_zones.geojson file.

    • str — path to a GeoJSON FeatureCollection file on disk.

    • dict — an already-parsed GeoJSON FeatureCollection.

Return type:

List[RadarExclusionConflict]

Returns:

List of RadarExclusionConflict, one for each swath/zone pair that intersects. An empty list means no conflicts.

Raises:
  • FileNotFoundError – If geojson is None and 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

class FrameCamera[source]

Bases: Sensor

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).

__init__(name, sensor_width, sensor_height, focal_length, resolution_x, resolution_y, frame_rate, f_speed, tilt_angle=0.0, tilt_direction=0.0)[source]
Parameters:
property ifov_x: float

Instantaneous field of view per pixel across-track (microradians).

property ifov_y: float

Instantaneous field of view per pixel along-track (microradians).

property fov_x: float

Calculate horizontal Field of View (FoV) in degrees.

property fov_y: float

Calculate vertical Field of View (FoV) in degrees.

ground_sample_distance(altitude_agl)[source]

Calculate the ground sample distance (GSD) for a given altitude AGL.

For nadir cameras, returns x (across-track) and y (along-track) GSD. For tilted cameras, additionally returns y_near and y_far showing 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.

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), returns width and height. For tilted cameras, additionally returns height_near and height_far (distances from the principal point to the near/far edges along the tilt axis).

Return type:

Dict[str, Quantity]

Parameters:

altitude_agl (Quantity)

swath_width(altitude_agl)[source]

Across-track swath width at a given altitude AGL.

This is the width component of footprint_at(), provided for API compatibility with LineScanner and flight_box.box_around_center_line().

Return type:

Quantity

Parameters:

altitude_agl (Quantity)

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

altitude_for_scale(scale_denominator)[source]

Altitude AGL required for a given image scale (1:N).

Parameters:

scale_denominator (float) – The denominator N of the desired image scale.

Return type:

Quantity

Returns:

Required altitude AGL in meters.

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.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • target_gsd (Quantity) – Desired ground sample distance.

Return type:

Quantity

Returns:

Required focal length in mm.

line_spacing(altitude_agl, sidelap_pct=60.0)[source]

Flight line spacing from sidelap percentage.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • sidelap_pct (float) – Desired sidelap between adjacent flight lines (0-100).

Return type:

Quantity

Returns:

Center-to-center distance between parallel flight lines in meters.

trigger_distance(altitude_agl, overlap_pct=80.0)[source]

Along-track distance between camera exposures from overlap percentage.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • overlap_pct (float) – Desired forward overlap between successive images (0-100).

Return type:

Quantity

Returns:

Distance between exposure centers in meters.

trigger_interval(altitude_agl, ground_speed, overlap_pct=80.0)[source]

Time between camera triggers for a given speed and overlap.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • ground_speed (Quantity) – Aircraft ground speed.

  • overlap_pct (float) – Desired forward overlap between successive images (0-100).

Return type:

Quantity

Returns:

Time interval between triggers in seconds.

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.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • overlap_pct (float) – Desired forward overlap between successive images (0-100).

  • n_frames (int) – Number of extra frames beyond the boundary (default 4).

Return type:

Quantity

Returns:

Buffer distance in meters.

critical_ground_speed(altitude_agl)[source]

Calculate the maximum ground speed (m/s) to maintain proper along-track sampling.

Parameters:

altitude_agl (Quantity) – Altitude above ground level in meters.

Returns:

Maximum allowable ground speed in meters per second.

Return type:

Quantity

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.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • overlap_pct (float) – Forward overlap between successive images (0-100).

Return type:

float

Returns:

Dimensionless B/H ratio.

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_y where σ_p is the parallax measurement error in pixels.

Parameters:
  • altitude_agl (Quantity) – Altitude above ground level.

  • overlap_pct (float) – Forward overlap (0-100).

  • sigma_parallax (float) – Parallax measurement error in pixels (default 0.5).

Return type:

Quantity

Returns:

Vertical accuracy (σ_z) in meters.

range_accuracy(altitude_agl, baseline, sigma_q=None)[source]

Stereo range accuracy using the range-error formula.

σ_R = × σ_q / B where 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:
  • altitude_agl (Quantity) – Altitude above ground level.

  • baseline (Quantity) – Distance between stereo exposure centres.

  • sigma_q (float | None) – Angular uncertainty in radians. If None, derived from ifov_y / 3 (sub-pixel matching at ⅓ pixel).

Return type:

Quantity

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, and altitude_msl are 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, and altitude_msl are provided. Rays are intersected with the DEM via ray_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:

Polygon

Returns:

A shapely.geometry.Polygon with 3-D coordinates.

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() with lat, lon, and altitude_msl keyword arguments instead. It uses the camera’s own FOV and tilt parameters automatically.

Return type:

List[Tuple[float, float, float]]

Parameters:
class MultiCameraRig[source]

Bases: Sensor

A rig of multiple FrameCamera instances with known orientations.

Each camera carries its own tilt_angle and tilt_direction. The rig stores optional lateral/longitudinal offsets for each camera.

Parameters:
  • name (str) – Rig name.

  • cameras (List[Dict]) – List of dicts, each with keys: "camera" (FrameCamera), "label" (str), "dx" (Quantity, lateral offset, default 0 m), "dy" (Quantity, longitudinal offset, default 0 m).

__init__(name, cameras)[source]
Parameters:
swath_width(altitude_agl)[source]

Combined across-track swath width (union of all cameras).

Return type:

Quantity

Parameters:

altitude_agl (Quantity)

ground_sample_distance(altitude_agl)[source]

Finest GSD across all cameras.

Return type:

Dict[str, Quantity]

Parameters:

altitude_agl (Quantity)

combined_footprints(altitude_agl)[source]

Per-camera footprint dicts with labels.

Return type:

List[Dict]

Parameters:

altitude_agl (Quantity)

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 dx cross-track angular offset stored in the rig layout.

Return type:

List[Dict]

Returns:

List of dicts with "label" (str) and "polygon" (shapely.geometry.Polygon).

Parameters:
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.

Return type:

List[Tuple[Dict, Dict]]

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.

Return type:

List[Dict]

Returns:

List of dicts with "pair" (labels) and "bh_ratio".

Parameters:

altitude_agl (Quantity)

line_spacing(altitude_agl, sidelap_pct=60.0)[source]

Flight line spacing from sidelap and combined swath width.

Return type:

Quantity

Parameters:
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:

MultiCameraRig

Returns:

A MultiCameraRig with 8 cameras (4 forward + 4 aft).

Factory function

create_sensor(sensor_type)[source]

Factory function to create and return an instance of a sensor.

Parameters:

sensor_type (str) – The name of the sensor class to instantiate. Must be one of the keys in SENSOR_REGISTRY.

Returns:

An instance of the requested sensor type.

Return type:

Sensor

Raises:

HyPlanValueError – If the specified sensor_type is not found in SENSOR_REGISTRY.