Last updated on Jun 04, 2026.

Example 1: Characterize a sea state from sea surface elevation time series#

1. Introduction#

In this first example, it is shown how NetSSE can be used to analyse measurements at the sea surface. In particular, measurements of the water elevation by three wave probes around a single-point location are exploited to derive a wave spectrum and extract sea state parameters.

We would like to assess whether the three probes are experiencing the same sea state.

Import relevant packages#

The following modules and packages are imported:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from netsse.analys.spec import spec1d_to_params
from netsse.dataset import load_example_data
from netsse.tools.viz import fig_settings
===============================
Registration Request for NetSSE
To help us improve and better understand our user community, we kindly ask all users to register to use NetSSE. Registration is free.
If you have not already registered, please do so here:
https://forms.office.com/Pages/ResponsePage.aspx?id=I_FR8s7JjkSSdzS7KFkR2Xd1K-8FtOJFrL9QLVM8cJZUQ1hBS0VTN1E0OVU4QThTOTQ1WDA0TFg4Si4u
===============================
Matplotlib is building the font cache; this may take a moment.

As can be seen in the above import, this example illustrates the use of the following NetSSE functions:

Define default settings#

Those settings are used for the visual appearance of figures generated in this Python example.

fig_path, figcolors, props = fig_settings(font="serif", dpi=100, usetex=True)

Import the measurement data#

The input data to this example are the time series of sea surface elevation (in meters) measured by the three wave probes (WP1, WP2, and WP3), which have been deployed around the same location. The time series are synchronized and sampled at 20 Hz.

The time series are read from a .csv file in Pandas. The file is named "example_WP_meas.csv" located here.

df_WP = load_example_data("example_WP_meas.csv", index_col=0)
print("Table 1: Surface measurements of wave parameters at a given location.")
df_WP
Table 1: Surface measurements of wave parameters at a given location.
time WP1 WP2 WP3
0 0.00 -0.054108 0.108216 -0.054108
1 0.05 -0.077697 0.155393 -0.077697
2 0.10 -0.101172 0.202345 -0.101172
3 0.15 -0.124362 0.248723 -0.124362
4 0.20 -0.147087 0.294173 -0.147087
... ... ... ... ...
447205 22360.25 -0.018386 0.036773 -0.018386
447206 22360.30 -0.016299 0.032598 -0.016299
447207 22360.35 -0.014064 0.028128 -0.014064
447208 22360.40 -0.011657 0.023313 -0.011657
447209 22360.45 -0.009051 0.018102 -0.009051

447210 rows × 4 columns

2. Analyse the time series data#

These time series are quite long (around 22360 s, that is approximately 6.2 hours). We will therefore limit our analysis to the first hour of the data.

time_lb = 0  # Lower bound of time segment to be analyzed
time_ub = 3600  # Upper bound
df_WP_seg = df_WP[(df_WP["time"] >= time_lb) & (df_WP["time"] < time_ub)]
print("Table 2: Extracted time segment of surface measurements for analysis.")
df_WP_seg
Table 2: Extracted time segment of surface measurements for analysis.
time WP1 WP2 WP3
0 0.00 -0.054108 0.108216 -0.054108
1 0.05 -0.077697 0.155393 -0.077697
2 0.10 -0.101172 0.202345 -0.101172
3 0.15 -0.124362 0.248723 -0.124362
4 0.20 -0.147087 0.294173 -0.147087
... ... ... ... ...
71995 3599.75 -0.105144 0.210289 -0.105144
71996 3599.80 -0.082366 0.164733 -0.082366
71997 3599.85 -0.059133 0.118266 -0.059133
71998 3599.90 -0.035533 0.071067 -0.035533
71999 3599.95 -0.011661 0.023322 -0.011661

72000 rows × 4 columns

Plot the time series segment for different wave probes#

We would like to visually inspect the time series, to check for any major issue with the data. The three time series are plotted in three different panels (subplots) using the Matplotlib package.

