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

Last change on this file since 2736 was 2706, checked in by lfita, 5 years ago

Adding:

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