Add coastal gap-fill module for extending GeoTessera coverage#18
Open
PatBall1 wants to merge 1 commit into
Open
Add coastal gap-fill module for extending GeoTessera coverage#18PatBall1 wants to merge 1 commit into
PatBall1 wants to merge 1 commit into
Conversation
GeoTessera precomputed embeddings use a coarse land mask that clips coastal land (mangroves, intertidal zones, salt marshes) and blanks out nearshore waters entirely. This makes it difficult to use TESSERA embeddings for work that spans the land-sea boundary. tessera_coastal/ is a self-contained module that identifies tiles with incomplete coverage, regenerates them from Sentinel-1/2 imagery via the existing QAT inference pipeline, and exports seamless GeoTIFF tiles extending well beyond the shoreline. Also includes two small upstream improvements: - tessera_infer_QAT/infer_all_tiles.sh: make batch size, split ratio, and worker settings configurable via environment variables - tessera_infer/stitch_tiled_representation.py: support optional per-pixel scale factors during stitching
PatBall1
force-pushed
the
coastal-gap-fill
branch
from
April 9, 2026 11:49
986484d to
11cd2eb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GeoTessera precomputed embeddings use a relatively coarse land mask that causes two problems for coastal work:
This PR adds
tessera_coastal/, a self-contained module that identifies tiles with incomplete coverage, regenerates them from Sentinel-1/2 imagery via the existing QAT pipeline, and exports seamless GeoTIFF tiles extending well beyond the shoreline.Before and after (Jamaica, PCA false-colour)
What's included
New module --
tessera_coastal/:identify_coastal_tiles.py-- queries GeoTessera, downloads tiles, scans for blank pixels, groups tiles for regenerationrun_coastal_pipeline.sh-- orchestrates S1/S2 download, stacking, patchification, QAT inference, and stitching per groupexport_tiles.py-- merges GeoTessera + gap-fill into sliver-free 0.1-degree GeoTIFF tilescreate_preview.py-- PCA false-colour previews for visual QAChanges to existing files
This PR also touches two existing files. Both changes are backward-compatible and do not alter behaviour for existing workflows.
tessera_infer_QAT/infer_all_tiles.sh-- make settings overridable via environment variablesThe coastal pipeline processes many small tile groups in a loop, calling
infer_all_tiles.shonce per group with different data directories and memory settings each time. With the original hardcoded assignments, the only way to change settings likeBASE_DATA_DIRorGPU_BATCH_SIZEwas to edit the script before each invocation.This change wraps the assignments in
${VAR:=default}so that a caller can pass configuration via environment variables. If no environment variable is set, the original default is used -- so anyone callinginfer_all_tiles.shdirectly today will see no difference. The only defaults that change areCPU_GPU_SPLIT(1:0→0:1) andGPU_BATCH_SIZE(1024→512), reflecting the more common GPU-based usage.tessera_infer/stitch_tiled_representation.py-- apply QAT dequantization scales during stitchingThe coastal module uses the QAT inference path (
tessera_infer_QAT/) because GeoTessera's public embeddings are aligned with the QAT checkpoint -- not the older float32 one. This is the only way to produce new embeddings that are numerically compatible with existing GeoTessera tiles.The QAT inference pipeline already saves both int8 quantized representations and per-pixel float32 scale factors (
*_scales.npyviatile_processor.py). These scales are needed to dequantize the int8 values back to their original float32 range. However,stitch_tiled_representation.pywas not applying them -- it loads the raw int8 array, which NumPy auto-casts to float32, leaving values in the -128 to 127 range rather than the true embedding scale (magnitudes around 20-45 for GeoTessera tiles).This means anyone using QAT inference followed by stitching would get output in a different numeric range to GeoTessera. For the coastal module this is critical because the export step merges QAT-stitched tiles with existing GeoTessera tiles, and the values must be in the same range.
The fix is five lines: if a
*_scales.npyfile exists alongside a representation tile, multiply through before stitching. If no scale file exists (the float32 inference path), the check is skipped and behaviour is identical to before.Test plan
identify_coastal_tiles.pyon a small AOI to verify tile identification and manifest generationexport_tiles.pyandcreate_preview.pyto verify GeoTIFF and preview outputtessera_infer_QATandtessera_inferworkflows are not broken (no scale files present → no change; no env vars set → original defaults used)