Skip to content

Grid coverage feature sampling - #154

Merged
ptgrogan merged 20 commits into
mainfrom
grid-coverage-feature-sampling
Oct 26, 2026
Merged

ptgrogan merged 20 commits into
mainfrom
grid-coverage-feature-sampling

Conversation

@ptgrogan

Copy link
Copy Markdown
Contributor

No description provided.

collect_observations computes the observations of all points by each
satellite and instrument together: the orbit is propagated once to screen
the windows in which each point may be observed, and the periods, epochs,
and validity are refined in all windows at once (in blocks that bound
memory). Many points are about 50 times faster to collect, a point's
observations do not depend on the others, and short observations near the
perigee of eccentric orbits are no longer missed.

Add collect_feature_observations for features (regions that exist for a
period) sampled by ground track footprints, with the fraction and area
viewed and the viewing geometry, and use it in the OSSE examples.

Observation and downlink times are always in nanoseconds, fixing
compute_latencies for mixed units.
compute_sample_sizes adds to point or feature observations the extent on
the ground of a PointedInstrument's pixel at each target (along and across
track) and the spacing between pixels, with the slant range and scan
angle. PointedInstrument gains compute_sample_size, compute_sample_spacing,
and sample spacing getters, built on the new utility
compute_ground_sample_size, which projects rays at half an angular extent
on either side of the line of sight onto the WGS 84 ellipsoid.

Oversampling may be negative, for gaps between pixels, and pixel positions
of oversampled instruments are spaced across the whole field of view.
ConicalInstrument gains optional beam_width and scan_sample_spacing fields,
compute_sample_size (the footprint of the beam, longer in the oblique
direction of the view) and compute_sample_spacing (the distance the arc
advances per scan and between samples along the arc), which
compute_sample_sizes uses for conical scanners.

The OSSE examples model each sensor as its swath instrument with pixels
and compute its resolution elements with compute_sample_sizes rather than
by scaling nadir sizes, with unchanged results.
Attitude sets the orientation of a spacecraft's body relative to its orbit
(velocity frame, and yaw, roll, and pitch angles, constant or by argument
of latitude), and AttitudeSchedule switches between attitudes over time.
Satellites and constellations carry an attitude, instruments point
relative to the body (while fields of regard remain measured from nadir),
and analyses use get_instrument to bind an instrument to its satellite's
attitude. The projection utilities accept an attitude.

The GPM validation notebook models the yaw flip with one satellite and an
attitude schedule, with the same results as the analyses of each
orientation.
TargetAttitude points a spacecraft's body at the target closest to nadir within a maximum off-nadir angle (otherwise nadir), so that its instruments' views follow the targets; attitude schedules may switch to and from target pointing.
OCO-2 models its target mode with TargetAttitude, its slit yaw, and a schedule of its observing modes; ISS models the station's recorded attitude as an AttitudeSchedule; the imager, conical, SAR, and pushbroom notebooks express velocity frames (and Sentinel-1's roll steering) as satellite attitudes.
PointedInstrument.scan_period spaces the scans of a scanning instrument along track by the distance they advance on the ground in one period (compute_ground_advance), as for microwave sounders with one beam per scan position.
TAI seconds since 1993 are offset by 27 s (not 26 s) from UTC, and the reference observation times are interpolated between scan centers, to which the scan times refer.
ValidateSampleSizes compares sample spacings with ATMS, MODIS, VIIRS, AMSR2, and GMI geolocation and footprint sizes with published values; ValidateFeaturesTCPRIMED reproduces TC PRIMED's selection and coverage of 2025 Atlantic tropical cyclone overpasses with collect_feature_observations.
compute_specular_point and compute_glint_angle locate the sun glint and measure the glint angle at targets; Instrument.min_target_glint_angle and max_target_glint_angle avoid or require glint; observations and ground tracks report glint_angle; GlintAttitude points a spacecraft at or short of the glint.
The specular point matches OCO-2's glint spot within 0.05 km; a GlintAttitude with an offset profile fitted to one day places the view within 1.5 km on every day without drift. Frame times now use the 27 s TAI offset.
OCI's tilt keeps every sampled pixel at least 20 deg from the sun glint (5.2% within 20 deg without the tilt); the aft and forward tilts balance about 3.5 deg north of the subsolar latitude, within 0.9 deg of OCI's tilt change on one day and 5.3 deg on the next. Observation glint angles match OCI's within 0.26 deg.
collect_ro_observations now takes is_rising from the direction of the tangent point through sample_elevation (or from the profile's endpoints if it is not crossed) rather than the transmitter's pitch at the first sample, which mislabeled 0.2% of COSMIC-2 occultations at yaw angles of 75 to 90 deg. The RO validations report the absolute timing error: 0.25 to 0.30 s (COSMIC-2) and 0.25 to 0.26 s (PlanetiQ) at the 95th percentile.
GeneralPerturbationsOrbit.element_switch_times (with get_element_index) switches between elements at given times rather than midway between epochs. align_element_switches groups the epochs of satellites whose elements are published together into publication events and switches them at common times, so formation members no longer use elements of different epochs for the seconds between their switches (up to 4.3 km of range error for GRACE-FO).
ValidateSpaceCOSMIC2 places every recorded COSMIC-2 occultation at a collect_space_observations window edge (min_grazing_altitude of -80 km), within 0.25 to 0.30 s of the true times and 1 ms of collect_ro_observations. ValidateSpaceGRACEFO compares range and occlusion windows with GRACE-FO's precise orbits: range within 21 m, all altitude window edges within a few seconds, and no spurious windows with aligned element switches.
collect_ro_observations splits a grazing occultation into setting and rising observations where its tangent point turns. split_polygon keeps the vertex order of a polygon around a pole (sorting by longitude corrupted Antarctica's coastline). grid_observations averages revisits over the points that have one (and no longer fails without any). compute_ground_track uses the element selected by element_switch_times. aggregate_observations computes all targets together (about 100 times faster, same results).
find_coincident_observations compares the observations' epochs with instantaneous=True (each coincidence then spans the contributing epochs), and computes all targets together (hundreds of times faster, same results). collect_space_observations reports the closest approach in each window (closest_time and closest_range).
ValidateCoincidenceGMIAMSR2 finds GMI and AMSR2 coincidences within 15 minutes (97.7% of true ones, 99.9% of those found true, comparing epochs). ValidateSpaceSOCRATES reproduces SOCRATES's closest approaches to about a meter and a millisecond and confirms the min_duration guarantee. ValidateRegionPolarSentinel1 predicts all 210 Sentinel-1C passes over polar and anti-meridian regions. ValidateGridSMAP predicts 95% of SMAP's forward and aft looks within 0.2 s and its gridded revisits. The RO and space notebooks reflect the split of grazing occultations.
@ptgrogan
ptgrogan merged commit 631ed43 into main Oct 26, 2026
7 checks passed
@ptgrogan
ptgrogan deleted the grid-coverage-feature-sampling branch October 26, 2026 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant