id: cnn_burn_detect
name: SAR Burn-Scar CNN Detection
description: >
  Detect burn scars from a 5-channel Sentinel-1 SAR-anomaly raster using a
  small ONNX CNN (e.g. KTH SAR4Wildfire BAN-2020). The input bands are,
  in fixed order:
    1. VH log-ratio   — log10(post / baseline_mean)
    2. baseline μ
    3. baseline σ
    4. baseline p10
    5. baseline p90
  The model returns a single-channel probability raster, which is
  thresholded into a binary uint8 burn-scar mask. Optionally the float32
  probability raster is returned alongside via `emit_probability: true`.
version: 1.0.0
category: inference
type: raster-to-raster
default_implementation: native

inputs:
  - name: raster
    type: raster
    format: [cog, tif]
    description: 5-band SAR-anomaly raster (VH log-ratio + μ σ p10 p90 baseline stats)
    required: true

# Rolled-up band requirement: the SAR-anomaly stack is derived end-to-end from
# the VH polarization. Upstream resolvers should pick a SAR scene with `vh`.
requires:
  bands: [vh]

outputs:
  - name: prediction
    type: raster
    format: cog
    dtype: uint8
    concept: burned-area
    description: Binary burn-scar mask (0 = no burn, 1 = burn scar)
  - name: probability
    type: raster
    format: cog
    dtype: float32
    description: Per-pixel float32 burn probability (when emit_probability=true)

params:
  model:
    type: string
    default: sar4wildfire-ban-2020
    description: Model name from registry/models/ (e.g., "sar4wildfire-ban-2020")
  device:
    type: select
    options: [auto, cpu, cuda]
    default: auto
  batch_size:
    type: integer
    default: 16
    description: Number of chips to process per ONNX forward pass
  chip_size:
    type: integer
    default: 256
    description: Tile size (square); falls back to profile.input.image_size
  overlap:
    type: integer
    default: 32
    description: Overlap in pixels between adjacent chips
  threshold:
    type: number
    default: 0.5
    description: Probability cutoff for the binary mask
  emit_probability:
    type: boolean
    default: false
    description: When true, also return the float32 probability raster
  license_acceptance:
    type: boolean
    default: false
    description: >
      Required to be true for NC / commercial models. Has no effect for
      open-licensed or `to-be-confirmed` models (informational only).

execution:
  realtime_max_km2: 10
  cost_per_km2: 0.02
  time_per_km2_sec: 5
  memory_profile: low

cache_policy:
  ttl_days: 365
  invalidate_on: [model_update, source_update]

# 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).
backends:
  python:
    function: ml.burns.cnn_burn_detect
    dispatch: folia/compute.py _BUILTIN_OP_MAP
