Lab 5: The 2021 Heat Dome in the Salish Sea

Spectral indices, thresholds, and vectors: from pixel to polygon

Author

Dr. Francisco Laso, ESCI 442/542 — Introduction to Remote Sensing

Lab 5 Module 5 — Vectors and Spectral Indices
Readings due before lab: Campbell Ch. 16.3 — Leaf Optical Properties  |  Ch. 16.4 — Vegetation Indices  |  Ch. 16.5 — Vegetation Stress  |  Cardille Ch. F5 — Image Manipulation  |  Ch. F22 — Exploring Vectors  |  Sang & Hamann (2023) — Remote Sensing 15:2162

Background

Between 26 and 28 June 2021, a stationary atmospheric ridge over the Pacific Northwest produced the most intense heat event in the recorded history of the region. Surface air temperatures in the Puget Sound lowlands reached 42 °C; the Canadian town of Lytton broke the all-time Canadian heat record on three consecutive days and then burned to the ground in a wildfire on the fourth. The event killed hundreds of people. It also exposed a landscape of forests, farms, and wetlands to a thermal shock that many of those ecosystems had never experienced at any point in their evolutionary history — and it did so during the annual window when vegetation is most physiologically active.

In the days and weeks that followed, field observations, news photography, and then satellite imagery began to document the biological consequences. Sang and Hamann (2023), in the paper assigned for this lab, used MODIS and Landsat to track the post-event greenness of the Great Bear Rainforest on the British Columbia coast, and reported a result that was not the one most readers would have predicted. The forests that showed the largest greenness declines were not the hot, dry interior forests east of the Coast Range. They were the cooler, very wet, hyper-maritime ecosystems that are normally buffered from large temperature fluctuations. Ecosystems adapted to a narrow thermal band were the ones that broke; ecosystems adapted to heat were not. That finding is a testable prediction for this lab.

Your job in Lab 5 is to test that prediction across the Salish Sea bioregion. You will build two spectral indices from Landsat 8 surface reflectance — NDVI (a measure of canopy greenness) and NDWI (a measure of canopy water content) — and use them to compare a heat-dome summer (2021) to a reference summer (2020). Campbell Ch. 16.3 explains why a healthy leaf looks the way it does to a multispectral sensor: chlorophyll absorbs red wavelengths for photosynthesis and the spongy mesophyll scatters near-infrared strongly because no pigment absorbs it. The gap between “dark red” and “bright NIR” is the physical fingerprint NDVI exploits. Water in the leaf controls the short-wave infrared — that is the fingerprint NDWI exploits. Every other index in the remote sensing literature is a variation on the same template: pick two wavelengths where the target property has maximum contrast, ratio or difference them to cancel shared noise.

The second skill this lab builds is the bridge from continuous index values to a categorical answer. A map of ΔNDVI is an analytical result, not a decision. Cardille Ch. F5 introduces the simplest possible classifier — a threshold applied with .lt() or .gt(), combined with .updateMask() and .where() — and that is the tool you will use to identify “stressed” pixels in the post-heat-dome landscape. The third skill is the pivot from raster to vector: you will upload the Salish Sea bioregion boundary as a shapefile, clip the stress map to that boundary, and summarize it with reduceRegions to produce the one number that answers the scientific question. That tabular output is the form in which remote sensing results become usable to non-specialists.


Note

Lab Objectives

By the end of this lab you will be able to:

  1. Explain, from leaf optics, why the NDVI, NDWI, and NBR band choices produce maximum contrast between vegetation and other surfaces
  2. Compute NDVI and NDWI both from first-principles band math and using the .normalizedDifference() shortcut, and confirm they return identical values
  3. Build matched pre- and post-event median composites from Landsat 8 surface reflectance using the filter-map-reduce pipeline
  4. Produce and interpret ΔNDVI and ΔNDWI difference images as maps of vegetation change
  5. Apply thresholds to continuous index layers and combine them with logical operators to identify pixels that meet multiple criteria simultaneously
  6. Upload a shapefile as a GEE asset, use clipToCollection to restrict analysis to a study-area polygon, and compute area-based summary statistics with reduceRegions
  7. Export a bioregion-clipped raster as a GeoTIFF for downstream analysis in ArcGIS Pro
  8. Transfer the complete pipeline to a second disturbance — the 2020 Labor Day fires — using a different vegetation index (NBR) and a buffered point geometry instead of an uploaded vector

Warning

Before You Begin


Tip

First time uploading a shapefile?

Part 5 of this lab asks you to upload a zipped shapefile to your own GEE account as an asset. Assets are permanent files stored in your account that any of your scripts can reference by ID. Cardille Ch. F22 §3 walks through the upload dialog one click at a time. The exact path in the Code Editor is: Assets tab (top-left panel) → NEW → Shape files → upload the four-file shapefile bundle as a single asset.


Part 1 — Why Indices Exist: Spectral Contrast

The leaf as a spectral target

Campbell Ch. 16.3 describes the optical behavior of a healthy green leaf across the visible and near-infrared. Three processes interact to produce the curve. Chlorophyll a and b absorb strongly in the blue (around 0.45 μm) and the red (around 0.67 μm) to drive photosynthesis — the two absorption valleys give chlorophyll its green appearance to the eye. Between those valleys, a modest green reflectance peak is what your visual system registers as “leaf color.” Just past the red, absorption collapses. From roughly 0.75 to 1.3 μm the leaf is highly reflective: the spongy mesophyll scatters near-infrared light because no pigment absorbs it at those wavelengths. Past 1.3 μm, liquid water in the leaf takes over, producing two deep absorption features in the short-wave infrared.

