FV3 Bundle
make_saar_data.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # $id$
3 """
4 Make gsw_mod_saar_data.f from the current gsw_data_v3_0.nc. This is a developer
5 utility and not a part of the public distribution, but its end-product is.
6 Note that it generates gsw_saar_data.c but will not overwrite it if it exists.
7 General concept: we don't want end-users of this distribution to require having
8 netcdf installed, nor do we want to incur the I/O overhead every time this
9 library is used. So we simply generate static data from the netcdf file.
10 """
11 import math, os, sys
12 from netCDF4 import Dataset
13 
14 def float2string(val, sformat, addcomma):
15  if math.isnan(val):
16  str_val = "9e90_r8"
17  else:
18  str_val = sformat % val
19  if str_val.find(".") < 0 and str_val.find("e") < 0 :
20  str_val += "."
21  str_val += "_r8"
22  if addcomma:
23  str_val += ", "
24  return str_val;
25 
26 def write_variable_real(var_name, dims, v):
27  ndims = len(dims)
28  # list dimensions in reverse order (nz,ny,nx)
29  if ndims == 1:
30  fortran_dims = "(%s)" % v.dimensions[0]
31  elif ndims == 2:
32  fortran_dims = "(%s,%s)" % v.dimensions[::-1]
33  elif ndims == 3:
34  fortran_dims = "(%s,%s,%s)" % v.dimensions[::-1]
35 
36  out.write("real (r8), dimension%s :: %s\n" % (fortran_dims, var_name))
37 
38  buf = " "
39  maxlen = 78
40  numformat = "%.17g"
41  if ndims == 1:
42  out.write("data %s / &\n" % var_name)
43  lastx = dims[0]-1
44 #
45 # The following construct (and variations below) transfer the
46 # netcdf variable into a memory-resident buffer all at once.
47 # Anything else is not advised.
48 #
49  vv = v[:]
50  for val, x in [(vv[cx],cx) for cx in range(dims[0])]:
51  sval = float2string(val,numformat,(x != lastx))
52  if len(buf)+len(sval) > maxlen:
53  out.write(buf+"&\n")
54  buf = " "
55  buf += sval
56  if buf:
57  out.write(buf+" &\n")
58  out.write(" /\n\n")
59  elif ndims == 2:
60  out.write("data %s / &\n" % var_name)
61  lastx = dims[0]-1
62  lasty = dims[1]-1
63  vv = v[:][:]
64  for x in range(dims[0]):
65  for val,y in [(vv[x][cy],cy) for cy in range(dims[1])]:
66  sval = float2string(val,numformat,(x != lastx or y != lasty))
67  if len(buf)+len(sval) > maxlen:
68  out.write(buf+"&\n")
69  buf = " "
70  buf += sval
71  if buf:
72  out.write(buf+" &\n")
73  out.write(" /\n\n")
74  else:
75 #
76 # For 3d real arrays we construct separate data statements for short
77 # array sections (one row per statement) to avoid continuation line
78 # limits (gFortran is unlimited, but iFort has a 511 line limit).
79 #
80  lastz = dims[2]-1
81  vv = v[:][:][:]
82  for x in range(dims[0]):
83  for y in range(dims[1]):
84  out.write("data %s(:,%d,%d) / &\n" % (var_name, y+1, x+1))
85  for val,z in [(vv[x][y][cz],cz) for cz in range(dims[2])]:
86  sval = float2string(val,numformat,(z != lastz))
87  if len(buf)+len(sval) > maxlen:
88  out.write(buf+"&\n")
89  buf = " "
90  buf += sval
91  if buf:
92  out.write(buf+" &\n")
93  buf = " "
94  out.write(" /\n")
95  out.write("\n")
96 
97 def write_variable_int(var_name, dims, v):
98  ndims = len(dims)
99  # list dimensions in reverse order (nz,ny,nx)
100  if ndims == 1:
101  fortran_dims = "(%s)" % v.dimensions[0]
102  elif ndims == 2:
103  fortran_dims = "(%s,%s)" % v.dimensions[::-1]
104  elif ndims == 3:
105  fortran_dims = "(%s,%s,%s)" % v.dimensions[::-1]
106 
107  out.write("integer, dimension%s :: %s\n" % (fortran_dims, var_name))
108  out.write("data %s / &\n" % var_name)
109 
110  buf = " "
111  maxlen = 78
112  nan = "999"
113  if ndims == 1:
114  lastx = dims[0]-1
115 #
116 # The following construct (and variations below) transfer the
117 # netcdf variable into a memory-resident buffer all at once.
118 # Anything else is not advised.
119 #
120  vv = v[:]
121  for val, x in [(vv[cx],cx) for cx in range(dims[0])]:
122  if math.isnan(val):
123  sval = nan
124  else:
125  sval = "%d" % val
126  if x != lastx:
127  sval += ", "
128  if len(buf)+len(sval) > maxlen:
129  out.write(buf+"&\n")
130  buf = " "
131  buf += sval
132  elif ndims == 2:
133  lastx = dims[0]-1
134  lasty = dims[1]-1
135  vv = v[:][:]
136  for x in range(dims[0]):
137  for val,y in [(vv[x][cy],cy) for cy in range(dims[1])]:
138  if math.isnan(val):
139  sval = nan
140  else:
141  sval = "%d" % val
142  if x != lastx or y != lasty:
143  sval += ", "
144  if len(buf)+len(sval) > maxlen:
145  out.write(buf+"&\n")
146  buf = " "
147  buf += sval
148  else:
149  lastx = dims[0]-1
150  lasty = dims[1]-1
151  lastz = dims[2]-1
152  vv = v[:][:][:]
153  for x in range(dims[0]):
154  for y in range(dims[1]):
155  for val,z in [(vv[x][y][cz],cz) for cz in range(dims[2])]:
156  if math.isnan(val):
157  sval = nan
158  else:
159  sval = "%d" % val
160  if x != lastx or y != lasty or z != lastz:
161  sval += ", "
162  if len(buf)+len(sval) > maxlen:
163  out.write(buf+"&\n")
164  buf = " "
165  buf += sval
166  if buf:
167  out.write(buf+" &\n")
168  out.write(" /\n\n")
169 
170 rootgrp = Dataset('gsw_data_v3_0.nc', 'r')
171 v = rootgrp.variables
172 d = rootgrp.dimensions
173 
174 nx = len(d['nx'])
175 ny = len(d['ny'])
176 nz = len(d['nz'])
177 
178 version_date = rootgrp.version_date
179 version_number = rootgrp.version_number
180 
181 vars_real = [["p_ref", "", [nz]], ["lats_ref", "", [ny]],
182  ["longs_ref", "", [nx]], ["saar_ref", "SAAR_ref", [nx,ny,nz]],
183  ["delta_sa_ref", "deltaSA_ref", [nx,ny,nz]]]
184 
185 vars_int = [["ndepth_ref", "", [nx,ny]]]
186 
187 try:
188  fd = os.open("gsw_mod_saar_data.f90", os.O_CREAT|os.O_EXCL|os.O_RDWR, 0644)
189 except:
190  print str(sys.exc_info()[1])
191  print "Will not overwrite gsw_mod_saar_data.f90. Exiting."
192  sys.exit(1)
193 out = os.fdopen(fd, "w")
194 out.write("!\n!** $Id$\n!** Extracted from gsw_data_v3_0.nc\n!\n")
195 out.write("""
196 !==========================================================================
197 module gsw_mod_saar_data
198 !==========================================================================
199 
200 use gsw_mod_kinds
201 
202 implicit none
203 
204 integer, dimension(4) :: deli = (/0,1,1,0/), delj = (/0,0,1,1/)
205 
206 integer, parameter :: npan = 6
207 real (r8), dimension(npan) :: longs_pan, lats_pan
208 
209 data longs_pan /260.00_r8, 272.59_r8, 276.50_r8, 278.65_r8, 280.73_r8, 292.0_r8/
210 data lats_pan / 19.55_r8, 13.97_r8, 9.60_r8, 8.10_r8, 9.33_r8, 3.4_r8/
211 
212 """)
213 
214 out.write("integer, parameter :: nx = %d\n"% nx)
215 out.write("integer, parameter :: ny = %d\n"% ny)
216 out.write("integer, parameter :: nz = %d\n"% nz)
217 out.write("\n")
218 out.write("character(*), parameter :: gsw_version_date = \"%s\"\n" % version_date)
219 out.write("character(*), parameter :: gsw_version_number = \"%s\"\n\n" % version_number)
220 
221 for var_label, var_name, dims in [var for var in vars_real]:
222  if not var_name:
223  var_name = var_label
224  write_variable_real(var_label, dims, v[var_name])
225 
226 for var_label, var_name, dims in [var for var in vars_int]:
227  if not var_name:
228  var_name = var_label
229  write_variable_int(var_label, dims, v[var_name])
230 
231 out.write("""
232 contains
233 
234  subroutine gsw_get_version (version_date, version_number)
235 
236  implicit none
237 
238  character(*), intent(out) :: version_date, version_number
239 
240  version_date = gsw_version_date
241  version_number = gsw_version_number
242 
243  end subroutine gsw_get_version
244 
245 end module gsw_mod_saar_data
246 !--------------------------------------------------------------------------
247 """)
248 
249 out.close()
250 sys.exit(0)
def write_variable_int(var_name, dims, v)
def float2string(val, sformat, addcomma)
str
Definition: c2f.py:15
def write_variable_real(var_name, dims, v)