AIS support for ground truthing app#68
Conversation
a016258 to
2984a6c
Compare
5d7b71c to
2e25d65
Compare
2984a6c to
eddc605
Compare
b27b335 to
a2ef533
Compare
| } | ||
|
|
||
| POINT_COLUMNS = ("MMSI", "TIME", "lat", "lon") | ||
| EVENT_GAP_SECONDS = 1200 |
There was a problem hiding this comment.
For Adsb we use 900 seconds. Let's use the same here, too...
|
|
||
| df.drop_duplicates(subset=list(POINT_COLUMNS), keep="last") | ||
|
|
||
| # 20-minute gap threshold splits vessel transits (mirrors ADSB event logic). |
There was a problem hiding this comment.
To your point a few weeks ago, this inline comment is true only when EVENT_GAP_SECONDS = 1200. Let's use more generic language or remove the comment altogether?
There was a problem hiding this comment.
That sneakily stayed in there, good callout
| starttime = points.point_dt.iat[0] | ||
| endtime = points.point_dt.iat[-1] | ||
| flight_times = (points.point_dt - starttime).dt.total_seconds().values # Seconds after initial point | ||
| flight_times = (points.point_dt - starttime).dt.total_seconds().values |
There was a problem hiding this comment.
Do you agree that flight_times is still the appropriate name for this variable? Something more generic seems better...
There was a problem hiding this comment.
How about something quite general like elapsed_seconds? Or did you have anything else in mind?
There was a problem hiding this comment.
Discussed - we confirmed elapsed_seconds seems like a clear name here
| dem_glob, | ||
| description=( | ||
| f"elevation DEM for {unit}{site} " | ||
| f"(expected GeoTIFF in Input_Data/01_ELEVATION/elevation_m_nad83_utm*.tif)" |
There was a problem hiding this comment.
Let's chat about what this line/function is doing.
There was a problem hiding this comment.
Discussed - Python automatically concats strings together if they span across multiple lines.
| faa, TrackSource.ADSB, "A98046_0_20250623", _adsb_points(icao="DEADBE") | ||
| ) == (None, None, None) | ||
|
|
||
| def test_gps_no_match_returns_nones(self): |
There was a problem hiding this comment.
I'm not sure I understand this test. Let's chat about it.
There was a problem hiding this comment.
This is verifying the logic in the vehicle info lookup that returns a tuple of None for aircraft in the event of a missing FAA DB.
This logic could arguably be changed, but this was effectively what the ground truthing app was doing before we split it into more files
NPS-ActiveSpace/nps_active_space/ground_truthing/vehicle_info.py
Lines 41 to 50 in aea2935
| from nps_active_space.utils.ais.query import query_ais_mxak | ||
| from nps_active_space.utils.ais.reader import MxakAis | ||
|
|
||
| REPO = Path(__file__).resolve().parents[3] |
There was a problem hiding this comment.
Yes! Ideally we move to using pathlib generally across the repo to better support potential cross-platform work.
| REPO = Path(__file__).resolve().parents[3] | ||
| AIS_FIXTURE = REPO / "example_data" / "AIS" / "MXAK-AIS-GLBA-20250107.csv" | ||
| AIS_DIR = AIS_FIXTURE.parent | ||
|
|
||
| METADATA_COLS = ["TIME", "MMSI", "lat", "lon", "ship_name", "shiptype", "altitude", "event_id"] | ||
|
|
||
|
|
||
| def _tabular(gdf: gpd.GeoDataFrame, columns: list[str]) -> pd.DataFrame: | ||
| return pd.DataFrame(gdf)[columns].reset_index(drop=True) | ||
|
|
||
|
|
||
| @pytest.fixture(scope="module") |
There was a problem hiding this comment.
A decorator, right? Let's chat
There was a problem hiding this comment.
Discussed - these are pytest fixtures, which are basically a way to specify some generic setup (and/or teardown) that happens before/after a unit test is run. A common use case (and why we have them here) is to provide a generic input that is freshly initialized for each unit test that includes the fixture.
6fd06b1 to
558511b
Compare
Extract MXAK AIS parsing into utils/ais, add site-local timezone conversion for NVSPL alignment, and wire AIS as a track source in the ground-truthing CLI. Co-authored-by: Cursor <cursoragent@cursor.com>
The new name states the contract: resolve a glob pattern to a file path or raise FileNotFoundError with a descriptive message. Co-authored-by: Cursor <cursoragent@cursor.com>
Restore DST-transition and UTC-offset documentation from the original models.py implementation, deduplicate AKST/AKDT handling, and rename the test module to test_timestamp_parsing.py. Co-authored-by: Cursor <cursoragent@cursor.com>
Move query_ais_mxak tests out of test_reader.py so test modules align with nps_active_space.utils.ais.reader and .query. Co-authored-by: Cursor <cursoragent@cursor.com>
Extract shared alignment helpers, add self-documenting synthetic tests for UTC-to-local CPA matching and NVSPL window peaks, and parametrize the May 24 example-data regression tests by MMSI. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace per-column row asserts with an expected DataFrame comparison, matching the pattern used in AIS reader tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce a shared TrackSource StrEnum, move per-source track queries into ground_truthing/tracks.py, and adopt the enum in ground-truthing and metrics entry points. Co-authored-by: Cursor <cursoragent@cursor.com>
Rename tracks.py to load_tracks.py and load_ground_truthing_tracks() to load_tracks() so the module name matches its public entry point. Co-authored-by: Cursor <cursoragent@cursor.com>
Rename database_type to track_source in the GUI, unify AIS and aircraft metadata via lookup_track_vehicle, and use match/case with TrackSource. Co-authored-by: Cursor <cursoragent@cursor.com>
Cover UTC format variants, AKST/AKDT mixed rows with DST fallback, and unrecognized formats using assert_series_equal. Co-authored-by: Cursor <cursoragent@cursor.com>
Exercise lookup_aircraft and lookup_track_vehicle with synthetic FAA fixtures alongside existing AIS vessel tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Use SQLAlchemy URL.create so usernames and passwords are percent-encoded before connecting for GPS track loading. Co-authored-by: Cursor <cursoragent@cursor.com>
…ll fields separately
…ble in spline fit
Ground-truthing does not depend on 3D viz behavior; the DEM sampling patch belongs in feature/vis_improvements_for_ais with the fuller package refactor and performance fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
93f8c07 to
a09b4ab
Compare
Overview
--track-sourcefor ground truthing (GPS / ADSB / AIS)utils/ais/where I've moved logic that previously lived inmodels.py. This includes the MXAK AIS reader, query MXAK data function, and timestamp parsing.utils/time_utils/site.pyfor logic around finding timezones for sites and converting UTC -> local time.TrackSourceenum;track_sourcenaming;lookup_track_vehicle()for AIS vs ADSB/GPSload_tracks()functionality for importing tracks from different data sources moved to own file to split logic out more cleanlyDepends on #67 (
fix/split_ground_truthing_into_multiple_files).Testing
pytestlocallyGLBALSTL 2024 annotations with AIS tracks
nps_active_space/scripts/run_ground_truthing.py -e DENA -u GLBA -s LSTL -y 2024 -t AISwith the following config:
Example annotation screen:

Ground truthing GUI with ADS-B data for DENATRLA 2025
python nps_active_space/scripts/run_ground_truthing.py -e DENA -u DENA -s TRLA -y 2025 -t ADSBGround truthing GUI with GPS data for DENATRLA 2023
python nps_active_space/scripts/run_ground_truthing.py -e DENA -u DENA -s TRLA -y 2023 -t GPSNext steps
1-2 additional PRs for:
viz.pyto better display AIS [WIP] Refactor viz.py to attempt to improve code quality and better display AIS tracks #72