Skip to content

Fix ground truthing CRS regression and extract nps_active_space/setup - #102

Merged
elliott-ruebush merged 5 commits into
mainfrom
fix/ground-truthing-crs-tuple-regression
Jul 24, 2026
Merged

Fix ground truthing CRS regression and extract nps_active_space/setup#102
elliott-ruebush merged 5 commits into
mainfrom
fix/ground-truthing-crs-tuple-regression

Conversation

@elliott-ruebush

@elliott-ruebush elliott-ruebush commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fix #75 regression in run_ground_truthing.py: use microphone.crs from get_deployment() instead of the coords_to_utm() tuple
  • Extract project_setup.py into nps_active_space/setup/ (site_writer.py, site_decoder.py, elevation.py, workflow.py); CLI is argparse + config only
  • Align .sit microphone coords to NMSIM project UTM zone (western study-area edge); fixes cross-zone deployments (e.g. DENABULL)
  • Legacy mic-local .sit files: get_deployment() raises with a copy-paste project_setup command; migrate_project_sites.py rewrites on-disk .sit files without full re-setup
  • Deduplicate ActiveSpaceGenerator site dir / .sit writing via shared setup helpers

Context

PR #75 changed coords_to_utm to return tuple[str, int]. This PR fixes the missed ground-truthing caller and refactors project setup. PR #84 will need the new coords_to_utm signature.

Test plan

  • pytest tests/setup/ (16 passed)
  • pytest (96 passed)
  • Manual: ground truthing app with existing .sit/study area
  • Manual: project_setup.py against a configured environment
  • Manual: migrate_project_sites.py --dry-run on legacy .sit if available
Example Creation of Bull River site folder

$ python -m nps_active_space.scripts.project_setup -e DENA -u DENA -s BULL -y 2026 --mic-coord -149.62901 63.39192 --studyarea-sw -150.02907 63.21250 --studyarea-ne -149.22895 63.57134
python -m nps_active_space.scripts.viz DENABULL2026 -e DENA
image

Migration script dry run on current `T:\ResMgmt\Sound\NMSim_Partial_Extract\NMSim\01 SITES` contents

python -m nps_active_space.scripts.migrate_project_sites -e DENA --all --dry-run
Skipping non-canonical .sit file: T:\ResMgmt\Sound\NMSim_Partial_Extract\NMSim\01 SITES\DENANTRL\Input_Data\05_SITES\DENANTRL.sit
Skipping non-canonical .sit file: T:\ResMgmt\Sound\NMSim_Partial_Extract\NMSim\01 SITES\DENANTRL\Input_Data\05_SITES\NONSENSE.sit
Skipping non-canonical .sit file: T:\ResMgmt\Sound\NMSim_Partial_Extract\NMSim\01 SITES\DENASUSH_\Input_Data\05_SITES\DENASUSH2018.sit
Skipping non-canonical .sit file: T:\ResMgmt\Sound\NMSim_Partial_Extract\NMSim\01 SITES\DENASUSH_\Input_Data\05_SITES\DENASUSH2026.sit
Skipping non-canonical .sit file: T:\ResMgmt\Sound\NMSim_Partial_Extract\NMSim\01 SITES\GLBALSTL\Input_Data\05_SITES\GLBALSTL.sit
ok       DENA BULL 2019  already project zone (epsg:26905)
ok       DENA BULL 2026  already project zone (epsg:26905)
ok       DENA CNTW 2021  already project zone (epsg:26906)
ok       DENA NTRL 2011  already project zone (epsg:26906)
ok       DENA NTRL 2019  already project zone (epsg:26906)
ok       DENA SUSH 2026  already project zone (epsg:26906)
ok       DENA TRLA 2009  already project zone (epsg:26906)
ok       DENA TRLA 2016  already project zone (epsg:26906)
ok       DENA TRLA 2017  already project zone (epsg:26906)
ok       DENA TRLA 2018  already project zone (epsg:26906)
ok       DENA TRLA 2019  already project zone (epsg:26906)
ok       DENA TRLA 2020  already project zone (epsg:26906)
ok       DENA TRLA 2021  already project zone (epsg:26906)
ok       DENA TRLA 2022  already project zone (epsg:26906)
ok       DENA TRLA 2023  already project zone (epsg:26906)
ok       DENA TRLA 2024  already project zone (epsg:26906)
ok       DENA TRLA 2025  already project zone (epsg:26906)
ok       GLBA BEARD 2023  already project zone (epsg:26908)
ok       GLBA LSTL 2024  already project zone (epsg:26908)
ok       GLBA MCLEOD 2023  already project zone (epsg:26908)
ok       GLBA REID 2020  already project zone (epsg:26908)
ok       GLBA RENDU 2020  already project zone (epsg:26908)
ok       GLBA RENDU 2021  already project zone (epsg:26908)
ok       GLBA RENDU 2022  already project zone (epsg:26908)
ok       GLBA RENDU 2023  already project zone (epsg:26908)
ok       GLBA TARR 2024  already project zone (epsg:26908)
ok       GLBA WILL 2025  already project zone (epsg:26908)
ok       NACA 001 2026  already project zone (epsg:26918)
---
Summary: 0 migrated, 28 ok, 0 dry-run, 0 failed

