March 23: Smoothing the MIRI Seam
The MIRI boundary kept leaking visual artifacts through the blend — fixed the transition math (smoothstep + CIELAB lerp + sRGB gamma on the mask) and then chased a related OOM that only showed up at multi-instrument resolution.
Developer Journal
Refining the MIRI transition
March 20 shipped the "feather the color, not the signal" approach for multi-instrument composites, but the boundary still wasn't clean. Three distinct issues were compounding:
- Linear ramp — the mask used a straight linear fade from 0 to 1 across the feather width, which produced visible banding where the eye is most sensitive.
- RGB-space blending — lerping between two RGB palettes linearly is perceptually wrong because equal RGB steps aren't equal perceptual steps. The transition looked muddy in the middle.
- Gamma mismatch — the mask itself was applied in sRGB display space while the blend was happening in linear space, so the transition midpoint was shifted.
Fix: smoothstep the mask (3t² - 2t³) for a perceptually smoother ramp, lerp in CIELAB instead of sRGB so interpolated colors follow a perceptual path, then re-encode to sRGB gamma at the end. The seam is now visually invisible without having to blow out the feather width.
The CIELAB memory cliff
Converting full-size images to CIELAB allocates three double-precision float arrays per channel — on a 12k × 10k NIRCAM mosaic that's ~2.9 GB per instrument for the intermediate buffers alone. With two instruments in memory plus the source arrays, the process was getting OOM-killed halfway through the blend.
Fixed by chunking the CIELAB blend into row-major strips sized to fit the available memory budget. Each strip converts to CIELAB, lerps, converts back, and frees its buffers before the next strip starts. Peak memory dropped from "blows up on 12k images" to constant-per-chunk, and the wall-clock time barely moved because the strips process in parallel across cores.
Dependabot backlog
Dependabot continues its weekly march — ruff, uvicorn, eslint, typescript-eslint parser, AWSSDK.S3, MongoDB.Driver, and @eslint-react/eslint-plugin all bumped with clean CI. The hook pipeline is reliable enough now that most of these merge on a quick skim.
What shipped
| PR | Title |
|---|---|
| #904 | fix: chunked CIELAB blending to prevent OOM on multi-instrument composites |
| #903 | fix: refine MIRI boundary transition — smoothstep, CIELAB lerp, sRGB gamma |
| #901 | Bump MongoDB.Driver from 3.7.0 to 3.7.1 |
| #900 | chore(deps-dev): Bump @eslint-react/eslint-plugin |
| #899 | Bump AWSSDK.S3 from 4.0.19 to 4.0.19.1 |
| #897 | chore(deps-dev): Bump @typescript-eslint/parser |
| #895 | chore(deps): Bump uvicorn from 0.41.0 to 0.42.0 in /processing-engine |
| #894 | chore(deps-dev): Bump eslint in /frontend/jwst-frontend |
| #893 | chore(deps): Bump ruff from 0.15.6 to 0.15.7 in /processing-engine |