Skip to content

Commit cad8d4c

Browse files
committed
Add CI testing for climatology
1 parent 8af611d commit cad8d4c

File tree

6 files changed

+224
-0
lines changed

6 files changed

+224
-0
lines changed
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
"""
2+
Unit test infrastructure for the generalized_reader.
3+
4+
Xylar Asay-Davis
5+
02/16/2017
6+
"""
7+
8+
import pytest
9+
import tempfile
10+
import shutil
11+
import os
12+
import numpy
13+
14+
from mpas_analysis.test import TestCase, loaddatadir
15+
from mpas_analysis.shared.generalized_reader.generalized_reader \
16+
import open_multifile_dataset
17+
from mpas_analysis.configuration.MpasAnalysisConfigParser \
18+
import MpasAnalysisConfigParser
19+
from mpas_analysis.shared.climatology import climatology
20+
from mpas_analysis.shared.constants import constants
21+
22+
@pytest.mark.usefixtures("loaddatadir")
23+
class TestClimatology(TestCase):
24+
25+
def setUp(self):
26+
# Create a temporary directory
27+
self.test_dir = tempfile.mkdtemp()
28+
29+
def tearDown(self):
30+
# Remove the directory after the test
31+
shutil.rmtree(self.test_dir)
32+
33+
def setup_config(self, autocloseFileLimitFraction=0.5,
34+
maxChunkSize=10000):
35+
config = MpasAnalysisConfigParser()
36+
config.add_section('input')
37+
config.set('input', 'autocloseFileLimitFraction',
38+
str(autocloseFileLimitFraction))
39+
config.set('input', 'maxChunkSize', str(maxChunkSize))
40+
config.set('input', 'mpasMeshName', 'QU240')
41+
42+
config.add_section('output')
43+
config.set('output', 'baseDirectory', self.test_dir)
44+
config.set('output', 'mappingSubdirectory', '.')
45+
config.set('output', 'mpasClimatologySubdirectory', 'clim/mpas')
46+
config.set('output', 'mpasRegriddedClimSubdirectory',
47+
'clim/mpas/regrid')
48+
49+
config.add_section('climatology')
50+
config.set('climatology', 'startYear', '2')
51+
config.set('climatology', 'endYear', '2')
52+
config.set('climatology', 'comparisonLatResolution', '0.5')
53+
config.set('climatology', 'comparisonLonResolution', '0.5')
54+
55+
config.set('climatology', 'overwriteMapping', 'False')
56+
config.set('climatology', 'overwriteMpasClimatology', 'False')
57+
config.set('climatology', 'mpasInterpolationMethod', 'bilinear')
58+
59+
config.add_section('oceanObservations')
60+
config.set('oceanObservations', 'interpolationMethod', 'bilinear')
61+
config.set('oceanObservations', 'climatologySubdirectory', 'clim/obs')
62+
config.set('oceanObservations', 'regriddedClimSubdirectory',
63+
'clim/obs/regrid')
64+
65+
return config
66+
67+
def test_write_mpas_mapping_file(self):
68+
config = self.setup_config()
69+
mpasMeshFileName = str(self.datadir.join('mpasMesh.nc'))
70+
climatology.write_mpas_mapping_file(config, mpasMeshFileName)
71+
72+
mappingFileName = '{}/map_QU240_to_0.5x0.5degree_' \
73+
'bilinear.nc'.format(self.test_dir)
74+
assert os.path.exists(mappingFileName)
75+
76+
mappingFileName = '{}/mapping.nc'.format(self.test_dir)
77+
config.set('climatology', 'mpasMappingFile', mappingFileName)
78+
climatology.write_mpas_mapping_file(config, mpasMeshFileName)
79+
assert os.path.exists(mappingFileName)
80+
81+
def test_write_observations_mapping_file(self):
82+
config = self.setup_config()
83+
gridFileName = str(self.datadir.join('obsGrid.nc'))
84+
componentName = 'ocean'
85+
fieldName = 'sst'
86+
climatology.write_observations_mapping_file(config,
87+
componentName,
88+
fieldName,
89+
gridFileName,
90+
latVarName='lat',
91+
lonVarName='lon')
92+
93+
mappingFileName = '{}/map_obs_{}_1.0x1.0degree_to_0.5x0.5degree_' \
94+
'bilinear.nc'.format(self.test_dir, fieldName)
95+
assert os.path.exists(mappingFileName)
96+
97+
mappingFileName = '{}/mapping.nc'.format(self.test_dir)
98+
config.set('oceanObservations', 'sstClimatologyMappingFile',
99+
mappingFileName)
100+
climatology.write_observations_mapping_file(config,
101+
componentName,
102+
fieldName,
103+
gridFileName,
104+
latVarName='lat',
105+
lonVarName='lon')
106+
assert os.path.exists(mappingFileName)
107+
108+
def test_get_mpas_climatology_file_names(self):
109+
config = self.setup_config()
110+
fieldName = 'sst'
111+
monthNames = 'JFM'
112+
(climatologyFileName, regriddedFileName) = \
113+
climatology.get_mpas_climatology_file_names(config, fieldName,
114+
monthNames)
115+
expectedClimatologyFileName = '{}/clim/mpas/sst_QU240_JFM_' \
116+
'years0002-0002.nc'.format(self.test_dir)
117+
self.assertEqual(climatologyFileName, expectedClimatologyFileName)
118+
119+
expectedRegriddedFileName = '{}/clim/mpas/regrid/sst_QU240_to_' \
120+
'0.5x0.5degree_JFM_' \
121+
'years0002-0002.nc'.format(self.test_dir)
122+
self.assertEqual(regriddedFileName, expectedRegriddedFileName)
123+
124+
def test_get_observation_climatology_file_names(self):
125+
config = self.setup_config()
126+
fieldName = 'sst'
127+
monthNames = 'JFM'
128+
gridFileName = str(self.datadir.join('obsGrid.nc'))
129+
componentName = 'ocean'
130+
(climatologyFileName, regriddedFileName) = \
131+
climatology.get_observation_climatology_file_names(
132+
config, fieldName, monthNames, componentName, gridFileName,
133+
latVarName='lat', lonVarName='lon')
134+
expectedClimatologyFileName = '{}/clim/obs/sst_1.0x1.0degree_' \
135+
'JFM.nc'.format(self.test_dir)
136+
self.assertEqual(climatologyFileName, expectedClimatologyFileName)
137+
138+
expectedRegriddedFileName = '{}/clim/obs/regrid/sst_1.0x1.0degree_' \
139+
'to_0.5x0.5degree_' \
140+
'JFM.nc'.format(self.test_dir)
141+
self.assertEqual(regriddedFileName, expectedRegriddedFileName)
142+
143+
def open_test_ds(self, config, calendar):
144+
fileNames = ['{}/timeSeries.0002-{:02d}-01.nc'.format(self.datadir,
145+
month)
146+
for month in [1, 2, 3]]
147+
148+
variableMap = {'mld': ['timeMonthly_avg_tThreshMLD'],
149+
'Time': [['xtime_startMonthly', 'xtime_endMonthly']]}
150+
variableList = ['mld']
151+
152+
ds = open_multifile_dataset(
153+
fileNames=fileNames,
154+
calendar=calendar,
155+
config=config,
156+
timeVariableName='Time',
157+
variableList=variableList,
158+
variableMap=variableMap)
159+
160+
assert(len(ds.Time) == 3)
161+
return ds
162+
163+
def test_compute_climatology(self):
164+
config = self.setup_config()
165+
calendar = 'gregorian_noleap'
166+
ds = self.open_test_ds(config, calendar)
167+
168+
assert('month' not in ds.coords.keys())
169+
assert('daysInMonth' not in ds.coords.keys())
170+
171+
ds = climatology.add_months_and_days_in_month(ds, calendar)
172+
173+
self.assertArrayEqual(ds.month.values, [1, 2, 3])
174+
self.assertArrayEqual(numpy.round(ds.daysInMonth.values), [31, 28, 31])
175+
176+
monthNames = 'JFM'
177+
monthValues = constants.monthDictionary[monthNames]
178+
dsClimatology = climatology.compute_climatology(ds, monthValues,
179+
calendar)
180+
181+
assert('Time' not in dsClimatology.dims.keys())
182+
183+
self.assertEqual(dsClimatology.data_vars.keys(), ['mld'])
184+
185+
def test_compute_monthly_climatology(self):
186+
config = self.setup_config()
187+
calendar = 'gregorian_noleap'
188+
ds = self.open_test_ds(config, calendar)
189+
190+
monthlyClimatology = climatology.compute_monthly_climatology(ds,
191+
calendar)
192+
193+
assert(len(monthlyClimatology.month) == 3)
194+
195+
self.assertEqual(monthlyClimatology.data_vars.keys(), ['mld'])
196+
197+
def test_update_start_end_year(self):
198+
config = self.setup_config()
199+
calendar = 'gregorian_noleap'
200+
ds = self.open_test_ds(config, calendar)
201+
202+
changed, startYear, endYear = \
203+
climatology.update_start_end_year(ds, config, calendar)
204+
205+
assert(not changed)
206+
assert(startYear == 2)
207+
assert(endYear == 2)
208+
209+
config.set('climatology', 'endYear', '50')
210+
ds = self.open_test_ds(config, calendar)
211+
212+
with self.assertWarns('climatology start and/or end year different from requested'):
213+
changed, startYear, endYear = \
214+
climatology.update_start_end_year(ds, config, calendar)
215+
216+
assert(changed)
217+
assert(startYear == 2)
218+
assert(endYear == 2)
219+
220+
# vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_interpolate/mpasMesh.nc
5.3 KB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_interpolate/timeSeries.0002-01-01.nc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_interpolate/timeSeries.0002-02-01.nc
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../test_interpolate/timeSeries.0002-03-01.nc

0 commit comments

Comments
 (0)