rOpenSci | wateRinfo - Downloading tidal data to understand the behaviour of a migrating eel

wateRinfo - Downloading tidal data to understand the behaviour of a migrating eel

Do you know what that sound is, Highness? Those are the Shrieking Eels — if you don’t believe me, just wait. They always grow louder when they’re about to feed on human flesh. If you swim back now, I promise, no harm will come to you. I doubt you will get such an offer from the Eels.

Vizzini, The Princess Bride

European eels (Anguilla anguilla) have it tough. Not only are they depicted as monsters in movies, they are critically endangered in real life. One of the many aspects that is contributing to their decline is the reduced connectivity between their freshwater and marine habitats. Eels are catadromous: they live in freshwater, but migrate to the Sargasso Sea to spawn, a route that is blocked by numerous human structures (shipping locks, sluices, pumping stations, etc.). Pieterjan Verhelst studies the impact of these structures on the behaviour of eels, making use of the fish acoustic receiver network that was established as part of the Belgian LifeWatch observatory. This animated video gives a quick introduction to his research and the receiver network:

Tagging research on eel in Belgium

In this blog post, we’ll explore if the migration of one eel is influenced by the tide. It’s a research use case for our R package wateRinfo, which was recently peer reviewed (thanks to reviewer Laura DeCicco and editor Karthik Ram for their constructive feedback!) and accepted as a community-contributed package to rOpenSci.

🔗 Meet Princess Buttercup

Pieterjan provided us the tracking data for eel with transmitter A69-1601-52622. Let’s call her Princess Buttercup, after the princess that almost got eaten by the Shrieking Eels in the classic and immensly quotable movie The Princess Bride.

eel <- read_csv(here("data", "eel_track.csv"))

Her tracking data consists of the residence time interval (arrival until departure) at each receiver station that detected her along the Scheldt river. It also contains the calculated residencetime (in seconds), as well as the station name, latitude and longitude.

datereceiverlatitudelongitudestationarrivaldepartureresidencetime
2016-10-19VR2W-11229751.001643.85695s-Wetteren2016-10-19 23:44:002016-10-19 23:48:00240
2016-10-19VR2W-11228751.005883.77876s-22016-10-19 16:07:002016-10-19 19:12:0011100
2016-10-20VR2W-12232251.020323.96965s-2a2016-10-20 13:18:002016-10-20 13:23:00300
2016-10-20VR2W-12232251.020323.96965s-2a2016-10-20 02:21:002016-10-20 02:29:00480
2016-10-20VR2W-11543851.016803.92527s-Wichelen2016-10-20 01:01:002016-10-20 01:09:00480
2016-10-20VR2W-12232251.020323.96965s-2a2016-10-20 05:52:002016-10-20 06:00:00480

Using the latitude, longitude and total residencetime for each station, we can map where Princess Buttercup likes to hang out:

🔗 Moving up and down the Scheldt river

To get a better sense of her journey along the river, we add a distance_to_sea (in meters) for the stations, by joining the tracking data with a distance reference file 1. We can now plot her movement over time and distance:

Princess Buttercup’s signal was picked up by receivers in Merelbeke (near Ghent) shortly after she was captured and released there on October 11. She resided in a 40 km stretch of the river (between Wetteren and Sint-Amands) for about a month before migrating towards the sea and starting the long journey towards the Sargasso Sea. The periodic movement pattern up and down the river during the second half of November is of particular interest: it looks like tidal frequency 2. It would be interesting to compare the movement pattern with real water level data from the Scheldt river… which is where our wateRinfo package comes in.

🔗 Getting tidal data with the wateRinfo package

Waterinfo.be, managed by the Flanders Environment Agency (VMM) and Flanders Hydraulics Research, is a website where one can find real-time water and weather related environmental variables for Flanders (Belgium), such as rainfall, air pressure, discharge, and water level. The website also provides an API to download time series of these measurements as open data, but compositing the download URL with the proper system codes can be challenging. To facilitate users in searching for stations and variables, subsequently downloading data of interest and incorporating waterinfo.be data access in repeatable workflows, we developed the R package wateRinfo to do just that. See the package documentation for more information on how to install and get started with the package.

Timeseries in waterinfo.be (identified by a ts_id) are a combination of a variable, location (station_id) and measurement frequency (15min by default). For example:

library(wateRinfo)
get_stations("water_level") %>%
  select(ts_id, station_id, station_name, parametertype_name) %>%
  head()
ts_idstation_idstation_nameparametertype_name
9295604239483Kieldrecht/NoordzuidverbindingH
3168304221995Leuven/Dijle1e arm/stuw K3H
2068204220301StMichiels/Kerkebeek/RoosterH
9649504210413Oudenburg/MagdalenakreekH
2507404220788Schulen/Inlaat A/WB_SchulensbroekH
200604210432Merkem/SteenbeekH

