|
3 | 3 | # I've only tested it with a periodic_hex grid, but it should work with any MPAS grid. |
4 | 4 | # Currently variable attributes are not copied (and periodic_hex does not assign any, so this is ok). If variable attributes are added to periodic_hex, this script should be modified to copy them (looping over dir(var), skipping over variable function names "assignValue", "getValue", "typecode"). |
5 | 5 |
|
| 6 | +from __future__ import absolute_import, division, print_function, \ |
| 7 | + unicode_literals |
| 8 | + |
6 | 9 | import sys, numpy |
7 | 10 | from netCDF4 import Dataset |
8 | 11 | from optparse import OptionParser |
|
11 | 14 |
|
12 | 15 | sphere_radius = 6.37122e6 # earth radius, if needed |
13 | 16 |
|
14 | | -print "** Gathering information. (Invoke with --help for more details. All arguments are optional)" |
| 17 | +print("** Gathering information. (Invoke with --help for more details. All arguments are optional)") |
15 | 18 | parser = OptionParser() |
16 | 19 | parser.add_option("-i", "--in", dest="fileinName", help="input filename. Defaults to 'grid.nc'", metavar="FILENAME") |
17 | 20 | parser.add_option("-o", "--out", dest="fileoutName", help="output filename. Defaults to 'landice_grid.nc'", metavar="FILENAME") |
|
26 | 29 | options, args = parser.parse_args() |
27 | 30 |
|
28 | 31 | if not options.fileinName: |
29 | | - print "No input filename specified, so using 'grid.nc'." |
| 32 | + print("No input filename specified, so using 'grid.nc'.") |
30 | 33 | options.fileinName = 'grid.nc' |
31 | 34 | else: |
32 | | - print "Input file is:", options.fileinName |
| 35 | + print("Input file is: {}".format(options.fileinName)) |
33 | 36 | if not options.fileoutName: |
34 | | - print "No output filename specified, so using 'landice_grid.nc'." |
| 37 | + print("No output filename specified, so using 'landice_grid.nc'.") |
35 | 38 | options.fileoutName = 'landice_grid.nc' |
36 | | -print '' # make a space in stdout before further output |
| 39 | +print('') # make a space in stdout before further output |
37 | 40 |
|
38 | 41 | # Get the input file |
39 | 42 | filein = Dataset(options.fileinName,'r') |
|
47 | 50 | # ============================================ |
48 | 51 | # Do this first as doing it last is slow for big files since adding |
49 | 52 | # attributes forces the contents to get reorganized. |
50 | | -print "---- Copying global attributes from input file to output file ----" |
| 53 | +print("---- Copying global attributes from input file to output file ----") |
51 | 54 | for name in filein.ncattrs(): |
52 | 55 | # sphere radius needs to be set to that of the earth if on a sphere |
53 | 56 | if name == 'sphere_radius' and getattr(filein, 'on_a_sphere') == "YES ": |
54 | 57 | setattr(fileout, 'sphere_radius', sphere_radius) |
55 | | - print 'Set global attribute sphere_radius = ', str(sphere_radius) |
| 58 | + print('Set global attribute sphere_radius = {}'.format(sphere_radius)) |
56 | 59 | elif name =='history': |
57 | 60 | # Update history attribute of netCDF file |
58 | 61 | newhist = '\n'.join([getattr(filein, 'history'), ' '.join(sys.argv[:]) ] ) |
59 | 62 | setattr(fileout, 'history', newhist ) |
60 | 63 | else: |
61 | 64 | # Otherwise simply copy the attr |
62 | 65 | setattr(fileout, name, getattr(filein, name) ) |
63 | | - print 'Copied global attribute ', name, '=', getattr(filein, name) |
| 66 | + print('Copied global attribute {} = {}'.format(name, getattr(filein, name))) |
64 | 67 |
|
65 | 68 | # Update history attribute of netCDF file if we didn't above |
66 | 69 | if not hasattr(fileout, 'history'): |
67 | 70 | setattr(fileout, 'history', sys.argv[:] ) |
68 | 71 |
|
69 | 72 | fileout.sync() |
70 | | -print '' # make a space in stdout before further output |
| 73 | +print('') # make a space in stdout before further output |
71 | 74 |
|
72 | 75 |
|
73 | 76 | # ============================================ |
|
78 | 81 | # It may be better to list them explicitly as I do for the grid variables, |
79 | 82 | # but this way ensures they all get included and is easier. |
80 | 83 | # Note: The UNLIMITED time dimension will return a dimension value of None with Scientific.IO. This is what is supposed to happen. See below for how to deal with assigning values to a variable with a unlimited dimension. Special handling is needed with the netCDF module. |
81 | | -print "---- Copying dimensions from input file to output file ----" |
| 84 | +print("---- Copying dimensions from input file to output file ----") |
82 | 85 | for dim in filein.dimensions.keys(): |
83 | 86 | if dim == 'nTracers': |
84 | 87 | pass # Do nothing - we don't want this dimension |
|
91 | 94 | if options.levels is None: |
92 | 95 | # If nVertLevels is in the input file, and a value for it was not |
93 | 96 | # specified on the command line, then use the value from the file (do nothing here) |
94 | | - print "Using nVertLevels from the intput file:", len(filein.dimensions[dim]) |
| 97 | + print("Using nVertLevels from the intput file: {}".format(len(filein.dimensions[dim]))) |
95 | 98 | dimvalue = len(filein.dimensions[dim]) |
96 | 99 | else: |
97 | 100 | # if nVertLevels is in the input file, but a value WAS specified |
98 | 101 | # on the command line, then use the command line value |
99 | | - print "Using nVertLevels specified on the command line:", int(options.levels) |
| 102 | + print("Using nVertLevels specified on the command line: {}".format(int(options.levels))) |
100 | 103 | dimvalue = int(options.levels) |
101 | 104 | else: |
102 | 105 | dimvalue = len(filein.dimensions[dim]) |
|
105 | 108 | # it has not been added to the output file yet. Treat those here. |
106 | 109 | if 'nVertLevels' not in fileout.dimensions: |
107 | 110 | if options.levels is None: |
108 | | - print "nVertLevels not in input file and not specified. Using default value of 10." |
| 111 | + print("nVertLevels not in input file and not specified. Using default value of 10.") |
109 | 112 | fileout.createDimension('nVertLevels', 10) |
110 | 113 | else: |
111 | | - print "Using nVertLevels specified on the command line:", int(options.levels) |
| 114 | + print("Using nVertLevels specified on the command line: {}".format(int(options.levels))) |
112 | 115 | fileout.createDimension('nVertLevels', int(options.levels)) |
113 | 116 | # Also create the nVertInterfaces dimension, even if none of the variables require it. |
114 | 117 | fileout.createDimension('nVertInterfaces', len(fileout.dimensions['nVertLevels']) + 1) # nVertInterfaces = nVertLevels + 1 |
115 | | -print 'Added new dimension nVertInterfaces to output file with value of ' + str(len(fileout.dimensions['nVertInterfaces'])) + '.' |
| 118 | +print('Added new dimension nVertInterfaces to output file with value of {}.'.format(len(fileout.dimensions['nVertInterfaces']))) |
116 | 119 |
|
117 | 120 | fileout.sync() |
118 | | -print 'Finished creating dimensions in output file.\n' # include an extra blank line here |
| 121 | +print('Finished creating dimensions in output file.\n') # include an extra blank line here |
119 | 122 |
|
120 | 123 | # ============================================ |
121 | 124 | # Copy over all of the required grid variables to the new file |
122 | 125 | # ============================================ |
123 | | -print "Beginning to copy mesh variables to output file." |
| 126 | +print("Beginning to copy mesh variables to output file.") |
124 | 127 | vars2copy = ['latCell', 'lonCell', 'xCell', 'yCell', 'zCell', 'indexToCellID', 'latEdge', 'lonEdge', 'xEdge', 'yEdge', 'zEdge', 'indexToEdgeID', 'latVertex', 'lonVertex', 'xVertex', 'yVertex', 'zVertex', 'indexToVertexID', 'cellsOnEdge', 'nEdgesOnCell', 'nEdgesOnEdge', 'edgesOnCell', 'edgesOnEdge', 'weightsOnEdge', 'dvEdge', 'dcEdge', 'angleEdge', 'areaCell', 'areaTriangle', 'cellsOnCell', 'verticesOnCell', 'verticesOnEdge', 'edgesOnVertex', 'cellsOnVertex', 'kiteAreasOnVertex'] |
125 | 128 | # Add these optional fields if they exist in the input file |
126 | 129 | for optionalVar in ['meshDensity', 'gridSpacing', 'cellQuality', 'triangleQuality', 'triangleAngleQuality', 'obtuseTriangle']: |
127 | 130 | if optionalVar in filein.variables: |
128 | 131 | vars2copy.append(optionalVar) |
129 | 132 |
|
130 | 133 | for varname in vars2copy: |
131 | | - print "-", |
132 | | -print "|" |
| 134 | + print("-"), |
| 135 | +print("|") |
133 | 136 | for varname in vars2copy: |
134 | 137 | thevar = filein.variables[varname] |
135 | 138 | datatype = thevar.dtype |
|
146 | 149 | del newVar, thevar |
147 | 150 | sys.stdout.write("* "); sys.stdout.flush() |
148 | 151 | fileout.sync() |
149 | | -print "|" |
150 | | -print "Finished copying mesh variables to output file.\n" |
| 152 | +print("|") |
| 153 | +print("Finished copying mesh variables to output file.\n") |
151 | 154 |
|
152 | 155 | # ============================================ |
153 | 156 | # Create the land ice variables (all the shallow water vars in the input file can be ignored) |
|
170 | 173 | layerInterfaces[k] = 4.0/3.0 * (1.0 - ((k+1.0-1.0)/(nInterfaces-1.0) + 1.0)**-2) |
171 | 174 | for k in range(nVertLevels): |
172 | 175 | layerThicknessFractionsData[k] = layerInterfaces[k+1] - layerInterfaces[k] |
173 | | - print "Setting layerThicknessFractions to:", layerThicknessFractionsData |
| 176 | + print("Setting layerThicknessFractions to: {}".format(layerThicknessFractionsData)) |
174 | 177 | else: |
175 | 178 | sys.exit('Unknown method for vertical spacing method (--vert): '+options.vertMethod) |
176 | 179 |
|
|
192 | 195 | newvar[:] = numpy.zeros(newvar.shape) |
193 | 196 | newvar = fileout.createVariable('floatingBasalMassBal', datatype, ('Time', 'nCells')) |
194 | 197 | newvar[:] = numpy.zeros(newvar.shape) |
195 | | -print 'Added default variables: thickness, temperature, bedTopography, sfcMassBal, floatingBasalMassBal' |
| 198 | +print('Added default variables: thickness, temperature, bedTopography, sfcMassBal, floatingBasalMassBal') |
196 | 199 |
|
197 | 200 | if options.beta: |
198 | 201 | newvar = fileout.createVariable('beta', datatype, ('Time', 'nCells')) |
199 | 202 | newvar[:] = 1.0e8 # Give a default beta that won't have much sliding. |
200 | | - print 'Added optional variable: beta' |
| 203 | + print('Added optional variable: beta') |
201 | 204 |
|
202 | 205 | if options.effecpress: |
203 | 206 | newvar = fileout.createVariable('effectivePressure', datatype, ('Time', 'nCells')) |
204 | 207 | newvar[:] = 1.0e8 # Give a default effective pressure that won't have much sliding. |
205 | | - print 'Added optional variable: effectivePressure' |
| 208 | + print('Added optional variable: effectivePressure') |
206 | 209 |
|
207 | 210 | if options.dirichlet: |
208 | 211 | newvar = fileout.createVariable('dirichletVelocityMask', datatypeInt, ('Time', 'nCells', 'nVertInterfaces')) |
|
211 | 214 | newvar[:] = 0.0 |
212 | 215 | newvar = fileout.createVariable('uReconstructY', datatype, ('Time', 'nCells', 'nVertInterfaces',)) |
213 | 216 | newvar[:] = 0.0 |
214 | | - print 'Added optional dirichlet variables: dirichletVelocityMask, uReconstructX, uReconstructY' |
| 217 | + print('Added optional dirichlet variables: dirichletVelocityMask, uReconstructX, uReconstructY') |
215 | 218 |
|
216 | 219 | if options.thermal: |
217 | 220 | newvar = fileout.createVariable('temperature', datatype, ('Time', 'nCells', 'nVertLevels')) |
|
220 | 223 | newvar[:] = 273.15 # Give default value for temperate ice |
221 | 224 | newvar = fileout.createVariable('basalHeatFlux', datatype, ('Time', 'nCells')) |
222 | 225 | newvar[:] = 0.0 # Default to none (W/m2) |
223 | | - print 'Added optional thermal variables: temperature, surfaceAirTemperature, basalHeatFlux' |
| 226 | + print('Added optional thermal variables: temperature, surfaceAirTemperature, basalHeatFlux') |
224 | 227 |
|
225 | 228 | if options.hydro: |
226 | 229 | newvar = fileout.createVariable('waterThickness', datatype, ('Time', 'nCells')) |
|
237 | 240 | newvar[:] = 0.0 |
238 | 241 | newvar = fileout.createVariable('waterFluxMask', 'i', ('Time', 'nEdges')) |
239 | 242 | newvar[:] = 0.0 |
240 | | - print 'Added optional hydro variables: waterThickness, tillWaterThickness, meltInput, frictionAngle, waterPressure, waterFluxMask' |
| 243 | + print('Added optional hydro variables: waterThickness, tillWaterThickness, meltInput, frictionAngle, waterPressure, waterFluxMask') |
241 | 244 |
|
242 | 245 | if options.obs: |
243 | 246 | newvar = fileout.createVariable('observedSurfaceVelocityX', datatype, ('Time', 'nCells')) |
|
252 | 255 | newvar[:] = 0.0 |
253 | 256 | newvar = fileout.createVariable('thicknessUncertainty', datatype, ('Time', 'nCells')) |
254 | 257 | newvar[:] = 0.0 |
255 | | - print 'Added optional velocity optimization variables: observedSurfaceVelocityX, observedSurfaceVelocityY, observedSurfaceVelocityUncertainty, observedThicknessTendency, observedThicknessTendencyUncertainty, thicknessUncertainty' |
| 258 | + print('Added optional velocity optimization variables: observedSurfaceVelocityX, observedSurfaceVelocityY, observedSurfaceVelocityUncertainty, observedThicknessTendency, observedThicknessTendencyUncertainty, thicknessUncertainty') |
256 | 259 |
|
257 | 260 | # Update history attribute of netCDF file |
258 | 261 | thiscommand = datetime.now().strftime("%a %b %d %H:%M:%S %Y") + ": " + " ".join(sys.argv[:]) |
|
262 | 265 | newhist = thiscommand |
263 | 266 | setattr(fileout, 'history', newhist ) |
264 | 267 |
|
265 | | -print "Completed creating land ice variables in new file. Now syncing to file." |
| 268 | +print("Completed creating land ice variables in new file. Now syncing to file.") |
266 | 269 | fileout.sync() |
267 | 270 |
|
268 | 271 | filein.close() |
269 | 272 | fileout.close() |
270 | 273 |
|
271 | | -print '\n** Successfully created ' + options.fileoutName + '.**' |
| 274 | +print('\n** Successfully created {}.**'.format(options.fileoutName)) |
0 commit comments