Track observations

Track observations#

Track observations are point observations for moving points. The index therefore consists of time, x- and y-positions. Altimetry data acquired from satellite is an example of track observations; data obtained from boat is another example.

The track observation data may come from a file or web api. We will cover the following situations here:

  • File

    • dfs0

    • csv/excel

  • REST API

modelskill has the class TrackObservation for working with track observations.

Track observations consist of time-position-value (data) and meta data such as

  • data type (e.g. water level)

  • unit (e.g. meter)

ModelSkill is agnostic to the coordinate reference system (CRS) and it is therefore the responsibility of the user to make sure that all data (observations and model) use the same CRS.

import pandas as pd
import modelskill as ms

Data from file#

The two first items in the file must be x- and y- coordinate values.

dfs0 files can be read directly by TrackObservation.

csv files needs to be read by pandas first and passed to TrackObservation as a DataFrame.

fn = "data/SW/altimetry_NorthSea_20171027.csv"
df = pd.read_csv(fn, index_col=0, parse_dates=True)  # step 1: create DataFrame
df.head()
lon lat surface_elevation significant_wave_height wind_speed
date
2017-10-26 04:37:37 8.757272 53.926136 1.6449 0.426 6.100000
2017-10-26 04:37:54 8.221631 54.948459 1.1200 1.634 9.030000
2017-10-26 04:37:55 8.189390 55.008547 1.0882 1.717 9.370000
2017-10-26 04:37:56 8.157065 55.068627 1.0309 1.869 9.559999
2017-10-26 04:37:58 8.124656 55.128700 1.0369 1.939 9.980000
o1 = ms.TrackObservation(df, item="surface_elevation")  # step 2: create TrackObservation
o1
/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/modelskill/timeseries/_track.py:135: UserWarning: Removed 22 duplicate timestamps with keep=first
  warnings.warn(
<TrackObservation>: surface_elevation
Time: 2017-10-26 04:37:37 - 2017-10-30 20:54:47
Quantity:  []

DHI Altimetry API#

You need to pip install “watobs” for this part!

See Altimetry_data.ipynb example notebook.

import os
from watobs import DHIAltimetryRepository
api_key = os.environ["DHI_ALTIMETRY_API_KEY"]
repo = DHIAltimetryRepository(api_key)
data = repo.get_altimetry_data(area="lon=2.9&lat=53.9&radius=100", start_time="2019-10-1", 
end_time="2019-10-8")
data.df.head()
Succesfully retrieved 268 records from API in 4.03 seconds
longitude latitude water_level significant_wave_height wind_speed distance_from_land water_depth satellite quality absolute_dynamic_topography water_level_rms significant_wave_height_raw significant_wave_height_rms wind_speed_raw wind_speed_rads
datetime
2019-10-01 01:53:00.499 4.095785 53.379154 -0.6561 1.548305 8.837844 53818.833235 -23.745530 c2 0 0.4700 0.041 1.551 0.340 8.840398 7.78
2019-10-01 01:53:01.443 4.086177 53.436186 -0.6729 1.474444 9.411201 56835.494763 -23.182199 c2 0 0.4329 0.033 1.471 0.384 9.404725 8.34
2019-10-01 01:53:02.386 4.076554 53.493216 -0.6507 1.598252 9.267605 60378.720102 -24.143654 c2 0 0.4297 0.031 1.605 0.290 9.263391 8.22
2019-10-01 01:53:03.330 4.066916 53.550246 -0.6268 1.665887 9.124174 64265.423518 -28.753282 c2 0 0.4221 0.050 1.678 0.398 9.122218 8.08
2019-10-01 01:53:04.273 4.057262 53.607274 -0.6301 1.705789 8.802106 68516.513146 -34.857509 c2 0 0.3841 0.044 1.721 0.313 8.805222 7.77
data.plot_map()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
File /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/matplotlib/style/core.py:137, in use(style)
    136 try:
--> 137     style = _rc_params_in_file(style)
    138 except OSError as err:

File /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/matplotlib/__init__.py:866, in _rc_params_in_file(fname, transform, fail_on_error)
    865 rc_temp = {}
--> 866 with _open_file_or_url(fname) as fd:
    867     try:

File /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/contextlib.py:119, in _GeneratorContextManager.__enter__(self)
    118 try:
--> 119     return next(self.gen)
    120 except StopIteration:

File /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/matplotlib/__init__.py:843, in _open_file_or_url(fname)
    842 fname = os.path.expanduser(fname)
--> 843 with open(fname, encoding='utf-8') as f:
    844     yield f

FileNotFoundError: [Errno 2] No such file or directory: 'seaborn-whitegrid'

The above exception was the direct cause of the following exception:

OSError                                   Traceback (most recent call last)
Cell In[7], line 1
----> 1 data.plot_map()

File /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/watobs/altimetry.py:121, in AltimetryData.plot_map(self, fig_size, markersize)
    112 """plot map of altimetry data
    113 
    114 Parameters
   (...)
    117     size of figure, by default (12,10)
    118 """
    119 df = self.df
--> 121 plt.style.use("seaborn-whitegrid")
    122 plt.figure(figsize=fig_size)
    123 markers = ["o", "x", "+", "v", "^", "<", ">", "s", "d", ",", "."]

File /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/matplotlib/style/core.py:139, in use(style)
    137         style = _rc_params_in_file(style)
    138     except OSError as err:
--> 139         raise OSError(
    140             f"{style!r} is not a valid package style, path of style "
    141             f"file, URL of style file, or library style name (library "
    142             f"styles are listed in `style.available`)") from err
    143 filtered = {}
    144 for k in style:  # don't trigger RcParams.__getitem__('backend')

OSError: 'seaborn-whitegrid' is not a valid package style, path of style file, URL of style file, or library style name (library styles are listed in `style.available`)
o1 = ms.TrackObservation(data.df, item="significant_wave_height", name='Alti_from_df', quantity=ms.Quantity("Significant wave height", "m"))
o1
<TrackObservation>: Alti_from_df
Time: 2019-10-01 01:53:00.499000 - 2019-10-07 10:38:34
Quantity: Significant wave height [m]

Or you can save the data to a dfs0 first…

data.to_dfs0('alti_NS_20191001.dfs0')
o2 = ms.TrackObservation('alti_NS_20191001.dfs0', item="Significant Wave Height", quantity=ms.Quantity("Significant wave height", "m")
o2
  Cell In[10], line 2
    o2
    ^
SyntaxError: invalid syntax