Repository navigation
What's Changed
Added new observing capabilities for limb sounding, ground-based radar, fixed surface platforms, and regions (polygons), with support for shapely points. Changed how general perturbations orbits are propagated, with options to model orbits maintained on a repeat ground track. Also changed the tangent point for GNSS radio occultation (RO) and limb sounding to the point of minimum WGS 84 geodetic altitude along the line of sight.
Added:
- Analysis method
collect_limb_observations(with enumerationScanDirection) for limb sounding observations from periodic scans at a constant angular rate. - Analysis method
collect_space_observationsfor the periods when satellites can observe other satellites (as by a sensor or a radio frequency link), subject to slant range limits and Earth occlusion (a minimum WGS 84 geodetic altitude of the line of sight). Each observation records the lines of sight at its start and end as its geometry, and the satellites' closest approach during the period (closest_timeandclosest_range). - Object schemas
RadarStation(withRadarBandandRadarStation.from_band) andTerrainMask, and analysis methodscollect_radar_trackandcompute_radar_track, for ground-based radar coverage.AllSurfaceObjectsincludesRadarStation. - Object schema
SurfacePlatform(included inAllSurfaceObjects) for instruments on platforms fixed above the Earth's surface, such as towers or tethered balloons, with aheadingthat orients their views, and analysis methodscollect_platform_trackandcompute_platform_trackfor the static footprints of theirInstrumentandPointedInstrumentviews at a target elevation, either below the instruments (looking down) or above them (looking up, as at clouds), with views clipped to the horizon of the ground below (argumentground_elevationof the footprint and pixel methods) and to an optionalterrain_mask(aTerrainMask, as for aRadarStation), with methodSurfacePlatform.compute_visible_regionfor the region of a target above the instruments visible over them. Utility methodcompute_static_trackgives a fixed position the form of an orbit track, from which instruments project their views as from a satellite. - Module
preprocessto derive inputs from external datasets, including terrain masks from Copernicus DEM data (compute_terrain_mask,compute_terrain_mask_for_station,compute_terrain_mask_for_platform,get_copernicus_dem_tile_urls, andsample_dem_elevation, with aneffective_earth_radius_factorfor refraction, also an argument ofcompute_terrain_elevation_angle), and gridded weights from GeoTIFF rasters (read_raster_weights). - Generation method
generate_points_randomfor random points, uniform by area or weighted by a raster (for example, of population counts or densities), optionally within a mask, with a seed for reproducibility. - Analysis methods
collect_region_observationsandcollect_multi_region_observationsto collect the periods (start and end) when an instrument observes any part of a region (shapelyPolygonorMultiPolygon), using the footprints of pointed and conical instruments and the field of regard of other instruments. Each observation records its swath (the part of the region swept by the footprint) as its geometry and identifies the region by the hash of its geometry (target_hash). Methodsaggregate_observationsandreduce_observationscombine the swaths of a region into the part of it observed. - Analysis methods
find_coincident_observations, the periods when two or more satellites observe the same point at once (or within a maximum time difference), comparing their observation periods or, withinstantaneous, their epochs (as the times scanning instruments sample the point), andfind_coincident_ground_track, the overlapping footprints of pairs of satellites at the same time (or within a maximum time difference), with example notebookFindCoincidentObservations(Metop-SG-B ICI and NASA FALCON). - Analysis method
collect_feature_observationsfor the observations of features: regions that exist for a period of time (starttoend), such as the storms of a nature run in an observing system simulation experiment (OSSE), sampled by the footprints of the ground track. Each observation is a satellite's view of the part of a feature inside its swath, with the fraction and area viewed and the viewing geometry (elevation angle, azimuth, slant range, and satellite height) at the viewed part. - Analysis method
compute_sample_sizesfor the sizes of the samples of point or feature observations: the extent on the ground of aPointedInstrument's pixel at each target, along and across track, and the spacing between pixels (which bound the detail an observation can resolve), with the satellite's slant range and the target's scan angle. MethodsPointedInstrument.compute_sample_size,compute_sample_spacing,get_cross_track_sample_spacing, andget_along_track_sample_spacing, and utility methodcompute_ground_sample_size(the size on the ground of an angular extent centered on the line of sight to a target). FieldPointedInstrument.scan_periodfor scanning instruments, whose scans are spaced along track by the distance they advance on the ground in one period (as for microwave sounders with one beam per scan position), and utility methodcompute_ground_advance. - Fields
ConicalInstrument.beam_widthandscan_sample_spacing, and methodsConicalInstrument.compute_sample_size(the footprint of the beam, longer in the oblique direction of the view) andcompute_sample_spacing(the distance the scanned arc advances per scan, and between samples along the arc), for the sample sizes of conical scanners. - Analysis methods
compute_access_periods, the periods when a satellite is in view of a point above a minimum elevation angle, andcompute_region_access_periods, a conservative superset of the periods when an instrument's field of regard may observe any part of a region (for example, to cull analysis times). - Support for shapely
Pointobjects (longitude, latitude, and optional elevation) wherever a TAT-CPointis accepted (collect_observations,collect_multi_observations,compute_dop, andGeneralPerturbationsOrbit.get_observation_events), in anticipation of replacing TAT-C points. - Object schema
ConicalInstrument(included inAllInstruments) for conically scanning instruments, observed when a point crosses the scanned cone, and utility methodcompute_cone_and_azimuth. - Object schemas
AttitudeandAttitudeSchedule(withAttitudeSegment), and fieldattitudeof satellites and constellations, for the attitude of a spacecraft's body: its velocity frame (yaw steering) and yaw, roll, and pitch angles (constant or by argument of latitude), or a schedule of attitudes over time (for example, the yaw flips of a satellite that alternately flies forward and backward, or alternating observing modes). Instruments point relative to the body (their roll and pitch angles, scan azimuths, and pixels are measured from its axes), while their fields of regard remain measured from nadir. Methodget_instrumentof satellites and constellations gets an instrument bound to the attitude (seeInstrument.bind_attitudeandInstrument.platform_attitude), and projection utilities accept anattitude. - Object schema
TargetAttitudefor a spacecraft that points its body at ground targets (as an agile satellite imaging sites, or a target mode): at each time, at the target closest to nadir within a maximum off-nadir angle, and otherwise along nadir, so that its instruments' views follow the targets. Schedules may switch to and from target pointing. - Sun glint: utility methods
compute_specular_point(the specular point, or center of the sun glint, on the WGS 84 ellipsoid seen from a satellite) andcompute_glint_angle(the angle between the directions toward the satellite and of the Sun's specular reflection at a target); fieldsInstrument.min_target_glint_angleandmax_target_glint_angleto avoid or require sun glint (for example, for ocean color or glint observations); aglint_anglecolumn of observations and ground tracks with solar angles; and object schemaGlintAttitudefor a spacecraft that points its body at the specular point, or short of it toward nadir by an offset angle (constant or a function of the specular point's angle from nadir), as for a glint observing mode, which schedules may switch to and from. - Instrument pointing options: fields
PointedInstrument.velocity_frame(enumerationVelocityFrame, for spacecraft without yaw steering),Instrument.nadir_reference(enumerationNadirReference, for a geocentric nadir),PointedInstrument.view_geometry(enumerationViewGeometry, for cross-track scanners), andPointedInstrument.roll_angle_profileandpitch_angle_profile(with methodsget_roll_angleandget_pitch_angle) to vary pointing around the orbit. Projection functions accept matching arguments, includingtilt_angle. - Fields
Instrument.min_target_solar_elevationandInstrument.max_target_solar_elevationto require a range of solar elevation angles at the target. - Fields
GeneralPerturbationsOrbit.remove_drag, to propagate without drag, andGeneralPerturbationsOrbit.repeat_cycle, to propagate the elements directly (None, the default), maintained on a repeat ground track with a repeat cycle found from the elements ("auto"), or with a declared repeat cycle (a duration), also accepted byfrom_tle,from_omm_csv, andfrom_omm_json. Related methodsGeneralPerturbationsOrbit.get_repeat_elementandGeneralPerturbationsElements.get_repeat_element,refine_repeat_cycle,without_drag,is_sun_synchronous, and propertyhas_drag. - Field
GeneralPerturbationsOrbit.element_switch_times(with methodget_element_index) to switch between elements at given times rather than midway between their epochs, and utility methodalign_element_switchesto switch satellites whose elements are published together (as for a formation or a constellation) at common times, so that their relative positions do not jump while their elements switch at slightly different times. - Field
inclinationofMolniyaOrbitandTundraOrbit(by default, the critical inclination), and methodsfrom_apogee_longitudeandget_apogee_longitudeto place an orbit by the longitude of its apogee. - Field
WalkerConstellation.seam_spacing(and methodget_seam_spacing) to set the seam of a star configuration. - Argument
during_contactofcompute_latenciesto choose when an observation that ends during a downlink is downlinked ("end","next", or"immediate"). - Argument
systemsofcompute_dopto estimate a receiver clock bias for each navigation system. - Utility methods
compute_view_tangents,compute_view_angles,compute_along_track_field_of_view,compute_argument_of_latitude,geodesic_destination,pressure_to_altitude, andaltitude_to_pressure, radar geometry methods (compute_radar_beam_height,compute_radar_ground_range,compute_radar_ground_range_bounds,compute_radar_slant_range,compute_terrain_elevation_angle,compute_radar_footprint, andcompute_radar_footprint_profile), and methodPointedInstrument.is_in_field_of_view. - Utility methods for the WGS 84 ellipsoid (module
tatc.utils.ellipsoid):geodetic_to_rectangular,rectangular_to_geodetic,compute_ellipsoid_intersection(intersections of rays with the ellipsoid), andcompute_tangent_point(the point of minimum geodetic altitude on a line), utility methodcompute_vnb_frame(a satellite's velocity, normal, and binormal frame), and utility methodhash_geometry(a compact hash identifying a geometry). - Runtime configurations
footprint_points_radar_azimuthal,repeat_cycle_delta_semimajor_axis_m, andnutation_interpolation_minutes(the step of a cached table from which nutation angles are interpolated, ornullto compute them for every time), and constantsEFFECTIVE_EARTH_RADIUS_FACTOR,EARTH_ROTATION_RATE, andTROPICAL_YEAR_S. - Utility method
compute_local_incidence_angle, the angle between the line of sight to a satellite and the normal to sloped terrain at a target, and preprocessing methodscompute_terrain_slope_aspect(the slope and aspect of a DEM, by central differences of bilinearly interpolated elevations, across the seams of adjacent tiles) andadd_local_incidence_angles(the terrain slope, aspect, and local incidence angle at the targets of ground pixels or observations with satellite angles), to constrain observations of mountainous terrain, as by side-looking instruments. - Validation notebooks in
docs/validationcomparing TAT-C with data from operational missions, with a summary of their results by capability, modeling guidance, and the limits of what TAT-C models (docs/validation/summary.rst). - Example notebook
docs/examples/RunOSSEMonsoon.ipynb, an observing system simulation experiment (OSSE) that samples cold cloud top features of the 7-km GEOS-5 Nature Run over the American Southwest with the swaths of current (ATMS, CrIS) and notional future sounders, compares their horizontal resolution, and trades the number of satellites and orbit planes of the constellation. - A section of example notebook
docs/examples/CollectOrbitGroundTrack.ipynbcomparing the nadir field of regard model of NOAA-20 VIIRS with a detailed model from its validation (aPointedInstrumentwith the measured scan extent, scan view geometry, an along-track field of view tailored to the scan period, and the inertial velocity frame): their footprints, scans at nadir and the swath edge, and swaths over a pass. - Example notebook
docs/examples/RunOSSEHurricane.ipynb, an OSSE of a simulated North Atlantic hurricane in the GEOS-5 Nature Run (located with its coarsened 0.5 degree collection), which samples its cold cloud tops and heavy precipitation with the same sensors. - Optional dependencies
preprocessandvalidation, and development dependencypytest-xdistto run tests in parallel (e.g.pytest -n 8).
Changed:
GeneralPerturbationsOrbitpropagates orbit tracks and observation events consistently, as selected by itsrepeat_cycle: if set, times before the first and after the last element's epoch are propagated with that element maintained on its repeat ground track; other times use the closest element. Orbits are now propagated directly with SGP4 by default; useremove_drag=Trueandrepeat_cycle="auto"for the former default. Removed the runtime settingsrepeat_cycle_for_orbit_trackandrepeat_cycle_for_observation_events, thetry_repeatarguments, and methodsget_observation_repeat_cycle,get_repeat_shifts, andget_repeat_orbit_track. A warning is issued when elements with drag are propagated far from their epoch.get_repeat_cycleverifies repeat cycles without drag, reports a whole number of nodal days (or mean solar days for a sun-synchronous orbit), and also confirms repeat cycles for elements withinrepeat_cycle_delta_semimajor_axis_mof an exact repeat. Cached repeat cycles are recomputed when the search options change. Elements with a perigee below the Earth's surface (for example, from a mean motion in revolutions per day rather than radians per minute) have no repeat cycle, with a warning, rather than a search lasting minutes.- Removed the runtime settings
repeat_cycle_lazy_loadandgp_orbit_lazy_loadand thelazy_loadarguments ofto_gp_orbitandget_repeat_cycle: converted general perturbations orbits and repeat cycles are always cached, and recomputed when the fields or search options they depend on change. - Guards against common input errors: orbit and general perturbations element epochs must be timezone-aware, orbits with a perigee below the Earth's surface (for example, from a semimajor axis in kilometers) raise a validation error, and analyses warn of satellites with a perigee below 100 km (for example, from an altitude in kilometers). Analysis time windows must have timezone-aware
startandenddatetimes withendno earlier thanstart(aValueError), and aninstrument_indexout of range raises anIndexErrornaming the satellite. get_observation_eventsrefines rise and set times to a millisecond, and finds passes that culminate outside the search period or span a switch between elements.get_observation_eventscompletes passes whose rise or set Skyfield misses (grazing passes, which barely exceed the minimum elevation angle), finding the missing event from the culmination and dropping culminations below the minimum.compute_access_periodsandcollect_observationsno longer treated such a pass as visible from the start (or to the end) of the analysis period, which made a conical instrument observe points through the Earth.collect_observationsrefines access periods to the instrument's field of regard, uses the time the view sweeps over the point as the epoch of aPointedInstrumentobservation, and evaluates orbits with a repeat cycle consistently.collect_observationsandcollect_region_observationsaccept one or more points or regions and one or more satellites, andinstrument_index=Nonefor every instrument of each satellite, computing all of their observations together (concatenated and sorted by start).collect_multi_observationsandcollect_multi_region_observationsare kept as wrappers for backwards compatibility.collect_observationscomputes the observations of all points by each satellite and instrument together, vectorized across the points: the orbit is propagated once to screen the windows in which each point may be observed, and the periods, epochs, and validity of the observations are refined in all windows at once (in blocks that bound memory). Many points are about 50 times faster to collect (for example, 649 points, 24 satellites, and one day, from about 220 to 4.5 seconds), and a point's observations do not depend on the other points (to within a microsecond). Observation times are always in nanoseconds (datetime64[ns, UTC]), as are those ofcollect_downlinks.collect_orbit_track,collect_ground_track,collect_ground_pixels,collect_limb_observations, andcollect_downlinksaccept one or more satellites (and the track methodsinstrument_index=Nonefor every instrument), andcollect_ro_observationsone or more receivers, with the results of several concatenated and sorted by time (or start). Downlinks and RO observations of several satellites are computed together.PointedInstrumentroll and pitch angles rotate the view rigidly (roll, then pitch about the rolled cross-track axis), andcompute_view_tangentsaccepts them. Documented the pointing conventions (positive roll looks left, positive pitch looks forward, and cross-track pixel indices run from right to left).compute_latenciesdownlinks an observation that ends during a downlink at the end of that downlink by default (during_contact="end"; formerly"next").PointedInstrument.cross_track_oversamplingandalong_track_oversamplingmay be negative, for gaps between pixels (as of an undersampling sounder).collect_ro_observationsuses the point of minimum WGS 84 geodetic altitude on the receiver-transmitter line as the tangent point.SOCConstellationuses the polar streets-of-coverage pattern for near-polar orbits (new fieldpolarand methodsis_polar,get_footprint_angle,get_polar_design,get_satellites_per_plane, andget_number_planes;generate_walkerraises aValueErrorfor polar designs) and a continuously covering hexagonal lattice for inclined orbits, which requires more satellites at a given packing distance.collect_ground_trackandcollect_ground_pixelscull times with a mask using the periods when the instrument's field of regard may observe it, which no longer misses footprints near the poles or across the anti-meridian. Masks are split along the anti-meridian and poles before use, and results are sorted by time.- Observations of points (
collect_observations,collect_multi_observations, andcompute_latencies) identify each point by the hash of its geometry (target_hash, seehash_geometry) rather than apoint_id, andaggregate_observations,reduce_observations, andreduce_latenciesgroup observations bytarget_hash. Theidof a TAT-CPointis no longer used. - Generated points and cells are identified by the hashes of their geometries (
point_idandcell_id) rather than integer indices, so that a generated point'spoint_idequals thetarget_hashof its observations. - Generating points and cells is about 3 to 15 times faster (vectorized geometry construction, hashing, and clipping). Points and cells clipped to a mask keep the grid or lattice order rather than the arbitrary order of
geopandas.clip. - Analysis methods that accept satellites raise a
TypeErrorfor a constellation (use itsgenerate_membersmethod). - Deprecated utility method
buffer_target. collect_observationsaccepts a GeoDataFrame or GeoSeries of points (for example, generated points), as the list of its geometries.- Moved
joblib, used only by the example and validation notebooks, from the required to theexamplesoptional dependencies. - Replaced the deprecated
shapely.ops.transformwithshapely.transforminbuffer_footprintandbuffer_target. - Fixed
SunSynchronousOrbitto place the ascending node in local mean solar time and to keep the local time of its equator crossings constant as propagated. - Fixed
TrainConstellationfor long intervals between members, andMolniyaOrbitandTundraOrbitperiods to repeat the ground track as propagated. - Fixed rectangular footprints of wide, elongated views.
- Fixed
PointedInstrument.compute_footprint_pixel_arrayfor a single-time (scalar) orbit track. - Fixed
collect_observationsmissing short observations (and misplacing the ends of long ones) when a field of regard extends to the horizon of a long access period, as near the perigee of a Molniya orbit, which were refined from too few samples of the access period. - Fixed the pixel positions of a
PointedInstrumentwith oversampling (compute_projected_pixel_position,compute_footprint_pixel_array, andcollect_ground_pixels), which spaced the pixels by a fraction of the field of view rather than across all of it. - Fixed
split_polygonfor polygons around a pole whose boundary is not monotonic in longitude (such as Antarctica's coastline), which it reconstructed by sorting their vertices by longitude, removing and adding strips of the polygon: they are now reconstructed in their vertex order, unrolled across the anti-meridian. - Fixed
grid_observationsfor cells whose points each have a single sample (and so no revisit), which raised an error, and to average the revisit of a cell over only the points with a revisit. - Fixed
compute_ground_trackto identify orbits with the period of the element that propagates the orbit (as selected byelement_switch_times), rather than the element whose epoch is closest. - Fixed
collect_ro_observationslabeling some occultations of transmitters nearly abeam of the receiver (yaw angles near 90 degrees) as setting rather than rising:is_risingfollows the direction of the tangent point throughsample_elevation.collect_ro_observationsalso splits a grazing occultation, whose tangent point descends and rises again, into a setting and a rising observation where the tangent point turns, so that each observation crossessample_elevationat most once. - Fixed
compute_latenciesfor observations and downlinks whose times have different units (for example, microseconds and nanoseconds). - Fixed
split_polygonfor longitudes beyond 180 degrees, for polygons spanning -180 to 180 degrees of longitude, and for holes across the anti-meridian or around a pole (holes are now split like exteriors), and to drop degenerate (zero-area) parts left by repairing invalid polygons. - Fixed
compute_along_track_field_of_viewto subtend the ground track's advance from the satellite's height above the WGS 84 ellipsoid rather than its mean altitude above the mean Earth radius: at low latitudes, where a satellite is about 7 km lower above the ellipsoid, consecutive footprints left gaps of up to about 0.7% of their length (83 m per scan for NOAA-20 VIIRS). Tailored fields of view are about 1% larger in low Earth orbit. - Fixed cached orbit computations for copies with changed fields, and orbits and satellites to be picklable after propagation.
- Fixed numba-compiled utility methods (in
tatc.utils.orbital,observation,radar,atmosphere, andsurface) returningnanfor integer inputs, which overflowed in compiled integer arithmetic (for example,semimajor_axis_to_mean_motion(7000000)): inputs are now converted to floats. - Improved the performance of footprints (rays projected together from one view frame, vectorized ray and limb intersections, polygon assembly, splitting along the anti-meridian, and
split_polygon), masked ground tracks, multi-element orbit propagation,collect_ro_observations(observation periods of all transmitters searched and sampled together, with sample times and profiles built at once),collect_limb_observations(all scans sampled together, with sample times built at once), radar footprints (terrain masks interpolated at all azimuths at once, and a closed-form local projection instead of PROJ transformers for each station),collect_observations(linear-time pairing of rise and set events, and validity checks of all epochs at once),collect_region_observations(validity checks and swaths of all periods at once),collect_orbit_track(masks tested and points built for all times at once), observations of several points, regions, or satellites (Earth orientation computed together at each step of their searches), rise and set times (each bracketed near Skyfield's estimate and bisected only until it is narrower than a millisecond), orbit propagation (IAU 2000A nutation angles interpolated from a cached table, to within about a microarcsecond, rather than computed for every time), instrument validity checks (without iterating over Skyfield times), and the searches that refine observation periods (times built from offsets withoutdatetimeobjects).to_datetime64_nsandGeneralPerturbationsOrbit.get_closest_element_indexaccept SkyfieldTimeobjects. find_coincident_observationsandaggregate_observationscompute all targets together rather than one at a time, with the same results: for a day of observations of about 100,000 to 250,000 points, in seconds rather than 5 to 13 minutes.collect_region_observationsis about 3 times faster for detailed regions (for example, 30 days of observations of four regions of 2000 vertices each, from about 13 to 4 seconds), computing the distances to a region's boundary with a numba-compiled function.- Numba-compiled functions cache their machine code (
cache=True) in__pycache__directories next to the source files (or in the directory set byNUMBA_CACHE_DIR), so that new processes (for example, the workers of a multiprocessing pool) load rather than recompile them. After editing a constant or compiled function in an editable install, clear the cache (see the README). - Unit tests run numba-compiled functions compiled rather than as Python (set
NUMBA_DISABLE_JIT=1to include them in a coverage report). - Reorganized modules:
tatc.analysis.coverageis split intopoint_sampling,region_sampling,sampling(shared by both), andcoverage_metrics(the aggregation, reduction, and gridding of observations), andtatc.analysis.trackintoorbit_trackandground_track;tatc.analysis.ro_coverage,latency, anddopare renamedro_sampling,latency_sampling, anddop_sampling; tangent point geometry moved fromtatc.analysistotatc.utils.ellipsoid, and the radar footprint functions fromtatc.utils.projectiontotatc.utils.radar. Public functions remain available fromtatc.analysisandtatc.utils. Orbit propagation algorithms moved totatc.utils.propagation, with the conversion of Skyfield times intatc.utils.time, interpolated nutation angles intatc.utils.earth_orientation, and computations run together intatc.utils.computation. - Updated example notebooks.
Full Changelog: v3.5.1...v3.6.0