|
PISM, A Parallel Ice Sheet Model stable 0.4.1779
|
00001 #!/usr/bin/env python 00002 00003 ## @package vnreport 00004 ## Plots error graphs using \c pismv of \c vfnow.py report files. 00005 ## 00006 ## Has two command-line options: -i specifies a \c pismv report file to use, \c 00007 ## -t selects tests to plot. Use "-t all" to plot error graphs using all the 00008 ## error reports saved in a file given with -i. 00009 ## 00010 ## For example: 00011 ## \verbatim 00012 ## vnreport.py -i r1084.nc -t G,B 00013 ## \endverbatim 00014 ## will use \c r1084.nc and plot tests "G" and "B". 00015 00016 from pylab import close, figure, clf, hold, plot, xlabel, ylabel, xticks, yticks, axis, legend, title, grid, show, savefig 00017 from numpy import array, polyfit, polyval, log10, floor, ceil, unique 00018 #from matplotlib.font_manager import FontProperties 00019 import getopt 00020 import sys 00021 00022 try: 00023 from netCDF4 import Dataset as NC 00024 except: 00025 from netCDF3 import Dataset as NC 00026 00027 def plot_errors(nc, x, vars, testname, plot_title, filename = None): 00028 # This mask lets us choose data corresponding to a particular test: 00029 test = array(map(chr, nc.variables['test'][:])) 00030 mask = (test == testname) 00031 00032 # If we have less than 2 points to plot, then bail. 00033 if (sum(mask) < 2): 00034 print "Skipping Test %s %s (not enough data to plot)" % (testname, plot_title) 00035 return 00036 00037 # Get the independent variable and transform it. Note that everywhere here 00038 # I assume that neither dx (dy, dz) nor errors can be zero or negative. 00039 dx = nc.variables[x][mask] 00040 dim = log10(dx) 00041 00042 figure(figsize=(10,6));clf();hold(True) 00043 00044 colors = ['red', 'blue', 'green', 'black', 'brown', 'cyan'] 00045 for (v,c) in zip(vars,colors): 00046 # Get a particular variable, transform and fit a line through it: 00047 data = log10(nc.variables[v][mask]) 00048 p = polyfit(dim, data, 1) 00049 00050 # Try to get the long_name, use short_name if it fails: 00051 try: 00052 name = nc.variables[v].long_name 00053 except: 00054 name = v 00055 00056 # Create a label for the independent variable: 00057 if (x == "dx"): 00058 dim_name = "\Delta x" 00059 if (x == "dy"): 00060 dim_name = "\Delta y" 00061 if (x == "dz"): 00062 dim_name = "\Delta z" 00063 if (x == "dzb"): 00064 dim_name = "\Delta z_{bed}" 00065 00066 # Variable label: 00067 var_label = "%s, $O(%s^{%1.2f})$" % (name, dim_name, p[0]) 00068 00069 # Plot errors and the linear fit: 00070 plot(dim, data, label=var_label, marker='o', color=c) 00071 plot(dim, polyval(p, dim), ls="--", color=c) 00072 00073 # Shrink axes, then expand vertically to have integer powers of 10: 00074 axis('tight') 00075 _,_,ymin,ymax = axis() 00076 axis(ymin = floor(ymin), ymax = ceil(ymax)) 00077 00078 # Switch to km if dx (dy, dz) are big: 00079 units = nc.variables[x].units 00080 if (dx.min() > 1000.0 and (units == "meters")): 00081 dx = dx / 1000.0 00082 units = "km" 00083 # Round grid spacing in x-ticks: 00084 xticks(dim, map(lambda(x): "%d" % x, dx)) 00085 xlabel("$%s$ (%s)" % (dim_name, units)) 00086 00087 # Use default (figured out by matplotlib) locations, but change labels for y-ticks: 00088 loc,_ = yticks() 00089 yticks(loc, map(lambda(x) : "$10^{%1.1f}$" % x, loc)) 00090 00091 # Make sure that all variables given have the same units: 00092 try: 00093 ylabels = array(map(lambda(x): nc.variables[x].units, vars)) 00094 if (any(ylabels != ylabels[0])): 00095 print "Incompatible units!" 00096 else: 00097 ylabel(ylabels[0]) 00098 except: 00099 pass 00100 00101 # Legend, grid and the title: 00102 legend(loc='best', borderpad=1, labelspacing = 0.5, handletextpad = 0.75, handlelength = 0.02) 00103 # prop = FontProperties(size='smaller'), 00104 grid(True) 00105 title("Test %s %s (%s)" % (testname, plot_title, nc.source)) 00106 00107 if (filename): 00108 savefig(filename) 00109 00110 def plot_tests(nc, list_of_tests): 00111 for test_name in list_of_tests: 00112 # thickness, volume and eta errors: 00113 if test_name in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'L']: 00114 plot_errors(nc, 'dx', ["maximum_thickness", "average_thickness"], test_name, "ice thickness errors") 00115 plot_errors(nc, 'dx', ["relative_volume"], test_name, "relative ice volume errors") 00116 plot_errors(nc, 'dx', ["relative_max_eta"], test_name, r"relative max $\eta$ errors") 00117 00118 # errors that are reported for test E only: 00119 if (test_name == 'E'): 00120 plot_errors(nc, 'dx', ["maximum_basal_velocity", "average_basal_velocity"], 'E' , r"basal velocity errors") 00121 plot_errors(nc, 'dx', ["maximum_basal_u", "maximum_basal_v"], 'E' , "basal velocity (ub and vb) errors") 00122 plot_errors(nc, 'dx', ["relative_basal_velocity"], 'E', "relative basal velocity errors") 00123 00124 # F and G temperature, sigma and velocity errors: 00125 if test_name in ['F', 'G']: 00126 plot_errors(nc, 'dx', ["maximum_sigma", "average_sigma"], 00127 test_name, "strain heating errors") 00128 plot_errors(nc, 'dx', ["maximum_temperature", "average_temperature", 00129 "maximum_basal_temperature", "average_basal_temperature"], 00130 test_name, "ice temperature errors") 00131 00132 plot_errors(nc, 'dx', ["maximum_surface_velocity", "maximum_surface_w"], 00133 test_name, "maximum ice surface velocity errors") 00134 plot_errors(nc, 'dx', ["average_surface_velocity", "average_surface_w"], 00135 test_name, "average ice surface velocity errors") 00136 00137 00138 # test I: plot only the u component 00139 if test_name == 'I': 00140 plot_errors(nc, 'dy', ["relative_velocity"], 00141 test_name, "relative velocity errors") 00142 plot_errors(nc, 'dy', ["maximum_u", "average_u"], 00143 test_name, "velocity errors") 00144 00145 # tests J and M: 00146 if test_name in ['J', 'M']: 00147 plot_errors(nc, 'dx', ["relative_velocity"], 00148 test_name, "relative velocity errors") 00149 plot_errors(nc, 'dx', ["maximum_velocity", "maximum_u", "average_u", "maximum_v", "average_v"], 00150 test_name, "velocity errors") 00151 00152 # test K temperature errors: 00153 if (test_name == 'K'): 00154 plot_errors(nc, 'dz', ["maximum_temperature", "average_temperature", 00155 "maximum_bedrock_temperature", "average_bedrock_temperature"], 00156 'K', "temperature errors") 00157 00158 # test O temperature and basal melt rate errors: 00159 if (test_name == 'O'): 00160 plot_errors(nc, 'dz', ["maximum_temperature", "average_temperature", 00161 "maximum_bedrock_temperature", "average_bedrock_temperature"], 00162 'K', "temperature errors") 00163 plot_errors(nc, 'dz', ["maximum_basal_melt_rate"], 00164 'O', "basal melt rate errors") 00165 00166 def print_help(): 00167 print """Usage: 00168 -i specifies an input file, a result of running pismv (or vfnow.py) 00169 with the -report_file option 00170 -t,--tests= specifies a comma-separated list of tests. Use '-t all' 00171 to plot all the tests available in the -i file. 00172 --help prints this message 00173 """ 00174 00175 tests_to_plot = None 00176 input = None 00177 try: 00178 opts, args = getopt.getopt(sys.argv[1:], "i:t:", ["tests=", "help"]) 00179 for opt, arg in opts: 00180 if opt in ["-t", "--tests"]: 00181 tests_to_plot = arg.split(',') 00182 if opt == "-i": 00183 input = arg 00184 if opt == "--help": 00185 print_help() 00186 sys.exit(0) 00187 if input: 00188 nc = NC(input, 'r') 00189 available_tests = unique(array(map(chr, nc.variables['test'][:]))) 00190 00191 if len(available_tests) == 1: 00192 if tests_to_plot == None: 00193 tests_to_plot = available_tests 00194 else: 00195 if (tests_to_plot == None): 00196 print """Please choose tests to plot using the -t option. 00197 (Input file %s has reports for tests %s available.)""" % (input, str(available_tests)) 00198 sys.exit(0) 00199 00200 if (tests_to_plot[0] == "all"): 00201 tests_to_plot = available_tests 00202 00203 close('all') 00204 plot_tests(nc, tests_to_plot) 00205 try: 00206 # show() will break if we didn't plot anything 00207 show() 00208 except: 00209 pass 00210 else: 00211 print_help() 00212 except getopt.GetoptError: 00213 print "Processing command-line options failed." 00214 print_help() 00215 sys.exit(1) 00216
1.7.3