Every spectral vegetation index exploits this curve. NDVI picks the two wavelengths with the largest difference across the visible-to-NIR boundary — the red absorption valley and the NIR plateau — and normalizes their difference. NDWI (as defined by Gao, 1996, the version this lab uses) picks NIR and SWIR1 to capture the leaf-water absorption feature. NBR picks NIR and SWIR2 because burned vegetation collapses the NIR plateau and exposes charred substrate that absorbs strongly in the longer SWIR. The band choice is not arbitrary in any of these cases — each index encodes a specific physical question in the two wavelengths it selects.

Proving that a shortcut is still the same arithmetic

Script L5.1 builds a mid-summer 2020 composite over the Salish Sea and samples the full spectral profile at three contrasting targets: a Cascade conifer forest in the Snoqualmie National Forest, the Seattle urban core, and open Salish Sea water in Haro Strait. The three points were chosen to land in the interior of each surface type — far enough from any land-water boundary that the 2.5 km buffer used for sampling does not cross the boundary and contaminate the average. The chart that prints to the Console shows three curves that look very different from each other, color-coded for instant visual recognition: forest = green, urban = red, water = blue. The shape of each curve is the visual argument for why NDVI works. The forest curve has a steep red-to-NIR rise. The urban curve is comparatively flat. The water curve collapses toward zero in the NIR and SWIR.

The script then computes NDVI two ways over the forest buffer: once by hand — (NIR − RED) / (NIR + RED) — and once by calling .normalizedDifference([NIR, RED]). Both print to the Console. They are within floating-point noise of each other because they are the same operation. Cardille Ch. F5 §1 makes this point explicitly: the convenience functions in Earth Engine are not magic; they are named wrappers around arithmetic you already understand.

Note

Script L5.1 covers: median compositing on Landsat 8 C2 L2; buffered reference geometries; ui.Chart.image.regions for spectral profiles; .normalizedDifference() vs. hand-coded band math; reduceRegion over a buffer. Confirm Checkpoint L5-CP1 before continuing.


Part 2 — Building the Baseline (2020)

The comparison summer

A difference image is only as meaningful as the reference it subtracts from. Script L5.2 builds that reference: a nine-week median composite spanning 29 June through 31 August 2020 across the Salish Sea bounding box. The window is chosen deliberately. It starts the day after the calendar peak of the 2021 heat dome (so the 2020 and 2021 windows are symmetric) and it is long enough to survive the Pacific Northwest marine layer — a single clear scene over any given path-row is rare, but fifty-odd scenes over a nine-week window produce a robust median even after per-pixel cloud masking.

The preprocessing stack is the same one you built in Lab 4, generalized to a two-index workflow. The maskAndScaleL8 helper applies the QA_PIXEL bitmask (cloud, cloud shadow, dilated cloud, cirrus — four separate bit flags) and the USGS C2 L2 scale factors. Two new helpers, addNDVI and addNDWI, append each index to the image as a new band so the composite carries its own derived products forward through the rest of the pipeline. Cardille Ch. F5 §2 calls this the band-as-metadata pattern — indices stay attached to the imagery that produced them, rather than floating as separate objects.

Reading a two-index composite

When the script adds three layers to the map — true color, NDVI, NDWI — the three give you complementary views of the same surface. True color is orienting: you recognize water, land, and urban footprint by appearance. The NDVI layer is the greenness map: dense forest canopy returns values near 0.8; urban cores fall to 0.1 or lower; water is negative. The NDWI layer is the canopy-water map: the same forests that were bright green in NDVI return mid-range NDWI values (0.2 to 0.4), reflecting the water content of their leaves. In the reference summer, the two index maps show a healthy, fully hydrated late-summer forest canopy across both the Olympics and the Cascades.

Tip

Color choices and accessibility

Lab 5 displays NDVI on a sequential yellow → green ramp (yellow = sparse / stressed canopy, dark green = dense, healthy canopy) and ΔNDVI / ΔNDWI on a diverging red → white → blue ramp (red = loss, white = no change, blue = gain). Both palettes are drawn from ColorBrewer and pass colorblind-safety checks for the most common color-vision deficiencies (protanopia, deuteranopia, tritanopia).

This is a deliberate choice. The intuitive “red-to-green” NDVI ramp common in older remote sensing texts is not colorblind-safe — about 8 percent of male readers cannot distinguish dark red from dark green. When designing your own outputs, both for this course and beyond, prefer ColorBrewer’s sequential or diverging palettes, or use a contrast-checking tool such as Adobe Color before committing to a color scheme. The lab document and the GEE scripts use the same palettes so the two visual contexts agree.

Note

Script L5.2 covers: maskAndScaleL8 helper; addNDVI and addNDWI helpers using normalizedDifference(); two-index median composite; displaying NDVI and NDWI with colorblind-safe palettes. Confirm Checkpoint L5-CP2 before continuing.


Part 3 — The Heat-Dome Summer (2021) and Difference Images

Running the same recipe on a different year

