Generate Climos¶
This process runs generate_climos, which creates files with climatological means/standard deviations of input data from a netcdf file.
In [1]:
from birdy import WPSClient
from netCDF4 import Dataset
import os
import re
from wps_tools.testing import get_target_url
from wps_tools.output_handling import auto_construct_outputs, txt_to_string, get_metalink_content, nc_to_dataset
In [2]:
# NBVAL_IGNORE_OUTPUT
url = get_target_url("thunderbird")
print(f"Using thunderbird on {url}")
Using thunderbird on https://marble-dev01.pcic.uvic.ca/twitcher/ows/proxy/thunderbird/wps
In [3]:
thunderbird = WPSClient(url)
In [4]:
# NBVAL_IGNORE_OUTPUT
# Check info on `generate_climos` process
thunderbird.generate_climos?
Signature: thunderbird.generate_climos( netcdf, operation, dry_run=None, convert_longitudes=True, split_vars=True, split_intervals=True, loglevel='INFO', climo=None, resolutions=None, ) Docstring: Generate files containing climatological means from input files of daily, monthly, or yearly data that adhere to the PCIC metadata standard (and consequently to CMIP5 and CF standards). Parameters ---------- netcdf : ComplexData:mimetype:`application/x-netcdf`, :mimetype:`application/x-ogc-dods` NetCDF file operation : {'mean', 'std'}string Operation to perform on the datasets climo : {'6190', '7100', '8110', '2020', '2050', '2080'}string Year ranges resolutions : {'all', 'yearly', 'seasonal', 'monthly'}string Temporal Resolutions convert_longitudes : boolean Transform longitude range from [0, 360) to [-180, 180) split_vars : boolean Generate a separate file for each dependent variable in the file split_intervals : boolean Generate a separate file for each climatological period dry_run : boolean Checks file to ensure compatible with process loglevel : {'CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'}string Logging level Returns ------- output : ComplexData:mimetype:`application/metalink+xml; version=4.0` Metalink object between output files dry_output : ComplexData:mimetype:`application/metalink+xml; version=4.0` Metalink object between dry output files File: ~/code/thunderbird/notebooks/</home/eyvorchuk/.cache/pypoetry/virtualenvs/thunderbird-7g6X3rbj-py3.10/lib/python3.10/site-packages/birdy/client/base.py-0> Type: method
Single File run¶
Dry Run - Checks file to ensure compatible with process
In [5]:
# Set up variables for thunderbird.generate_climos
daccs_host = os.getenv("DACCS_HOST", "marble-dev01.pcic.uvic.ca")
seasonal_opendap = f'https://{daccs_host}/twitcher/ows/proxy/thredds/dodsC/datasets/storage/data/projects/comp_support/daccs/test-data/fdd_seasonal_CanESM2_rcp85_r1i1p1_1951-2100.nc'
annual_opendap = f'https://{daccs_host}/twitcher/ows/proxy/thredds/dodsC/datasets/storage/data/projects/comp_support/daccs/test-data/gdd_annual_CanESM2_rcp85_r1i1p1_1951-2100.nc'
operation = 'mean'
climo = '6190'
resolutions = 'yearly'
dry_run = True
# Dry run process
dry_output = thunderbird.generate_climos(
netcdf=seasonal_opendap,
operation=operation,
climo=climo,
resolutions=resolutions,
dry_run=dry_run
)
Access the output with auto_construct_outputs() or get_metalink_content() with txt_to_string() from wps_tools.output_handling
In [6]:
# NBVAL_IGNORE_OUTPUT
auto_construct_outputs(dry_output.get())
Out[6]:
["Dry Run\ngenerate_climos:\nINFO:dp.generate_climos:Processing: https://marble-dev01.pcic.uvic.ca/twitcher/ows/proxy/thredds/dodsC/datasets/storage/data/projects/comp_support/daccs/test-data/fdd_seasonal_CanESM2_rcp85_r1i1p1_1951-2100.nc\nINFO:dp.generate_climos:climo_periods: {'6190'}\nINFO:dp.generate_climos:project: CMIP5\nINFO:dp.generate_climos:institution: PCIC\nINFO:dp.generate_climos:model: CanESM2\nINFO:dp.generate_climos:emissions: historical, rcp85\nINFO:dp.generate_climos:run: r1i1p1\nINFO:dp.generate_climos:dependent_varnames: ['fdd']\nINFO:dp.generate_climos:time_resolution: seasonal\nINFO:dp.generate_climos:is_multi_year_mean: False\n"]
In [7]:
# NBVAL_IGNORE_OUTPUT
meta_content = get_metalink_content(dry_output.get()[0])
print(meta_content)
txt_content = txt_to_string(meta_content[0])
print(txt_content)
['https://marble-dev01.pcic.uvic.ca/wpsoutputs/11cdc88a-1c66-11ef-8399-0242ac120003/fdd_seasonal_CanESM2_rcp85_r1i1p1_1951-2100_dry.txt'] Dry Run generate_climos: INFO:dp.generate_climos:Processing: https://marble-dev01.pcic.uvic.ca/twitcher/ows/proxy/thredds/dodsC/datasets/storage/data/projects/comp_support/daccs/test-data/fdd_seasonal_CanESM2_rcp85_r1i1p1_1951-2100.nc INFO:dp.generate_climos:climo_periods: {'6190'} INFO:dp.generate_climos:project: CMIP5 INFO:dp.generate_climos:institution: PCIC INFO:dp.generate_climos:model: CanESM2 INFO:dp.generate_climos:emissions: historical, rcp85 INFO:dp.generate_climos:run: r1i1p1 INFO:dp.generate_climos:dependent_varnames: ['fdd'] INFO:dp.generate_climos:time_resolution: seasonal INFO:dp.generate_climos:is_multi_year_mean: False
In [8]:
expected_items = ['6190', 'CMIP5', 'PCIC', 'CanESM2', 'historical', 'rcp85', 'r1i1p1', 'fdd', 'seasonal']
for item in expected_items:
assert item in txt_content
Normal Run
In [9]:
# generate climos
output = thunderbird.generate_climos(
netcdf=seasonal_opendap,
operation=operation,
climo=climo,
resolutions=resolutions,
dry_run=False
)
In [10]:
""" Helper function to test netCDF file output -
Creating a 30 year average with this process given the parameters should squash the time
dimension down from x (where x is the number of days in the input data) to 1 in the output data.
"""
def test_nc_data(url):
output_data = nc_to_dataset(url)
assert output_data.dimensions['time'].size == 1
In [11]:
# Test normal output data
url = get_metalink_content(output.get()[0])
test_nc_data(url[0])
Multiple File Run¶
Dry Run - Checks files to ensure compatible with process
In [12]:
# process dry run for multiple files
dry_output = thunderbird.generate_climos(
netcdf=[seasonal_opendap, annual_opendap],
operation=operation,
climo=climo,
resolutions=resolutions,
dry_run=dry_run
)
In [13]:
# Test dry output for multiple files
metalinks = get_metalink_content(dry_output.get()[0])
assert len(metalinks) == 2
for link, tr in zip(metalinks, ['seasonal', 'yearly']):
output_data = txt_to_string(link)
assert re.search(r'time_resolution: {}'.format(tr), output_data)
Normal Run
In [14]:
# Process normal output for multiple files
output = thunderbird.generate_climos(
netcdf=[seasonal_opendap,annual_opendap],
operation=operation,
climo=climo,
resolutions=resolutions,
dry_run=False
)
In [15]:
# Test multiple files
metalinks = get_metalink_content(output.get()[0])
assert len(metalinks) == 2
for url in metalinks:
test_nc_data(url)