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

Last change on this file since 1784 was 1757, checked in by lfita, 7 years ago

Fixing generic use of 'datetimeStr_conversion' to take into account when `cfTime' is used

File size: 14.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# coincident_CFtimes: Function to make coincident times for two different sets of CFtimes
24# count_cond: Function to count values of a variable which attain a condition
25# datetimeStr_conversion: Function to transform a string date to an another date object
26# grid_combinations: Function to provide all the possible grid points combination for a given pair of values
27#   x,y= pair of grid points
28# interpolate_locs: Function to provide interpolate locations on a given axis
29# PolyArea: Function to compute the area of the polygon following 'Shoelace formula'
30# radial_points: Function to provide a number of grid point positions for a given angle
31# radius_dist: Function to generate a matrix with the distance at a given point
32# rmNOnum: Removing from a string all that characters which are not numbers
33# running_mean: Function to compute a running mean of a series of values
34# significant_decomposition: Function to decompose a given number by its signifcant potencies
35# squared_radial: Function to provide the series of radii as composite of pairs (x,y) of gid cells
36#   Npt= largest amount of grid points on x and y directions
37# table_tex_file: Function to write into a file a LaTeX tabular from a table of values
38# unitsDate: Function to know how many units of time are from a given pair of dates
39# variables_values: Function to provide values to plot the different variables values from ASCII file
40# wdismean: Function to compute the mean value weighted to its 4 distances
41# Character to split passed values
42
43cS = ','
44# Character to split serie of values
45cV = '@'
46# Character for spaces
47cE = '!'
48
49# List of available operations
50operations=['coincident_CFtimes', 'count_cond', 'datetimeStr_conversion',            \
51  'grid_combinations',                                                               \
52  'interpolate_locs', 'latex_fig_array', 'list_operations', 'PolyArea',              \
53  'radial_points', 'radius_dist',                                                    \
54  'rmNOnum', 'running_mean',                                                         \
55  'significant_decomposition', 'squared_radial',                                     \
56  'table_tex_file', 'unitsDate', 'variables_values', 'wdismean']
57
58hundredvals = '0'
59for i in range(1,100): hundredvals = hundredvals + cV + str(i)
60
61vs100 = '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'
62vs100 = vs100 + '@28@29@30@31@32@33@34@35@36@37@38@39@40@41@42@43@44@45@46@47@48@49'
63vs100 = vs100 + '@50@51@52@53@54@55@56@57@58@59@60@61@62@63@64@65@66@67@68@69@70@71'
64va100 = vs100 + '@72@73@74@75@76@77@78@79@80@81@82@83@84@85@86@87@88@89@90@91@92@93'
65va100 = vs100 + '@94@95@96@97@98@99'
66
67## 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'
68## e.g. # generic.py -o count_cond -S 0@1@2@3@4@5@6@7@8@9,4,le
69## e.g. # generic.py -o datetimeStr_conversion -S '1976-02-17_08:32:05,Y-m-d_H:M:S,matYmdHMS'
70## e.g. # generic.py -o grid_combinations -S 1,2
71## e.g. # generic.py -o interpolate_locs -S -1.2@2.4@5.6@7.8@12.0,0.5@2.5,lin
72## e.g. # generic.py -o PolyArea -S -0.5@0.5@0.5@-0.5,0.5@0.5@-0.5@-0.5
73## e.g. # generic.py -o radial_points -S 0.785398163397,5
74## e.g. # generic.py -o radius_dist -S 3,5,2,2
75## e.g. # generic.py -o rmNOnum -S LMD123IPSL
76## e.g. # generic.py -o significant_decomposition -S 3.576,-2
77## 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'
78## e.g. # generic.py -o unitsDate -S '19490101000000,19760217082932,second'
79## e.g. # generic.py -o running_mean -S 0@1@2@3@4@5@6@7@8@9,10
80## e.g. # generic.py -o squared_radial -S 3
81## e.g. # generic.py -o variables_values -S 'hus'
82## e.g. # generic.py -o wdismean -S 0.005@0.005,0.@1.@2.@3.
83
84operationnames = "'" + gen.numVector_String(operations, "', '") + "'"
85valuesinf = "'" + cS + "' list of values to use according to the operation ('" + cV +\
86  "' for list of values)"
87
88parser = OptionParser()
89parser.add_option("-o", "--operation", type='choice', dest="operation", 
90  choices=operations, help="operation to make: " + operationnames, metavar="OPER")
91parser.add_option("-S", "--valueS (when applicable)", dest="values", 
92  help=valuesinf, metavar="VALUES")
93(opts, args) = parser.parse_args()
94
95#######    #######
96## MAIN
97    #######
98oper = opts.operation
99
100if oper == 'list_operations':
101# From: http://www.diveintopython.net/power_of_introspection/all_together.html
102    object = gen
103    for opern in operations:
104        if  opern != 'list_operations': 
105            print opern + '_______ ______ _____ ____ ___ __ _'
106            print getattr(object, opern).__doc__
107
108elif oper == 'coincident_CFtimes':
109    Nvals = 3
110    vals = opts.values.split(cS)
111    if vals[0] == 'h':
112        print gen.coincident_CFtimes.__doc__
113        quit(-1)
114    else:
115        if len(vals) != Nvals:
116            print errormsg
117            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
118              len(vals), ' has passed!!'
119            print gen.coincident_CFtimes.__doc__
120            quit(-1)
121        vals0 = np.array(vals[0].split(cV), dtype=np.float)
122        print gen.coincident_CFtimes(vals0, vals[1], vals[2])
123
124elif oper == 'count_cond':
125    Nvals = 3
126    vals = opts.values.split(cS)
127    if vals[0] == 'h':
128        print gen.count_cond.__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.count_cond.__doc__
136            quit(-1)
137        vals0 = np.array(vals[0].split(cV), dtype=np.float)
138        print gen.count_cond(np.array(vals[0].split(cV), dtype=np.float),           \
139          np.float(vals[1]), vals[2])
140
141elif oper == 'datetimeStr_conversion':
142    Nvals = 3
143    vals = opts.values.split(cS)
144    newvals = []
145    if vals[1] == 'cfTime':
146        newvals.append(vals[0])
147        newvals.append(vals[1]+','+vals[2])
148        if vals[2] == 'cfTime': newvals.append(vals[3]+','+vals[4])
149        vals = list(newvals)
150    if vals[2] == 'cfTime':
151        newvals.append(vals[0])
152        newvals.append(vals[1])
153        newvals.append(vals[2]+','+vals[3])
154        vals = list(newvals)
155
156    if vals[0] == 'h':
157        print gen.datetimeStr_conversion.__doc__
158        quit(-1)
159    else:
160        if len(vals) != Nvals:
161            print errormsg
162            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
163              len(vals), ' has passed!!'
164            print gen.datetimeStr_conversion.__doc__
165            quit(-1)
166        print gen.datetimeStr_conversion(vals[0], vals[1], vals[2])
167
168#'days_period'
169
170elif oper == 'grid_combinations':
171    Nvals = 2
172    vals = opts.values.split(cS)
173    if vals[0] == 'h':
174        print gen.grid_combinations.__doc__
175        quit(-1)
176    else:
177        if len(vals) != Nvals:
178            print errormsg
179            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
180              len(vals), ' has passed!!'
181            print gen.grid_combinations.__doc__
182            quit(-1)
183
184        print gen.grid_combinations(np.int(vals[0]), np.int(vals[1]))
185
186elif oper == 'latex_fig_array':
187    vals = opts.values.split(cS)
188    if vals[0] == 'h':
189        print gen.latex_fig_array.__doc__
190        print "  NOTE: first argument as existing LaTeX file"
191        print "  figs: passing list of figures as '@' separated list"
192        print "  caption: using '!' for spaces"
193        quit(-1)
194    else:
195        expectargs = '[latexfile],[figs],[figcaption],[figlabel],[dist],[refsize],'+ \
196         '[width],[height],[dorest]'
197        gen.check_arguments(oper,opts.values,expectargs,cS)
198
199        objf = open(vals[0], 'a')
200
201        figs = vals[1].split('@')
202        caption = vals[2].replace('!',' ')
203        gen.latex_fig_array(figs, objf, caption, vals[3], dist=vals[4],              \
204          refsize=vals[5], width=vals[6], height=vals[7], dorest=vals[8])
205        objf.write('\\end{document}\n')
206        objf.close()
207 
208elif oper == 'interpolate_locs':
209    Nvals = 3
210    vals = opts.values.split(cS)
211    if vals[0] == 'h':
212        print gen.interpolate_locs.__doc__
213        quit(-1)
214    else:
215        if len(vals) != Nvals:
216            print errormsg
217            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
218              len(vals), ' has passed!!'
219            print gen.interpolate_locs.__doc__
220            quit(-1)
221        vals0 = np.array(vals[0].split(cV), dtype=np.float)
222        vals1 = np.array(vals[1].split(cV), dtype=np.float)
223
224        print gen.interpolate_locs(vals0, vals1, vals[2])
225
226elif oper == 'PolyArea':
227    Nvals = 2
228    vals = opts.values.split(cS)
229    if vals[0] == 'h':
230        print gen.PolyArea.__doc__
231        quit(-1)
232    else:
233        if len(vals) != Nvals:
234            print errormsg
235            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
236              len(vals), ' has passed!!'
237            print gen.PolyArea.__doc__
238            quit(-1)
239        xvals = np.array(vals[0].split(cV), dtype=np.float)
240        yvals = np.array(vals[1].split(cV), dtype=np.float)
241
242        print gen.PolyArea(xvals, yvals)
243
244elif oper == 'radial_points':
245    Nvals = 2
246    vals = opts.values.split(cS)
247    if vals[0] == 'h':
248        print gen.radial_points.__doc__
249        quit(-1)
250    else:
251        if len(vals) != Nvals:
252            print errormsg
253            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
254              len(vals), ' has passed!!'
255            print gen.radial_points.__doc__
256            quit(-1)
257        print gen.radial_points(np.float(vals[0]), int(vals[1]))
258
259elif oper == 'radius_dist':
260    Nvals = 1
261    vals = opts.values.split(cS)
262    if vals[0] == 'h':
263        print gen.radius_dist.__doc__
264        quit(-1)
265    else:
266        if len(vals) != Nvals:
267            print errormsg
268            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
269              len(vals), ' has passed!!'
270            print gen.radius_dist.__doc__
271            quit(-1)
272        print gen.radius_dist(int(vals[0]), int(vals[1]), int(vals[2]), int(vals[2]))
273
274elif oper == 'rmNOnum':
275    Nvals = 1
276    vals = opts.values.split(cS)
277    if vals[0] == 'h':
278        print gen.rmNOnum.__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.rmNOnum.__doc__
286            quit(-1)
287        print gen.rmNOnum(vals[0])
288
289elif oper == 'running_mean':
290    Nvals = 2
291    vals = opts.values.split(cS)
292    if vals[0] == 'h':
293        print gen.running_mean.__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.running_mean.__doc__
301            quit(-1)
302        print gen.running_mean(np.array(vals[0].split(cV), dtype=np.float), int(vals[1]))
303
304elif oper == 'significant_decomposition':
305    Nvals = 2
306    vals = opts.values.split(cS)
307    if vals[0] == 'h':
308        print gen.significant_decomposition.__doc__
309        quit(-1)
310    else:
311        if len(vals) != Nvals:
312            print errormsg
313            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
314              len(vals), ' has passed!!'
315            print gen.significant_decomposition.__doc__
316            quit(-1)
317        print gen.significant_decomposition(np.float(vals[0]), int(vals[1]))
318
319elif oper == 'squared_radial':
320    Nvals = 1
321    vals = opts.values.split(cS)
322    if vals[0] == 'h':
323        print gen.squared_radial.__doc__
324        quit(-1)
325    else:
326        if len(vals) != Nvals:
327            print errormsg
328            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
329              len(vals), ' has passed!!'
330            print gen.squared_radial.__doc__
331            quit(-1)
332        print gen.squared_radial(int(vals[0]))
333
334elif oper == 'table_tex_file':
335    Nvals = 6
336    vals = opts.values.split(cS)
337    if vals[0] == 'h':
338        print gen.table_tex_file.__doc__
339        quit(-1)
340    else:
341        if len(vals) != Nvals:
342            print errormsg
343            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
344              len(vals), ' has passed!!'
345            print gen.table_tex_file.__doc__
346            quit(-1)
347        vals2 = np.array(vals[2].split(cV),dtype=np.float).reshape(int(vals[0]),     \
348          int(vals[1]))
349        vals3 = vals[3].replace(cE,' ').split(cV)
350        vals4 = vals[4].replace(cE,' ').split(cV)
351
352        print gen.table_tex_file(int(vals[0]), int(vals[1]), vals2, vals3, vals4,    \
353          vals[5])
354
355elif oper == 'unitsDate':
356    Nvals = 3
357    vals = opts.values.split(cS)
358    if vals[0] == 'h':
359        print gen.unitsDate.__doc__
360        quit(-1)
361    else:
362        if len(vals) != Nvals:
363            print errormsg
364            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
365              len(vals), ' has passed!!'
366            print gen.unitsDate.__doc__
367            quit(-1)
368        print gen.unitsDate(vals[0], vals[1], vals[2])
369
370elif oper == 'variables_values':
371    Nvals = 1
372    vals = opts.values.split(cS)
373    if vals[0] == 'h':
374        print gen.variables_values.__doc__
375        quit(-1)
376    else:
377        if len(vals) != Nvals:
378            print errormsg
379            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
380              len(vals), ' has passed!!'
381            print gen.variables_values.__doc__
382            quit(-1)
383        result = gen.variables_values(vals[0])
384        print gen.numVector_String(result,':')
385
386elif oper == 'wdismean':
387    Nvals = 2
388    vals = opts.values.split(cS)
389    if vals[0] == 'h':
390        print gen.wdismean.__doc__
391        quit(-1)
392    else:
393        if len(vals) != Nvals:
394            print errormsg
395            print '  ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \
396              len(vals), ' has passed!!'
397            print gen.wdismean.__doc__
398            quit(-1)
399        vals0 = np.array(vals[0].split(cV), dtype=np.float)
400        vals1 = np.array(vals[1].split(cV), dtype=np.float).reshape(2,2)
401
402        print gen.wdismean(vals0, vals1)
403
Note: See TracBrowser for help on using the repository browser.