source: lmdz_wrf/trunk/tools/generic.py @ 2445

Last change on this file since 2445 was 2433, checked in by lfita, 6 years ago

Fixing 'datetimeStr_conversion' for `cfTimeCal' output

File size: 19.5 KB
Line 
1# Wrapper for the generic functions written in python from 'generic_tools.py'
2# L. Fita, LMD. June 2016
3# Python to manage netCDF files.
4# From L. Fita work in different places: LMD (France)
5# More information at: http://www.xn--llusfb-5va.cat/python/PyNCplot
6#
7# pyNCplot and its component generic.py comes with ABSOLUTELY NO WARRANTY.
8# This work is licendes under a Creative Commons
9#   Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0)
10#
11
12from optparse import OptionParser
13import numpy as np
14import datetime as dt
15import generic_tools as gen
16
17main = 'generic.py'
18errormsg = 'ERROR -- error -- ERROR -- error'
19warnmsg = 'WARNING -- warning --WARNING -- warning'
20import os
21import re
22
23# ASCIIfile_stats: Function to provide the statistics of a series of values from an ASCII file
24# coincident_CFtimes: Function to make coincident times for two different sets of CFtimes
25# count_cond: Function to count values of a variable which attain a condition
26# create_LateX_figs: Function to create a LaTeX from a folder with multiple plots from different values
27# datetimeStr_conversion: Function to transform a string date to an another date object
28# get_right_CFtimeunits: Function to get the right CFtime units from any given format
29# grid_combinations: Function to provide all the possible grid points combination for a given pair of values
30#   x,y= pair of grid points
31# inf_operSlist: Function to provide information from a string as a list separated by
32#   a given character followig a given operation and a set of values
33# interpolate_locs: Function to provide interpolate locations on a given axis
34# PolyArea: Function to compute the area of the polygon following 'Shoelace formula'
35# radial_points: Function to provide a number of grid point positions for a given angle
36# radius_dist: Function to generate a matrix with the distance at a given point
37# rmNOnum: Removing from a string all that characters which are not numbers
38# running_mean: Function to compute a running mean of a series of values
39# significant_decomposition: Function to decompose a given number by its signifcant potencies
40# squared_radial: Function to provide the series of radii as composite of pairs (x,y) of gid cells
41#   Npt= largest amount of grid points on x and y directions
42# table_tex_file: Function to write into a file a LaTeX tabular from a table of values
43# unitsDate: Function to know how many units of time are from a given pair of dates
44# variables_values: Function to provide values to plot the different variables values from ASCII file
45# wdismean: Function to compute the mean value weighted to its 4 distances
46# WRFsetup: Function to check the set-up of a series of model namelist
47
48# Character to split passed values
49cS = ','
50# Character to split a serie of values
51cV = '@'
52# Character for spaces
53cE = '!'
54
55# List of available operations
56operations=['ASCIIfile_stats', 'coincident_CFtimes', 'count_cond',                   \
57  'create_LateX_figs', 'datetimeStr_conversion', 'get_right_CFtimeunits',            \
58  'grid_combinations', 'inf_operSlist',                                              \
59  'interpolate_locs', 'latex_fig_array', 'list_operations', 'PolyArea',              \
60  'radial_points', 'radius_dist',                                                    \
61  'rmNOnum', 'running_mean',                                                         \
62  'significant_decomposition', 'squared_radial',                                     \
63  'table_tex_file', 'unitsDate', 'variables_values', 'wdismean', 'WRFsetup']
64
65hundredvals = '0'
66for i in range(1,100): hundredvals = hundredvals + cV + str(i)
67
68vs100 = '0@1@2@3@4@5@6@7@8@9@10@11@12@13@14@15@16@17@18@19@20@21@22@23@24@25@26@27'
69vs100 = vs100 + '@28@29@30@31@32@33@34@35@36@37@38@39@40@41@42@43@44@45@46@47@48@49'
70vs100 = vs100 + '@50@51@52@53@54@55@56@57@58@59@60@61@62@63@64@65@66@67@68@69@70@71'
71va100 = vs100 + '@72@73@74@75@76@77@78@79@80@81@82@83@84@85@86@87@88@89@90@91@92@93'
72va100 = vs100 + '@94@95@96@97@98@99'
73
74## e.g. # generic.py -o 'coincident_CFtimes' -S '0@1@2@3@4@5@6@7@8@9,seconds since 1949-12-01 00:00:00,hours since 1949-12-01 00:00:00'
75## e.g. # generic.py -o count_cond -S 0@1@2@3@4@5@6@7@8@9,4,le
76## e.g. # generic.py -o datetimeStr_conversion -S '1976-02-17_08:32:05,Y-m-d_H:M:S,matYmdHMS'
77## e.g. # generic.py -o grid_combinations -S 1,2
78## e.g. # generic.py -o interpolate_locs -S -1.2@2.4@5.6@7.8@12.0,0.5@2.5,lin
79## e.g. # generic.py -o PolyArea -S -0.5@0.5@0.5@-0.5,0.5@0.5@-0.5@-0.5
80## e.g. # generic.py -o radial_points -S 0.785398163397,5
81## e.g. # generic.py -o radius_dist -S 3,5,2,2
82## e.g. # generic.py -o rmNOnum -S LMD123IPSL
83## e.g. # generic.py -o significant_decomposition -S 3.576,-2
84## e.g. # generic.py -o table_tex_file -S '5,3,0@5@10@1@6@11@2@7@12@3@8@13@4@9@14,!@a@b@c@d@e,i@ii@iii,table.tex'
85## e.g. # generic.py -o unitsDate -S '19490101000000,19760217082932,second'
86## e.g. # generic.py -o running_mean -S 0@1@2@3@4@5@6@7@8@9,10
87## e.g. # generic.py -o squared_radial -S 3
88## e.g. # generic.py -o variables_values -S 'hus'
89## e.g. # generic.py -o wdismean -S 0.005@0.005,0.@1.@2.@3.
90## e.g. # generic.py -o WRFsetup -S '/home/lluis/estudios/RELAMPAGO/SimCoor/UBA/namelist.input@/home/lluis/estudios/RELAMPAGO/SimCoor/SMN/namelist.input@/home/lluis/estudios/RELAMPAGO/SimCoor/NOA-IERSD/namelist.input@/home/lluis/estudios/RELAMPAGO/SimCoor/UBAmili/namelist.input,basic,textabrow'
91## e.g. # generic.py -o ASCIIfile_stats -S times_CDXWRF1.dat,#,R
92## e.g. # generic.py -o inf_operSlist -S '-98.21:1.2:3.45:100.1:34321.1,threshold,:,3.'
93## e.g. # generic.py -o create_LateX_figs -S '/home/lluis/estudios/FPS_ALPS/additional/IOP/analysis/figs,WindRose_obs_@SkewT-logP_obs_ta-tda@SkewT-logP_obs_evol@WindRose_obs-sim_step@SkewT-logP_obs-sim_step@SkewT-logP_obs-sim_evol,10868@16080@16144@16546,png'
94## e.g. # generic.py -o get_right_CFtimeunits -S 'minutes!since!1-1-1'
95
96operationnames = "'" + gen.numVector_String(operations, "', '") + "'"
97valuesinf = "'" + cS + "' list of values to use according to the operation ('" + cV +\
98  "' for list of values)"
99
100parser = OptionParser()
101parser.add_option("-o", "--operation", type='choice', dest="operation", 
102  choices=operations, help="operation to make: " + operationnames, metavar="OPER")
103parser.add_option("-S", "--valueS (when applicable)", dest="values", 
104  help=valuesinf, metavar="VALUES")
105(opts, args) = parser.parse_args()
106
107#######    #######
108## MAIN
109    #######
110oper = opts.operation
111
112if oper == 'list_operations':
113# From: http://www.diveintopython.net/power_of_introspection/all_together.html
114    object = gen
115    for opern in operations:
116        if  opern != 'list_operations': 
117            print opern + '_______ ______ _____ ____ ___ __ _'
118            print getattr(object, opern).__doc__
119
120elif oper == 'ASCIIfile_stats':
121    Nvals = 3
122    vals = opts.values.split(cS)
123    if vals[0] == 'h':
124        print gen.ASCIIfile_stats.__doc__
125        quit(-1)
126    else:
127        if len(vals) != Nvals:
128            print errormsg
129            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
130              len(vals), ' has passed!!'
131            print gen.ASCIIfile_stats.__doc__
132            quit(-1)
133        vals0 = vals[0]
134        vals1 = vals[1]
135        vals2 = vals[2]
136       
137        print gen.ASCIIfile_stats(vals0, vals1, vals2)
138
139elif oper == 'coincident_CFtimes':
140    Nvals = 3
141    vals = opts.values.split(cS)
142    if vals[0] == 'h':
143        print gen.coincident_CFtimes.__doc__
144        quit(-1)
145    else:
146        if len(vals) != Nvals:
147            print errormsg
148            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
149              len(vals), ' has passed!!'
150            print gen.coincident_CFtimes.__doc__
151            quit(-1)
152        vals0 = np.array(vals[0].split(cV), dtype=np.float)
153        print gen.coincident_CFtimes(vals0, vals[1], vals[2])
154
155elif oper == 'count_cond':
156    Nvals = 3
157    vals = opts.values.split(cS)
158    if vals[0] == 'h':
159        print gen.count_cond.__doc__
160        quit(-1)
161    else:
162        if len(vals) != Nvals:
163            print errormsg
164            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
165              len(vals), ' has passed!!'
166            print gen.count_cond.__doc__
167            quit(-1)
168        vals0 = np.array(vals[0].split(cV), dtype=np.float)
169        print gen.count_cond(np.array(vals[0].split(cV), dtype=np.float),           \
170          np.float(vals[1]), vals[2])
171
172
173elif oper == 'create_LateX_figs':
174    Nvals = 4
175    vals = opts.values.split(cS)
176    if vals[0] == 'h':
177        print gen.create_LateX_figs.__doc__
178        quit(-1)
179    else:
180        if len(vals) != Nvals:
181            print errormsg
182            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
183              len(vals), ' has passed!!'
184            print gen.create_LateX_figs.__doc__
185            quit(-1)
186        vals0 = vals[0]
187        vals1 = vals[1].split('@')
188        vals2 = vals[2].split('@')
189        vals3 = vals[3]
190       
191        print gen.create_LateX_figs(vals0, vals1, vals2, vals3)
192
193elif oper == 'datetimeStr_conversion':
194    Nvals = 3
195    vals = opts.values.split(cS)
196    if vals[0] == 'h':
197        print gen.datetimeStr_conversion.__doc__
198        quit(-1)
199
200    newvals = []
201    if vals[1] == 'cfTime':
202        newvals.append(vals[0])
203        newvals.append(vals[1]+','+vals[2])
204        if vals[2] == 'cfTime': 
205            newvals.append(vals[3]+','+vals[4].replace('!',' '))
206        else:
207            newvals.append(vals[2])
208    elif vals[1] == 'cfTimeCal':
209        newvals.append(vals[0])
210        newvals.append(vals[1]+','+vals[2]+','+vals[3])
211        if vals[2] == 'cfTimeCal': newvals.append(vals[3] + ',' +                    \
212          vals[4].replace('!',' ')+','+vals[5])
213        else:
214            newvals.append(vals[4])
215    if vals[2] == 'cfTime':
216        newvals.append(vals[0])
217        newvals.append(vals[1])
218        newvals.append(vals[2]+','+vals[3].replace('!',' '))
219    elif vals[2] == 'cfTimeCal':
220        newvals.append(vals[0])
221        newvals.append(vals[1])
222        newvals.append(vals[2] + ',' + vals[3].replace('!',' ')+','+vals[4])
223    if len(newvals) > 0:
224        vals = list(newvals)
225
226    if len(vals) != Nvals:
227        print errormsg
228        print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and',     \
229          len(vals), ' has passed!!'
230        print gen.datetimeStr_conversion.__doc__
231        quit(-1)
232    print gen.datetimeStr_conversion(vals[0], vals[1], vals[2])
233
234#'days_period'
235
236elif oper == 'get_right_CFtimeunits':
237    Nvals = 1
238    vals = opts.values.split(cS)
239    if vals[0] == 'h':
240        print gen.get_right_CFtimeunits.__doc__
241        quit(-1)
242    else:
243        if len(vals) != Nvals:
244            print errormsg
245            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
246              len(vals), ' has passed!!'
247            print gen.get_right_CFtimeunits.__doc__
248            quit(-1)
249        print gen.get_right_CFtimeunits(vals[0].replace('!', ' '))
250
251elif oper == 'grid_combinations':
252    Nvals = 2
253    vals = opts.values.split(cS)
254    if vals[0] == 'h':
255        print gen.grid_combinations.__doc__
256        quit(-1)
257    else:
258        if len(vals) != Nvals:
259            print errormsg
260            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
261              len(vals), ' has passed!!'
262            print gen.grid_combinations.__doc__
263            quit(-1)
264
265        print gen.grid_combinations(np.int(vals[0]), np.int(vals[1]))
266
267elif oper == 'latex_fig_array':
268    vals = opts.values.split(cS)
269    if vals[0] == 'h':
270        print gen.latex_fig_array.__doc__
271        print "  NOTE: first argument as existing LaTeX file"
272        print "  figs: passing list of figures as '@' separated list"
273        print "  caption: using '!' for spaces"
274        quit(-1)
275    else:
276        expectargs = '[latexfile],[figs],[figcaption],[figlabel],[dist],[refsize],'+ \
277         '[width],[height],[dorest]'
278        gen.check_arguments(oper,opts.values,expectargs,cS)
279
280        objf = open(vals[0], 'a')
281
282        figs = vals[1].split('@')
283        caption = vals[2].replace('!',' ')
284        gen.latex_fig_array(figs, objf, caption, vals[3], dist=vals[4],              \
285          refsize=vals[5], width=vals[6], height=vals[7], dorest=vals[8])
286        objf.write('\\end{document}\n')
287        objf.close()
288 
289elif oper == 'inf_operSlist':
290    Nvals = 4
291    vals = opts.values.split(cS)
292    if vals[0] == 'h':
293        print gen.inf_operSlist.__doc__
294        quit(-1)
295    else:
296        if len(vals) != Nvals:
297            print errormsg
298            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
299              len(vals), ' has passed!!'
300            print gen.inf_operSlist.__doc__
301            quit(-1)
302        vals0 = vals[0]
303        vals1 = vals[1]
304        vals2 = vals[2]
305        vals3 = vals[3]
306
307        print gen.inf_operSlist(vals0, vals1, char=vals2, values=vals3)
308 
309elif oper == 'interpolate_locs':
310    Nvals = 3
311    vals = opts.values.split(cS)
312    if vals[0] == 'h':
313        print gen.interpolate_locs.__doc__
314        quit(-1)
315    else:
316        if len(vals) != Nvals:
317            print errormsg
318            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
319              len(vals), ' has passed!!'
320            print gen.interpolate_locs.__doc__
321            quit(-1)
322        vals0 = np.array(vals[0].split(cV), dtype=np.float)
323        vals1 = np.array(vals[1].split(cV), dtype=np.float)
324
325        print gen.interpolate_locs(vals0, vals1, vals[2])
326
327elif oper == 'PolyArea':
328    Nvals = 2
329    vals = opts.values.split(cS)
330    if vals[0] == 'h':
331        print gen.PolyArea.__doc__
332        quit(-1)
333    else:
334        if len(vals) != Nvals:
335            print errormsg
336            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
337              len(vals), ' has passed!!'
338            print gen.PolyArea.__doc__
339            quit(-1)
340        xvals = np.array(vals[0].split(cV), dtype=np.float)
341        yvals = np.array(vals[1].split(cV), dtype=np.float)
342
343        print gen.PolyArea(xvals, yvals)
344
345elif oper == 'radial_points':
346    Nvals = 2
347    vals = opts.values.split(cS)
348    if vals[0] == 'h':
349        print gen.radial_points.__doc__
350        quit(-1)
351    else:
352        if len(vals) != Nvals:
353            print errormsg
354            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
355              len(vals), ' has passed!!'
356            print gen.radial_points.__doc__
357            quit(-1)
358        print gen.radial_points(np.float(vals[0]), int(vals[1]))
359
360elif oper == 'radius_dist':
361    Nvals = 1
362    vals = opts.values.split(cS)
363    if vals[0] == 'h':
364        print gen.radius_dist.__doc__
365        quit(-1)
366    else:
367        if len(vals) != Nvals:
368            print errormsg
369            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
370              len(vals), ' has passed!!'
371            print gen.radius_dist.__doc__
372            quit(-1)
373        print gen.radius_dist(int(vals[0]), int(vals[1]), int(vals[2]), int(vals[2]))
374
375elif oper == 'rmNOnum':
376    Nvals = 1
377    vals = opts.values.split(cS)
378    if vals[0] == 'h':
379        print gen.rmNOnum.__doc__
380        quit(-1)
381    else:
382        if len(vals) != Nvals:
383            print errormsg
384            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
385              len(vals), ' has passed!!'
386            print gen.rmNOnum.__doc__
387            quit(-1)
388        print gen.rmNOnum(vals[0])
389
390elif oper == 'running_mean':
391    Nvals = 2
392    vals = opts.values.split(cS)
393    if vals[0] == 'h':
394        print gen.running_mean.__doc__
395        quit(-1)
396    else:
397        if len(vals) != Nvals:
398            print errormsg
399            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
400              len(vals), ' has passed!!'
401            print gen.running_mean.__doc__
402            quit(-1)
403        print gen.running_mean(np.array(vals[0].split(cV), dtype=np.float), int(vals[1]))
404
405elif oper == 'significant_decomposition':
406    Nvals = 2
407    vals = opts.values.split(cS)
408    if vals[0] == 'h':
409        print gen.significant_decomposition.__doc__
410        quit(-1)
411    else:
412        if len(vals) != Nvals:
413            print errormsg
414            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
415              len(vals), ' has passed!!'
416            print gen.significant_decomposition.__doc__
417            quit(-1)
418        print gen.significant_decomposition(np.float(vals[0]), int(vals[1]))
419
420elif oper == 'squared_radial':
421    Nvals = 1
422    vals = opts.values.split(cS)
423    if vals[0] == 'h':
424        print gen.squared_radial.__doc__
425        quit(-1)
426    else:
427        if len(vals) != Nvals:
428            print errormsg
429            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
430              len(vals), ' has passed!!'
431            print gen.squared_radial.__doc__
432            quit(-1)
433        print gen.squared_radial(int(vals[0]))
434
435elif oper == 'table_tex_file':
436    Nvals = 6
437    vals = opts.values.split(cS)
438    if vals[0] == 'h':
439        print gen.table_tex_file.__doc__
440        quit(-1)
441    else:
442        if len(vals) != Nvals:
443            print errormsg
444            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
445              len(vals), ' has passed!!'
446            print gen.table_tex_file.__doc__
447            quit(-1)
448        vals2 = np.array(vals[2].split(cV),dtype=np.float).reshape(int(vals[0]),     \
449          int(vals[1]))
450        vals3 = vals[3].replace(cE,' ').split(cV)
451        vals4 = vals[4].replace(cE,' ').split(cV)
452
453        print gen.table_tex_file(int(vals[0]), int(vals[1]), vals2, vals3, vals4,    \
454          vals[5])
455
456elif oper == 'unitsDate':
457    Nvals = 3
458    vals = opts.values.split(cS)
459    if vals[0] == 'h':
460        print gen.unitsDate.__doc__
461        quit(-1)
462    else:
463        if len(vals) != Nvals:
464            print errormsg
465            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
466              len(vals), ' has passed!!'
467            print gen.unitsDate.__doc__
468            quit(-1)
469        print gen.unitsDate(vals[0], vals[1], vals[2])
470
471elif oper == 'variables_values':
472    Nvals = 1
473    vals = opts.values.split(cS)
474    if vals[0] == 'h':
475        print gen.variables_values.__doc__
476        quit(-1)
477    else:
478        if len(vals) != Nvals:
479            print errormsg
480            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
481              len(vals), ' has passed!!'
482            print gen.variables_values.__doc__
483            quit(-1)
484        result = gen.variables_values(vals[0])
485        print gen.numVector_String(result,':')
486
487elif oper == 'wdismean':
488    Nvals = 2
489    vals = opts.values.split(cS)
490    if vals[0] == 'h':
491        print gen.wdismean.__doc__
492        quit(-1)
493    else:
494        if len(vals) != Nvals:
495            print errormsg
496            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
497              len(vals), ' has passed!!'
498            print gen.wdismean.__doc__
499            quit(-1)
500        vals0 = np.array(vals[0].split(cV), dtype=np.float)
501        vals1 = np.array(vals[1].split(cV), dtype=np.float).reshape(2,2)
502
503        print gen.wdismean(vals0, vals1)
504
505elif oper == 'WRFsetup':
506    Nvals = 3
507    vals = opts.values.split(cS)
508    if vals[0] == 'h':
509        print gen.WRFsetup.__doc__
510        quit(-1)
511    else:
512        if len(vals) != Nvals:
513            print errormsg
514            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
515              len(vals), ' has passed!!'
516            print gen.WRFsetup.__doc__
517            quit(-1)
518        vals0 = vals[0].replace('@', ',')
519        vals1 = vals[1]
520        vals2 = vals[2]
521       
522        print gen.WRFsetup(vals0, vals1, vals2)
523
Note: See TracBrowser for help on using the repository browser.