At the time of writing (see this issue), the stations measuring water levels in the Scheldt tidal zone are not yet included by the API under the core variable water_level and are thus not yet available via get_stations("water_level"). We therefore rely on a precompiled list of tidal time series identifiers (tidal_zone_ts_ids):

tidal_zone_ts_ids <- read_csv(here("data", "tidal_zone_ts_ids.csv"))

From which we select the 10-min frequency tidal timeseries in the Scheldt river:

ts_idstation_idstation_nameportal_bekken
554190100430087Sint-Amands tij/ZeescheldeBeneden-Scheldebekken
555650100430029Tielrode tij/DurmeBeneden-Scheldebekken
554930100430081Temse tij/ZeescheldeBeneden-Scheldebekken
541860100419418Dendermonde tij/ZeescheldeBeneden-Scheldebekken
544930100430078Hemiksem tij/ZeescheldeBeneden-Scheldebekken
553550100430091Schoonaarde tij/ZeescheldeBeneden-Scheldebekken
539890100419484Antwerpen tij/ZeescheldeBeneden-Scheldebekken
546060100430071Kallosluis tij/ZeescheldeBeneden-Scheldebekken
560880100430062Prosperpolder tij/ZeescheldeBeneden-Scheldebekken
549360100430068Liefkenshoek tij/ZeescheldeBeneden-Scheldebekken
550590100430242Melle tij/ZeescheldeBeneden-Scheldebekken

This wateRinfo vignette shows how to download data for multiple stations at once using wateRinfo and dplyr. We use a similar approach, but instead of manually providing the start and end date, we get these from Princess Buttercup’s tracking data:

tidal_data <-
  tidal_zone_ts_ids %>%
  group_by(ts_id) %>%
  
  # Download tidal data for each ts_id (time series id)
  do(get_timeseries_tsid(
      .$ts_id,
      from = min(eel$date), # Start of eel tracking data
      to = max(eel$date),   # End of eel tracking data
      datasource = 4
  )) %>%
  
  # Join data back with tidal_zone_ts_id metadata
  ungroup() %>%
  left_join(tidal_zone_ts_ids, by = "ts_id")

In just a few lines of code, we downloaded the tidal data for each measurement station for the required time period. 👌

The water level is expressed in mTAW (meter above mean sea level) 3. Let’s plot the data for a station (here Dendermonde in November 2016) to have a look:

We now have all the pieces to verify if Princess Buttercup was surfing the tide back and forth.

🔗 Is Princess Buttercup surfing the tide?

Let’s add the tidal data to Princess Buttercup’s journey plot we created before. The first step is to join the tidal data with the same distance reference file to know the distance from each tidal station to the sea:

tidal_data <-
  tidal_data %>%
  left_join(
    distance_from_sea %>% select(station, distance_from_sea, municipality),
    by = c("station_name" = "station")
  ) %>%
  filter(station_name != "Hemiksem tij/Zeeschelde") # Exclude (probably erroneous) data from Hemiksem

To avoid visual clutter, we’ll use ridges (from ggridges) to display the tidal data for each station over time:

Looking at the plot, Princess Buttercup seems to be “lazy” and drift with the tide. Rising water levels push her upstream, while decreasing water levels bring her closer to sea again. On November 22 (see also previous plot), she embarks on her migration for real.

🔗 Conclusion

In this blogpost we used the wateRinfo package to gain some insight in the movement/migration behaviour of an individual eel. We hope the package can support many more research questions and that you have fun storming the castle.

🔗 Acknowledgements

Waterinfo.be data is made available by the Flanders Environment Agency, Flanders Hydraulics Research, Agentschap Maritieme Dienstverlening & Kust and De Vlaamse Waterweg. The fish acoustic receiver network, as well as the work by Stijn and Peter, is funded by FWO as part of the Flemish contribution to LifeWatch. The animated video on eel research was funded by the Flanders Marine Institute (VLIZ), coordinated by Karen Rappé and Pieterjan Verhelst, animated by Steve Bridger, and narrated by Bryan Kopta.

If you want to get in touch with our team, contact us via Twitter or email.


  1. To represent the data along a straight line (y-axis), we calculated the distance along the river from each station to a reference station close to the sea (ws-TRAWL), using a costDistance function. See this script for more the details on the calculation. ↩︎

  2. The Scheldt is under tidal influence from its river mouth all the way to Ghent (160km upstream) where it is stopped by sluices. The tide goes much further than the freshwater-saltwater boundary of the river. ↩︎

  3. TAW means Tweede Algemene Waterpassing, a reference height for Belgium. ↩︎