Script L5.3 runs the identical filter-map-reduce pipeline on the 2021 nine-week window (29 June through 31 August). Same bounding box, same cloud threshold, same two helpers, same reducer. What changes is the year. The result is a second median composite with the same structure as the baseline — NDVI and NDWI bands attached — but representing a canopy that has just lived through the most extreme heat event on record.

The direct comparison is the difference image. ΔNDVI is NDVI_2021 − NDVI_2020, computed pixel-by-pixel across the full bounding box. ΔNDWI is the analogous subtraction for the water-content index. The diverging red-to-blue palette the script uses maps negative values (canopy lost greenness, canopy lost water) to red and positive values (gains) to blue. The color choice is not decorative: the red-white-blue scheme is the convention for signed difference maps because the white midpoint makes the zero line perceptually unambiguous.

What the maps show

A well-executed ΔNDVI map for this event has a characteristic spatial pattern. Coastal and lowland forests on the east side of the Olympic Peninsula, the west slopes of the Cascades, and the San Juan Islands cluster toward the red end of the scale. Urban cores sit near zero — impervious surfaces cannot “brown,” so they have no signal to give. Open water is speckled and should be disregarded; the cloud mask performs unreliably over water because the QA algorithm is tuned for land. The ΔNDWI map shows the same broad spatial pattern as ΔNDVI but muted: canopy water-content changes are smaller in magnitude than canopy greenness changes because the SWIR reflectance is a less sensitive indicator of stress at the time scales this lab samples.

Figure 1: 2020 baseline NDVI (Jun 29 – Sep 15)
Figure 2: 2021 heat-dome NDVI (Jun 29 – Sep 15)

Side-by-side NDVI composites for the matched 2020 and 2021 windows. Yellow = sparse / stressed canopy, dark green = dense, healthy canopy. The visual change is subtle — a difference image is needed to see it cleanly.

Figure 3: 2020 baseline NDWI (Gao canopy-water)
Figure 4: 2021 heat-dome NDWI (Gao canopy-water)

Side-by-side NDWI composites. NDWI tracks leaf water content rather than chlorophyll greenness, so the spatial pattern is similar to NDVI but the magnitudes are different.

Testing the maritime-buffering hypothesis

Sang and Hamann’s (2023) headline finding — that the heat dome’s canopy impact varied with maritime exposure, hitting cool buffered coastal forests harder than dry interior forests — is a directly testable prediction in the Salish Sea. Script L5.3 makes that test concrete by computing the mean ΔNDVI and ΔNDWI over two forest buffers, not one: an inland reference at the Snoqualmie National Forest in the east Cascades, and a coastal reference in the San Juan Islands at (−122.7971, 48.5704). Both numbers print to the Console. Together they are a one-pair statistical test of Sang and Hamann’s prediction at the Salish Sea scale.

This is the bare minimum. A more interesting story comes from picking your own contrasting pair — for example, a stand on the east slope of the Olympic Peninsula compared to a stand in the dry interior on the lee side of the Cascades, or two coastal sites at different latitudes. Choose two forest pixels (or 2.5 km buffers) that test a hypothesis you find interesting, run the same reduceRegion for each, and compare. Your Methods section documents which pair you picked and why; your Results section reports the four numbers; your interpretation explains whether the contrast supports or undermines the maritime-buffering prediction in your chosen pair.

Note

Script L5.3 covers: redeclaring year-specific variables in sloppy-mode JS; reapplying the full pipeline to a second year; image subtraction for difference mapping; coastal-vs-inland forest comparison via two reduceRegion calls. Confirm Checkpoint L5-CP3 before continuing.


Part 4 — Thresholds and Masks: From Index to Decision

The simplest possible classifier

A ΔNDVI map is a continuous surface. A question like “where was there stress?” is categorical. Bridging from one to the other requires a threshold — a number below (or above) which a pixel is classified as “stressed” and above (or below) which it is not. Cardille Ch. F5 §2 treats thresholding as the simplest possible classifier, and it is: a single inequality applied with .lt() or .gt() turns a continuous raster into a binary one.

Script L5.4 applies two thresholds independently and then combines them. A pixel is NDVI-stressed if dNDVI < −0.10; it is NDWI-stressed if dNDWI < −0.05. The two thresholds are chosen to be stricter than the year-to-year noise floor for PNW forest canopies in cloud-free summer medians — most of the baseline noise fluctuates within ±0.05 of zero for ΔNDVI, so −0.10 is a defensible floor for “this is real, not just noise.” The NDWI threshold is set lower in magnitude because canopy-water changes are inherently smaller. Both thresholds are defended in your SOP Methods section.

Combining the indices with AND

The scientific argument for requiring both indices to cross threshold is an argument about confounders. Campbell Ch. 16.5 lists the usual suspects for a spurious NDVI decline: a dry soil background that got dustier between years, a phenological shift where the 2021 window caught an earlier senescence stage than the 2020 window, atmospheric differences between the two composites. Each of those confounders should produce a ΔNDVI signal without necessarily producing a matching ΔNDWI signal. By requiring that both indices drop — greenness AND canopy water — the combined classifier rejects most of the non-stress explanations.

The combination is performed with .and() on the two binary rasters. The output is 1 only where both thresholds were crossed; 0 everywhere else. .selfMask() then drops the zeros to transparent so only the stressed pixels render on the map. This is the heat-dome stress footprint — the spatially explicit answer to the question that opened the lab.

