# catalog/operations/raster/morph_open.yaml

id: morph_open
name: Morphological Open
description: >
  Morphological opening: erode then dilate. Removes small bright features
  (smaller than the structuring element) while preserving the overall shape
  of larger features. Useful for cleaning noisy binary masks.
version: 1.0.0
category: raster
type: raster-to-raster
default_implementation: native

inputs:
  - name: raster
    type: raster
    format: geotiff
    description: Input raster to open
    required: true

requires: {}  # structural — morphological op on any raster

outputs:
  - name: opened
    type: raster
    format: cog
    description: Opened raster with small bright features removed

params:
  radius:
    type: integer
    default: 1
    min: 1
    max: 50
    description: Radius of the disk structuring element in pixels

cache_policy:
  ttl_days: 30
  invalidate_on: [source_update, param_change]

# backends: audited 2026-08-14 (defect 50). A key means a runtime that DISPATCHES this op —
# folia-engine `dispatch_op` (products/sdk/folia-engine/src/lib.rs), a `registerOp`/OP_TABLE
# entry in packages/compute, `_BUILTIN_OP_MAP` in folia/compute.py, or a backend manifest
# (folia/backends/*/backend.yaml).
# packages/compute-wasm/src/handle_ops.rs:1311 `h_morph_open` is exported but no OP_TABLE entry calls it.
backends:
  gee:
    function: folia.backends.gee.ops.morph_open
    dispatch: folia/backends/gee/backend.yaml

display_hints:
  map:
    renderer: maplibre

ui:
  icon: sun
  color: "#DAA520"
