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

Last change on this file since 2546 was 2490, checked in by lfita, 6 years ago

Adding:

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