Note

Script L5.4 covers: .lt() and .gt() for thresholding; .and() for combining binary rasters; .selfMask() for transparent backgrounds; ee.Image.pixelArea() for area quantification; reduceRegion over the study bounding box. Confirm Checkpoint L5-CP4 before continuing.


Part 5 — Vectors: The Bioregion as an Analytical Boundary

Upload, then clip

Every analysis in Parts 1 through 4 ran over a rectangular bounding box. That is computationally convenient but scientifically indefensible: the question is about the Salish Sea bioregion, not about a rectangle that approximately contains it. Script L5.5 closes that gap. The Salish Sea Bioregion Land layer exists as a multipart polygon shapefile (~623 features covering the mainland coastal strip plus every named island and archipelago) hosted on the Salish Sea Atlas Data hub; you downloaded it in the Before You Begin checklist. Cardille Ch. F22 §3 walks through uploading that shapefile to your own Earth Engine account as an asset — a permanent, referenceable vector that any of your future scripts can load with a single line. We use the Land layer rather than the outer Boundary layer because NDVI and NDWI are physically meaningful only over land; clipping to land removes the noisy over-water pixels that the QA mask handles unreliably.

Figure 5: The Salish Sea Bioregion Land layer — a multipart polygon (~623 features) covering the mainland coastal strip plus every named island and archipelago in the bioregion.

Once the asset is uploaded, it becomes a standard ee.FeatureCollection. The script loads it, confirms the feature count in the Console (~623), and then uses clipToCollection to restrict every reportable raster — the 2020 NDVI, the 2021 NDVI, ΔNDVI, ΔNDWI, and the stress mask — to the bioregion’s land area. The clip is not just cosmetic: it ensures that every area statistic you compute downstream is a statistic about the bioregion’s land, not about water or about an arbitrary rectangle.

Tip

Reproject your shapefile to EPSG:4326 before uploading

Earth Engine stores every ee.FeatureCollection internally in EPSG:4326 (WGS 84 geographic), regardless of what coordinate system the source shapefile is in. If you upload a shapefile in some other projection — Web Mercator, a Washington State Plane projection, an undefined CRS — GEE will either reproject silently on ingest (sometimes with a small coordinate shift, especially across NAD 83 / WGS 84 datums) or refuse the upload outright if the .prj file is missing or unreadable. The fix is simple: reproject the shapefile to EPSG:4326 yourself before uploading, so the coordinates GEE stores are exactly the coordinates you intend.

This is the course-wide convention for every vector asset you upload to GEE for the rest of the term — Salish Sea Bioregion Land for Lab 5, any future shapefiles for Labs 6 and 7, and any of your own vectors for the final project. Always reproject to EPSG:4326 (WGS 84) before upload.

ArcGIS Pro: Geoprocessing pane → search Project (Data Management Tools → Projections and Transformations → Project). Set Input Dataset to your downloaded shapefile, Output Dataset to a new name with a _WGS84 suffix (e.g., Salish_Sea_Bioregion_Land_WGS84.shp), and Output Coordinate System to WGS 1984 (search for 4326 in the picker). If ArcGIS prompts for a Geographic Transformation, accept the default (it will pick the right NAD-83-to-WGS-84 transformation for the Salish Sea region automatically). Run. Upload the new four-file bundle (_WGS84.shp, .shx, .dbf, .prj).

QGIS: right-click the layer in the Layers panel → Export → Save Features As…. Set Format to ESRI Shapefile, choose a new filename with a _WGS84 suffix, set CRS to EPSG:4326 - WGS 84, and click OK. Upload the resulting four-file bundle.

Quick check before upload: open the .prj file in any text editor. If it contains GEOGCS["GCS_WGS_1984", … 4326], you are ready. If it contains PROJCS[…] or any State Plane / UTM / Web Mercator string, reproject first.

Tip

Add proper metadata to your uploaded asset

A GEE asset without metadata is a black box — anyone reusing it (including future-you) has to guess where it came from. Adding metadata at upload time is a five-minute habit that pays off forever. The Salish Sea Atlas hub provides the canonical fields under the About tab on the Salish Sea Bioregion Land hub page. Copy from the hub into the GEE upload dialog under Properties:

Property name Value to enter
title Salish Sea Bioregion — Land
source Salish Sea Atlas Data, Western Washington University
source_url https://salish-sea-atlas-data-wwu.hub.arcgis.com/datasets/wwu::salish-sea-bioregion-land/about
license Check the hub “About” page; record the license name (typically Creative Commons)
accessed The date you downloaded the shapefile (ISO format, e.g., 2026-04-25)
description One sentence describing what the layer is and why you uploaded it

After upload, click your asset in the Assets tab and confirm the properties appear under the asset details. This is a course-wide expectation: every asset you upload for the rest of the term should carry these six fields.

From pixels to a table

reduceRegions is the pivot point. It takes an image and a FeatureCollection and returns one row of statistics per feature. For our 623-feature Land layer, that means 623 rows — one per island or coastal landmass — which is itself an interesting output (per-island variation in canopy stress is visible in the column). The headline single-number summary then comes from aggregating across those 623 rows. The script does this two ways, both of which appear in your Console:

  • An area-weighted bioregion mean of ΔNDVI and ΔNDWI. Each feature carries an Area_SqKm attribute; weighting each feature’s per-feature mean by its area, summing, and dividing by the total area gives a true bioregion mean (an unweighted mean would over-count tiny islands).
  • A total stressed area in km² across the bioregion’s land, computed by summing the per-feature stress areas with aggregate_sum.

