Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ notebooks/datasets/dask-worker-space
/_site/
.quarto/
_site/

**/*.quarto_ipynb
Original file line number Diff line number Diff line change
@@ -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) <https://www.swordexplorer.com/>. \n- Interact with Hydrocron <https://podaac.github.io/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<https://sealevel.jpl.nasa.gov/news/1599/water-mission-to-gauge-alaskan-rivers-on-front-lines-of-climate-change/>\n\nExplore the SWORD River Database to find your river reach_id of interest\n\nVisit the interactive dashboard:\n\n**<https://www.swordexplorer.com/>**\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
}
}
9 changes: 4 additions & 5 deletions notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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**

Expand Down
583 changes: 583 additions & 0 deletions notebooks/datasets/SWOT_River_Time_Series_Tutorial_in_R.html

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions quarto_text/SWOT_HydrocronLandingPage.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Loading