source: lmdz_wrf/trunk/tools/checking_output.py @ 549

Last change on this file since 549 was 403, checked in by lfita, 10 years ago

Adding 'ALB' on the list of varibales

File size: 11.1 KB
RevLine 
[401]1## Python script to check model outputs within a given set of values from an external ASII file
2# L. Fita, LMD. April 2015
3## e.g. # checking_output.py -f histins.nc -v t2m -l 'limitsVariables.inf'
[403]4## e.g. # python checking_output.py -f limit.nc -v SST,ALB -l 'limitsVariables.inf'
[401]5# NOTE:
6# `nc_var_tools.py' set of python scripts is required
7# can be found in subversion `http://svn.lmd.jussieu.fr/LMDZ_WRF/trunk/tools/nc_var_tools.py'
8import numpy as np
9from netCDF4 import Dataset as NetCDFFile
10import os
11import re
12from optparse import OptionParser
13import nc_var_tools as ncvar
14
15main = 'checking_output.py'
16version = 0.1
17author = 'L. Fita'
18institution = 'Laboratoire de Meteorologie Dynamique'
19city = ' Paris'
20country = 'France'
21
22errormsg = 'ERROR -- error -- ERROR -- error'
23warnmsg = 'WARNING -- warning -- WARNING -- warning'
24
25fillValue = 1.e20
26
27def compute_stddev(vals):
28    """ Function to compute standard deviation
29      vals= values
30    """
31    fname = 'compute_stddev'
32
33    mvals = np.mean(vals)
34    m2vals = np.mean(vals*vals)
35
36    stddev = np.sqrt(m2vals - mvals*mvals)
37
38    return stddev
39
40def checking(cn,valc,vern,lval,Vn):
41    """ Function to check a variable with
42      cn= checking name
43      valc= value to check
44      vern= verification value
45      lval= value to use for checking
46      Vn= variable name
47    """
48    fname = 'checking'
49
50    VerN = vern[0:1]
51
52    good = True
53    if VerN == '<' and valc < lval:
54        print warnmsg
55        print '  ' + fname + "  variable '" + vn + "' has a '" +cn+ "'",valc,vern,lval
56        good = False
57    elif VerN == '>' and valc > lval:
58        print warnmsg
59        print '  ' + fname + "  variable '" + vn + "' has a '" +cn+ "'",valc,vern,lval
60        good = False
61    elif VerN == '%' and np.abs((valc-lval)*100./lval)>np.float(vern[1:len(vern)+1]):
62        print warnmsg
63        print '  ' + fname + "  variable '" + vn + "' has a '" +cn+ "'", valc, '>',  \
64          VerN, np.float(vern[1:len(vern)+1]), 'than',lval
65        good = False
66
67    return good
68
69
70####### ###### ##### #### ### ## #
71
72parser = OptionParser()
73parser.add_option("-f", "--file", dest="ncfile",
74  help="file to check", metavar="FILE")
75parser.add_option("-v", "--variable", dest="varns",
76  help="var to check (',' list of variables; 'all', for all variables)", metavar="VALUE")
77parser.add_option("-l", "--ASCIIvarlimits", dest="lfile",
78  help="ASCII file with the limits for the variables (long explanation with -l h)", metavar="FILE")
79
80(opts, args) = parser.parse_args()
81
82#######    #######
83## MAIN
84    #######
85
86# Available statistics
87Availablestats = ['min', 'max', 'mean', 'stddev']
[402]88LAvailablestats = {'min':'minimum', 'max':'maximum', 'mean':'mean',                  \
89  'stddev':'standard deviation'}
90
[401]91Availableverifs = ['<', '>', '%']
[402]92SAvailableverifs = {'<':'lt', '>':'gt', '%':'percen'}
93LAvailableverifs = {'<':'smaller', '>':'bigger', '%':'percentage'}
[401]94
95#######
96ofile = 'wrongvariables.nc'
97
98if not os.path.isfile(opts.ncfile):
99    print errormsg
100    print '   ' + main + ": file '" + opts.ncfile + "' does not exist !!"
101    quit(-1)
102
103if opts.varns is None:
104    print warnmsg
105    print '   ' + main + ": no variables given!!"
106    print '    checking all'
107    varns = 'all'
108else:
109    varns = opts.varns
110
111if opts.lfile is None:
112    print warnmsg
113    print '   ' + main + ": no ASCII file with limits for the variables is given!!"
114    quit(-1)
115elif opts.lfile == 'h':
116    print 'HELP: ASCII limits of the variables_____________'
117    print 'First line: varname [stat1] [stat2] .... [statn]'
118    print 'Second line: - [verif1] [verif2] ... [verifn]'
119    print 'afterwards: [varname] [value1] [value2] ... [valuen]'
120    print '  [stat]: statistics/parameter to compute. Has to exist wihin the script'
121    print '    directly with an if or as function compute[stat]. Available ones are:'
122    print '    ',Availablestats
123    print '  [verif]: verification to make with the stat'
124    print '    <: Error if variable has values smaller than the limit'
125    print '    >: Error if variable has values bigger than the limit'
126    print '    %N: Error if variable has values +/- N % than the limit'
127    quit()
128
129ncobj = NetCDFFile(opts.ncfile, 'r')
130filevars = ncobj.variables.keys()
131
132# Getting variables names
133if varns == 'all':
134    vns = filevars
135else:
136    vns = opts.varns.split(',')
137
138Nvars = len(vns)
139print "From file '" + opts.ncfile + "' checking",Nvars,'variables...'
140
141# Getting ASCII file and its values
142##
143# Assuming first line with something like varname min max mean stddev
144# Continuted with a line for each variable and value like:
145# t2m -70. 50. 20. 40.
146# (...)
147# It is required than this script some function called compute_[value] must be placed
148# '#' for comment
149olval = open(opts.lfile, 'r')
150ili = 0
151statsverif = {}
152limitvals = {}
153
154for line in olval:
155    linevals = ncvar.reduce_spaces(line)
156    if len(linevals) != 0 and linevals[0][0:0] != '#':
157#        print ili,linevals
158        if ili == 0:
159            NVals = len(linevals) - 1
160            stats = linevals[1:NVals + 1]
161        elif ili == 1:
162            for ist in range(NVals):
163                statsverif[stats[ist]] = linevals[1+ist]
164        else:
165            limitvals[linevals[0]] = np.zeros((NVals), dtype=np.float)
166            for ist in range(NVals):
167                limitvals[linevals[0]][ist] = np.float(linevals[1+ist])
168
169    ili = ili + 1
170
171# Checking stats to compute
172for st in stats:
173    if not ncvar.searchInlist(Availablestats,st):
174        print errormsg
175        print '  ' + main + ": statistics/value '" + st + "' not ready!!"
176        print '    available parameters:', Availablestats
177        quit(-1)
178
179# Checking verifiaction to make
180for st in stats:
181    verin = statsverif[st]
182    if not ncvar.searchInlist(Availableverifs,verin[0:1]):
183        print errormsg
184        print '  ' + main + ": verification '" + verin + "' not ready!!"
185        print '    available verifications:', Availableverifs
186        quit(-1)
187
188print 'Checking',NVals,'parameters:',stats,'verifyed as:',statsverif.values()
189
[402]190# Creating output file
191oobj = NetCDFFile(ofile, 'w')
192
193# Dimensinos
194newdim = oobj.createDimension('stats', NVals)
195newdim = oobj.createDimension('verif', NVals)
196newdim = oobj.createDimension('checks', 2)
197newdim = oobj.createDimension('Lstring', 50)
198
199# Variables with Dimensions values
200newvar = oobj.createVariable('stats', 'c', ('stats', 'Lstring'))
201newattr = ncvar.basicvardef(newvar, 'stats', 'statistics/parameters used to check',  \
202  '-')
203newvals = ncvar.writing_str_nc(newvar, stats, 50)
204
205newvar = oobj.createVariable('verifs', 'c', ('stats', 'Lstring'))
206newattr = ncvar.basicvardef(newvar, 'verifs', 'verifications used to check', '-')
207newvals = ncvar.writing_str_nc(newvar, stats, 50)
208
209newvar = oobj.createVariable('checks', 'c', ('checks', 'Lstring'))
210newattr = ncvar.basicvardef(newvar, 'checks', 'values used to check', '-')
211newvals = ncvar.writing_str_nc(newvar, ['computed', 'limits'], 50)
212
213# Global attributes
214newattr = ncvar.set_attribute(oobj, 'script', main)
215newattr = ncvar.set_attribute(oobj, 'version', version)
216newattr = ncvar.set_attribute(oobj, 'author', author)
217newattr = ncvar.set_attribute(oobj, 'institution', institution)
218newattr = ncvar.set_attribute(oobj, 'city', city)
219newattr = ncvar.set_attribute(oobj, 'country', country)
220
221newattr = ncvar.set_attribute(oobj, 'description', 'Variables from ' + opts.ncfile + \
222  ' with a wrong value according to ' + opts.lfile)
223
224oobj.sync()
225
[401]226# Getting netCDF file and its values
227##
228valsstats = np.zeros((NVals,Nvars), dtype = np.float)
229wrongVars = {}
230iv = 0
231for iv in range(Nvars):
232    vn = vns[iv]
233    print vn + '...'
234    if not ncvar.searchInlist(filevars, vn):
235        print errormsg
236        print '  ' + main + ": file '" + opts.ncfile + "' does not have variable '" +\
237          vn + "' !!"
238        quit(-1)
239
240    vals = ncobj.variables[vn][:]
241    wrongstats = []
242    for ist in range(NVals):
243        stn = stats[ist]
[402]244        Lstn = LAvailablestats[stn]
[401]245        statpos = stats.index(stn)
246        limitval = limitvals[vn][statpos]
247        verif = statsverif[stn]
248#        print '  ', ist, stn, ':',limitval,verif
249        if stn == 'max':
250            valsstats[ist,iv] = np.max(vals)
251        elif stn == 'mean':
252            valsstats[ist,iv] = np.mean(vals)
253        elif stn == 'min':
254            valsstats[ist,iv] = np.min(vals)
255        elif stn == 'stddev':
256            valsstats[ist,iv] = compute_stddev(vals)
257
258# checks
259        if not checking(stn,valsstats[ist,iv],verif,limitval,vn):
[402]260            vval = valsstats[ist,iv]
261            Sverif = SAvailableverifs[verif[0:1]]
262            Lverif = LAvailableverifs[verif[0:1]]
263            if verif[0:1] != '<' and verif[0:1] != '>':
264                Vverif = np.float(verif[1:len(verif)])
265                VverifS = str(Vverif)
266            else:
267                VverifS = ''
268
[401]269            wrongstats.append(stn)
[402]270            if not ncvar.searchInlist(oobj.variables.keys(), vn):
271                oobj.close()
272                ncvar.fvaradd(opts.ncfile + ':' + vn, ofile)
[401]273
[402]274            oobj = NetCDFFile(ofile ,'a')
275            vobj = oobj.variables[vn]
276            if ncvar.searchInlist(vobj.ncattrs(),('units')):
277                vunits = vobj.getncattr('units')
278            else:
279                vunits = '-'
280
281            dims = vobj.dimensions
282# 1/0 Matrix with wrong values
283            if stn == 'max':
284                wrongvals = np.where(vals > limitval, 1, 0)
285                newvar = oobj.createVariable(vn+'Wrong'+stn+Sverif, 'i', dims)
286                newattr = ncvar.basicvardef(newvar, vn+'_wrong_'+stn+'_'+Sverif,     \
287                  'wrong ' + vn + ' ' + str(vval) + ' ' + Lstn + ' ' + VverifS + ' '+\
288                  Lverif + ' ' + str(limitval), vunits)
289                newvar[:] = wrongvals
290            elif stn == 'mean':
291                newattr = ncvar.set_attribute(vobj, 'wrong_'+stn+'_'+Sverif+VverifS, \
292                  'wrong ' + vn + ' ' + str(vval) + ' ' + Lstn + ' ' + VverifS + ' '+\
293                  Lverif + ' ' + str(limitval))
294            elif stn == 'min':
295                wrongvals = np.where(vals < limitval, 1, 0)
296                newvar = oobj.createVariable(vn+'Wrong'+stn+Sverif, 'i', dims)
297                newattr = ncvar.basicvardef(newvar, vn+'_wrong_'+stn+'_'+Sverif,     \
298                  'wrong ' + vn + ' ' + str(vval) + ' ' + Lstn + ' ' + VverifS + ' '+\
299                  Lverif + ' ' + str(limitval), vunits)
300                newvar[:] = wrongvals
301            elif stn == 'stddev':
302                newattr = ncvar.set_attribute(vobj, 'wrong_'+stn+'_'+Sverif+VverifS, \
303                  'wrong ' + vn + ' ' + str(vval) + ' ' + Lstn + ' ' + VverifS + ' '+\
304                  Lverif + ' ' + str(limitval))
305       
[401]306        if len(wrongstats) != 0: wrongVars[vn] = wrongstats
[402]307    newattr = ncvar.set_attribute(vobj, 'wrong',                                     \
308      ncvar.numVector_String(wrongVars[vn], ' '))
[401]309
[402]310    newvar = oobj.createVariable(vn + 'checks', 'f4', ('checks', 'stats'))
311    newattr = ncvar.basicvardef(newvar, vn + '_checks', vn +                         \
312      ' computed/checked', vunits)
313    for ist in range(NVals):
314        newvar[:,ist] = [valsstats[ist,iv], limitvals[vn][ist]]
[401]315
[402]316oobj.sync()
317oobj.close()
318
[401]319# Results
320##
321print ' Variables with Wrong results _______________________________________________'
322print wrongVars
323
[402]324print "succesfull writting of checking output file '" + ofile + "' !!"
Note: See TracBrowser for help on using the repository browser.