Those two numbers (plus the per-feature table for richer context) are the quantitative answer your SOP Results section reports. Everything before this point in the lab was infrastructure to produce defensible versions of those numbers.

Exporting for ArcGIS Pro

The last block of L5.5 exports a single GeoTIFF — the BOTH-stressed mask, clipped to the bioregion and projected to EPSG:32610 (UTM Zone 10N, the standard projection for PNW mapping). One image, because that mask is the headline result of the lab and one bioregion-wide layout is the deliverable. The export is queued in the GEE Tasks tab and must be manually started by clicking RUN. When it completes, it is available in your Drive for download and map layout in ArcGIS Pro, following the workflow you learned in Module 1.

Warning

Heads up — Salish Sea exports are large. A continuous 30 m raster covering the full bioregion (e.g., the ΔNDVI map) runs roughly 400 MB and 20 to 25 minutes to transfer to Drive. The BOTH-stressed mask is much smaller — usually a few megabytes and under 10 minutes — because most pixels are masked out and compress efficiently. The EX1 Beachie Creek severity raster is small as well (a 150 km buffer at 30 m, well under 100 MB and under 15 minutes).

Only export what you need for your one final layout. Additional supplementary exports are in the script, commented out — uncomment them only if you specifically need that raster for a follow-up analysis, and expect long Drive transfers.

Tip

Making zero-valued pixels transparent in ArcGIS Pro: the Set Null tool

When you load the BOTH-stressed mask (or the EX1 severity raster) in ArcGIS Pro, zero-valued background pixels render as a solid color and obscure the basemap. The Spatial Analyst Set Null tool replaces those zeros with NoData, which ArcGIS Pro then draws as transparent — exactly the visual effect you want for a stress or severity layer overlaid on a hillshade or imagery basemap.

The workflow is short. In the Geoprocessing pane, search for Set Null (Spatial Analyst Tools → Conditional → Set Null). Set the Input conditional raster to your imported GeoTIFF; set the Expression to Value = 0 (or, for the EX1 severity raster, Value < 1 to drop both zeros and any unburned pixels you do not want to display); set the Input false raster or constant value to the same input raster (so kept pixels keep their actual class value); choose an output name; and run. The result is a new raster identical to the input except that every pixel matching the expression is now NoData and renders transparent.

This is the standard ArcGIS Pro pattern for “show only the pixels that matter” and you will use it on every classified raster you produce for the rest of the term.

Note

Script L5.5 covers: shapefile upload workflow; ee.FeatureCollection from an asset ID; clipToCollection for study-area masking; reduceRegions for per-feature statistics; ee.Image.pixelArea() for area summaries within a vector; Export.image.toDrive with crs: 'EPSG:32610' for PNW-standard projection. Confirm Checkpoint L5-CP5 before continuing.


Part 6 — Independent Application: The 2020 Labor Day Fires

Transferring the template

Script L5-EX1 asks you to apply the Lab 5 pipeline to a different disturbance, a different index, and a different study area — with no new concepts, only adaptation of the template you already built. On 7 through 9 September 2020, high winds and dry fuels drove a complex of fires across western Oregon. The Beachie Creek Fire in the western Cascades burned roughly 193,000 acres in a single week. The same satellite archive that captured the 2021 heat dome captured this fire; the same filter-map-reduce pipeline can quantify its footprint.

What changes from Parts 1 through 5 is confined to a small, enumerable list. The index is NBR — (NIR − SWIR2) / (NIR + SWIR2) — which is sensitive to the loss of green canopy and the exposure of charred SWIR-absorbing substrate. The pre-fire window is 1 August through 6 September 2020; the post-fire window is 1 October through 15 November 2020 (smoke from the fires clears the Willamette Valley by early October). The study-area boundary is a 150-kilometer buffer around the Beachie Creek ignition point, created directly with ee.Geometry.Point().buffer(), with no shapefile upload. The thresholding step uses the Key–Benson (2006) dNBR severity classes (five discrete categories, with breakpoints at 0.100, 0.270, 0.440, and 0.660), implemented with a chain of .where() calls rather than a single .and() combination.

Everything else — maskAndScaleL8, the Landsat 8 collection, the median reducer, the reduceRegion pattern — is what you already wrote. This is the part of remote sensing where the same tool-kit, pointed at a different question, returns a different answer.

Figure 6: Fire-affected areas across the 150 km buffer around Beachie Creek — the Oregon Labor Day 2020 fire complex (Beachie Creek, Lionshead, Riverside, Holiday Farm, Archie Creek, and others). Severity classes from the Key–Benson dNBR breakpoints.

Reporting the answer: absolute area, not percentages

The 150 km buffer is a data-fetching window, not a denominator. It is wide enough to capture the entire Oregon Labor Day fire complex — Beachie Creek, Lionshead, Riverside, Holiday Farm, Archie Creek, and the smaller perimeters around them — but it has no ecological or administrative meaning of its own. It is simply a circle drawn around an ignition point so that GEE only does the work of compositing pixels that might be relevant. That distinction matters when you write up your results.

For the Salish Sea bioregion in Part 5, dividing stressed area by the bioregion’s land area gives a percentage that means something — “X percent of the bioregion’s land was classified as heat-stressed.” For the fire buffer, dividing burned area by the buffer’s area would give a meaningless number, because the buffer is just a circle. Your EX1 results should therefore report absolute burned area in km², by severity class, plus two totals across the burned classes — one that includes class 1 (low severity) and one that excludes it.

Reporting both totals is the intentional design of this exercise. Class 1 is permissive: it picks up genuine low-severity fire effects, but it also picks up non-fire signals that happen to look like a small NDVI/SWIR shift between pre- and post-fire windows — residual smoke deposits, phenological drift between an Aug–Sep pre-fire window and an Oct–Nov post-fire window, regional drought stress. Including class 1 typically produces an “all burned” total that overshoots the published fire perimeter by a factor of two to three. The “moderate-to-high” total (classes 2–4) drops that noisy floor and corresponds more closely to actual canopy mortality. Compare the moderate-to-high total to the published Oregon Labor Day complex perimeter total of approximately 4,300 km² as the more defensible sanity check on your pipeline; report the “all burned” total alongside it as the complete dNBR-positive footprint, and discuss the gap between the two in your interpretation.

Note

Script L5-EX1 covers: independent pipeline transfer; addNBR helper as a parallel to addNDVI and addNDWI; ee.Geometry.Point().buffer() for server-side study-area geometry; .where() chains for multi-class classification; Key–Benson (2006) dNBR severity breakpoints; per-class area aggregation with aggregate_sum; dual-total reporting (all-burned classes 1–4 vs moderate-to-high classes 2–4) for buffer-window aggregation. Confirm Checkpoint L5-EX1 when complete.


Interpretation Questions

Your answers to these questions belong in the Results section of your SOP.

Q1 (Script L5.1) The spectral profile chart shows three very different curves for forest, urban, and water. Describe the shape of each curve in physical terms — where does each target reflect strongly, where does each absorb strongly, and what biophysical process is responsible for each of those features? Using only the chart and Campbell Ch. 16.3, explain why NDVI (NIR − RED) separates forest from urban more cleanly than a simple red-band brightness threshold would. Then explain why a water index built from GREEN and NIR would look very different from the canopy-water NDWI (NIR − SWIR1) this lab uses — what does each of the two “NDWIs” actually measure, and why does the distinction matter when you are interpreting a map?

Q2 (Script L5.1) Script L5.1 computes NDVI two ways over the forest buffer — once by hand from band math, and once using .normalizedDifference([NIR, RED]). Report both values from your Console output. Within the floating-point precision of the chart, they should be identical. Using Cardille Ch. F5 §1, explain in your own words why they must be identical, what .normalizedDifference is doing internally, and what advantage the shortcut has over hand-coded band math once a script contains three or four indices. Is there any situation you can think of in which the hand-coded version would be preferable?

Q3 (Script L5.3) The ΔNDVI map shows the signed difference between 2021 and 2020 greenness across the Salish Sea. Describe the spatial pattern of red (loss) pixels: which parts of the bioregion show the strongest declines, and which parts show little or no change? Sang & Hamann (2023) reported that the hyper-maritime ecosystems of the British Columbia coast — cool, very wet, normally buffered from temperature extremes — showed the largest greenness declines after the heat dome, not the hot, dry interior forests. Does the Salish Sea ΔNDVI map support, contradict, or only partially support their finding? Identify a specific location on your map that you think tests the prediction, and explain what it tells you. If the Salish Sea pattern differs from the Great Bear Rainforest pattern, propose a physical reason why.

Q4 (Script L5.3) Compare the ΔNDVI and ΔNDWI maps side by side. The two indices measure different leaf properties (greenness versus canopy water content), and they do not have to agree. Describe (a) where the two maps agree — pixels that were red in both — and (b) where they disagree — pixels that were red in one but not the other. Then use the numerical ΔNDVI and ΔNDWI you computed over the Snoqualmie National Forest buffer in L5.3 to explain what it means for canopy stress when both indices drop by similar amounts versus when only one drops. Campbell Ch. 16.5 describes NDVI confounders (phenological shifts, soil-background changes, atmospheric differences); which of those confounders would you expect to move ΔNDVI without also moving ΔNDWI, and why does that difference make the two-index combination a stricter test than NDVI alone?

Q5 (Script L5.3) Sang & Hamann (2023) predict that cool, wet, maritime-buffered forests should show larger heat-dome canopy declines than warmer, drier, interior forests. Script L5.3 prints two ΔNDVI / ΔNDWI pairs over forest buffers — the inland Snoqualmie National Forest reference and the coastal San Juan Islands reference at (−122.7971, 48.5704). Report all four numbers from your Console output, and then state whether your coastal forest showed a larger canopy decline than your inland forest, a smaller one, or roughly the same. Does this two-point comparison support, contradict, or only partially support the maritime-buffering prediction? Now pick your own contrasting forest pair (move the coordinates in the script), describe why you chose those two locations, run the same comparison, and report the four numbers. Your interpretation belongs in your Methods section (which pair, and why) and your Results section (the four numbers, and what they tell you about Sang & Hamann’s prediction at the scale you tested).

Q6 (Script L5.4) Script L5.4 defines a “stressed” pixel as one where ΔNDVI < −0.10 AND ΔNDWI < −0.05. Both of those numbers are choices — you could have set them differently. Explain the reasoning behind each threshold: why is −0.10 the cutoff for ΔNDVI rather than −0.05 or −0.20, and why is the ΔNDWI threshold smaller in magnitude than the ΔNDVI threshold? What would the BOTH-stressed map look like if you loosened the thresholds to −0.05 and −0.02 respectively — would the total stressed area go up, go down, or stay the same, and would the interpretation of the map change? Now explain the .and() combination: what kind of pixel ends up in the BOTH-stressed layer that would not end up in the NDVI-stressed-alone layer, and why is that combination a more defensible definition of “heat-dome stress” than either single-index map?

Q7 (Script L5.5) Part 5 replaces the rectangular bounding box with the Salish Sea Bioregion Land polygon — a 623-feature multipart vector — and uses reduceRegions to produce one row of summary statistics per feature (per island or coastal landmass). The headline numbers come from aggregating across those rows. Report the three reportable bioregion-scale numbers from your Console output: the area-weighted bioregion-mean ΔNDVI, the area-weighted bioregion-mean ΔNDWI, and the total BOTH-stressed area in km² within the bioregion’s land. Then look at the per-feature FeatureCollection table the script prints and identify one feature (named island, archipelago, or mainland section) that has a notably more negative dNDVI than the bioregion mean and one with a notably less negative dNDVI. Where on the map are those features, and does the contrast match what you would predict from Sang & Hamann (2023)? Finally, explain why the area-weighted mean is the correct headline number rather than a simple unweighted mean across the 623 rows — what would happen to the headline if a tiny rocky islet with anomalous values were given the same weight as Vancouver Island? Cardille Ch. F22 §3 frames shapefile upload as a step that turns our own data into a queryable GEE layer; describe a second scientific question, distinct from this lab’s, that you could answer using the same bioregion polygon and a different spectral index or time window.

Q8 (Script L5-EX1) The Beachie Creek exercise transfers the Lab 5 pipeline to a disturbance that operates on a fundamentally different time scale (days of active fire versus one heat event) and leaves a fundamentally different spectral signature (charred substrate versus stressed-but-living canopy). Report the absolute burned area in km², by severity class (low, moderate-low, moderate-high, and high) and both total values from your Console output: the all-burned total (classes 1–4) and the moderate-to-high total (classes 2–4). Compare the moderate-to-high total to the published Oregon Labor Day complex perimeter of approximately 4,300 km² — does your pipeline land in the right order of magnitude, and what would explain a discrepancy of, say, ±500 km²? Then explain the gap between your two totals: why does the all-burned figure typically overshoot the published perimeter by a factor of two or three, what kinds of non-fire signals does class 1 absorb (smoke residue, phenological drift between Aug–Sep and Oct–Nov windows, drought), and why does dropping class 1 produce a number that compares more cleanly to a published perimeter? Now explain why you reported absolute km² rather than a percentage of the 150 km buffer area: what would a percentage of an arbitrary circular study window actually mean, and what would it have to be a percentage of to be scientifically defensible? Using your continuous dNBR map, describe the spatial pattern of burn severity (highest-severity pixels, relationship to topography in the basemap). Finally, explain at the leaf-and-substrate scale why NBR (NIR − SWIR2) is a better index than NDVI for a post-fire map — what happens to the NIR plateau when a canopy burns, what happens to SWIR2 reflectance, and why does the normalized difference between those two bands amplify the burn signal compared to NDVI’s red-NIR pair? Connect your answer to Campbell Ch. 16.4’s distinction between chlorophyll-driven and moisture/substrate-driven index design.


Standard Operating Procedure

Complete this section in your own words as you work through the lab. Your SOP documents your workflow so that a technically competent colleague could replicate your exact analysis.

Study Area

This lab spans two geographic regions, one per major task. Identify each study area by name, coordinates, and a brief description of the environmental or land use context that makes it relevant to the question that study area answers.

Data Sources

List every dataset loaded across the six scripts. For each entry, record the dataset name, collection ID as it appears in GEE, sensor, spatial resolution, and the date range you filtered to. Include the Salish Sea bioregion shapefile as a separate row, listing its source and the asset ID you assigned when you uploaded it to your own account.

Dataset Collection ID / Asset ID Sensor / Source Spatial Res. (m) Date Range

Add rows as needed.

Methods

Describe the workflow you applied in each script. Your Methods section should explain how you built the filter chain for both the 2020 and 2021 windows, what the maskAndScaleL8 helper does and why both steps are necessary, why you chose the specific thresholds DNDVI_STRESS_MAX = −0.10 and DNDWI_STRESS_MAX = −0.05 and what evidence would justify a different choice, which coastal-vs-inland forest pair you selected for your maritime-buffering test in L5.3 and why (the script ships with Snoqualmie NF and a San Juan Islands point at −122.7971, 48.5704; you may keep these or replace them with your own), how you uploaded the Salish Sea Bioregion Land shapefile and what asset ID and metadata properties you assigned it, why the per-feature → area-weighted aggregation in L5.5 is the right way to summarize the 623-feature collection, and how the EX1 pipeline differs from the main lab pipeline (different index, different windows, different boundary, different classifier structure, and a dual aggregation — absolute km² reported as both an “all burned” total including class 1 and a “moderate-to-high” total that drops the noisy class-1 floor, since the 150 km buffer is a data-fetching window rather than a meaningful denominator and class 1 absorbs non-fire signals along with genuine low-severity burn). Your Methods section should be specific enough that a colleague could re-run the analysis from the description alone.

