# catalog/operations/geo/evaluation/vector_iou.yaml

id: vector_iou
name: Vector IoU
description: >
  Intersection over Union between two polygon sets — the evaluation
  primitive for SAR4Wildfire (Ban & Zhang 2020) and any
  perimeter-vs-reference benchmark (MTBS, NBAC, EFFIS, validation
  polygons). Clean polygons in, scalar f64 out.
version: 1.0.0
category: evaluation
type: vector-pair-to-scalar
default_implementation: native

inputs:
  - name: predicted
    type: vector
    format: geojson
    description: >
      Predicted polygon set — Feature, FeatureCollection, Geometry,
      Polygon, or MultiPolygon. Multiple features are treated as their
      union. Non-polygon geometries are silently skipped.
    required: true
  - name: reference
    type: vector
    format: geojson
    description: >
      Reference (ground-truth) polygon set in the same CRS as
      `predicted`. Same shape rules apply.
    required: true

requires: {}

outputs:
  - name: iou
    type: scalar
    dtype: float64
    description: >
      IoU in [0, 1]. NaN if both inputs have zero polygon area
      (undefined). Returns 0.0 if exactly one side is empty.

params: {}

uncertainty:
  error_model: deterministic
  factors:
    - name: crs_mismatch
      description: >
        Inputs must be in the same CRS. Areas are computed in the input
        CRS's units squared — there is NO silent reprojection.
      severity: high
      mitigations:
        - "Project both inputs to a common UTM zone (or equal-area CRS) before calling"
        - "For continental-scale validation use Lambert Azimuthal Equal Area"
    - name: dirty_polygons
      description: >
        Self-intersecting / invalid input polygons break BooleanOps and
        produce undefined results. This op does NOT call make_valid —
        upstream geometry repair (typically the polygonization step) must
        emit clean polygons.
      severity: high
      mitigations:
        - "Run perimeter_progression with make_valid=true upstream"
        - "Use GEOS make_valid in Python pre-processing if shapes are user-supplied"
  limitations:
    - "Polygon clean-up is intentionally out of scope (would require GEOS)."
    - "Area is in the input CRS units² — meaningless for unprojected WGS84 in absolute terms but still valid for IoU since both sides cancel."

execution:
  realtime_max_km2: 100000
  cost_per_km2: 0.00001
  time_per_km2_sec: 0.01
  memory_profile: low
  profile:
    cpu: low
    memory: low
    io: low
  scaling:
    model: linear
    parallelizable: true
    min_chunk_km2: 1

cache_policy:
  ttl_days: 30
  invalidate_on: [source_update]

# backends: audited 2026-08-14 (defect 50). NOTHING dispatches this op: no arm in folia-engine
# `dispatch_op`, no `registerOp`/OP_TABLE entry in packages/compute, no `_BUILTIN_OP_MAP`
# key in folia/compute.py, no backend manifest. Declared EMPTY on purpose — an absent
# block would be indistinguishable from one nobody ever wrote.
# packages/compute-wasm/src/vector_ops.rs:1005 `vector_iou` exists as a crate fn; nothing registers an op for it.
backends: {}

display_hints:
  table:
    renderer: tanstack-table
    fields: [iou]
    format: "{value:.3f}"
  info:
    fields: [iou]
    format: "{value:.3f}"
    section: Validation

ui:
  icon: target
  color: "#2E8B57"

provenance:
  references:
    - "Ban, Y., Zhang, P., et al. (2020). Near Real-Time Wildfire Progression Monitoring with Sentinel-1 SAR Time Series and Deep Learning. Scientific Reports 10:1322. https://doi.org/10.1038/s41598-019-56967-x"
