name: pakistan-floods-2022
version: "0.1"
category: events-hazards
themes: [hydrology, hazards]
family: sar-flood-event-mapping
description: >
  The 2022 Pakistan megaflood — 33 million people displaced, 1,700 killed,
  one-third of the country submerged at peak. Pakistan emits less than 1% of
  global CO2 but bore enormous climate damage; a defining moment in Loss and
  Damage negotiations at COP27. SAR (Sentinel-1) is the only sensor that cut
  through the monsoon cloud cover to map actual flood extent in near real-time.
  This recipe implements change-detection flood mapping against a 2021 reference.

settings:
  default_bbox: [67.0, 25.5, 70.5, 28.5]   # Sindh + Balochistan provinces, peak flood zone
  default_crs: EPSG:32642                   # UTM 42N, metric
  flood_change_threshold_db: -3.0          # VV drop > 3dB vs reference → flood (standard)
  relative_orbit_number: null              # Set to specific orbit after first inspection
  # IMPORTANT: filter to a single relative orbit number to avoid look-angle artifacts
  # when comparing scenes from different orbit tracks. Inspect available orbits first.

inputs:
  aoi:
    bbox: [67.0, 25.5, 70.5, 28.5]
    crs_target: EPSG:32642
    notes: >
      Sindh province (Indus valley) and Balochistan highlands. Peak extent ~80,000 km²
      around 2022-08-25. The Indus corridor between Sukkur and Hyderabad bore the
      worst sustained inundation.

  date_range:
    start: "2022-06-01"
    end: "2022-11-30"

  reference_period:
    start: "2021-06-01"
    end: "2021-06-30"
    notes: >
      Same calendar month, same relative orbit track (critical). 2021 was a
      normal monsoon year — no major flooding. Using same orbit avoids look-angle
      artifacts that arise when comparing scenes from different tracks.

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

layers:

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

  source/s1-event:
    type: raster_timeseries
    uri: "@sentinel-1-grd"
    description: >
      Sentinel-1 GRD, individual 6-day-repeat acquisitions during the flood event.
      Not composited — each scene is a separate flood snapshot.
    params:
      bbox: [67.0, 25.5, 70.5, 28.5]   # COG spatial window
      datetime: "2022-06-01/2022-11-30"
      assets:
        - VV    # Primary — open water appears dark (low backscatter)
        - VH    # Secondary — helps with flooded vegetation detection
      # Filter to consistent relative orbit for valid change detection
      # query:
      #   "sat:relative_orbit": { eq: <orbit_number> }

  source/s1-reference:
    type: raster
    uri: "@sentinel-1-grd"
    description: >
      June 2021 composite — same season, no flood, same orbit track.
      Used as the pre-flood baseline for change detection.
    params:
      bbox: [67.0, 25.5, 70.5, 28.5]
      datetime: "2021-06-01/2021-06-30"
      assets: [VV, VH]
      aggregate: median

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

  compute/vv-db-event:
    type: raster_timeseries
    description: Event scenes converted to dB scale.
    compute:
      op: raster_calc
      inputs:
        data: { layer: source/s1-event }
      params:
        expression: "10.0 * log10(VV + 1e-10)"
        output_band: vv_db

  compute/vv-db-reference:
    type: raster
    description: Reference scene in dB scale.
    compute:
      op: raster_calc
      inputs:
        data: { layer: source/s1-reference }
      params:
        expression: "10.0 * log10(VV + 1e-10)"
        output_band: vv_db_ref

  compute/change-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/vv-db-event }   # band 1: event VV dB
          - { layer: compute/vv-db-reference }   # band 2: reference VV dB

  compute/flood-change:
    type: raster_timeseries
    description: >
      VV_dB change = event - reference. Negative = backscatter dropped (water appeared).
      Drop > 3 dB is the standard flood change-detection threshold.
    compute:
      op: raster_calc
      inputs:
        data: { layer: compute/change-stack }
      params:
        expression: "b1 - b2"   # event - reference
        output_band: vv_change_db

  compute/flood-mask:
    type: raster_timeseries
    description: Binary flood mask per scene. 1 = flooded (VV dropped > 3 dB vs reference).
    compute:
      op: raster_calc
      inputs:
        data: { layer: compute/flood-change }
      params:
        expression: "(vv_change_db < flood_change_threshold_db).astype('uint8')"
        flood_change_threshold_db: "${settings.flood_change_threshold_db}"
        output_band: flooded

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

  result/flood-progression-timeseries:
    type: table
    description: >
      Flood area per acquisition date. One row per scene: (date, flood_area_km2).
      Peak ~80,000 km² around 2022-08-25.
    compute:
      op: raster_area_timeseries
      inputs:
        mask: { layer: compute/flood-mask }
      params:
        condition: "flooded == 1"
        unit: km2

  result/flood-extent-peak:
    type: raster
    description: Maximum flood extent COG — the high-water-mark scene or temporal max.
    compute:
      op: raster_reduce
      inputs:
        timeseries: { layer: compute/flood-mask }
      params:
        reducer: max
        format: cog
        dtype: uint8

  result/total-affected-area-km2:
    type: scalar
    description: Total area flooded at any point during the event (union of all flood masks).
    compute:
      op: raster_union_area
      inputs:
        timeseries: { layer: compute/flood-mask }
      params:
        unit: km2

outputs:
  primary:
    - result/flood-extent-peak              # COG — maximum inundation footprint
    - result/flood-progression-timeseries   # Parquet — (date, flood_area_km2)
    - result/total-affected-area-km2        # Scalar — total affected area
  show_your_work:
    - compute/flood-change                  # zarr — VV change in dB (inspectable)
    - compute/vv-db-reference               # COG — baseline reference

cache:
  scope:
    - inputs.aoi.bbox
    - inputs.date_range
    - inputs.reference_period
    - settings.flood_change_threshold_db
  storage: ./cache/
  reuse_policy: hash_inputs

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