source: flexpart.git/flexpart-testing/flextest/FlexpartErrors.py @ 29feaef

FPv9.3.1FPv9.3.1b_testingFPv9.3.2fp9.3.1-20161214-nc4grib2nc4_repair
Last change on this file since 29feaef was 496c607, checked in by Don Morton <Don.Morton@…>, 8 years ago

Initial commit of FPv9.3.1

Currently, this is a clone of snapshot FPv9.3.0

  • Property mode set to 100644
File size: 15.4 KB
Line 
1# -*- coding: utf-8 -*-
2"""
3Created on Mon May  4 15:50:42 2015
4
5@author: morton
6"""
7
8
9import logging
10import numpy as np
11
12class FlexpartErrors(object):
13
14
15    """
16    A class that takes two FlexpartOutput objects as input and provides
17    methods for calculation of errors on slices, volumes and timeseries.
18   
19    The following arguments are included in most of the calls to methods,
20    so are described here rather than in each method.  There are a variety
21    of combinations, which might get confusing, as not all arguments are
22    used in all cases.
23   
24    timestamp : If it has a value, and if this is not a timeseries, then
25    the indicated timestamp is used
26   
27    timestamp_list : if timeseries is True, then this will be used to provide
28    the list of timestamps to use. 
29   
30    level : specifies the level to use for a slice.  Indexed from 1.
31   
32    level_list : if volume is True, then this will be used to provide the
33    list of levels to use.
34   
35    species : species number to use.  Indexed from 1
36   
37    release : release number to use.  Indexed from 1
38   
39    age_class : age_class number to use.  Indexed from 1
40   
41    wet : if True, use the wet deposition.  If dry is also True, the
42    result is non-deterministic
43   
44    dry : if True, use the dry deposition.  If wet is also True, the result
45    is non-deterministic
46   
47    timeseries : if True, then it will use a timeseries as defined in
48    timestamp_list.  If timestamp_list is None, then a timeseries of
49    all available timestamps will be used
50   
51    volume : if True, then it will use a volume as defined in level_list.
52    If level_list is None, then a volume of all available levels will be
53    used.
54    """
55
56
57
58
59
60   
61    def __init__(self, control=None, test=None):
62       
63        """
64        Constructor
65        control: a FlexpartOutput object to be used as control data
66        test: a FlexpartOutput object to be used as test data
67        """
68       
69        # Let's do a bit of a sanity check on equal dimensions.  Get
70        # a default volume from each and compare
71        # the dimensions.  Also check that timestamps are the same. 
72
73
74        control_volume_shape = control.get_volume().shape
75        test_volume_shape = test.get_volume().shape
76       
77        control_timestamps = control.get_timestamp_list()
78        test_timestamps = test.get_timestamp_list()       
79
80        if control_volume_shape == test_volume_shape and \
81            control_timestamps == test_timestamps:
82           
83            self._control_output = control
84            self._test_output = test
85           
86        else:
87               
88            print '** WARNING - FlexpartErrors __init__():'
89            print '    control and test volume shapes are not the same, and/or'
90            print '    control and test timestamps are not the same'
91            print '        control_volume_shape: ', control_volume_shape
92            print '        test_volume_shape: ', test_volume_shape
93            print '        control_timestamps: ', control_timestamps
94            print '        test_timestamps: ', test_timestamps
95
96            self._control_output = None
97            self._test_output = None
98
99
100
101               
102    def get_diff_grid(self, timestamp=None, 
103                      timestamp_list=None,
104                      level=1,
105                      level_list=None,
106                      species=1,
107                      release=1,
108                      age_class=1,
109                      wet=False,
110                      dry=False,
111                      timeseries=False,
112                      volume=False):
113                         
114        """
115        Gets the difference grid as specified by the parameters.
116       
117        Note the True/False values of the last parameters:
118       
119
120        """
121       
122        # Extract grids from the control and test FlexpartOutput objects.
123        # The grid is defined by the various parameters.         
124        control_grid = self._get_grid(flexout_obj=self._control_output,
125                                      timestamp=timestamp,
126                                      timestamp_list=timestamp_list,
127                                      level=level,
128                                      level_list=level_list,
129                                      species=species,
130                                      release=release,
131                                      age_class=age_class,
132                                      wet=wet,
133                                      dry=dry,
134                                      timeseries=timeseries,
135                                      volume=volume)
136
137        test_grid = self._get_grid(flexout_obj=self._test_output,
138                                      timestamp=timestamp,
139                                      timestamp_list=timestamp_list,
140                                      level=level,
141                                      level_list=level_list,
142                                      species=species,
143                                      release=release,
144                                      age_class=age_class,
145                                      wet=wet,
146                                      dry=dry,
147                                      timeseries=timeseries,
148                                      volume=volume)
149
150        diff_grid = test_grid - control_grid
151       
152       
153        return diff_grid
154
155
156    def mean_absolute_error(self, timestamp=None, 
157                      timestamp_list=None,
158                      level=1,
159                      level_list=None,
160                      species=1,
161                      release=1,
162                      age_class=1,
163                      wet=False,
164                      dry=False,
165                      timeseries=False,
166                      volume=False):       
167        """
168        Returns the mean absolute error of the test and control grid, as
169        defined by the parameters
170        """
171
172        diff_grid = self.get_diff_grid(timestamp=timestamp,
173                                       timestamp_list=timestamp_list,
174                                       level=level,
175                                       level_list=level_list,
176                                       species=species,
177                                       release=release,
178                                       age_class=age_class,
179                                       wet=wet,
180                                       dry=dry,
181                                       timeseries=timeseries,
182                                       volume=volume)
183                                       
184        return np.absolute(diff_grid).mean() 
185
186
187    def max_absolute_error(self, timestamp=None, 
188                      timestamp_list=None,
189                      level=1,
190                      level_list=None,
191                      species=1,
192                      release=1,
193                      age_class=1,
194                      wet=False,
195                      dry=False,
196                      timeseries=False,
197                      volume=False):       
198        """
199        Returns the max absolute error of the test and control grid, as
200        defined by the parameters
201        """
202
203        diff_grid = self.get_diff_grid(timestamp=timestamp,
204                                       timestamp_list=timestamp_list,
205                                       level=level,
206                                       level_list=level_list,
207                                       species=species,
208                                       release=release,
209                                       age_class=age_class,
210                                       wet=wet,
211                                       dry=dry,
212                                       timeseries=timeseries,
213                                       volume=volume)
214                                       
215        return np.absolute(diff_grid).max() 
216
217   
218    def max_error(self, timestamp=None, 
219                      timestamp_list=None,
220                      level=1,
221                      level_list=None,
222                      species=1,
223                      release=1,
224                      age_class=1,
225                      wet=False,
226                      dry=False,
227                      timeseries=False,
228                      volume=False):       
229        """
230        Returns the max error of the test and control grid, as
231        defined by the parameters. 
232        NOTE - I "think" this is the same as max_abs_error as written,
233        and maybe shouldn't have the key=abs...
234        """
235
236        diff_grid = self.get_diff_grid(timestamp=timestamp,
237                                       timestamp_list=timestamp_list,
238                                       level=level,
239                                       level_list=level_list,
240                                       species=species,
241                                       release=release,
242                                       age_class=age_class,
243                                       wet=wet,
244                                       dry=dry,
245                                       timeseries=timeseries,
246                                       volume=volume)
247                                       
248        return max(diff_grid.max(), diff_grid.min(), key=abs) 
249
250
251    def mean_bias(self, timestamp=None, 
252                      timestamp_list=None,
253                      level=1,
254                      level_list=None,
255                      species=1,
256                      release=1,
257                      age_class=1,
258                      wet=False,
259                      dry=False,
260                      timeseries=False,
261                      volume=False):       
262        """
263        Returns the mean of the biases of the test and control grid, as
264        defined by the parameters
265        """
266
267        diff_grid = self.get_diff_grid(timestamp=timestamp,
268                                       timestamp_list=timestamp_list,
269                                       level=level,
270                                       level_list=level_list,
271                                       species=species,
272                                       release=release,
273                                       age_class=age_class,
274                                       wet=wet,
275                                       dry=dry,
276                                       timeseries=timeseries,
277                                       volume=volume)
278                                       
279        return diff_grid.mean() 
280
281
282    def rmse(self, timestamp=None, 
283                      timestamp_list=None,
284                      level=1,
285                      level_list=None,
286                      species=1,
287                      release=1,
288                      age_class=1,
289                      wet=False,
290                      dry=False,
291                      timeseries=False,
292                      volume=False):       
293        """
294        Returns the root mean square error of the test and control grid, as
295        defined by the parameters
296        """
297
298        diff_grid = self.get_diff_grid(timestamp=timestamp,
299                                       timestamp_list=timestamp_list,
300                                       level=level,
301                                       level_list=level_list,
302                                       species=species,
303                                       release=release,
304                                       age_class=age_class,
305                                       wet=wet,
306                                       dry=dry,
307                                       timeseries=timeseries,
308                                       volume=volume)
309                                       
310        return np.sqrt( ( diff_grid**2).mean() )
311
312
313        return diff_grid.max() 
314
315
316
317
318
319
320       
321       
322    def _get_grid(self, flexout_obj=None,
323                      timestamp=None, 
324                      timestamp_list=None,
325                      level=1,
326                      level_list=None,
327                      species=1,
328                      release=1,
329                      age_class=1,
330                      wet=False,
331                      dry=False,
332                      timeseries=False,
333                      volume=False):
334
335
336                         
337        """
338        Gets the grid as specified by the parameters.  This is a private
339        method and flexout_obj is intended to be the control or test grid
340        that this class contains.
341       
342        Note the True/False values of the last parameters.  They will
343        dictate the flow of this routine.
344        """
345
346        if not timeseries and not volume:
347            # horiz slices
348
349            if not wet and not dry:
350                the_grid = flexout_obj.get_horiz_slice(
351                        timestamp=timestamp,
352                        level=level,
353                        species=species,
354                        release=release,
355                        age_class=age_class)
356
357            else:
358
359                if wet and dry:
360                    logging.error("Bad options - cannot specify both wet and dry")
361                    the_grid = None
362                else:
363                    if wet: depo_type = 'wet'
364                    if dry: depo_type = 'dry'
365                   
366                    the_grid = flexout_obj.get_deposition(
367                            timestamp=timestamp,
368                            species=species,
369                            release=release,
370                            age_class=age_class,
371                            depo_type=depo_type)
372                       
373           
374        elif volume and not timeseries:
375            # Volume grid
376            the_grid = flexout_obj.get_volume(
377                    timestamp=timestamp,
378                    level_list=level_list,
379                    species=species,
380                    release=release,
381                    age_class=age_class)           
382
383           
384        elif timeseries and not volume:
385            # Timeseries of horiz slices
386       
387            if not wet and not dry:       
388                the_grid = flexout_obj.get_horiz_timeseries(
389                        timestamp_list=timestamp_list,
390                        level=level,
391                        species=species,
392                        release=release,
393                        age_class=age_class)                     
394
395
396            else:
397
398                if wet and dry:
399                    logging.error("Bad options - cannot specify both wet and dry")
400                    the_grid = None
401                else:
402                    if wet: depo_type = 'wet'
403                    if dry: depo_type = 'dry'
404
405                    the_grid = flexout_obj.get_deposition_timeseries(
406                            timestamp_list=timestamp_list,
407                            species=species,
408                            release=release,
409                            age_class=age_class,
410                            depo_type=depo_type)
411
412           
413        elif timeseries and volume:
414            # Timeseries of volumes
415            the_grid = flexout_obj.get_volume_timeseries(
416                    timestamp_list=timestamp_list,
417                    level_list=level_list,
418                    species=species,
419                    release=release,
420                    age_class=age_class)                     
421
422        else:
423            # If we made it here, we have bad combination of options
424            # and can't select a routine to generate the the_grid
425            logging.error("Bad options - cannot generate a the_grid")
426            the_grid = None
427       
428        return the_grid
429
430
431       
432       
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG