Skip to content

Refactor BMI nexus mapping to use adjacency zarr instead of GeoPackage #175

@taddyb

Description

@taddyb

Context

ddr_bmi.py:508-575 (_build_nexus_mapping) reads the GeoPackage via sqlite3 to get the flowpaths table's idtoid mapping for translating ngen nexus IDs to DDR segment indices.

After #172, the toid array will be available in the adjacency zarr. The BMI module should use that instead of the GeoPackage.

Proposal

Refactor _build_nexus_mapping to read the toid array from the adjacency zarr:

# Instead of sqlite3 query on gpkg:
toid_array = self.conus_adjacency["toid"][:]
order_array = self.conus_adjacency["order"][:]
# Build nexus_to_seg mapping from these arrays

The mapping logic:

  • order[i] gives the segment integer ID at index i
  • toid[i] gives the downstream nexus string (e.g., nex-12345) for segment i
  • Invert to get: nexus integer ID → segment array index

Fallback

Keep the sqlite3/gpkg path as a fallback (it already has a try/except that falls back to identity mapping). This ensures backwards compatibility if someone has a gpkg but hasn't rebuilt their zarr.

Files to modify

  • src/ddr/bmi/ddr_bmi.py
  • src/ddr/bmi/config.py (if hydrofabric_gpkg field needs to become optional)

Acceptance criteria

  • BMI initialize() works without a GeoPackage when adjacency zarr has toid
  • BMI initialize() still works with GeoPackage (backwards compatible)
  • Nexus mapping produces identical results from zarr vs gpkg
  • Existing BMI tests pass

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions