Building ERDDAP Datasets
This notebook documents the process of creating XML fragments for nowcast system run results files for inclusion in /results/erddap-datasets/datasets.xml
which is symlinked to /opt/tomcat/content/erddap/datasets.xml
on the skookum
ERDDAP server instance.
The contents are a combination of:
instructions for using the
GenerateDatasetsXml.sh
andDasDds.sh
tools found in the/opt/tomcat/webapps/erddap/WEB-INF/
directoryinstructions for forcing the server to update the datasets collection via the
/results/erddap/flags/
directorycode and metadata to transform the output of
GenerateDatasetsXml.sh
into XML fragments that are ready for inclusion in/results/erddap-datasets/datasets.xml
This is a snapshot of the erddap-datasets/ERDDAP_datasets.ipynb
notebook that is used to maintain the datasets.xml
file. Please see https://github.com/SalishSeaCast/erddap-datasets for the active, version controlled version of this notebook, and the production `datasets.xml
file.
[ ]:
from collections import OrderedDict
from lxml import etree
NOTE
The next cell mounts the /results
filesystem on skookum
locally. It is intended for use if when this notebook is run on a laptop or other non-Waterhole machine that has sshfs
installed and a mount point for /results
available in its root filesystem.
Don’t execute the cell if that doesn’t describe your situation.
[2]:
!sshfs skookum:/results /results
The metadata
dictionary below contains information for dataset attribute tags whose values need to be changed, or that need to be added for all datasets.
The keys are the dataset attribute names.
The values are dicts containing a required text
item and perhaps an optional after
item.
The value associated with the text
key is the text content for the attribute tag.
When present, the value associated with the after
key is the name of the dataset attribute after which a new attribute tag containing the text
value is to be inserted.
[2]:
metadata = OrderedDict([
('coverage_content_type', {
'text': 'modelResult',
'after': 'cdm_data_type',
}),
('infoUrl', {
'text':
'https://salishsea-meopar-docs.readthedocs.io/en/latest/results_server/index.html#salish-sea-model-results',
}),
('institution', {'text': 'UBC EOAS'}),
('institution_fullname', {
'text': 'Earth, Ocean & Atmospheric Sciences, University of British Columbia',
'after': 'institution',
}),
('license', {
'text': '''The Salish Sea MEOPAR NEMO model results are copyright 2013-2021
by the Salish Sea MEOPAR Project Contributors and The University of British Columbia.
They are licensed under the Apache License, Version 2.0. https://www.apache.org/licenses/LICENSE-2.0''',
}),
('project', {
'text':'Salish Sea MEOPAR NEMO Model',
'after': 'title',
}),
('creator_name', {
'text': 'Salish Sea MEOPAR Project Contributors',
'after': 'project',
}),
('creator_email', {
'text': 'sallen@eos.ubc.ca',
'after': 'creator_name',
}),
('creator_url', {
'text': 'https://salishsea-meopar-docs.readthedocs.io/',
'after': 'creator_email',
}),
('acknowledgement', {
'text': 'MEOPAR, ONC, Compute Canada',
'after': 'creator_url',
}),
('drawLandMask', {
'text': 'over',
'after': 'acknowledgement',
}),
])
The datasets
dictionary below provides the content for the dataset title
and summary
attributes.
The title
attribute content appears in the the datasets list table (among other places). It should be <
80 characters long, and note that only the 1st 40 characters will appear in the table.
The summary
attribute content appears (among other places) when a user hovers the cursor over the ?
icon beside the title
content in the datasets list table. The text that is inserted into the summary
attribute tag by code later in this notebook is the title
content followed by the summary
content, separated by a blank line.
The keys of the datasets
dict are the datasetID
strings that are used in many places by the ERDDAP server. They are structured as follows:
ubc
to indicate that the dataset was produced at UBCSS
to indicate that the dataset is a product of the Salish Sea NEMO modela few letters to indicate the model runs that produce the dataset:
n
to indicate that the dataset is from a nowcast run,f
for forecast,f2
for forecast2 (aka preliminary forecast),hg
for hindcast-greenng
for nowcast-green,a
for atmospheric forcing,
a description of the dataset variables; e.g.
PointAtkinsonSSH
or3DuVelocity
the time interval of values in the dataset; e.g.
15m
,1h
,1d
the dataset version; e.g.
V16-10
, orV1
Versioning was changed to a CalVer type scheme in Oct-2016. Thereafter versions are of the form Vyymm
and indicate the year and month when the dataset entered production.
So:
ubcSSnPointAtkinsonSSH15mV1
is the version 1 dataset of 15 minute averaged sea surface height values at Point Atkinson fromPointAtkinson.nc
output filesubcSSn3DwVelocity1hV2
is the version 2 dataset of 1 hr averaged vertical (w) velocity values over the entire domain fromSalishSea_1h_*_grid_W.nc
output filesubcSSnSurfaceTracers1dV1
is the version 1 dataset of daily averaged surface tracer values over the entire domain fromSalishSea_1d_*_grid_T.nc
output filesubcSSnBathymetry2V16-07
is the version 16-07 dataset of longitude, latitude, and bathymetry of the Salish Sea NEMO model grid that came into use in Jul-2016. The corresponding NEMO-generated mesh mask variables are in theubcSSn2DMeshMaskDbo2V16-07
(y, x variables), and theubcSSn3DMeshMaskDbo2V16-07
(z, y, x variables) datasets.
The dataset version part of the datasetID
is used to indicate changes in the variables contained in the dataset. For example, the transition from the ubcSSn3DwVelocity1hV1
to the ubcSSn3DwVelocity1hV2
dataset occurred on 24-Jan-2016 when we started to output vertical eddy viscosity and diffusivity values at the w
grid points.
All dataset ids end with their version identifier and their summary
ends with a notation about the variables that they contain; e.g.
v1: wVelocity variable
When the a dataset version is incremented a line describing the change is added to the end of its summary
; e.g.
v1: wVelocity variable
v2: Added eddy viscosity & diffusivity variables ve_eddy_visc & ve_eddy_diff
[14]:
datasets = {
'ubcSSnBathymetry2V1' :{
'type': 'geolocation bathymetry',
'title': 'Salish Sea NEMO Model Grid, Geo-location and Bathymetry, v1',
'summary':'''Longitude, latitude, and bathymetry of the Salish Sea NEMO model grid.
The bathymetry values are those calculated by NEMO from the input bathymetry file.
NEMO modifies the input bathymetry to remove isolated holes, and too-small partial steps.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: longitude, latitude and bathymetry variables
''',
'fileNameRegex': '.*SalishSea2_NEMO_bathy\.nc$'
},
'ubcSSnBathymetry2V16-07' :{
'type': 'geolocation bathymetry',
'title': 'Salish Sea NEMO Model Grid, Geo-location and Bathymetry, v16-07',
'summary':'''Longitude, latitude, and bathymetry of the Salish Sea NEMO model grid.
The bathymetry values are those calculated by NEMO from the input bathymetry file.
NEMO modifies the input bathymetry to remove isolated holes, and too-small partial steps.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: longitude, latitude and bathymetry variables
v16-07: same variables,
bathymetry uniformly deepened by 1 grid level,
smoothed at Juan de Fuca & Johnstone Strait open boundaries,
Fraser River lengthened,
bathymetry deepened near mouth of Fraser River
''',
'fileNameRegex': '.*downbyone2_NEMO_bathy\.nc$'
},
'ubcSSn2DMeshMask2V1': {
'type': 'geolocation bathymetry',
'title': 'Salish Sea NEMO Model Grid, 2D Mesh Mask, v1',
'summary':'''NEMO grid variable value for the u-v plane of the
Salish Sea NEMO model Arakawa-C grid.
The values are those calculated by NEMO from the input coordinates and bathymetry files.
The variable names are those used by NEMO-3.4,
see the NEMO-3.4 book (https://www.nemo-ocean.eu/Media/Files/NEMO_book_V3_4.pdf) for details,
or the long_name attributes of the variables for succinct descriptions of the variables.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: e1t, e2t, e1u, e2u, e1v, e2v, e1f, e2f, glamt, gphit, glamu, gphiu, glamv, gphiv,
tmaskutil, umaskutil, vmaskutil, fmaskutil, ff, mbathy variables
''',
'fileNameRegex': '.*mesh_mask_SalishSea2\.nc$',
},
'ubcSSn2DMeshMask2V16-07': {
'type': 'geolocation bathymetry',
'title': 'Salish Sea NEMO Model Grid, 2D Mesh Mask, v16-07',
'summary':'''NEMO grid variable value for the u-v plane of the
Salish Sea NEMO model Arakawa-C grid.
The values are those calculated by NEMO from the input coordinates and bathymetry files.
The variable names are those used by NEMO-3.6,
see the NEMO-3.6 book (https://www.nemo-ocean.eu/Media/Files/NEMO_book_V3_6.pdf) for details,
or the long_name attributes of the variables for succinct descriptions of the variables.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: e1t, e2t, e1u, e2u, e1v, e2v, e1f, e2f, glamt, gphit, glamu, gphiu, glamv, gphiv,
tmaskutil, umaskutil, vmaskutil, fmaskutil, ff, mbathy variables
v16-07: e1t, e2t, e1u, e2u, e1v, e2v, e1f, e2f, glamt, gphit, glamu, gphiu, glamv, gphiv,
glamf, gphif, tmaskutil, umaskutil, vmaskutil, fmaskutil, ff, mbathy variables
''',
'fileNameRegex': '.*mesh_mask_downbyone2\.nc$',
},
'ubcSSn3DMeshMask2V1': {
'type': 'geolocation bathymetry',
'title': 'Salish Sea NEMO Model Grid, 3D Mesh Mask, v1',
'summary':'''NEMO grid variable value for the Salish Sea NEMO model Arakawa-C grid.
The values are those calculated by NEMO from the input coordinates and bathymetry files.
The variable names are those used by NEMO-3.4,
see the NEMO-3.4 book (https://www.nemo-ocean.eu/Media/Files/NEMO_book_V3_4.pdf) for details,
or the long_name attributes of the variables for succinct descriptions of the variables.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: e3t, e3u, e3v, e3w, gdept, gdepu, gdepv, gdepw, tmask, umask, vmask, fmask variables
''',
'fileNameRegex': '.*mesh_mask_SalishSea2\.nc$'
},
'ubcSSn3DMeshMask2V16-07': {
'type': 'geolocation bathymetry',
'title': 'Salish Sea NEMO Model Grid, 3D Mesh Mask, v16-07',
'summary':'''NEMO grid variable value for the Salish Sea NEMO model Arakawa-C grid.
The values are those calculated by NEMO from the input coordinates and bathymetry files.
The variable names are those used by NEMO-3.6,
see the NEMO-3.6 book (https://www.nemo-ocean.eu/Media/Files/NEMO_book_V3_6.pdf) for details,
or the long_name attributes of the variables for succinct descriptions of the variables.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: e3t_0, e3u_0, e3v_0, e3w_0, gdept_0, gdepu, gdepv, gdepw_0, tmask, umask, vmask, fmask variables
v16-07: e3t, e3u, e3v, e3w, gdept, gdepu, gdepv, gdepw, tmask, umask, vmask, fmask variables
''',
'fileNameRegex': '.*mesh_mask_downbyone2\.nc$'
},
'ubcSSnPointAtkinsonSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Point Atkinson, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minute intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Point Atkinson tide gauge station on the north side of English Bay,
near Vancouver, British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*PointAtkinson\.nc$',
},
'ubcSSnCampbellRiverSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Campbell River, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Campbell River tide gauge station at the north end of the Strait of Georgia,
near Campbell River, British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*CampbellRiver\.nc$',
},
'ubcSSnCherryPointSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Cherry Point, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Cherry Point tide gauge station in the southern Strait of Georgia,
near Birch Bay, Washington.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*CherryPoint\.nc$',
},
'ubcSSnFridayHarborSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Friday Harbor, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Friday Harbor tide gauge station at San Juan Island in Haro Strait,
near Friday Harbor, Washington.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*FridayHarbor\.nc$',
},
'ubcSSnNanaimoSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Nanaimo, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Nanaimo tide gauge station on the west side of the central Strait of Georgia,
near Nanaimo, British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*Nanaimo\.nc$',
},
'ubcSSnNeahBaySSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Neah Bay, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Neah Bay tide gauge station on the south side of the west end of the Juan de Fuca Strait,
near Neah Bay, Washington.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*NeahBay\.nc$',
},
'ubcSSnVictoriaSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Victoria, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Victoria tide gauge station on the north side of the east end of the Juan de Fuca Strait,
in the Victoria Inner Harbour, near Victoria, British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*Victoria\.nc$',
},
'ubcSSnSandHeadsSSH15mV1': {
'type': 'tide gauge',
'title': 'Nowcast, Sand Heads, Sea Surface Height, 15min, v1',
'summary': '''Sea surface height values averaged over 15 minutes intervals from
Salish Sea NEMO model nowcast runs. The values are calculated at the model grid point
closest to the Sand Heads light station on the east side of the central Strait of Georgia,
near Steveston, British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: ssh variable
''',
'fileNameRegex': '.*Sandheads\.nc$',
},
'ubcSSn3DTracerFields1hV1': {
'type': '3d fields',
'title': 'Nowcast, Salish Sea, 3d Tracer Fields, Hourly, v1',
'summary': '''3d salinity and water temperature field values averaged over 1 hour intervals
from Salish Sea NEMO model nowcast runs. The values are calculated for the entire model grid
that includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: salinity (practical) and temperature variables
''',
'fileNameRegex': '.*SalishSea_1h_\d{8}_\d{8}_grid_T\.nc$',
},
'ubcSSnSurfaceTracerFields1hV1': {
'type': 'surface fields',
'title': 'Nowcast, Salish Sea, Surface Tracer Fields, Hourly, v1',
'summary': '''2d sea surface height and rainfall rate field values averaged over 1 hour intervals
from Salish Sea NEMO model nowcast runs. The values are calculated for the surface of the model grid
that includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: sea surface height and rainfall rate variables
''',
'fileNameRegex': '.*SalishSea_1h_\d{8}_\d{8}_grid_T\.nc$',
},
'ubcSSn3DuVelocity1hV1': {
'type': '3d fields',
'title': 'Nowcast, Salish Sea, 3d u Velocity Field, Hourly, v1',
'summary': '''3d zonal (u) component velocity field values averaged over 1 hour intervals
from Salish Sea NEMO model nowcast runs. The values are calculated for the entire model grid
that includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: uVelocity variable
''',
'fileNameRegex': '.*SalishSea_1h_\d{8}_\d{8}_grid_U\.nc$',
},
'ubcSSn3DvVelocity1hV1': {
'type': '3d fields',
'title': 'Nowcast, Salish Sea, 3d v Velocity Field, Hourly, v1',
'summary': '''3d meridional (v) component velocity field values averaged over 1 hour intervals
from Salish Sea NEMO model nowcast runs. The values are calculated for the entire model grid
that includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: vVelocity variable
''',
'fileNameRegex': '.*SalishSea_1h_\d{8}_\d{8}_grid_V\.nc$',
},
'ubcSSn3DwVelocity1hV1': {
'type': '3d fields',
'title': 'Nowcast, Salish Sea, 3d w Velocity Field, Hourly, v1',
'summary': '''3d vertical (w) component velocity field values averaged over 1 hour intervals
from Salish Sea NEMO model nowcast runs. The values are calculated for the entire model grid
that includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: wVelocity variable
''',
'fileNameRegex': '.*SalishSea_1h_\d{8}_\d{8}_grid_W\.nc$',
},
'ubcSSaSurfaceAtmosphereFieldsV1': {
'type': 'surface fields',
'title': 'HRDPS, Salish Sea, Atmospheric Forcing Fields, Hourly, v1',
'summary': '''2d hourly atmospheric field values from the
Environment Canada HRDPS atmospheric forcing model that are used to force the Salish Sea NEMO model.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location data for the atmospheric forcing grid are available in the ubcSSaAtmosphereGridV1 dataset.
Atmospheric field values are interpolated on to the Salish Sea NEMO model grid (ubcSSnBathymetry2V1 dataset)
on-the-fly by NEMO.
v1: atmospheric pressure, precipitation rate, 2m specific humidity, 2m air temperature,
short-wave radiation flux, long-wave radiation flux, 10m u wind component, 10m v wind component variables
''',
'fileNameRegex': '.*ops_y\d{4}m\d{2}d\d{2}\.nc$',
},
}
datasets['ubcSSn3DwVelocity1hV2'] = datasets['ubcSSn3DwVelocity1hV1']
datasets['ubcSSn3DwVelocity1hV2'].update({
'title': datasets['ubcSSn3DwVelocity1hV1']['title'].replace(', v1', ', v2'),
'summary': datasets['ubcSSn3DwVelocity1hV1']['summary'] + '''
v2: Added eddy viscosity & diffusivity variables ve_eddy_visc & ve_eddy_diff''',
})
datasets['ubcSSn3DTracerFields1hV16-10'] = datasets['ubcSSn3DTracerFields1hV1']
datasets['ubcSSn3DTracerFields1hV16-10'].update({
'title': datasets['ubcSSn3DTracerFields1hV1']['title'].replace(', v1', ', v16-10'),
'summary': datasets['ubcSSn3DTracerFields1hV1']['summary'] + '''
v16-10: NEMO-3.6; ubcSSnBathymetry2V16-07 bathymetry; see infoUrl link for full details.
Changed salinity variable to reference salinity.
Made temperature variable explicitly potential temperature.
Added squared buoyancy frequency variable.''',
})
datasets['ubcSSnSurfaceTracerFields1hV16-10'] = datasets['ubcSSnSurfaceTracerFields1hV1']
datasets['ubcSSnSurfaceTracerFields1hV16-10'].update({
'title': datasets['ubcSSnSurfaceTracerFields1hV1']['title'].replace(', v1', ', v16-10'),
'summary': datasets['ubcSSnSurfaceTracerFields1hV1']['summary'] + '''
v16-10: NEMO-3.6; ubcSSnBathymetry2V16-07 bathymetry; see infoUrl link for full details.
Added mixed layer thickness defined by sigma theta variable.
Deleted rainfall rate variable.''',
})
datasets['ubcSSn3DuVelocity1hV16-10'] = datasets['ubcSSn3DuVelocity1hV1']
datasets['ubcSSn3DuVelocity1hV16-10'].update({
'title': datasets['ubcSSn3DuVelocity1hV1']['title'].replace(', v1', ', v16-10'),
'summary': datasets['ubcSSn3DuVelocity1hV1']['summary'] + '''
v16-10: NEMO-3.6; ubcSSnBathymetry2V16-07 bathymetry; see infoUrl link for full details.'''
})
datasets['ubcSSn3DvVelocity1hV16-10'] = datasets['ubcSSn3DvVelocity1hV1']
datasets['ubcSSn3DvVelocity1hV16-10'].update({
'title': datasets['ubcSSn3DvVelocity1hV1']['title'].replace(', v1', ', v16-10'),
'summary': datasets['ubcSSn3DvVelocity1hV1']['summary'] + '''
v16-10: NEMO-3.6; ubcSSnBathymetry2V16-07 bathymetry; see infoUrl link for full details.'''
})
The dataset_vars
dictionary below is used to rename variables from the often cryptic NEMO names to the names that appear in the ERDDAP generated files and web content.
The keys are the NEMO variable names to replace.
The values are dicts that map the variable names to use in ERDDAP to the destinationName
attribute name.
[6]:
dataset_vars = {
'sossheig': {'destinationName': 'ssh'},
'vosaline': {'destinationName': 'salinity'},
'votemper': {'destinationName': 'temperature'},
'vozocrtx': {'destinationName': 'uVelocity'},
'vomecrty': {'destinationName': 'vVelocity'},
'vovecrtz': {'destinationName': 'wVelocity'},
}
A few convenient functions to reduce code repetition:
[7]:
def print_tree(root):
"""Display an XML tree fragment with indentation.
"""
print(etree.tostring(root, pretty_print=True).decode('ascii'))
[8]:
def find_att(root, att):
"""Return the dataset attribute element named att
or raise a ValueError exception if it cannot be found.
"""
e = root.find('.//att[@name="{}"]'.format(att))
if e is None:
raise ValueError('{} attribute element not found'.format(att))
return e
[9]:
def replace_yx_with_lonlat(root):
new_axes = {
'y': {'sourceName': 'nav_lon', 'destinationName': 'longitude'},
'x': {'sourceName': 'nav_lat', 'destinationName': 'latitude'},
}
for axis in root.findall('.//axisVariable'):
if axis.find('.//sourceName').text in new_axes:
key = axis.find('.//sourceName').text
new_axis = etree.Element('axisVariable')
etree.SubElement(new_axis, 'sourceName').text = new_axes[key]['sourceName']
etree.SubElement(new_axis, 'destinationName').text = new_axes[key]['destinationName']
axis.getparent().replace(axis, new_axis)
Now we’re ready to produce a dataset!!!
Use the /opt/tomcat/webapps/erddap/WEB-INF/GenerateDatasetsXml.sh
script generate the initial version of an XML fragment for a dataset:
$ cd /opt/tomcat/webapps/erddap/WEB-INF/
$ bash GenerateDatasetsXml.sh EDDGridFromNcFiles /results/SalishSea/nowcast/
The EDDGridFromNcFiles
and /results/SalishSea/nowcast/
arguments tell the script which EDDType
and what parent directory to use, avoiding having to type those in answer to prompts. Answer the remaining prompts, for example:
File name regex (e.g., ".*\.nc") (default="")
? .*SalishSea_1h_\d{8}_\d{8}_grid_W\.nc$
Full file name of one file (default="")
? /results/SalishSea/nowcast/28jan16/SalishSea_1h_20160128_20160128_grid_W.nc
ReloadEveryNMinutes (e.g., 10080) (default="")
? 10080
Other examples of file name regex are:
.*PointAtkinson.nc$
.*SalishSea_1d_\d{8}_\d{8}_grid_W\.nc$
The output is written to /results/erddap/logs/GenerateDatasetsXml.out
Now, we:
set the
datasetID
we want to useparse the output of
GenerateDatasetsXml.sh
into an XML tree data structureset the
datasetID
dataset attribute valuere-set the
fileNameRegex
dataset attribute value because it looses its\
characters during parsing(?)edit and add dataset attributes from the
metadata
dictset the
title
andsummary
dataset attributes from thedatasets
dictset the names of the grid
x
andy
axis variablesrename data variables as specified in the
dataset_vars
dict
[10]:
def update_xml(root, datasetID, metadata, datasets, dataset_vars):
root.attrib['datasetID'] = datasetID
root.find('.//fileNameRegex').text = datasets[datasetID]['fileNameRegex']
title = datasets[datasetID]['title']
summary = find_att(root, 'summary')
summary.text = '{0}\n\n{1}'.format(title, datasets[datasetID]['summary'])
e = etree.Element('att', name='title')
e.text = title
summary.addnext(e)
for att, info in metadata.items():
e = etree.Element('att', name=att)
e.text = info['text']
try:
root.find('.//att[@name="{}"]'.format(info['after'])).addnext(e)
except KeyError:
find_att(root, att).text = info['text']
for axis_name in root.findall('.//axisVariable/destinationName'):
if axis_name.text in ('x', 'y'):
axis_name.text = 'grid{}'.format(axis_name.text.upper())
if datasets[datasetID]['type'] == 'tide gauge':
replace_yx_with_lonlat(root)
for var_name in root.findall('.//dataVariable/destinationName'):
if var_name.text in dataset_vars:
var_name.text = dataset_vars[var_name.text]['destinationName']
[17]:
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse('/results/erddap/logs/GenerateDatasetsXml.out', parser)
root = tree.getroot()
datasetID = 'ubcSSn3DvVelocity1hV16-10'
update_xml(root, datasetID, metadata, datasets, dataset_vars)
Inspect the resulting dataset XML fragment below and edit the dicts and code cell above until it is what is required for the dataset:
[18]:
print_tree(root)
<dataset type="EDDGridFromNcFiles" datasetID="ubcSSn3DvVelocity1hV16-10" active="true">
<reloadEveryNMinutes>10080</reloadEveryNMinutes>
<updateEveryNMillis>10000</updateEveryNMillis>
<fileDir>/results/SalishSea/nowcast-blue/</fileDir>
<recursive>true</recursive>
<fileNameRegex>.*SalishSea_1h_\d{8}_\d{8}_grid_V\.nc$</fileNameRegex>
<metadataFrom>last</metadataFrom>
<matchAxisNDigits>20</matchAxisNDigits>
<fileTableInMemory>false</fileTableInMemory>
<accessibleViaFiles>false</accessibleViaFiles>
<!-- sourceAttributes>
<att name="Conventions">CF-1.5</att>
<att name="description">ocean V grid variables</att>
<att name="history">Mon Dec 5 11:34:46 2016: ncks -4 -L4 -O SalishSea_1h_20161205_20161205_grid_V.nc SalishSea_1h_20161205_20161205_grid_V.nc</att>
<att name="name">SalishSea_1h_20161205_20161205</att>
<att name="NCO">4.4.2</att>
<att name="production">An IPSL model</att>
<att name="timeStamp">2016-Dec-05 11:03:34 PST</att>
<att name="title">ocean V grid variables</att>
</sourceAttributes -->
<addAttributes>
<att name="cdm_data_type">Grid</att>
<att name="coverage_content_type">modelResult</att>
<att name="Conventions">CF-1.6, COARDS, ACDD-1.3</att>
<att name="infoUrl">https://salishsea-meopar-docs.readthedocs.io/en/latest/results_server/index.html#salish-sea-model-results</att>
<att name="institution">UBC EOAS</att>
<att name="institution_fullname">Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="keywords">along, axis, circulation, current, currents, data, depthv, grid, j-axis, ocean, oceans,
Oceans > Ocean Circulation > Ocean Currents,
sea, sea_water_y_velocity, seawater, time_counter, v, velocity, vomecrty, water</att>
<att name="keywords_vocabulary">GCMD Science Keywords</att>
<att name="license">The Salish Sea MEOPAR NEMO model results are copyright 2013-2021
by the Salish Sea MEOPAR Project Contributors and The University of British Columbia.
They are licensed under the Apache License, Version 2.0. http://www.apache.org/licenses/LICENSE-2.0</att>
<att name="standard_name_vocabulary">CF Standard Name Table v29</att>
<att name="summary">Nowcast, Salish Sea, 3d v Velocity Field, Hourly, v16-10
3d meridional (v) component velocity field values averaged over 1 hour intervals
from Salish Sea NEMO model nowcast runs. The values are calculated for the entire model grid
that includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location and depth data for the Salish Sea NEMO model grid are available in the ubcSSnBathymetry2V1 dataset.
v1: vVelocity variable
v16-10: NEMO-3.6; ubcSSnBathymetry2V16-07 bathymetry; see infoUrl link for full details.</att>
<att name="title">Nowcast, Salish Sea, 3d v Velocity Field, Hourly, v16-10</att>
<att name="project">Salish Sea MEOPAR NEMO Model</att>
<att name="creator_name">Salish Sea MEOPAR Project Contributors</att>
<att name="creator_email">sallen@eos.ubc.ca</att>
<att name="creator_url">https://salishsea-meopar-docs.readthedocs.io/</att>
<att name="acknowledgement">MEOPAR, ONC, Compute Canada</att>
<att name="drawLandMask">over</att>
</addAttributes>
<axisVariable>
<sourceName>time_counter</sourceName>
<destinationName>time</destinationName>
<!-- sourceAttributes>
<att name="_ChunkSize" type="int">1</att>
<att name="axis">T</att>
<att name="bounds">time_counter_bounds</att>
<att name="calendar">gregorian</att>
<att name="long_name">Time axis</att>
<att name="standard_name">time</att>
<att name="time_origin">1900-01-01 00:00:00</att>
<att name="units">seconds since 1900-01-01 00:00:00</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="bounds">null</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>depthv</sourceName>
<destinationName>depth</destinationName>
<!-- sourceAttributes>
<att name="_ChunkSize" type="int">40</att>
<att name="axis">Z</att>
<att name="bounds">depthv_bounds</att>
<att name="long_name">Vertical V levels</att>
<att name="positive">down</att>
<att name="units">m</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="bounds">null</att>
<att name="standard_name">depth</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>y</sourceName>
<destinationName>gridY</destinationName>
<!-- sourceAttributes>
</sourceAttributes -->
<addAttributes>
<att name="long_name">Y</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>x</sourceName>
<destinationName>gridX</destinationName>
<!-- sourceAttributes>
</sourceAttributes -->
<addAttributes>
<att name="long_name">X</att>
</addAttributes>
</axisVariable>
<dataVariable>
<sourceName>vomecrty</sourceName>
<destinationName>vVelocity</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 12 285 126</att>
<att name="_FillValue" type="float">1.0E20</att>
<att name="cell_methods">time: mean (interval: 40 s)</att>
<att name="coordinates">time_centered depthv nav_lon nav_lat</att>
<att name="interval_operation">40 s</att>
<att name="interval_write">1 h</att>
<att name="long_name">ocean current along j-axis</att>
<att name="missing_value" type="float">1.0E20</att>
<att name="online_operation">average</att>
<att name="standard_name">sea_water_y_velocity</att>
<att name="units">m/s</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="colorBarMaximum" type="double">0.5</att>
<att name="colorBarMinimum" type="double">-0.5</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
</dataset>
Extra processing step are required for some types of datasets. See:
Store the XML fragment for the dataset:
[19]:
with open('/results/erddap-datasets/fragments/{}.xml'.format(datasetID), 'wb') as f:
f.write(etree.tostring(root, pretty_print=True))
Edit /results/erddap-datasets/datasets.xml
to include the XML fragment for the dataset that was stored by the above cell.
That file is symlinked to /opt/tomcat/content/erddap/datasets.xml
.
Create a flag file to signal the ERDDAP server process to load the dataset:
$ cd /results/erddap/flag/
$ touch <datasetID>
If the dataset does not appear on https://salishsea.eos.ubc.ca/erddap/info/, check /results/erddap/logs/log.txt
for error messages from the dataset load process (they may not be at the end of the file because ERDDAP is pretty chatty).
Once the dataset has been successfully loaded and you are happy with the metadata that ERDDAP is providing for it, commit the changes in /results/erddap-datasets/
and push them to GitHub.
Surface Field Datasets
The /opt/tomcat/webapps/erddap/WEB-INF/GenerateDatasetsXml.sh
script produces and XML fragment that uses all of the dimensions that it finds in the sample file it parses, and includes only the variables that have all of those dimensions. To produce an XML fragment for surface fields we need to do some additional work:
Delete the depth axis
Delete all of the
dataVariable
elementsAdd
dataVariable
elements for the surface variables
[22]:
for axis in root.findall('.//axisVariable'):
if axis.find('.//destinationName').text == 'depth':
axis.getparent().remove(axis)
break
for var in root.findall('.//dataVariable'):
var.getparent().remove(var)
var = etree.SubElement(root, 'dataVariable')
etree.SubElement(var, 'sourceName').text = 'sossheig'
etree.SubElement(var, 'destinationName').text = 'ssh'
etree.SubElement(var, 'dataType').text = 'float'
attrs = etree.SubElement(var, 'addAttributes')
etree.SubElement(attrs, 'att', name='_ChunkSize').text = 'null'
etree.SubElement(attrs, 'att', name='coordinates').text = 'null'
var = etree.SubElement(root, 'dataVariable')
etree.SubElement(var, 'sourceName').text = 'rain_rate'
etree.SubElement(var, 'destinationName').text = 'rain_rate'
etree.SubElement(var, 'dataType').text = 'float'
attrs = etree.SubElement(var, 'addAttributes')
etree.SubElement(attrs, 'att', name='_ChunkSize').text = 'null'
etree.SubElement(attrs, 'att', name='coordinates').text = 'null'
find_att(root, 'keywords').text = (
'model results, height, local, sea, sea surface height, sossheig, source, surface, time_counter')
[23]:
print_tree(root)
[22]:
with open('/results/erddap-datasets/fragments/{}.xml'.format(datasetID), 'wb') as f:
f.write(etree.tostring(root, pretty_print=True))
Model Grid Geo-location and Bathymetry Datasets
Model grid geo-location and bathymetry datasets require a lot of hand editing because they are not model generated. Here is an example of a finished one:
[26]:
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse('/results/erddap-datasets/fragments/ubcSSnBathymetry2V1.xml', parser)
root = tree.getroot()
print_tree(root)
<dataset type="EDDGridFromNcFiles" datasetID="ubcSSnBathymetry2V1" active="true">
<reloadEveryNMinutes>10080</reloadEveryNMinutes>
<updateEveryNMillis>10000</updateEveryNMillis>
<fileDir>/results/nowcast-sys/NEMO-forcing/grid/</fileDir>
<recursive>false</recursive>
<fileNameRegex>.*SalishSea2_NEMO_bathy\.nc$</fileNameRegex>
<metadataFrom>last</metadataFrom>
<matchAxisNDigits>20</matchAxisNDigits>
<fileTableInMemory>false</fileTableInMemory>
<accessibleViaFiles>false</accessibleViaFiles>
<!-- sourceAttributes>
<att name="comment">Bathymetry, Latitudes and Longitudes</att>
<att name="Conventions">CF-1.6</att>
<att name="history">[2016-02-05 Created]</att>
<att name="institution">Dept of Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="references">REQUIRED</att>
<att name="source">https://bitbucket.org/salishsea/analysis/src/tip/Susan/NEMOBathymetryfromMeshMask.ipynb</att>
<att name="title">Bathymetry after NEMO Processes, SalishSea Bathymetry 2</att>
</sourceAttributes -->
<addAttributes>
<att name="cdm_data_type">Grid</att>
<att name="coverage_content_type">modelResult</att>
<att name="Conventions">CF-1.6, COARDS, ACDD-1.3</att>
<att name="infoUrl">https://salishsea-meopar-tools.readthedocs.org/en/latest/results_server/index.html#salish-sea-model-results</att>
<att name="institution">UBC EOAS</att>
<att name="institution_fullname">Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="creator_name">Dept of Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="keywords">bathymetry, bottom, data, model results, depth, floor, latitude, longitude, nemo, ocean, oceans,
Oceans > Bathymetry/Seafloor Topography > Bathymetry, salishsea, sea, sea_floor_depth, seafloor, topography</att>
<att name="keywords_vocabulary">GCMD Science Keywords</att>
<att name="license">The Salish Sea MEOPAR NEMO model results are copyright 2013-2021
by the Salish Sea MEOPAR Project Contributors and The University of British Columbia.
They are licensed under the Apache License, Version 2.0. http://www.apache.org/licenses/LICENSE-2.0</att>
<att name="standard_name_vocabulary">CF Standard Name Table v29</att>
<att name="summary">Salish Sea NEMO Model Grid, Geo-location and Bathymetry, v1
Longitude, latitude, and bathymetry of the Salish Sea NEMO model grid.
The bathymetry values are those calculated by NEMO from the input bathymetry file.
NEMO modifies the input bathymetry to remove isolated holes, and too-small partial steps.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: longitude, latitude and bathymetry variables</att>
<att name="title">Salish Sea NEMO Model Grid, Geo-location and Bathymetry, v1</att>
<att name="project">Salish Sea MEOPAR NEMO Model</att>
<att name="creator_name">Salish Sea MEOPAR Project Contributors</att>
<att name="creator_email">sallen@eos.ubc.ca</att>
<att name="creator_url">https://salishsea-meopar-docs.readthedocs.org/</att>
<att name="acknowledgement">MEOPAR, ONC, Compute Canada</att>
<att name="drawLandMask">over</att>
</addAttributes>
<axisVariable>
<sourceName>y</sourceName>
<destinationName>gridY</destinationName>
<!-- sourceAttributes>
</sourceAttributes -->
<addAttributes>
<att name="long_name">Y</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>x</sourceName>
<destinationName>gridX</destinationName>
<!-- sourceAttributes>
</sourceAttributes -->
<addAttributes>
<att name="long_name">X</att>
</addAttributes>
</axisVariable>
<dataVariable>
<sourceName>longitude</sourceName>
<destinationName>longitude</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="long_name">Longitude</att>
<att name="units">degrees_east</att>
</sourceAttributes -->
<addAttributes>
<att name="colorBarMaximum" type="double">180.0</att>
<att name="colorBarMinimum" type="double">-180.0</att>
<att name="standard_name">longitude</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>latitude</sourceName>
<destinationName>latitude</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="long_name">Latitude</att>
<att name="units">degrees_north</att>
</sourceAttributes -->
<addAttributes>
<att name="colorBarMaximum" type="double">90.0</att>
<att name="colorBarMinimum" type="double">-90.0</att>
<att name="standard_name">latitude</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>bathymetry</sourceName>
<destinationName>bathymetry</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="coordinates">longitude latitude</att>
<att name="grid">Salish Sea 2</att>
<att name="long_name">Depth of Bottom</att>
<att name="units">m</att>
</sourceAttributes -->
<addAttributes>
<att name="colorBarMaximum" type="double">450.0</att>
<att name="colorBarMinimum" type="double">0.0</att>
<att name="colorBarPalette">OceanDepth</att>
<att name="coordinates">null</att>
<att name="standard_name">sea_floor_depth</att>
</addAttributes>
</dataVariable>
</dataset>
EC HDRPS Atmospheric Forcing Datasets
Atmospheric Forcing Grid Geo-location Dataset
Use the /opt/tomcat/webapps/erddap/WEB-INF/GenerateDatasetsXml.sh
script generate the initial version of an XML fragment for the dataset:
$ cd /opt/tomcat/webapps/erddap/WEB-INF/
$ bash GenerateDatasetsXml.sh EDDGridFromNcFiles /results/forcing/atmospheric/GEM2.5/operational/ ops_y\d{4}m\d{2}d\d{2}.nc$ /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d07.nc 10080
Like the model grid geo-location and bathymetry dataset, the atmospheric forcing grid dataset requires a lot of hand editing. Here is the finished dataset:
[12]:
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse('/results/erddap-datasets/fragments/ubcSSaAtmosphereGridV1.xml', parser)
root = tree.getroot()
print_tree(root)
<dataset type="EDDGridFromNcFiles" datasetID="ubcSSaAtmosphereGridV1" active="true">
<reloadEveryNMinutes>10080</reloadEveryNMinutes>
<updateEveryNMillis>10000</updateEveryNMillis>
<fileDir>/results/forcing/atmospheric/GEM2.5/operational/</fileDir>
<recursive>false</recursive>
<fileNameRegex>ops_y2016m03d07.nc$</fileNameRegex>
<metadataFrom>last</metadataFrom>
<matchAxisNDigits>20</matchAxisNDigits>
<fileTableInMemory>false</fileTableInMemory>
<accessibleViaFiles>false</accessibleViaFiles>
<!-- sourceAttributes>
<att name="Conventions">CF-1.0</att>
<att name="GRIB2_grid_template" type="int">20</att>
<att name="History">Mon Mar 7 10:07:34 2016: ncks -4 -L4 -O /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d07.nc /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d07.nc
created by wgrib2</att>
<att name="NCO">4.4.2</att>
</sourceAttributes -->
<addAttributes>
<att name="cdm_data_type">Grid</att>
<att name="coverage_content_type">modelResult</att>
<att name="Conventions">CF-1.6, COARDS, ACDD-1.3</att>
<att name="History">null</att>
<att name="history">Mon Mar 7 10:07:34 2016: ncks -4 -L4 -O /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d07.nc /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d07.nc
created by wgrib2</att>
<att name="infoUrl">https://salishsea-meopar-tools.readthedocs.org/en/latest/results_server/index.html#salish-sea-model-results</att>
<att name="institution">UBC EOAS</att>
<att name="institution_fullname">Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="creator_name">Dept of Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="keywords">atmosphere, model results, HRDPS, latitude, longitude, salishsea</att>
<att name="keywords_vocabulary">GCMD Science Keywords</att>
<att name="license">The Salish Sea MEOPAR NEMO model results are copyright 2013-2021
by the Salish Sea MEOPAR Project Contributors and The University of British Columbia.
They are licensed under the Apache License, Version 2.0. http://www.apache.org/licenses/LICENSE-2.0
This dataset is derived from a product of the Environment Canada HRDPS (High Resolution Deterministic Prediction System) model. The Terms and conditions of use of Meteorological Data from Environment Canada are available at http://dd.weather.gc.ca/doc/LICENCE_GENERAL.txt.</att>
<att name="standard_name_vocabulary">CF Standard Name Table v29</att>
<att name="summary">HRDPS, Salish Sea, Atmospheric Forcing Grid, Geo-location, v1
Longitude and latitude of the Environment Canada HRDPS atmospheric forcing model grid that is used to for the Salish Sea NEMO model.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
v1: longitude and latitude</att>
<att name="title">HRDPS, Salish Sea, Atmospheric Forcing Grid, Geo-location, v1</att>
<att name="project">Salish Sea MEOPAR NEMO Model</att>
<att name="creator_name">Salish Sea MEOPAR Project Contributors</att>
<att name="creator_email">sallen@eos.ubc.ca</att>
<att name="creator_url">https://salishsea-meopar-docs.readthedocs.org/</att>
<att name="acknowledgement">Environment Canada, MEOPAR, ONC, Compute Canada</att>
<att name="drawLandMask">over</att>
</addAttributes>
<axisVariable>
<sourceName>y</sourceName>
<destinationName>gridY</destinationName>
<addAttributes>
<att name="long_name">Y</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>x</sourceName>
<destinationName>gridX</destinationName>
<addAttributes>
<att name="long_name">X</att>
</addAttributes>
</axisVariable>
<dataVariable>
<sourceName>nav_lon</sourceName>
<destinationName>longitude</destinationName>
<dataType>float</dataType>
<addAttributes>
<att name="standard_name">longitude</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>nav_lat</sourceName>
<destinationName>latitude</destinationName>
<dataType>float</dataType>
<addAttributes>
<att name="standard_name">latitude</att>
</addAttributes>
</dataVariable>
</dataset>
Atmospheric Forcing Model Fields
Change the value of the
recursive
element tofalse
so that the/results/forcing/atmospheric/GEM2.5/operational/fcst/
directory is excludedAdd Environment Canada acknowledgement and terms & conditions of use to
license
elementAdd Environment Canada to
acknowledgement
element
[45]:
root.find('.//recursive').text = 'false'
find_att(root, 'license').text += '''
This dataset is derived from a product of the Environment Canada HRDPS (High Resolution Deterministic Prediction System)
model. The Terms and conditions of use of Meteorological Data from Environment Canada are available at
https://dd.weather.gc.ca/doc/LICENCE_GENERAL.txt.</att>'''
find_att(root, 'acknowledgement').text += ', Environment Canada'
[47]:
for axis in root.findall('.//axisVariable'):
axis_name = axis.find('.//sourceName').text
if 'time' not in axis_name:
attrs = axis.find('.//addAttributes')
etree.SubElement(attrs, 'att', name='grid_spacing').text = 'null'
etree.SubElement(attrs, 'att', name='units').text = 'null'
etree.SubElement(attrs, 'att', name='long_name').text = axis_name.upper()
etree.SubElement(attrs, 'att', name='standard_name').text = axis_name
[48]:
print_tree(root)
<dataset type="EDDGridFromNcFiles" datasetID="ubcSSaSurfaceAtmosphereFieldsV1" active="true">
<reloadEveryNMinutes>10080</reloadEveryNMinutes>
<updateEveryNMillis>10000</updateEveryNMillis>
<fileDir>/results/forcing/atmospheric/GEM2.5/operational/</fileDir>
<recursive>false</recursive>
<fileNameRegex>.*ops_y\d{4}m\d{2}d\d{2}\.nc$</fileNameRegex>
<metadataFrom>last</metadataFrom>
<matchAxisNDigits>20</matchAxisNDigits>
<fileTableInMemory>false</fileTableInMemory>
<accessibleViaFiles>false</accessibleViaFiles>
<!-- sourceAttributes>
<att name="Conventions">CF-1.0</att>
<att name="GRIB2_grid_template" type="int">20</att>
<att name="History">Thu Mar 10 10:11:37 2016: ncks -4 -L4 -O /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d10.nc /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d10.nc
created by wgrib2</att>
<att name="NCO">4.4.2</att>
</sourceAttributes -->
<addAttributes>
<att name="cdm_data_type">Grid</att>
<att name="coverage_content_type">modelResult</att>
<att name="Conventions">CF-1.6, COARDS, ACDD-1.3</att>
<att name="History">null</att>
<att name="history">Thu Mar 10 10:11:37 2016: ncks -4 -L4 -O /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d10.nc /results/forcing/atmospheric/GEM2.5/operational/ops_y2016m03d10.nc
created by wgrib2</att>
<att name="infoUrl">https://salishsea-meopar-tools.readthedocs.org/en/latest/results_server/index.html#salish-sea-model-results</att>
<att name="institution">UBC EOAS</att>
<att name="institution_fullname">Earth, Ocean & Atmospheric Sciences, University of British Columbia</att>
<att name="keywords">atmosphere,
Atmosphere > Atmospheric Water Vapor > Humidity,
atmospheric, atmpres, component, data, downward, flux, humidity, level, local, long, long-wave, mean, msl, precipitation, pressure, qair, rad, radiation, rain, rainfall, reduced, sea, seawater, short, short-wave, solar, source, specific, specific_humidity, tair, temperature, therm_rad, time_counter, total, u-component, u_wind, v-component, v_wind, vapor, water, wave, wind</att>
<att name="keywords_vocabulary">GCMD Science Keywords</att>
<att name="license">The Salish Sea MEOPAR NEMO model results are copyright 2013-2021
by the Salish Sea MEOPAR Project Contributors and The University of British Columbia.
They are licensed under the Apache License, Version 2.0. http://www.apache.org/licenses/LICENSE-2.0
This dataset is derived from a product of the Environment Canada HRDPS (High Resolution Deterministic Prediction System)
model. The Terms and conditions of use of Meteorological Data from Environment Canada are available at
http://dd.weather.gc.ca/doc/LICENCE_GENERAL.txt.</att></att>
<att name="standard_name_vocabulary">CF Standard Name Table v29</att>
<att name="summary">HRDPS, Salish Sea, Atmospheric Forcing Fields, Hourly, v1
2d hourly atmospheric field values from the
Environment Canada HRDPS atmospheric forcing model that are used to force the Salish Sea NEMO model.
The model grid includes the Juan de Fuca Strait, the Strait of Georgia, Puget Sound,
and Johnstone Strait on the coasts of Washington State and British Columbia.
Geo-location data for the atmospheric forcing grid are available in the ubcSSaAtmosphereGridV1 dataset.
Atmospheric field values are interpolated on to the Salish Sea NEMO model grid (ubcSSnBathymetry2V1 dataset)
on-the-fly by NEMO.
v1: atmospheric pressure, precipitation rate, 2m specific humidity, 2m air temperature,
short-wave radiation flux, long-wave radiation flux, 10m u wind component, 10m v wind component variables</att>
<att name="title">HRDPS, Salish Sea, Atmospheric Forcing Fields, Hourly, v1</att>
<att name="project">Salish Sea MEOPAR NEMO Model</att>
<att name="creator_name">Salish Sea MEOPAR Project Contributors</att>
<att name="creator_email">sallen@eos.ubc.ca</att>
<att name="creator_url">https://salishsea-meopar-docs.readthedocs.org/</att>
<att name="acknowledgement">MEOPAR, ONC, Compute Canada, Environment Canada</att>
<att name="drawLandMask">over</att>
</addAttributes>
<axisVariable>
<sourceName>time_counter</sourceName>
<destinationName>time</destinationName>
<!-- sourceAttributes>
<att name="_ChunkSize" type="int">1</att>
<att name="long_name">verification time generated by wgrib2 function verftime()</att>
<att name="reference_date">2016.03.09 18:00:00 UTC</att>
<att name="reference_time" type="double">1.4575464E9</att>
<att name="reference_time_description">kind of product unclear, reference date is variable, min found reference date is given</att>
<att name="reference_time_type" type="int">0</att>
<att name="time_origin">1970-Jan-01 00:00:00</att>
<att name="time_step" type="double">3600.0</att>
<att name="time_step_setting">auto</att>
<att name="units">seconds since 1970-01-01 00:00:00.0 0:00</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="standard_name">time</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>y</sourceName>
<destinationName>gridY</destinationName>
<!-- sourceAttributes>
<att name="_ChunkSize" type="int">266</att>
<att name="grid_spacing" type="double">2500.0</att>
<att name="long_name">y coordinate of projection</att>
<att name="standard_name">projection_y_coordinate</att>
<att name="units">m</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="grid_spacing">null</att>
<att name="units">null</att>
<att name="long_name">Y</att>
<att name="standard_name">y</att>
</addAttributes>
</axisVariable>
<axisVariable>
<sourceName>x</sourceName>
<destinationName>gridX</destinationName>
<!-- sourceAttributes>
<att name="_ChunkSize" type="int">256</att>
<att name="grid_spacing" type="double">2500.0</att>
<att name="long_name">x coordinate of projection</att>
<att name="standard_name">projection_x_coordinate</att>
<att name="units">m</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="grid_spacing">null</att>
<att name="units">null</att>
<att name="long_name">X</att>
<att name="standard_name">x</att>
</addAttributes>
</axisVariable>
<dataVariable>
<sourceName>atmpres</sourceName>
<destinationName>atmpres</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">mean sea level</att>
<att name="long_name">Pressure Reduced to MSL</att>
<att name="short_name">PRMSL_meansealevel</att>
<att name="units">Pa</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>precip</sourceName>
<destinationName>precip</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">surface</att>
<att name="long_name">Total Precipitation</att>
<att name="short_name">APCP_surface</att>
<att name="units">kg/m^2</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="colorBarMaximum" type="double">200.0</att>
<att name="colorBarMinimum" type="double">0.0</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>qair</sourceName>
<destinationName>qair</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">2 m above ground</att>
<att name="long_name">Specific Humidity</att>
<att name="short_name">SPFH_2maboveground</att>
<att name="units">kg/kg</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="colorBarMaximum" type="double">128.0</att>
<att name="colorBarMinimum" type="double">0.0</att>
<att name="coordinates">null</att>
<att name="standard_name">specific_humidity</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>solar</sourceName>
<destinationName>solar</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">surface</att>
<att name="long_name">Downward Short-Wave Radiation Flux</att>
<att name="short_name">DSWRF_surface</att>
<att name="units">W/m^2</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="colorBarMaximum" type="double">500.0</att>
<att name="colorBarMinimum" type="double">-500.0</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>tair</sourceName>
<destinationName>tair</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">2 m above ground</att>
<att name="long_name">Temperature</att>
<att name="short_name">TMP_2maboveground</att>
<att name="units">K</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="colorBarMaximum" type="double">313.0</att>
<att name="colorBarMinimum" type="double">263.0</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>therm_rad</sourceName>
<destinationName>therm_rad</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">surface</att>
<att name="long_name">Downward Long-Wave Rad. Flux</att>
<att name="short_name">DLWRF_surface</att>
<att name="units">W/m^2</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>u_wind</sourceName>
<destinationName>u_wind</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">10 m above ground</att>
<att name="long_name">U-Component of Wind</att>
<att name="short_name">UGRD_10maboveground</att>
<att name="units">m/s</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
<dataVariable>
<sourceName>v_wind</sourceName>
<destinationName>v_wind</destinationName>
<dataType>float</dataType>
<!-- sourceAttributes>
<att name="_ChunkSize" type="intList">1 266 256</att>
<att name="_FillValue" type="float">9.999E20</att>
<att name="coordinates">longitude latitude</att>
<att name="level">10 m above ground</att>
<att name="long_name">V-Component of Wind</att>
<att name="short_name">VGRD_10maboveground</att>
<att name="units">m/s</att>
</sourceAttributes -->
<addAttributes>
<att name="_ChunkSize">null</att>
<att name="coordinates">null</att>
</addAttributes>
</dataVariable>
</dataset>
[49]:
with open('/results/erddap-datasets/fragments/{}.xml'.format(datasetID), 'wb') as f:
f.write(etree.tostring(root, pretty_print=True))