colors = [figcolors["blue"], figcolors["green"], figcolors["orange"]]
fig, ax = plt.subplots(3, 1, figsize=(10, 5))
for i_plot in range(3):
    ax[i_plot].plot(
        df_WP_seg["time"],
        df_WP_seg[f"WP{i_plot + 1}"],
        label=f"WP{i_plot + 1}",
        color=colors[i_plot],
    )
    ax[i_plot].set_ylabel("Elevation [m]")
    ax[i_plot].legend()
    ax[i_plot].grid()
ax[-1].set_xlabel("Time [s]")
print("Fig. 1: Measured wave elevation time series")
# fig.tight_layout()
plt.show()
Fig. 1: Measured wave elevation time series
../_images/13f3d04ed4db7580c932b1f3148d35a9768a98893b6685c6b184975dd54ba280.png

It appears that the elevation measured by WP2 is generally higher than that measured by the other two probes (WP1 and WP3).

Plot a zoomed-in view of the recorded surface elevation#

For a more careful check of the time series, we plot a zoomed-in view of the recorded surface elevation for the three wave probes in a same plot.

linestyles = ["-", "-", "--"]
fig = plt.figure(figsize=(10, 2))
for i_plot in range(3):
    plt.plot(
        df_WP_seg["time"],
        df_WP_seg[f"WP{i_plot + 1}"],
        label=f"WP{i_plot + 1}",
        linestyle=linestyles[i_plot],
        color=colors[i_plot],
    )
plt.xlim(3000, 3100)
plt.xlabel("Time [s]")
plt.ylabel("Elevation [m]")
plt.legend()
print("Fig. 2: Zoomed-in wave elevation time series")
# fig.tight_layout()
plt.show()
Fig. 2: Zoomed-in wave elevation time series
../_images/422d8de10d0ad0ada8f4125bca4b8e5741a228bb3c6a75384c7d0a0d55663454.png

The signals from WP1 and WP3 seem to be nearly identical, while the signal from WP2 is out of phase.

Calculate basic statistics derived from a time-domain analysis#

We compute the mean \(\mu\) and standard deviation \(\sigma\) of the three time series.

means_WP = df_WP_seg[["WP1", "WP2", "WP3"]].mean()
std_WP = df_WP_seg[["WP1", "WP2", "WP3"]].std()

stats_WP = pd.DataFrame({"Mean [m]": means_WP, "Std [m]": std_WP})
stats_WP.index.name = "Probe"
print(
    "Table 3: Statistics of wave elevation time series for the extracted time segment."
)
stats_WP
Table 3: Statistics of wave elevation time series for the extracted time segment.
Mean [m] Std [m]
Probe
WP1 -0.000139 0.461323
WP2 0.000278 0.922646
WP3 -0.000139 0.461323

The signals have a mean value under 1 millimeter. It can therefore be considered that they are zero-mean signals.

3. Compute a wave spectrum of measured surface elevation#

Now, we would like to analyse the recorded surface elevation in the frequency domain. This includes the computation of a wave energy density spectrum, or wave spectrum, for each of the recorded signals.

To do this, we can use the scipy.signal.csd function from the Scipy package.

4. Extract the sea state parameters#

5. Fit a standard wave spectra#

In many engineering applications, such as the response analysis of marine structures exposed to waves, use of the wave spectrum is required in order to carry on the computations. In those cases, the sea state parameters can be exploited to reconstruct the wave spectrum by applying an adequately chosen parameterised spectrum.

There exist several standard forms of wave spectra. The choice of one form is application-specific and made based on the geographical area of study. Among other effects, the water depth, the predominance of wind sea over swell, or the opposite, and the fetch – defined as the length of the body of water that the wind blows over – should be considered (Mounet, 2023).

fmax = 0.5
Nf = 100
f = np.linspace(0, fmax, Nf)

References#

  1. Mounet, R.E.G. (2023). Sea State Estimation Based on Measurements from Multiple Observation Platforms. PhD Thesis. Technical University of Denmark. https://orbit.dtu.dk/en/publications/sea-state-estimation-based-on-measurements-from-multiple-observat