source: anuga_validation/automated_validation_tests/okushiri_tank_validation/compare_timeseries_with_measures.py @ 5183

Last change on this file since 5183 was 5183, checked in by ole, 16 years ago

Implemented a workaround the problem described in ticket:235
Windows machines will now do the automatic testing without attempting to plot.

File size: 7.5 KB
Line 
1"""Verify that simulation produced by ANUGA compares to published
2validation timeseries ch5, ch7 and ch9 as well as the boundary timeseries.
3
4RMS norm is printed and plots are produced as png files.
5No plots are shown on screen.
6"""
7
8from Numeric import allclose, argmin, argmax
9from Scientific.IO.NetCDF import NetCDFFile
10
11from anuga.abstract_2d_finite_volumes.util import file_function
12from anuga.utilities.numerical_tools import\
13     ensure_numeric, cov, get_machine_precision
14
15import project
16import sys
17
18if sys.platform == 'win32':
19    # Windows has a problem when this module is run through
20    # os.system as done by validate_okushiri.
21    # See https://datamining.anu.edu.au/anuga/ticket/235
22
23    # If you want to see the plots from this validation,
24    # run this module by itself with this if clause removed.
25    plotting = False
26   
27else:
28    try:
29        from pylab import ion, hold, plot, title, legend
30        from pylab import xlabel, ylabel, savefig
31    except:
32        print 'Could not import pylab'
33        plotting = False
34    else:
35        # Create plots as png files
36        plotting = True
37   
38
39#-------------------------
40# Basic data
41#-------------------------
42
43finaltime = 22.5
44timestep = 0.05
45
46gauge_locations = [[0.000, 1.696]] # Boundary gauge
47gauge_locations += [[4.521, 1.196],  [4.521, 1.696],  [4.521, 2.196]] #Ch 5-7-9
48gauge_names = ['Boundary', 'ch5', 'ch7', 'ch9']
49
50validation_data = {}
51for key in gauge_names:
52    validation_data[key] = []
53
54
55# Expected values
56expected_covariance = {'Boundary': 5.269569575007607815e-05, 
57                       'ch5': 1.166277999581819919e-04,
58                       'ch7': 1.127136457890861503e-04,
59                       'ch9': 1.250659477418482129e-04}
60
61expected_difference = {'Boundary': 8.350712673810733924e-04,
62                       'ch5': 3.405426180525532483e-03,
63                       'ch7': 2.852870417368218517e-03,
64                       'ch9': 3.248778982037564891e-03}
65
66expected_maximum = {'Boundary': 1.611749508386188523e-02, 
67                    'ch5': 3.551308418158714147e-02,
68                    'ch7': 3.858418457126511908e-02,
69                    'ch9': 4.317962986578308127e-02}
70
71expected_minimum = {'Boundary': -1.164547474575844919e-02, 
72                    'ch5': -8.664439185502026408e-03,
73                    'ch7': -2.726335488279797541e-03,
74                    'ch9': -5.977581218447349659e-03}
75
76expected_argmax = {'Boundary': 1.255000000000000071e+01, 
77                   'ch5': 1.839999999999999858e+01,
78                   'ch7': 1.700000000000000000e+01,
79                   'ch9': 1.685000000000000142e+01}
80
81expected_argmin = {'Boundary': 2.064999999999999858e+01, 
82                   'ch5': 1.459999999999999964e+01,
83                   'ch7': 1.230000000000000071e+01,
84                   'ch9': 1.315000000000000036e+01}
85
86#-------------------------
87# Read validation dataa
88#-------------------------
89
90print 'Reading', project.boundary_filename
91fid = NetCDFFile(project.boundary_filename, 'r')
92input_time = fid.variables['time'][:]
93validation_data['Boundary'] = fid.variables['stage'][:]
94
95reference_time = []
96fid = open(project.validation_filename)
97lines = fid.readlines()
98fid.close()
99
100for i, line in enumerate(lines[1:]):
101    if i == len(input_time): break
102   
103    fields = line.split()
104
105    reference_time.append(float(fields[0]))    # Record reference time
106    for j, key in enumerate(gauge_names[1:]):  # Omit boundary gauge
107        value = float(fields[1:][j])           # Omit time
108        validation_data[key].append(value/100) # Convert cm2m
109
110
111# Checks
112assert reference_time[0] == 0.0
113assert reference_time[-1] == finaltime
114assert allclose(reference_time, input_time)
115
116for key in gauge_names:
117    validation_data[key] = ensure_numeric(validation_data[key])
118
119#--------------------------------------------------
120# Read and interpolate model output
121#--------------------------------------------------
122
123import sys
124if len(sys.argv) > 1:
125    sww_filename = sys.argv[1]
126else:   
127    sww_filename = project.output_filename
128   
129f = file_function(sww_filename,
130                  quantities='stage',
131                  interpolation_points=gauge_locations,
132                  use_cache=True,
133                  verbose=True)
134
135
136def report_difference(name, computed_value, reference_value, rtol, atol):
137
138    if abs(reference_value) > 0:
139        msg = '%s (expected, computed):\n  (%.18e, %.18e):\n  Relative error=%.18e'\
140              %(name, reference_value, computed_value,
141                abs(reference_value-computed_value)/reference_value)
142        print msg
143       
144
145    msg = '  Absolute error=%.18e'\
146          %(abs(reference_value-computed_value))       
147    print msg
148
149   
150    #print 'Allclose:', allclose(reference_value, computed_value,
151    #                            rtol=rtol, atol=atol)
152    if plotting is False:
153        assert allclose(reference_value, computed_value,
154                        rtol=rtol, atol=atol), msg
155   
156
157
158#--------------------------------------------------
159# Compare model output to validation data
160#--------------------------------------------------
161
162
163#eps = get_machine_precision()
164
165# Windows tolerances
166rtol = 1.0e-2
167atol = 1.0e-3
168print 'Precisions used: rtol=%e, atol=%e' %(rtol, atol)
169
170for k, name in enumerate(gauge_names):
171
172    sqsum = 0
173    denom = 0
174    model = []
175    print 
176    print 'Validating ' + name
177    observed_timeseries = validation_data[name]
178    for i, t in enumerate(reference_time):
179        model.append(f(t, point_id=k)[0])
180
181    # Covariance measure   
182    res = cov(observed_timeseries, model)
183    report_difference('Covariance', res, expected_covariance[name], rtol, atol)
184     
185    # Difference measures   
186    res = sum(abs(observed_timeseries-model))/len(model)
187    report_difference('Accumulated difference', res,
188                      expected_difference[name], rtol, atol)   
189
190    # Extrema
191    res = max(model)
192    report_difference('Maximum', res, expected_maximum[name], rtol, atol)
193   
194    res = min(model)
195    report_difference('Minimum', res, expected_minimum[name], rtol, atol)   
196
197    # Locations of extrema
198    #i0 = argmax(observed_timeseries)
199    i1 = argmax(model)
200    res = reference_time[i1]
201    report_difference('Location of maximum', res, expected_argmax[name], rtol, atol)   
202   
203
204    if not name in ['ch7', 'ch9']:
205        # Minima of ch7 and ch9 are very flat and hard to pinpoint
206        i1 = argmin(model)
207        res = reference_time[i1]
208        report_difference('Location of minimum', res, expected_argmin[name],
209                          rtol, atol)       
210
211
212    if plotting is True:
213        #ion() # No plotting on screen
214        hold(False)
215   
216        plot(reference_time, validation_data[name], 'r-',
217             reference_time, model, 'k-')
218        title('Gauge %s' %name)
219        xlabel('time(s)')
220        ylabel('stage (m)')   
221        legend(('Observed', 'Modelled'), shadow=True, loc='upper left')
222        savefig(name, dpi = 300)       
223
224
225
226
227# Check max runup
228
229from anuga.shallow_water.data_manager import get_maximum_inundation_elevation
230from anuga.shallow_water.data_manager import get_maximum_inundation_location
231from anuga.utilities.polygon import is_inside_polygon
232
233q = get_maximum_inundation_elevation(sww_filename)
234loc = get_maximum_inundation_location(sww_filename)
235
236
237print 'Max runup elevation: ', q
238print 'Max runup elevation (scaled by 400): ', q*400
239print 'Max runup location:  ', loc
240
241
242from create_okushiri import gulleys
243assert is_inside_polygon(loc, gulleys)
244
245# FIXME more asserts here
246
247
248
249#msg = 'We got %f, should have been %f' %(q, q_max)
250#assert allclose(q, q_max, rtol=1.0/N), msg
251##print 'loc', loc, q
252#assert allclose(-loc[0]/2, q) # From topography formula
253
254print 'OK'
Note: See TracBrowser for help on using the repository browser.