Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ host = Database host.
site_metadata = Absolute path to the the file containing site metadata. Value required for all run_ground_truthing.py and generate_active_space.py
nvspl_archive = Absolute path to the directory where all NVSPL sound data is stored. Value required for all run_ground_truthing.py and generate_active_space.py
adsb = Absolute path to the directory where ADSB track data is stored. Value required if pulling ADSB tracks in run_ground_truthing.py or run_audible_transits.py
dem = Absolute path to the DEM tif file to use for active space generation. Value required for generate_active_space.py and generate_active_space_mesh.py
dem = Absolute path to the source DEM GeoTIFF for project_setup and active space generation. Required for project_setup.py, generate_active_space.py, and generate_active_space_mesh.py
dem_elevation_units = Vertical units of the source DEM raster: ``feet`` or ``meters``. Defaults to ``feet``. Used by project_setup.py when clipping/reprojecting elevation to a site location.
mennitt = Absolute path to the mennitt ambience tif. Value required for generate_active_space.py and generate_active_space_mesh.py

[project]
Expand Down
36 changes: 5 additions & 31 deletions nps_active_space/active_space/active_space_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from warnings import warn

from nps_active_space import ACTIVE_SPACE_DIR
from nps_active_space.setup.site_writer import create_site_dir, write_listener_site_file
from nps_active_space.utils.models import Microphone
from nps_active_space.utils.computation import (
build_src_point_mesh,
Expand Down Expand Up @@ -87,29 +88,7 @@ def __init__(self, NMSIM: str, study_area: gpd.GeoDataFrame, root_dir: str, dem_
self._flt_file = None
self._site_file = None

self._make_dir_tree()

def _make_dir_tree(self):
"""Create a canonical NMSIM project directory. Copied from NMSIM_Create_Base_Layers.py"""
directories = [
"Input_Data",
"Input_Data/01_ELEVATION",
"Input_Data/02_IMPEDANCE",
"Input_Data/03_TRAJECTORY",
"Input_Data/04_LAYERS",
"Input_Data/05_SITES",
"Input_Data/06_AMBIENCE",
"Input_Data/07_WEATHER",
"Input_Data/08_TREES",
"Output_Data",
"Output_Data/ASCII",
"Output_Data/IMAGES",
"Output_Data/SITE",
"Output_Data/TIG_TIS"
]
for directory in directories:
if not os.path.exists(f"{self.root_dir}/{directory}"):
os.makedirs(f"{self.root_dir}/{directory}")
create_site_dir(self.root_dir)

def _mask_dem_file(self, dem_src: str, study_area: gpd.GeoDataFrame, project: bool = False,
buffer: Optional[int] = None, suffix: str = '') -> str:
Expand Down Expand Up @@ -299,14 +278,9 @@ def _create_site_file(self, mic: Microphone, dem_file: str) -> str:
-------
The name of the site file.
"""
site_filename = f"{self.root_dir}/Input_Data/05_SITES/{mic.name}.sit"
with open(site_filename, 'w') as site_file:
site_file.write(" 0\n")
site_file.write(" 1\n")
site_file.write("{0:19.0f}.{1:9.0f}.{2:10.5f} {3:20}\n".format(mic.x, mic.y, mic.z, mic.name))
site_file.write(f"{dem_file}\n")

return site_filename
return str(write_listener_site_file(
self.root_dir, mic.name, mic.x, mic.y, mic.z, dem_file
))

def _create_instruction_files(self, flt_file: str, site_file: str, trajectory_file: str,
omni_source_file: str) -> str:
Expand Down
1 change: 1 addition & 0 deletions nps_active_space/config/DENA_example.config
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ nvspl_archive = example_data/nvspl_archive
adsb = example_data/ADS-B/healy_repeater
ais =
dem =
dem_elevation_units = feet
mennitt =

[project]
Expand Down
1 change: 1 addition & 0 deletions nps_active_space/config/GLBA_example.config
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ nvspl_archive = example_data/nvspl_archive
adsb =
ais = example_data/MXAK-AIS-GLBA
dem =
dem_elevation_units = feet
mennitt =

[project]
Expand Down
1 change: 1 addition & 0 deletions nps_active_space/config/template.config
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ nvspl_archive =
adsb =
ais =
dem =
dem_elevation_units = feet
mennitt =

[project]
Expand Down
24 changes: 24 additions & 0 deletions nps_active_space/scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ The `nps_active_space` [toolkit architecture](https://github.com/dbetchkal/NPS-A
This directory contains the scripts along with instruction for their use via a command line interface. See [below](#use-cases) for the most common use cases, and [further below](#script-usage) for detailed documentation of each script.

- [project_setup.py](#project-setup)
- [migrate_project_sites.py](#migrate-project-sites)
- [run_ground_truthing.py](#run-ground-truthing)
- [plot_altitudes.py](#plot-altitudes)
- [generate_3d_active_space.py](#generate-3d-active-space)
Expand Down Expand Up @@ -207,6 +208,29 @@ Example executions:
$ python -u -W ignore nps_active_space/scripts/project_setup.py -e production -u DENA -s CNTW -y 2021 --mic-coord -148.98987 63.39493 --studyarea-sw -149.060585 63.345825 --studyarea-ne -148.770107 63.462577
```

### Migrate Project Sites

Rewrites legacy `.sit` microphone coordinates to the NMSIM project UTM zone (western study-area edge). Use this when on-disk deployments were created before the project-zone `.sit` fix. Updates only the `.sit` file; it does not re-clip elevation data.

| command-line arg | description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `-e`, `--environment` | **required.**<br/>The configuration environment to use. _Ex_: To use `production.config` pass `-e production` |
| `--all` | Migrate every deployment found under the configured project directory. Mutually exclusive with `-u`/`-s`/`-y`. |
| `-u`, `--unit` | Four letter NPS unit code. Required with `-s` and `-y` when not using `--all`. |
| `-s`, `--site` | Four letter site code. Required with `-u` and `-y` when not using `--all`. |
| `-y`, `--year` | Deployment year, YYYY. Required with `-u` and `-s` when not using `--all`. |
| `--dry-run` | Report legacy `.sit` files without writing changes. |

Example executions:

```bash
$ python -m nps_active_space.scripts.migrate_project_sites -e DENA -u DENA -s BULL -y 2019
```

```bash
$ python -m nps_active_space.scripts.migrate_project_sites -e DENA --all --dry-run
```

### Run Ground Truthing

This script is used to launch the ground truthing application to annotate the audibility of sound source tracks.
Expand Down
98 changes: 98 additions & 0 deletions nps_active_space/scripts/migrate_project_sites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
Rewrite legacy ``.sit`` microphone coordinates to the NMSIM project UTM zone.

Use this after upgrading to the project-zone ``.sit`` writer fix when on-disk deployments
were created with mic-local UTM easting/northing. This updates only the ``.sit`` file; it
does not re-clip elevation data or require ``data.dem`` in the config.
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

import nps_active_space.utils.config as cfg
from nps_active_space.setup.site_migrate import (
SitMigrationResult,
migrate_deployment_sit,
migrate_project_sites,
)


def _print_result(result: SitMigrationResult) -> None:
label = f"{result.unit} {result.site} {result.year}"
match result.action:
case "skipped_ok":
print(f"ok {label} already project zone ({result.project_utm})")
case "migrated":
print(
f"migrate {label} {result.decoded_utm} -> {result.project_utm} "
f"{result.sit_path}"
)
case "dry_run_would_migrate":
print(
f"dry-run {label} would migrate {result.decoded_utm} -> "
f"{result.project_utm}"
)
case "failed":
print(f"failed {label} {result.message or result.sit_path}")


def _summarize(results: list[SitMigrationResult]) -> int:
migrated = sum(result.action == "migrated" for result in results)
ok = sum(result.action == "skipped_ok" for result in results)
dry_run = sum(result.action == "dry_run_would_migrate" for result in results)
failed = sum(result.action == "failed" for result in results)
print("---")
print(f"Summary: {migrated} migrated, {ok} ok, {dry_run} dry-run, {failed} failed")
return 1 if failed else 0


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Rewrite legacy .sit files to use the NMSIM project UTM zone."
)
parser.add_argument(
"-e",
"--environment",
required=True,
help="The configuration environment to run the script in.",
)
target = parser.add_mutually_exclusive_group(required=True)
target.add_argument("--all", action="store_true", help="Migrate every deployment found.")
target.add_argument("-u", "--unit", help="Four letter unit code. E.g. DENA")
parser.add_argument("-s", "--site", help="Four letter site code. E.g. BULL")
parser.add_argument("-y", "--year", type=int, help="Four digit year. E.g. 2019")
parser.add_argument(
"--dry-run",
action="store_true",
help="Report legacy .sit files without writing changes.",
)
args = parser.parse_args()

if args.unit and not (args.site and args.year):
parser.error("-u requires -s and -y")
if (args.site or args.year) and not args.unit:
parser.error("-s and -y require -u")

cfg.initialize(environment=args.environment)
project_dir = Path(cfg.read("project", "dir"))

if args.all:
results = migrate_project_sites(project_dir, dry_run=args.dry_run)
else:
results = [
migrate_deployment_sit(
project_dir,
args.unit,
args.site,
args.year,
dry_run=args.dry_run,
)
]

for result in results:
_print_result(result)

sys.exit(_summarize(results))
Loading
Loading