Follow-ups (future PR?)

Already deduped here: create_site_dir, write_site_file.

Remaining ActiveSpaceGenerator overlap:

  • Elevation: setup.create_elevation_tif (rasterio, feet→meters, int16) vs _mask_dem_file (GDAL warp, no unit conversion)
  • GridFloat: setup.write_gridfloat vs _create_dem_flt
  • .sit: _create_site_file still writes mic-local UTM coords; only project_setup/setup_site uses project zone today

Other: NLCD landcover setup, flexible study-area ingestion.

Question:

Is it intended that the active space generator _mask_dem_file function does not convert feet-> meters? maybe I'm missing something here

@elliott-ruebush elliott-ruebush changed the title Fix ground truthing CRS regression from coords_to_utm tuple return Fix ground truthing CRS regression and extract nps_active_space/setup Jul 14, 2026
elliott-ruebush and others added 3 commits July 21, 2026 16:30
Use microphone.crs from get_deployment() when launching the ground-truthing app instead of passing the coords_to_utm() tuple.

Co-authored-by: Cursor <cursoragent@cursor.com>
Move DEM clipping, GridFloat output, site directory creation, and setup_site orchestration into a library package. Thin project_setup.py to argparse and config only. Deduplicate site directory and .sit writing in ActiveSpaceGenerator. Add dem_elevation_units config and setup integration tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
…tion.

Write and read .sit easting/northing in the NMSIM project UTM zone (western study-area edge). Split site helpers into site_writer and site_decoder; fail clearly on legacy mic-local zone files with a project_setup rerun command. Add migrate_project_sites.py for in-place .sit rewrites and cross-zone regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@elliott-ruebush
elliott-ruebush force-pushed the fix/ground-truthing-crs-tuple-regression branch from fcac5f2 to ad82b48 Compare July 22, 2026 00:34
Comment thread nps_active_space/scripts/project_setup.py
elliott-ruebush and others added 2 commits July 21, 2026 16:41
No active callers use the PR #75 create_NMSIM_* names; project_setup and tests already import the canonical symbols.

Co-authored-by: Cursor <cursoragent@cursor.com>
Keep __init__ as a thin entry point for setup_site and NMSIM_DST_CRS; import site helpers from submodules. Use read_sit_file() instead of re-parsing .sit lines in helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>

@dbetchkal dbetchkal left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work! Despite some nuance, this is clear to read and makes geographic sense.

nvspl=nvspl,
mic=microphone,
crs=coords_to_utm(microphone.lat, microphone.lon),
crs=microphone.crs,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes!! nice edit

Comment thread tests/setup/test_setup.py

with rasterio.open(output_tif) as ds:
values = ds.read(1, masked=True)
assert float(values.mean()) == pytest.approx(expected_mean, abs=1.0)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! pytest.approx seems very useful

Comment thread tests/setup/test_setup.py
assert float(hdr_lines["cellsize"]) == pytest.approx(dst_transform.a)

flt = np.fromfile(output_base.with_suffix(".flt"), dtype=np.float32).reshape(2, 2)
assert flt[0, 0] == pytest.approx(100.0)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I read this, line 211 initializes a 2x2 matrix and here we simply test each cell to see if the correct values were written to the .flt, right?

@elliott-ruebush
elliott-ruebush merged commit ddd442a into main Jul 24, 2026
1 check passed
elliott-ruebush added a commit that referenced this pull request Jul 28, 2026
Keep pyproject README structure and document dem_elevation_units in template.config comments after merging setup changes from #102.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants