From 9f1ffed27618f4ad7f1a7be08221db44dde7fac0 Mon Sep 17 00:00:00 2001 From: Brandi Downs <34132383+BrandiDowns@users.noreply.github.com> Date: Wed, 19 Aug 2026 11:29:45 -0700 Subject: [PATCH] Add rendered R html file - Upload rendered R html file - Update Hydrocron landing page to point to rendered R html file - Update .Rmd file png links --- .gitignore | 2 + .../execute-results/html.json | 15 + .../SWOT_River_Time_Series_Tutorial_in_R.Rmd | 9 +- .../SWOT_River_Time_Series_Tutorial_in_R.html | 583 ++++++++++++++++++ quarto_text/SWOT_HydrocronLandingPage.qmd | 2 + 5 files changed, 606 insertions(+), 5 deletions(-) create mode 100644 _freeze/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R/execute-results/html.json create mode 100644 notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.html diff --git a/.gitignore b/.gitignore index 3d73e97c..f385cecf 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ notebooks/datasets/dask-worker-space /_site/ .quarto/ _site/ + +**/*.quarto_ipynb diff --git a/_freeze/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R/execute-results/html.json b/_freeze/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R/execute-results/html.json new file mode 100644 index 00000000..392ec3d1 --- /dev/null +++ b/_freeze/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R/execute-results/html.json @@ -0,0 +1,15 @@ +{ + "hash": "a607ce752fd1a2c78b7051b930bc6785", + "result": { + "engine": "knitr", + "markdown": "SWOT River Time-Series Tutorial in R\n================\nNavid Khizri (NASA JPL PO.DAAC Summer Intern; Alaska Pacific University\nStudent)\n\n**Summary**\n\nThis introductory tutorial guides students through plotting a river\nwater surface elevation (WSE) time series in R using observations from\nNASA’s Surface Water and Ocean Topography (SWOT) mission. Students will\nlearn how to locate river reach identifiers (reach_id) in the SWOT River\nDatabase (SWORD), request observations via the Hydrocron API, clean\nmissing-data placeholders, and visualize the results using base R.\n\n**Requirements**\n\nAny compute environment (local RStudio or cloud-based RStudio).\n\n**Learning Objectives**\n\n- Identify river reach IDs of interest using the SWOT River Database\n (SWORD) . \n- Interact with Hydrocron , NASA’s\n API for accessing SWOT hydrology time series. \n- Clean raw river height and slope time series. \n- Plot a time series using base R.\n\n**Why SWOT Matters**\n\nSWOT (Surface Water and Ocean Topography) is the first satellite mission\nto survey nearly 90% of Earth’s rivers, lakes, and hydrologic systems.\nSWOT uses Ka-band radar interferometry to measure water surface\nelevation globally, providing data crucial for hydrology, flood\nforecasting, and water management.\n\nAlaska, with more than 12,000 rivers and limited stream gauges due to\nhigh installation and maintenance costs, stands to benefit\nsignificantly. SWOT’s wide-swath coverage provides consistent 21‑day\nrevisit observations — helping fill data gaps for remote communities and\nimproving hydrologic modeling, especially under climate change.\n\nThis tutorial shows an example of exploring river observations from SWOT\nfor a river in Alaska.\n\nAs a student at Alaska Pacific University in Anchorage, I had the\nprivilege of learning about Alaska Native communities. Many of these\ncommunities are accessible only by plane or boat, and face increasing\nflood risks driven by climate change. SWOT can help improve flood models\nand provide critical water-level data to support flood readiness in\nrural Alaska. For additional reading, see Water Mission to Gauge Alaskan\nRivers on Front Lines of Climate Change.\n\nLink:\n\n\nExplore the SWORD River Database to find your river reach_id of interest\n\nVisit the interactive dashboard:\n\n****\n\n``` r\nlibrary(knitr)\n```\n![](../../images/SWOT_RiverDB_Basin.png?raw=true)\n\nClick on the North American basin, then click on one of the numbers that\nhas your river in it. I will click on Alaska which is \\#81.\n\n![](../../images/Alaska.png?raw=true)\n\nAfter clicking on the basin you will see colorful lines which represent\nreach_ids. You can zoom in on the map into the river area of interest.\n\n![](../../images/Area_Of_interest.png?raw=true)\n\nThe example in this tutorial uses reaches from the Kuskokwim River in\nSouthwestern Alaska. In the right-hand corner, you can see fields that\nare available. For now, just keep reach_id selected. Hovering the mouse\nover a river reach will display information about that reach, including\nthe reach ID. When you find your reach ID, note it because will use it\nlater when creating a time series.\n\n**What is Hydrocron?**\n\nHydrocron is an API developed by NASA’s PO.DAAC that provides\ntime-series hydrology data from SWOT in formats such as GeoJSON and CSV.\nAt the time of the making of this tutorial each request retrieves data\nfor a **single reach_id**.\n\n**Required Packages**\n\n``` r\nlibrary(httr)\nlibrary(jsonlite)\n```\n\n**Functions Used in This Tutorial**\n\nTo simplify utilization of this workflow, several helper functions are\ndefined. - This part of the tutorial typically would only need to be run\nonce. - After that, if the user wishes to change the Hydrocron API query\nparameters (start_time,end_time,fields), they can do so in the next\nsection below: Fetch, Clean, and Plot. - If a user wishes to modify the\nAPI parameters requested, some modification of the helper functions may\nbe needed.\n\nWhat the functions do: get_reach_data() creates the url to connect with\nHydrocron API to get your river reach data.\n\nclean_hydrocron() filters out missing data.\n\nplot_reach() plots the data.\n\n``` r\n# Fetch Hydrocron data\n# Send a request to NASA's Hydrocron API, download SWOT river data, and prepare it for R.\n\nget_reach_data <- function(reach_id, start_time, end_time, fields = \"reach_id,time_str,wse,slope\") {\n \n # Constructs a valid Hydrocron API URL by plugging in: your reach_id, your start date, your end date\n url <- paste0(\n \"https://soto.podaac.earthdatacloud.nasa.gov/hydrocron/v1/timeseries?\",\n \"feature=Reach\",\n \"&feature_id=\", reach_id,\n \"&output=geojson\",\n \"&start_time=\", start_time,\n \"&end_time=\", end_time,\n \"&fields=\", fields\n )\n\n # R sends the request to NASA's servers\n res <- GET(url) \n\n # Convert returned JSON into an R list\n geo <- fromJSON(content(res, \"text\")) \n\n # Extract the actual river measurements\n data <- geo$results$geojson$features$properties \n\n # Convert time strings into real time stamps\n data$time <- as.POSIXct(data$time_str, format = \"%Y-%m-%dT%H:%M:%SZ\", tz = \"UTC\")\n \n # Return the clean data table\n return(data)\n}\n\n\nclean_hydrocron <- function(df) {\n\n # Convert wse and slope to numeric. Hydrocron stores data as characters strings instead of numeric which will crash the plot if not converted.\n df$wse <- as.numeric(df$wse)\n df$slope <- as.numeric(df$slope)\n\n # Remove rows with \"no_data\"\n df <- df[df$time_str != \"no_data\", ]\n\n # Remove fill value rows\n df <- df[df$wse != -999999999999.0, ] \n df <- df[df$slope != -999999999999.0, ]\n\n # Remove rows where timestamp conversion failed\n df <- df[!is.na(df$time), ]\n\n # Output the cleaned dataset\n return(df) \n}\n\n\n# Plot a SWOT river reach\nplot_reach <- function(data, title = \"SWOT River Time-Series\") {\n\n plot(\n data$time, data$wse,\n main = title,\n xlab = \"Time\",\n ylab = \"Water Surface Elevation (m)\",\n col = \"red\",\n pch = 16\n )\n\n lines(data$time, data$wse, col = \"black\")\n grid() # Improves readability for students\n}\n```\n\n**Fetch, Clean, and Plot SWOT Data**\n\nIn this example, we request all observations for reach `81181700021`\nfrom 2023–2026. A user can change these inputs to request different time\nperiods and/or river IDs. User only needs to re-run the cell below when\nmodifying the query parameters(reach_id,start_time,end_time).\n\nNote: At the time of writing this tutorial, there is a limit on how much\ndata the API can query. If you’re reach is too large, consider breaking\nthe query up into smaller requests. If interested in 2023 to 2027 data,\nyou could do two queries: 2023-10-01 to 2025-05-31 and 2025-06-01 to\n2027-07-25.\n\n``` r\ndata_raw <- get_reach_data(\n reach_id = \"81181700021\", # Insert your reach ID here\n start_time = \"2025-06-01T00:00:00Z\", # Insert Start Date\n end_time = \"2027-07-25T00:00:00Z\" # Insert End Date\n)\n```\n\n ## No encoding supplied: defaulting to UTF-8.\n\n``` r\ndata <- clean_hydrocron(data_raw)\n\nplot_reach(data, title = \"Kuskokwim River\")\n```\n\n![](SWOT_River_Time_Series_Tutorial_in_R4_files/figure-gfm/unnamed-chunk-7-1.png)\n\n**Conclusion**\n\nYou successfully retrieved SWOT river surface elevation data using\nHydrocron, cleaned missing data, and plotted a time series. This\nworkflow can be reused for any river reach available in the SWORD\ndatabase.\n\nSWOT offers valuable high-resolution hydrologic data — especially for\nremote and ungauged regions like rural Alaska — unlocking new\nopportunities for hydrology education, research, and community impact.\n", + "supporting": [], + "filters": [ + "rmarkdown/pagebreak.lua" + ], + "includes": {}, + "engineDependencies": {}, + "preserve": {}, + "postProcess": true + } +} \ No newline at end of file diff --git a/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.Rmd b/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.Rmd index dc0c165a..3e1a9f61 100644 --- a/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.Rmd +++ b/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.Rmd @@ -62,18 +62,17 @@ Visit the interactive dashboard: ``` r library(knitr) ``` - -![](https://github.com/podaac/tutorials/blob/master/images/SWOT_RiverDB_Basin.png?raw=true) +![](../../images/SWOT_RiverDB_Basin.png?raw=true) Click on the North American basin, then click on one of the numbers that has your river in it. I will click on Alaska which is \#81. -![](https://github.com/podaac/tutorials/blob/master/images/Alaska.png?raw=true) +![](../../images/Alaska.png?raw=true) After clicking on the basin you will see colorful lines which represent reach_ids. You can zoom in on the map into the river area of interest. -![](https://github.com/podaac/tutorials/blob/master/images/Area_Of_interest.png?raw=true) +![](../../images/Area_Of_interest.png?raw=true) The example in this tutorial uses reaches from the Kuskokwim River in Southwestern Alaska. In the right-hand corner, you can see fields that @@ -214,7 +213,7 @@ data <- clean_hydrocron(data_raw) plot_reach(data, title = "Kuskokwim River") ``` -![](SWOT_River_Time_Series_Tutorial_in_R4_files/figure-gfm/unnamed-chunk-7-1.png) +![](SWOT_River_Time_Series_Tutorial_in_R4_files/figure-gfm/unnamed-chunk-7-1.png) **Conclusion** diff --git a/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.html b/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.html new file mode 100644 index 00000000..82d7cff4 --- /dev/null +++ b/notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.html @@ -0,0 +1,583 @@ + + + + + + + + + + + + + +SWOT_River_Time_Series_Tutorial_in_R--1-.knit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+

SWOT River Time-Series Tutorial in R

+

Navid Khizri (NASA JPL PO.DAAC Summer Intern; Alaska Pacific +University Student)

+

Summary

+

This introductory tutorial guides students through plotting a river +water surface elevation (WSE) time series in R using observations from +NASA’s Surface Water and Ocean Topography (SWOT) mission. Students will +learn how to locate river reach identifiers (reach_id) in the SWOT River +Database (SWORD), request observations via the Hydrocron API, clean +missing-data placeholders, and visualize the results using base R.

+

Requirements

+

Any compute environment (local RStudio or cloud-based RStudio).

+

Learning Objectives

+ +

Why SWOT Matters

+

SWOT (Surface Water and Ocean Topography) is the first satellite +mission to survey nearly 90% of Earth’s rivers, lakes, and hydrologic +systems. SWOT uses Ka-band radar interferometry to measure water surface +elevation globally, providing data crucial for hydrology, flood +forecasting, and water management.

+

Alaska, with more than 12,000 rivers and limited stream gauges due to +high installation and maintenance costs, stands to benefit +significantly. SWOT’s wide-swath coverage provides consistent 21‑day +revisit observations — helping fill data gaps for remote communities and +improving hydrologic modeling, especially under climate change.

+

This tutorial shows an example of exploring river observations from +SWOT for a river in Alaska.

+

As a student at Alaska Pacific University in Anchorage, I had the +privilege of learning about Alaska Native communities. Many of these +communities are accessible only by plane or boat, and face increasing +flood risks driven by climate change. SWOT can help improve flood models +and provide critical water-level data to support flood readiness in +rural Alaska. For additional reading, see Water Mission to Gauge Alaskan +Rivers on Front Lines of Climate Change.

+

Link: https://sealevel.jpl.nasa.gov/news/1599/water-mission-to-gauge-alaskan-rivers-on-front-lines-of-climate-change/

+

Explore the SWORD River Database to find your river reach_id of +interest

+

Visit the interactive dashboard:

+

https://www.swordexplorer.com/

+
library(knitr)
+

+

Click on the North American basin, then click on one of the numbers +that has your river in it. I will click on Alaska which is #81.

+

+

After clicking on the basin you will see colorful lines which +represent reach_ids. You can zoom in on the map into the river area of +interest.

+

+

The example in this tutorial uses reaches from the Kuskokwim River in +Southwestern Alaska. In the right-hand corner, you can see fields that +are available. For now, just keep reach_id selected. Hovering the mouse +over a river reach will display information about that reach, including +the reach ID. When you find your reach ID, note it because will use it +later when creating a time series.

+

What is Hydrocron?

+

Hydrocron is an API developed by NASA’s PO.DAAC that provides +time-series hydrology data from SWOT in formats such as GeoJSON and CSV. +At the time of the making of this tutorial each request retrieves data +for a single reach_id.

+

Required Packages

+
library(httr)
+library(jsonlite)
+

Functions Used in This Tutorial

+

To simplify utilization of this workflow, several helper functions +are defined. - This part of the tutorial typically would only need to be +run once. - After that, if the user wishes to change the Hydrocron API +query parameters (start_time,end_time,fields), they can do so in the +next section below: Fetch, Clean, and Plot. - If a user wishes to modify +the API parameters requested, some modification of the helper functions +may be needed.

+

What the functions do: get_reach_data() creates the url to connect +with Hydrocron API to get your river reach data.

+

clean_hydrocron() filters out missing data.

+

plot_reach() plots the data.

+
# Fetch Hydrocron data
+# Send a request to NASA's Hydrocron API, download SWOT river data, and prepare it for R.
+
+get_reach_data <- function(reach_id, start_time, end_time, fields = "reach_id,time_str,wse,slope") {
+  
+  # Constructs a valid Hydrocron API URL by plugging in: your reach_id, your start date, your end date
+  url <- paste0(
+    "https://soto.podaac.earthdatacloud.nasa.gov/hydrocron/v1/timeseries?",
+    "feature=Reach",
+    "&feature_id=", reach_id,
+    "&output=geojson",
+    "&start_time=", start_time,
+    "&end_time=", end_time,
+    "&fields=", fields
+  )
+
+  # R sends the request to NASA's servers
+  res <- GET(url) 
+
+  # Convert returned JSON into an R list
+  geo <- fromJSON(content(res, "text")) 
+
+  # Extract the actual river measurements
+  data <- geo$results$geojson$features$properties 
+
+  # Convert time strings into real time stamps
+  data$time <- as.POSIXct(data$time_str, format = "%Y-%m-%dT%H:%M:%SZ", tz = "UTC")
+ 
+  # Return the clean data table
+  return(data)
+}
+
+
+clean_hydrocron <- function(df) {
+
+  # Convert wse and slope to numeric. Hydrocron stores data as characters strings instead of numeric which will crash the plot if not converted.
+  df$wse   <- as.numeric(df$wse)
+  df$slope <- as.numeric(df$slope)
+
+  # Remove rows with "no_data"
+  df <- df[df$time_str != "no_data", ]
+
+  # Remove fill value rows
+  df <- df[df$wse   != -999999999999.0, ] 
+  df <- df[df$slope != -999999999999.0, ]
+
+  # Remove rows where timestamp conversion failed
+  df <- df[!is.na(df$time), ]
+
+  # Output the cleaned dataset
+  return(df) 
+}
+
+
+# Plot a SWOT river reach
+plot_reach <- function(data, title = "SWOT River Time-Series") {
+
+  plot(
+    data$time, data$wse,
+    main = title,
+    xlab = "Time",
+    ylab = "Water Surface Elevation (m)",
+    col = "red",
+    pch = 16
+  )
+
+  lines(data$time, data$wse, col = "black")
+  grid() # Improves readability for students
+}
+

Fetch, Clean, and Plot SWOT Data

+

In this example, we request all observations for reach +81181700021 from 2023–2026. A user can change these inputs +to request different time periods and/or river IDs. User only needs to +re-run the cell below when modifying the query +parameters(reach_id,start_time,end_time).

+

Note: At the time of writing this tutorial, there is a limit on how +much data the API can query. If you’re reach is too large, consider +breaking the query up into smaller requests. If interested in 2023 to +2027 data, you could do two queries: 2023-10-01 to 2025-05-31 and +2025-06-01 to 2027-07-25.

+

r kuskokwim_wse_timeseries data_raw <- get_reach_data( reach_id = "81181700021", # Insert your reach ID here start_time = "2025-06-01T00:00:00Z", # Insert Start Date end_time = "2027-07-25T00:00:00Z" # Insert End Date )

+
## No encoding supplied: defaulting to UTF-8.
+
data <- clean_hydrocron(data_raw)
+
+plot_reach(data, title = "Kuskokwim River")
+

+

Conclusion

+

You successfully retrieved SWOT river surface elevation data using +Hydrocron, cleaned missing data, and plotted a time series. This +workflow can be reused for any river reach available in the SWORD +database.

+

SWOT offers valuable high-resolution hydrologic data — especially for +remote and ungauged regions like rural Alaska — unlocking new +opportunities for hydrology education, research, and community +impact.

+
+ + + + +
+ + + + + + + + + + + + + + + diff --git a/quarto_text/SWOT_HydrocronLandingPage.qmd b/quarto_text/SWOT_HydrocronLandingPage.qmd index 17de1cb9..8d64e284 100644 --- a/quarto_text/SWOT_HydrocronLandingPage.qmd +++ b/quarto_text/SWOT_HydrocronLandingPage.qmd @@ -9,3 +9,5 @@ subtitle: Example workflows using Hydrocron #### [Advanced Hydrocron time series example using Python and Dask to parallelize the workflow](../notebooks/datasets/Hydrocron_SWOT_timeseries_examples.ipynb) +#### [Hydrocron time series example using R](../notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.html) +