GOTM: ERSEM in a water column
To run the model, you must first obtain or generate a set of input or forcing files. Setups for the L4 and BATS sites which were used in [2] are stored under version control and can be accessed here. Forcing data for the SSB sampling sites can be accessed here. The following example uses the L4 setup described in [2].
Running GOTM-FABM-ERSEM
The L4 sampling site is one part of the Western Channel Observatory (WCO), and is located at (50°15.0’N; 4°13.0’W).
To run the tutorial, you will first need to clone the configuration files and then run gotm. This is done with the following:
1#!/bin/bash
2
3echo "Cloning config repo"
4git clone https://github.com/pmlmodelling/ersem-setups.git
5
6cp ersem/testcases/fabm-ersem-26.02-dvm.yaml ersem-setups/L4/fabm.yaml
7cd ersem-setups/L4
8
9echo "Running GOTM with repo configuration"
10~/local/gotm/bin/gotm --ignore_unknown_config
Note
The following script requires matplotlib, netCDF4 and numpy to be
installed. This can easily be done via pip in the following way:
python -m pip install matplotlib numpy netCDF4
To visualise the results, we again use a python script. Running the script you will need
to add a commandline argument --model-path which is the path to the output from
the GOTM-FABM-ERSEM run.
1import argparse
2import matplotlib.pyplot as plt
3from matplotlib import ticker
4import numpy as np
5import os
6import sys
7import re
8
9
10try:
11 import netCDF4 as nc
12except ImportError:
13 print("Please install the Python interface to netCDF")
14 sys.exit()
15
16
17def main(model_path):
18 """
19 Run GOTM-ERSEM tutorial
20
21 :param model_path: Full path to netCDF model output
22 :type model_path: str
23
24 :return: Dictionary containing output model variables for systests
25 :rtype: dict
26 """
27
28 # Dictionary used to save output variables for testing
29 output_vars = {}
30 def plot_time_series(axes, data, depth, model_var_name):
31 # sets the maximum number of labels on the x axis to be 10
32 xticks = ticker.MaxNLocator(10)
33
34 times = data.variables['time']
35 dates = nc.num2date(times[:],
36 units=times.units,
37 calendar=times.calendar)
38
39 z = data.variables['z'][:].squeeze()
40 zi = data.variables['zi'][:].squeeze()
41 var = data.variables[model_var_name]
42
43 long_label = '{} ({})'.format(var.long_name, var.units)
44 y_label = re.sub(r'(\s\S*?)\s', r'\1\n',long_label)
45
46 # Interpolate variable data to the given depth below the moving free surface
47 var_time_series = []
48 for i in range(var.shape[0]):
49 # Remove offset introduced by the moving free surface
50 depth_offset = depth + zi[i, -1]
51
52 var_time_series.append(np.interp(depth_offset, z[i, :], var[i, :].squeeze()))
53
54 dates = [str(d).split(" ")[0] for d in dates]
55 axes.plot(dates, var_time_series)
56 axes.set_ylabel(y_label)
57 axes.xaxis.set_major_locator(xticks)
58 output_vars[model_var_name] = var_time_series
59 output_vars['dates'] = dates
60
61 data = nc.Dataset(model_path, 'r')
62 data.set_auto_maskandscale(True)
63
64 # Depth at which to compare the model and data, given as relative to the moving free surface.
65 depth = 0.0
66
67 fig, ax_arr = plt.subplots(3,1)
68 DPI = fig.get_dpi()
69 fig.set_size_inches(1200.0/float(DPI),800.0/float(DPI))
70
71 names = ['N1_p', 'N3_n', 'N5_s']
72 for ax, name in zip(ax_arr, names):
73 plot_time_series(ax, data, depth, name)
74
75 ax.tick_params(axis='both', which='major')
76 ax.tick_params(axis='both', which='minor')
77 ax.set_ylim(0)
78
79 plt.show()
80
81 return output_vars
82
83if __name__ == "__main__":
84 parser = argparse.ArgumentParser()
85 parser.add_argument('-p', '--model-path', type=str, required=True,
86 help='Path to GOTM-FABM-ERSEM output')
87 args, _ = parser.parse_known_args()
88 model_path = args.model_path
89
90 main(model_path)