name: masaya
version: "0.1"
category: events-hazards
themes: [hazards]
family: active-lava-flow-mapping
description: >
  Active lava lake monitoring at Masaya volcano, Nicaragua, using Sentinel-2
  SWIR and NBR. Masaya hosts one of the planet's few persistent lava lakes,
  active in the Santiago crater since December 2015. The primary signal here
  is the continuous B12 SWIR thermal anomaly from the active-lava-mask layer,
  which tracks the lake's persistent thermal emission; dNBR is retained for
  consistency with the family but is secondary because no large discrete flow
  field has developed outside the crater rim.

settings:
  default_bbox: [-86.3188, 11.8344, -86.0188, 12.1344]   # Masaya caldera, Nicaragua
  default_crs: EPSG:32616                                   # UTM 16N, 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: 60           # Central American dry season gives cleaner windows
  prefire_reference:
    start: "2015-01-01"
    end: "2015-11-01"               # Before lava lake onset (December 2015)

inputs:
  aoi:
    bbox: [-86.3188, 11.8344, -86.0188, 12.1344]
    crs_target: EPSG:32616
    notes: Covers Masaya caldera including Santiago and Nindiri craters

  date_range:
    start: "2016-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: [-86.3188, 11.8344, -86.0188, 12.1344]   # COG spatial window
      datetime: "2016-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: 60 }

  source/s2-prefire:
    type: raster
    uri: "@sentinel-2-l2a"
    description: Pre-lake-onset reference composite for dNBR calculation.
    params:
      bbox: [-86.3188, 11.8344, -86.0188, 12.1344]
      datetime: "2015-01-01/2015-11-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+).
      Primary signal for this site — tracks the persistent lava lake thermal
      anomaly in Santiago crater across every clear acquisition.
    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-lake-onset NBR reference from the Jan-Nov 2015 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 anomaly polygons: cooled/altered surface (NBR < -0.5) per
      acquisition. At Masaya the active-lava-mask (B12 thermal) is the primary
      signal; this flow-extent layer is retained for family consistency but
      represents crater-floor alteration rather than a spreading flow field.
      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-onset 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 anomaly 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 (primary signal)

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 }
