# Wrapper for the generic functions written in python from 'generic_tools.py' # L. Fita, LMD. June 2016 # Python to manage netCDF files. # From L. Fita work in different places: LMD (France) # More information at: http://www.xn--llusfb-5va.cat/python/PyNCplot # # pyNCplot and its component generic.py comes with ABSOLUTELY NO WARRANTY. # This work is licendes under a Creative Commons # Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0) # from optparse import OptionParser import numpy as np import datetime as dt import generic_tools as gen main = 'generic.py' errormsg = 'ERROR -- error -- ERROR -- error' warnmsg = 'WARNING -- warning --WARNING -- warning' import os import re # coincident_CFtimes: Function to make coincident times for two different sets of CFtimes # count_cond: Function to count values of a variable which attain a condition # datetimeStr_conversion: Function to transform a string date to an another date object # grid_combinations: Function to provide all the possible grid points combination for a given pair of values # x,y= pair of grid points # interpolate_locs: Function to provide interpolate locations on a given axis # PolyArea: Function to compute the area of the polygon following 'Shoelace formula' # radial_points: Function to provide a number of grid point positions for a given angle # radius_dist: Function to generate a matrix with the distance at a given point # rmNOnum: Removing from a string all that characters which are not numbers # running_mean: Function to compute a running mean of a series of values # significant_decomposition: Function to decompose a given number by its signifcant potencies # squared_radial: Function to provide the series of radii as composite of pairs (x,y) of gid cells # Npt= largest amount of grid points on x and y directions # table_tex_file: Function to write into a file a LaTeX tabular from a table of values # unitsDate: Function to know how many units of time are from a given pair of dates # variables_values: Function to provide values to plot the different variables values from ASCII file # wdismean: Function to compute the mean value weighted to its 4 distances # Character to split passed values cS = ',' # Character to split serie of values cV = '@' # Character for spaces cE = '!' # List of available operations operations=['coincident_CFtimes', 'count_cond', 'datetimeStr_conversion', \ 'grid_combinations', \ 'interpolate_locs', 'latex_fig_array', 'list_operations', 'PolyArea', \ 'radial_points', 'radius_dist', \ 'rmNOnum', 'running_mean', \ 'significant_decomposition', 'squared_radial', \ 'table_tex_file', 'unitsDate', 'variables_values', 'wdismean'] hundredvals = '0' for i in range(1,100): hundredvals = hundredvals + cV + str(i) vs100 = '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' vs100 = vs100 + '@28@29@30@31@32@33@34@35@36@37@38@39@40@41@42@43@44@45@46@47@48@49' vs100 = vs100 + '@50@51@52@53@54@55@56@57@58@59@60@61@62@63@64@65@66@67@68@69@70@71' va100 = vs100 + '@72@73@74@75@76@77@78@79@80@81@82@83@84@85@86@87@88@89@90@91@92@93' va100 = vs100 + '@94@95@96@97@98@99' ## 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' ## e.g. # generic.py -o count_cond -S 0@1@2@3@4@5@6@7@8@9,4,le ## e.g. # generic.py -o datetimeStr_conversion -S '1976-02-17_08:32:05,Y-m-d_H:M:S,matYmdHMS' ## e.g. # generic.py -o grid_combinations -S 1,2 ## e.g. # generic.py -o interpolate_locs -S -1.2@2.4@5.6@7.8@12.0,0.5@2.5,lin ## e.g. # generic.py -o PolyArea -S -0.5@0.5@0.5@-0.5,0.5@0.5@-0.5@-0.5 ## e.g. # generic.py -o radial_points -S 0.785398163397,5 ## e.g. # generic.py -o radius_dist -S 3,5,2,2 ## e.g. # generic.py -o rmNOnum -S LMD123IPSL ## e.g. # generic.py -o significant_decomposition -S 3.576,-2 ## 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' ## e.g. # generic.py -o unitsDate -S '19490101000000,19760217082932,second' ## e.g. # generic.py -o running_mean -S 0@1@2@3@4@5@6@7@8@9,10 ## e.g. # generic.py -o squared_radial -S 3 ## e.g. # generic.py -o variables_values -S 'hus' ## e.g. # generic.py -o wdismean -S 0.005@0.005,0.@1.@2.@3. operationnames = "'" + gen.numVector_String(operations, "', '") + "'" valuesinf = "'" + cS + "' list of values to use according to the operation ('" + cV +\ "' for list of values)" parser = OptionParser() parser.add_option("-o", "--operation", type='choice', dest="operation", choices=operations, help="operation to make: " + operationnames, metavar="OPER") parser.add_option("-S", "--valueS (when applicable)", dest="values", help=valuesinf, metavar="VALUES") (opts, args) = parser.parse_args() ####### ####### ## MAIN ####### oper = opts.operation if oper == 'list_operations': # From: http://www.diveintopython.net/power_of_introspection/all_together.html object = gen for opern in operations: if opern != 'list_operations': print opern + '_______ ______ _____ ____ ___ __ _' print getattr(object, opern).__doc__ elif oper == 'coincident_CFtimes': Nvals = 3 vals = opts.values.split(cS) if vals[0] == 'h': print gen.coincident_CFtimes.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.coincident_CFtimes.__doc__ quit(-1) vals0 = np.array(vals[0].split(cV), dtype=np.float) print gen.coincident_CFtimes(vals0, vals[1], vals[2]) elif oper == 'count_cond': Nvals = 3 vals = opts.values.split(cS) if vals[0] == 'h': print gen.count_cond.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.count_cond.__doc__ quit(-1) vals0 = np.array(vals[0].split(cV), dtype=np.float) print gen.count_cond(np.array(vals[0].split(cV), dtype=np.float), \ np.float(vals[1]), vals[2]) elif oper == 'datetimeStr_conversion': Nvals = 3 vals = opts.values.split(cS) if vals[0] == 'h': print gen.datetimeStr_conversion.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.datetimeStr_conversion.__doc__ quit(-1) print gen.datetimeStr_conversion(vals[0], vals[1], vals[2]) #'days_period' elif oper == 'grid_combinations': Nvals = 2 vals = opts.values.split(cS) if vals[0] == 'h': print gen.grid_combinations.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.grid_combinations.__doc__ quit(-1) print gen.grid_combinations(np.int(vals[0]), np.int(vals[1])) elif oper == 'latex_fig_array': vals = opts.values.split(cS) if vals[0] == 'h': print gen.latex_fig_array.__doc__ print " NOTE: first argument as existing LaTeX file" print " figs: passing list of figures as '@' separated list" print " caption: using '!' for spaces" quit(-1) else: expectargs = '[latexfile],[figs],[figcaption],[figlabel],[dist],[refsize],'+ \ '[width],[height],[dorest]' gen.check_arguments(oper,opts.values,expectargs,cS) objf = open(vals[0], 'a') figs = vals[1].split('@') caption = vals[2].replace('!',' ') gen.latex_fig_array(figs, objf, caption, vals[3], dist=vals[4], \ refsize=vals[5], width=vals[6], height=vals[7], dorest=vals[8]) objf.write('\\end{document}\n') objf.close() elif oper == 'interpolate_locs': Nvals = 3 vals = opts.values.split(cS) if vals[0] == 'h': print gen.interpolate_locs.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.interpolate_locs.__doc__ quit(-1) vals0 = np.array(vals[0].split(cV), dtype=np.float) vals1 = np.array(vals[1].split(cV), dtype=np.float) print gen.interpolate_locs(vals0, vals1, vals[2]) elif oper == 'PolyArea': Nvals = 2 vals = opts.values.split(cS) if vals[0] == 'h': print gen.PolyArea.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.PolyArea.__doc__ quit(-1) xvals = np.array(vals[0].split(cV), dtype=np.float) yvals = np.array(vals[1].split(cV), dtype=np.float) print gen.PolyArea(xvals, yvals) elif oper == 'radial_points': Nvals = 2 vals = opts.values.split(cS) if vals[0] == 'h': print gen.radial_points.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.radial_points.__doc__ quit(-1) print gen.radial_points(np.float(vals[0]), int(vals[1])) elif oper == 'radius_dist': Nvals = 1 vals = opts.values.split(cS) if vals[0] == 'h': print gen.radius_dist.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.radius_dist.__doc__ quit(-1) print gen.radius_dist(int(vals[0]), int(vals[1]), int(vals[2]), int(vals[2])) elif oper == 'rmNOnum': Nvals = 1 vals = opts.values.split(cS) if vals[0] == 'h': print gen.rmNOnum.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.rmNOnum.__doc__ quit(-1) print gen.rmNOnum(vals[0]) elif oper == 'running_mean': Nvals = 2 vals = opts.values.split(cS) if vals[0] == 'h': print gen.running_mean.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.running_mean.__doc__ quit(-1) print gen.running_mean(np.array(vals[0].split(cV), dtype=np.float), int(vals[1])) elif oper == 'significant_decomposition': Nvals = 2 vals = opts.values.split(cS) if vals[0] == 'h': print gen.significant_decomposition.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.significant_decomposition.__doc__ quit(-1) print gen.significant_decomposition(np.float(vals[0]), int(vals[1])) elif oper == 'squared_radial': Nvals = 1 vals = opts.values.split(cS) if vals[0] == 'h': print gen.squared_radial.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.squared_radial.__doc__ quit(-1) print gen.squared_radial(int(vals[0])) elif oper == 'table_tex_file': Nvals = 6 vals = opts.values.split(cS) if vals[0] == 'h': print gen.table_tex_file.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.table_tex_file.__doc__ quit(-1) vals2 = np.array(vals[2].split(cV),dtype=np.float).reshape(int(vals[0]), \ int(vals[1])) vals3 = vals[3].replace(cE,' ').split(cV) vals4 = vals[4].replace(cE,' ').split(cV) print gen.table_tex_file(int(vals[0]), int(vals[1]), vals2, vals3, vals4, \ vals[5]) elif oper == 'unitsDate': Nvals = 3 vals = opts.values.split(cS) if vals[0] == 'h': print gen.unitsDate.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.unitsDate.__doc__ quit(-1) print gen.unitsDate(vals[0], vals[1], vals[2]) elif oper == 'variables_values': Nvals = 1 vals = opts.values.split(cS) if vals[0] == 'h': print gen.variables_values.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.variables_values.__doc__ quit(-1) result = gen.variables_values(vals[0]) print gen.numVector_String(result,':') elif oper == 'wdismean': Nvals = 2 vals = opts.values.split(cS) if vals[0] == 'h': print gen.wdismean.__doc__ quit(-1) else: if len(vals) != Nvals: print errormsg print ' ' + main + ": operation '" + oper + "' requires", Nvals, 'and', \ len(vals), ' has passed!!' print gen.wdismean.__doc__ quit(-1) vals0 = np.array(vals[0].split(cV), dtype=np.float) vals1 = np.array(vals[1].split(cV), dtype=np.float).reshape(2,2) print gen.wdismean(vals0, vals1)