# Classification Prediction Operation
#
# Apply a trained classifier to new imagery to produce a classified map.

id: classification_predict
name: Classify Image
description: >
  Apply a trained machine learning model to classify imagery. Produces a
  classification map where each pixel is assigned a class label, plus
  optional confidence/probability maps.
version: 1.0.0
category: classification
type: raster-model-to-raster
default_implementation: otb

inputs:
  - name: image
    type: raster
    format: cog
    description: >
      Image to classify. Must have the same bands as the training images
      used to create the model.
    required: true

  - name: model
    type: file
    format: model
    description: >
      Trained classifier model from classification_train.
    required: true

  - name: mask
    type: raster
    format: cog
    description: >
      Optional mask image. Pixels with value 0 will not be classified.
    required: false

# Parametric on the trained model file — the bands and target classes are
# fixed by whatever `classification_train` was given. The op has no static
# knowledge of either; the resolver should validate band compatibility
# between the model and the input image at run time.
requires: {}

outputs:
  - name: classification
    type: raster
    format: cog
    dtype: uint8
    # No fixed output concept — the trained model may target land-cover,
    # crop-type, burned-area, or any other categorical phenomenon. Recipes
    # that pin a model should declare the concept at the recipe layer.
    description: >
      Classified image with integer class labels. Values correspond to
      the class labels in the training data.

  - name: confidence
    type: raster
    format: cog
    dtype: float32
    description: >
      Classification confidence map (0-1). Higher values indicate more
      confident predictions. Only output if output_confidence is true.

  - name: probabilities
    type: raster
    format: cog
    dtype: float32
    description: >
      Per-class probability map (one band per class). Only output if
      output_probabilities is true. Useful for uncertainty analysis.

params:
  output_confidence:
    type: boolean
    default: false
    description: Output a confidence map alongside classification

  output_probabilities:
    type: boolean
    default: false
    description: Output per-class probability maps

  nodata_value:
    type: integer
    default: 0
    description: Value to use for unclassified/masked pixels

granularity:
  min_resolution_m: 1
  max_resolution_m: 100
  recommended_resolution_m: 10
  output_resolution: inherit
  requires_continuous: true
  suitable_aoi_km2:
    min: 0.01
    max: 50000
  realtime_max_km2: 200

uncertainty:
  error_model: unknown
  factors:
    - name: model_accuracy
      description: "Classification accuracy depends on training data quality and quantity"
      severity: high
      mitigations:
        - "Use output_confidence=true to get per-pixel confidence scores"
        - "Validate model with independent test data before applying"
    - name: domain_shift
      description: "Model trained in one area may not generalize to other areas"
      severity: high
      mitigations:
        - "Ensure training data covers the spectral range of the target area"
        - "Retrain or fine-tune model for new geographic regions"
    - name: temporal_mismatch
      description: "Model trained on one season may fail on different seasons"
      severity: medium
      mitigations:
        - "Use imagery from the same season as training data"
  limitations:
    - "Accuracy is entirely dependent on training data quality"
    - "Cannot detect classes not present in training data"
    - "Confidence scores are model-dependent and may not be well-calibrated"

execution:
  realtime_max_km2: 200
  cost_per_km2: 0.005
  time_per_km2_sec: 1.0
  memory_profile: medium
  profile:
    cpu: high
    memory: medium
    io: medium
  scaling:
    model: linear
    parallelizable: true
    min_chunk_km2: 0.5

# 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:
  js:
    function: classification_predict
    dispatch: packages/compute/src/ops/classify-rf.ts
  python:
    function: geo.otb.classify_image
    dispatch: folia/compute.py _BUILTIN_OP_MAP

display_hints:
  map:
    renderer: maplibre
    palette: categorical
    opacity: 0.8

cache_policy:
  regional_precompute: []
  ttl_days: 30
  invalidate_on: [model_update, source_update]

examples:
  - name: Apply land cover model
    description: Classify new imagery using trained model
    inputs:
      image: "sentinel2_new_area.tif"
      model: "landcover_model.model"
    params:
      output_confidence: true

  - name: Classify with mask
    description: Only classify valid data areas
    inputs:
      image: "imagery.tif"
      model: "classifier.model"
      mask: "valid_data_mask.tif"
    params:
      nodata_value: 255
