name: lascar
version: "0.1"
category: events-hazards
themes: [hazards]
family: active-lava-flow-mapping
description: >
  Active thermal anomaly and flow mapping at Láscar volcano, Chile, using
  Sentinel-2 SWIR and NBR. Láscar is the most active volcano of the central
  Andes, with a history of vulcanian explosions and a persistent high-temperature
  fumarole field at the summit crater. Its high-altitude arid setting in the
  Atacama gives some of the clearest viewing conditions of any active volcano on
  Earth, making the B12 SWIR thermal anomaly over the active crater unusually
  clean and detectable even at low eruption intensity.

settings:
  default_bbox: [-67.88, -23.52, -67.58, -23.22]   # Láscar summit caldera, Atacama, Chile
  default_crs: EPSG:32719                            # UTM 19S, metric
  active_lava_b12_threshold: 0.5    # B12 reflectance > this → thermally active lava
  cooled_lava_nbr_threshold: -0.5   # NBR < this → dark cooled lava / severe burn
  cloud_cover_max_pct: 50           # High-altitude Atacama gives frequent clear skies
  prefire_reference:
    start: "2018-01-01"
    end: "2018-06-01"               # Pre-activity reference window

inputs:
  aoi:
    bbox: [-67.88, -23.52, -67.58, -23.22]
    crs_target: EPSG:32719
    notes: Covers Láscar summit caldera and proximal pyroclastic apron

  date_range:
    start: "2018-01-01"
    end: "2026-06-01"

  collection:
    uri: "@sentinel-2-l2a"
    stac_endpoint: "https://earth-search.aws.element84.com/v1"

layers:

  # ── SOURCE ──────────────────────────────────────────────────────────────────

  source/s2:
    type: raster_timeseries
    uri: "@sentinel-2-l2a"
    description: >
      Sentinel-2 L2A, bi-weekly scenes (not composited — individual acquisitions
      preserve active-flow evolution). Minimum bands for NBR + thermal anomaly.
    params:
      bbox: [-67.88, -23.52, -67.58, -23.22]   # COG spatial window
      datetime: "2018-01-01/2026-06-01"
      assets:
        - B04    # Red — for NBR denominator context; also RGB
        - B08    # NIR — numerator of NBR; dark over cooled lava
        - B12    # SWIR2 — saturates at lava temperatures; penetrates SO2 plume
        - SCL    # Scene classification — mask cloud and cloud shadow
      query:
        "eo:cloud_cover": { lt: 50 }

  source/s2-prefire:
    type: raster
    uri: "@sentinel-2-l2a"
    description: Pre-activity reference composite for dNBR calculation.
    params:
      bbox: [-67.88, -23.52, -67.58, -23.22]
      datetime: "2018-01-01/2018-06-01"
      assets: [B08, B12, SCL]
      query:
        "eo:cloud_cover": { lt: 40 }
      aggregate: median

  # ── COMPUTE ─────────────────────────────────────────────────────────────────

  compute/cloud-masked:
    type: raster_timeseries
    compute:
      op: cloud_mask_sentinel2
      inputs:
        data: { layer: source/s2 }
      params:
        scl_classes: [4, 5, 6, 11]   # keep: vegetation, bare soil, water, snow/ice

  compute/nbr:
    type: raster_timeseries
    description: NBR = (B08 - B12) / (B08 + B12). High = healthy veg; low = bare/burned.
    compute:
      op: raster_calc
      inputs:
        data: { layer: compute/cloud-masked }
      params:
        expression: "(B08 - B12) / (B08 + B12)"
        output_band: nbr

  compute/active-lava-mask:
    type: raster_timeseries
    description: >
      Active lava: B12 > 0.5 (SWIR2 saturation from thermal emission at ~600°C+).
      Identifies actively flowing or fountaining lava in each scene.
    compute:
      op: raster_calc
      inputs:
        data: { layer: compute/cloud-masked }
      params:
        expression: "(B12 > active_lava_b12_threshold).astype('uint8')"
        active_lava_b12_threshold: "${settings.active_lava_b12_threshold}"
        output_band: active_lava

  compute/prefire-nbr:
    type: raster
    description: Pre-activity NBR reference from the Jan-Jun 2018 composite.
    compute:
      op: raster_calc
      inputs:
        data: { layer: source/s2-prefire }
      params:
        expression: "(B08 - B12) / (B08 + B12)"
        output_band: nbr_prefire

  compute/dnbr-stack:
    type: raster_timeseries
    # raster_calc reads ONE raster and binds bands positionally (b1..bN), so two-layer
    # arithmetic composes through stack_concat: stack the pair, difference the bands.
    compute:
      op: stack_concat
      inputs:
        rasters:
          - { layer: compute/prefire-nbr }   # band 1: prefire NBR
          - { layer: compute/nbr }   # band 2: postfire NBR

  compute/dnbr:
    type: raster_timeseries
    description: >
      dNBR = NBR_prefire - NBR_postfire. Positive = vegetation/surface loss.
      USGS severity classes: low 0.1-0.27, mod-low 0.27-0.44, mod-high 0.44-0.66, high >0.66.
    compute:
      op: raster_calc
      inputs:
        data: { layer: compute/dnbr-stack }
      params:
        expression: "b1 - b2"   # NBR_prefire - NBR_postfire
        output_band: dnbr

  # ── RESULTS ─────────────────────────────────────────────────────────────────

  result/lava-flow-extent:
    type: vector
    description: >
      Dated lava flow polygons: cooled lava (NBR < -0.5) per acquisition.
      Attributes: date, area_km2, type (active | cooled), dnbr_mean.
    compute:
      op: raster_to_vector_timeseries
      inputs:
        active: { layer: compute/active-lava-mask }
        dnbr: { layer: compute/dnbr }
      params:
        cooled_threshold: "${settings.cooled_lava_nbr_threshold}"
        min_area_ha: 0.5

  result/dnbr-severity:
    type: raster
    description: Peak dNBR severity COG — maximum dNBR value per pixel across all post-activity scenes.
    compute:
      op: raster_reduce
      inputs:
        timeseries: { layer: compute/dnbr }
      params:
        reducer: max
        format: cog
        dtype: float32

outputs:
  primary:
    - result/lava-flow-extent   # GeoParquet — dated flow polygons
    - result/dnbr-severity      # COG — peak burn severity map
  show_your_work:
    - compute/nbr               # zarr — per-scene NBR
    - compute/active-lava-mask  # zarr — active lava detections

cache:
  scope:
    - inputs.aoi.bbox
    - inputs.date_range
    - settings.active_lava_b12_threshold
    - settings.cooled_lava_nbr_threshold
  storage: ./cache/
  reuse_policy: hash_inputs

license:
  recipe: Apache-2.0
  output_dataset: CC-BY-4.0
  upstream_data:
    - { source: sentinel-2-l2a, license: copernicus-open }