Results

Your Results section has two complementary deliverables:

  1. GEE workflow evidence — Console screenshots and map captures from each of the six scripts that document what you computed at every step of the pipeline. Use the Suggested Screenshots list below as a checklist; together these screenshots form the trail a colleague would follow to verify your analysis.

  2. One ArcGIS Pro layout — a single finished cartographic layout, exported as a PNG or PDF, that tells the story of one of the two disturbances we analyzed in this lab. Choose either:

  • Option A — The 2021 Salish Sea heat dome. Layout could feature the BOTH-stressed footprint over the bioregion, the ΔNDVI image clipped to the bioregion, or both side-by-side. Zoom and framing are your call.
  • Option B — The 2020 Labor Day fires. Layout could feature the dNBR severity raster around Beachie Creek, with severity classes symbolized using the Set Null technique to make unburned pixels transparent over a hillshade or imagery basemap.

For whichever option you pick, your one layout must include the standard cartographic elements (title, legend, scale bar, north arrow, projection note) and tell a clear visual story at the zoom level you choose. A bioregion-wide overview and a single-island close-up are both defensible — pick the framing that best supports the question you want your layout to answer.

Figure 7: Example final layout — an Option A heat-dome layout showing the BOTH-stressed footprint over the Salish Sea bioregion. The layout you submit should include the same cartographic elements (title, legend, scale bar, north arrow, projection note), but framing, basemap, and zoom level are your call.
Tip

Suggested screenshots — clues for your Results section

A complete Results section needs roughly the following captures. Treat this as a working checklist as you move through the scripts.

  • Spectral profile chart with all three reference curves (forest / urban / water) — Script L5.1
  • 2020 baseline NDVI composite over the bioregion — Script L5.2
  • 2021 heat-dome NDVI composite — Script L5.3
  • ΔNDVI difference image on the red-white-blue diverging ramp — Script L5.3 or L5.5
  • 2020 baseline NDWI and 2021 heat-dome NDWI composites — Scripts L5.2 / L5.3
  • Reference-area sample / buffer locations plus the four maritime-buffering numbers (inland and coastal ΔNDVI / ΔNDWI) — Script L5.3
  • Salish Sea Bioregion Land layer loaded and confirmed in the Map — Script L5.5
  • Bioregion summary values in the Console — area-weighted ΔNDVI, area-weighted ΔNDWI, total stressed area in km² — Script L5.5
  • Fire-affected severity map for the 2020 Labor Day complex with the per-class km² table — Script L5-EX1
  • One finished ArcGIS Pro layout (Option A or Option B) with all cartographic elements

The numerical values you report in your Results prose should include the four maritime-buffering numbers from L5.3 (inland and coastal ΔNDVI and ΔNDWI), the three bioregion-scale numbers from L5.5 (area-weighted ΔNDVI, area-weighted ΔNDWI, total stressed km²), and the per-class burned area plus both total figures (all-burned classes 1–4, and moderate-to-high classes 2–4) from EX1. Your answers to Interpretation Questions Q1–Q7 belong in this section as well.

Limitations

Identify the limitations of the analysis you performed in this lab. These should be methodological or data-related — not personal difficulties with the software.

Consider: the interpretation of ΔNDVI pixels over open water and the reliability of the QA_PIXEL cloud mask off the coast; the difference between Gao’s canopy-water NDWI (used here) and McFeeters’ surface-water NDWI (a different index with the same acronym) and which kinds of mistakes each invites; the fact that a median composite collapses time and cannot distinguish a canopy that recovered by the end of August from one that stayed brown; the defensibility of the fixed ±−0.10/−0.05 threshold pair when applied to biomes with very different baseline variability; the effect of the nine-week window length on the number of Landsat scenes contributing to each composite; and the spatial generalizability of a Salish Sea result to other parts of the heat-dome footprint.


Submission Checklist

GEE workflow screenshots (every script):

One ArcGIS Pro layout (your choice of disturbance):

Documentation:

Note

Grading Note

This lab is graded as a Weekly Methods Log (SOP). The interpretation questions carry the most weight — particularly Q3 and Q4-bonus (Sang & Hamann prediction tests), Q5 (threshold and AND-logic defense), Q6 (per-feature → area-weighted aggregation), and Q7 (NBR band rationale, the absolute-vs-percentage reasoning for an arbitrary buffer, and the dual-total comparison against the ~4,300 km² Labor Day complex perimeter). Answers that describe what you see without connecting it to leaf optics, classifier logic, or the physical basis of each index will receive partial credit. The single ArcGIS Pro layout is graded on cartographic completeness (title, legend, scale bar, north arrow, projection note), correct use of Set Null to handle the background, and whether the framing tells a coherent story for the disturbance you chose. The shapefile upload step is graded on whether your Data Sources table documents your asset ID, your asset carries the six metadata properties (title, source, source_url, license, accessed, description), and your Methods section describes the upload workflow. The Limitations section is evaluated on specificity: a limitation that names a general category without explaining its mechanism and consequence in this specific context will receive less credit than one that ties the limitation to a concrete choice you made during the lab.


ESCI 442/542 — Introduction to Remote Sensing | Western Washington University