FV3 Bundle
make_check_data.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # $Id$
3 """
4 Make gsw_mod_check_data.c 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. Note
6 that it generates gsw_mod_check_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, numpy, re
12 from netCDF4 import Dataset
13 
14 nan = "9e90_r8"
15 
16 pzeros = re.compile("0{7,}[1-9]*")
17 pnines = re.compile("9{7,}[0-8]*")
18 
19 def float2string(val, sformat, addcomma):
20  if math.isnan(val):
21  str_val = nan
22  else:
23  str_val = sformat % val
24 #
25 # Need to ensure all floats contain a decimal point because gFortran
26 # versions prior to 6.3.1 could give an internal compiler error or
27 # generate the wrong result internally (see
28 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80388).
29 #
30  if str_val.find(".") < 0 and str_val.find("e") < 0 :
31  str_val += "."
32 #
33 # Prettify the result by rounding down long sequences of zeros and
34 # rounding up long sequences of nines (this is just a machine
35 # precision issue that won't affect any GSW results), eg.
36 # 35.784000000000002 = 35.784 (this is easy - just truncate)
37 # 34.456999999999995 = 34.457 (a bit harder - truncate and add +1
38 # to last digit)
39 #
40  (str_val, nsubs) = pnines.subn("",str_val)
41  if nsubs > 0 :
42  last_digit = "%d" % (int(str_val[-1]) + 1)
43  str_val = str_val[:-1] + last_digit
44  else:
45  str_val = pzeros.sub("",str_val)
46  str_val += "_r8"
47  if addcomma:
48  str_val += ", "
49  return str_val
50 
51 def write_variable(var_name, dims, v):
52  ndims = len(dims)
53  if ndims == 1:
54  if dims[0] == 1:
55  fortran_dims = ""
56  else:
57  fortran_dims = (", dimension(" + work_dims[""][2] + ")")
58  else:
59  fortran_dims = (", dimension(" + work_dims[v.dimensions[1]][1] + ","
60  + work_dims[v.dimensions[1]][2] + ")")
61 
62  out.write("real (r8)%s :: %s\n" % (fortran_dims, var_name))
63  out.write("data %s / &\n" % var_name)
64 
65  buf = " "
66  maxlen = 78
67  num_format = "%.17g"
68  if ndims == 1:
69  lastx = dims[0]-1
70 #
71 # The following construct (and variations below) transfer the
72 # netcdf variable into a memory-resident buffer all at once.
73 # Anything else is not advised.
74 #
75  vv = v[:]
76  for val, x in [(vv[cx],cx) for cx in range(dims[0])]:
77  sval = float2string(val,num_format,(x != lastx))
78  if len(buf)+len(sval) > maxlen:
79  out.write(buf+"&\n")
80  buf = " "
81  buf += sval
82  elif ndims == 2:
83  lastx = dims[0]-1
84  lasty = dims[1]-1
85  vv = v[:][:]
86  for x in range(dims[0]):
87  for val,y in [(vv[x][cy],cy) for cy in range(dims[1])]:
88  sval = float2string(val,num_format,(x != lastx or y != lasty))
89  if len(buf)+len(sval) > maxlen:
90  out.write(buf+"&\n")
91  buf = " "
92  buf += sval
93  else:
94  lastx = dims[0]-1
95  lasty = dims[1]-1
96  lastz = dims[2]-1
97  vv = v[:][:][:]
98  for x in range(dims[0]):
99  for y in range(dims[1]):
100  for val,z in [(vv[x][y][cz],cz) for cz in range(dims[2])]:
101  sval = float2string(val,num_format,
102  (x != lastx or y != lasty or z != lastz))
103  if len(buf)+len(sval) > maxlen:
104  out.write(buf+"&\n")
105  buf = " "
106  buf += sval
107  if buf:
108  out.write(buf+" /\n\n")
109 
110 def write_structure(var_name, dims, v):
111  ndims = len(dims)
112  if ndims == 1:
113  gsw_type = work_dims[""][3]
114  else:
115  gsw_type = work_dims[v.dimensions[1]][3]
116 
117  out.write("type(%s) :: %s\n\n" % (gsw_type, var_name.lower()))
118  out.write("data %s / %s( &\n" % (var_name.lower(), gsw_type))
119 
120  if math.isnan(v.computation_accuracy):
121  str_ca = nan
122  else:
123  str_ca = "%.5g_r8" % v.computation_accuracy
124 
125  out.write(" \"%s\", %s, (/ &\n" % (var_name, str_ca))
126 
127  vmax = numpy.nanmax(v)
128  if vmax != 0.:
129  precision = v.computation_accuracy/abs(vmax)
130  else:
131  precision = v.computation_accuracy
132 
133  if precision < 1e-12:
134  num_format = "%.16g"
135  elif precision < 1e-10:
136  num_format = "%.14g"
137  else:
138  num_format = "%.12g"
139 
140  buf = " "
141  maxlen = 78
142  if ndims == 1:
143  lastx = dims[0]-1
144 #
145 # The following construct (and variations below) transfer the
146 # netcdf variable into a memory-resident buffer all at once.
147 # Anything else is not advised.
148 #
149  vv = v[:]
150  for val, x in [(vv[cx],cx) for cx in range(dims[0])]:
151  sval = float2string(val,num_format,(x != lastx))
152  if len(buf)+len(sval) > maxlen:
153  out.write(buf+"&\n")
154  buf = " "
155  buf += sval
156  elif ndims == 2:
157  lastx = dims[0]-1
158  lasty = dims[1]-1
159  vv = v[:][:]
160  for x in range(dims[0]):
161  for val,y in [(vv[x][cy],cy) for cy in range(dims[1])]:
162  sval = float2string(val,num_format,(x != lastx or y != lasty))
163  if len(buf)+len(sval) > maxlen:
164  out.write(buf+"&\n")
165  buf = " "
166  buf += sval
167  else:
168  lastx = dims[0]-1
169  lasty = dims[1]-1
170  lastz = dims[2]-1
171  vv = v[:][:][:]
172  for x in range(dims[0]):
173  for y in range(dims[1]):
174  for val,z in [(vv[x][y][cz],cz) for cz in range(dims[2])]:
175  sval = float2string(val,num_format,
176  (x != lastx or y != lasty or z != lastz))
177  if len(buf)+len(sval) > maxlen:
178  out.write(buf+"&\n")
179  buf = " "
180  buf += sval
181  if buf:
182  out.write(buf+" &\n")
183  out.write(" /) ) /\n\n")
184 
185 work_dims = {
186  "test_cast_length": ["test_cast_number",
187  "cast_m", "cast_n", "gsw_result"],
188  "Arctic_test_cast_length": ["Arctic_test_cast_number",
189  "cast_ice_m", "cast_ice_n", "gsw_result_ice"],
190  "test_cast_midpressure_length": ["test_cast_midpressure_number",
191  "cast_mpres_m", "cast_mpres_n", "gsw_result_mpres"],
192  "": ["", "", "cast_n", "gsw_result_cast"]
193 }
194 work_vars = [
195  ["ct", "CT_chck_cast"],
196  ["rt", "Rt_chck_cast"],
197  ["sa", "SA_chck_cast"],
198  ["sk", "SK_chck_cast"],
199  ["sp", "SP_chck_cast"],
200  ["t", "t_chck_cast"],
201  ["p", "p_chck_cast"],
202  ["delta_p", "delta_p_chck_cast"],
203  ["p_shallow", "p_chck_cast_shallow"],
204  ["p_deep", "p_chck_cast_deep"],
205  ["lat_cast", "lat_chck_cast"],
206  ["long_cast", "long_chck_cast"],
207  ["ct_arctic", "CT_Arctic"],
208  ["sa_arctic", "SA_Arctic"],
209  ["t_arctic", "t_Arctic"],
210  ["p_arctic", "p_Arctic"],
211  ["sa_seaice", "SA_seaice"],
212  ["t_seaice", "t_seaice"],
213  ["w_seaice", "w_seaice"],
214  ["t_ice", "t_ice"],
215  ["w_ice", "w_ice"],
216  ["sa_bulk", "SA_bulk"],
217  ["h_pot_bulk", "h_pot_bulk"],
218  ["h_bulk", "h_bulk"],
219  ["pref", "pr"]
220 ]
221 vars = [
222  ['C_from_SP', ""],
223  ['SP_from_C', ""],
224  ['SP_from_SK', ""],
225  ['SA_from_SP', ""],
226  ['Sstar_from_SP', ""],
227  ['CT_from_t', ""],
228  ['deltaSA_from_SP', ""],
229  ['SR_from_SP', ""],
230  ['SP_from_SR', ""],
231  ['SP_from_SA', ""],
232  ['Sstar_from_SA', ""],
233  ['SA_from_Sstar', ""],
234  ['SP_from_Sstar', ""],
235  ['pt_from_CT', ""],
236  ['t_from_CT', ""],
237  ['CT_from_pt', ""],
238  ['pt0_from_t', ""],
239  ['pt_from_t', ""],
240  ['z_from_p', ""],
241  ['p_from_z', ""],
242  ['entropy_from_pt', ""],
243  ['pt_from_entropy', ""],
244  ['CT_from_entropy', ""],
245  ['entropy_from_t', ""],
246  ['adiabatic_lapse_rate_from_CT', ""],
247  ['specvol', ""],
248  ['alpha', ""],
249  ['beta', ""],
250  ['alpha_on_beta', ""],
251  ['v_vab', ""],
252  ['alpha_vab', ""],
253  ['beta_vab', ""],
254  ['v_SA', ""],
255  ['v_CT', ""],
256  ['v_P', ""],
257  ['v_SA_SA', ""],
258  ['v_SA_CT', ""],
259  ['v_CT_CT', ""],
260  ['v_SA_P', ""],
261  ['v_CT_P', ""],
262  ['v_SA_wrt_h', ""],
263  ['v_h', ""],
264  ['v_SA_SA_wrt_h', ""],
265  ['v_SA_h', ""],
266  ['v_h_h', ""],
267  ['specvol_anom_standard', ""],
268  ['rho', ""],
269  ['rho_rab', ""],
270  ['alpha_rab', ""],
271  ['beta_rab', ""],
272  ['rho_SA', ""],
273  ['rho_CT', ""],
274  ['rho_P', ""],
275  ['rho_SA_SA', ""],
276  ['rho_SA_CT', ""],
277  ['rho_CT_CT', ""],
278  ['rho_SA_P', ""],
279  ['rho_CT_P', ""],
280  ['rho_SA_wrt_h', ""],
281  ['rho_h', ""],
282  ['rho_SA_SA_wrt_h', ""],
283  ['rho_SA_h', ""],
284  ['rho_h_h', ""],
285  ['sigma0', ""],
286  ['sigma1', ""],
287  ['sigma2', ""],
288  ['sigma3', ""],
289  ['sigma4', ""],
290  ['sound_speed', ""],
291  ['kappa', ""],
292  ['cabbeling', ""],
293  ['thermobaric', ""],
294  ['SA_from_rho', ""],
295  ['CT_from_rho', ""],
296  ['CT_maxdensity', ""],
297  ['internal_energy', ""],
298  ['enthalpy', ""],
299  ['enthalpy_diff', ""],
300  ['CT_from_enthalpy', ""],
301  ['dynamic_enthalpy', ""],
302  ['h_SA', ""],
303  ['h_CT', ""],
304  ['h_SA_SA', ""],
305  ['h_SA_CT', ""],
306  ['h_CT_CT', ""],
307  ['CT_SA', ""],
308  ['CT_pt', ""],
309  ['CT_SA_SA', ""],
310  ['CT_SA_pt', ""],
311  ['CT_pt_pt', ""],
312  ['eta_SA', ""],
313  ['eta_CT', ""],
314  ['eta_SA_SA', ""],
315  ['eta_SA_CT', ""],
316  ['eta_CT_CT', ""],
317  ['pt_SA', ""],
318  ['pt_CT', ""],
319  ['pt_SA_SA', ""],
320  ['pt_SA_CT', ""],
321  ['pt_CT_CT', ""],
322  ['CT_freezing', ""],
323  ['CT_freezing_poly', ""],
324  ['t_freezing', ""],
325  ['t_freezing_poly', ""],
326  ['pot_enthalpy_ice_freezing', ""],
327  ['pot_enthalpy_ice_freezing_poly', ""],
328  ['SA_freezing_from_CT', ""],
329  ['SA_freezing_from_CT_poly', ""],
330  ['SA_freezing_from_t', ""],
331  ['SA_freezing_from_t_poly', ""],
332  ['CTfreezing_SA', ""],
333  ['CTfreezing_P', ""],
334  ['CTfreezing_SA_poly', ""],
335  ['CTfreezing_P_poly', ""],
336  ['tfreezing_SA', ""],
337  ['tfreezing_P', ""],
338  ['tfreezing_SA_poly', ""],
339  ['tfreezing_P_poly', ""],
340  ['pot_enthalpy_ice_freezing_SA', ""],
341  ['pot_enthalpy_ice_freezing_P', ""],
342  ['pot_enthalpy_ice_freezing_SA_poly', ""],
343  ['pot_enthalpy_ice_freezing_P_poly', ""],
344  ['latentheat_melting', ""],
345  ['latentheat_evap_CT', ""],
346  ['latentheat_evap_t', ""],
347  ['grav', ""],
348  ['enthalpy_CT_exact', ""],
349  ['h_SA_CT_exact', ""],
350  ['h_CT_CT_exact', ""],
351  ['h_SA_SA_CT_exact', ""],
352  ['h_SA_CT_CT_exact', ""],
353  ['h_CT_CT_CT_exact', ""],
354  ['rho_t_exact', ""],
355  ['pot_rho_t_exact', ""],
356  ['alpha_wrt_t_exact', ""],
357  ['beta_const_t_exact', ""],
358  ['specvol_t_exact', ""],
359  ['sound_speed_t_exact', ""],
360  ['kappa_t_exact', ""],
361  ['enthalpy_t_exact', ""],
362  ['CT_SA_wrt_t', ""],
363  ['CT_T_wrt_t', ""],
364  ['CT_P_wrt_t', ""],
365  ['chem_potential_water_t_exact', ""],
366  ['t_deriv_chem_potential_water_t_exact', ""],
367  ['dilution_coefficient_t_exact', ""],
368  ['deltaSA_atlas', ""],
369  ['Fdelta', ""],
370  ['n2', ""],
371  ['p_mid_n2', ""],
372  ['Tu', ""],
373  ['Rsubrho', ""],
374  ['p_mid_TuRsr', ""],
375  ['n2min', ""],
376  ['n2min_pmid', ""],
377  ['n2min_specvol', ""],
378  ['n2min_alpha', ""],
379  ['n2min_beta', ""],
380  ['n2min_dsa', ""],
381  ['n2min_dct', ""],
382  ['n2min_dp', ""],
383  ['IPVfN2', ""],
384  ['p_mid_IPVfN2', ""],
385  ['n2_lowerlimit', ""],
386  ['mlp', ""],
387  ['geo_strf_dyn_height', ""],
388  ['geo_strf_dyn_height_pc', ""],
389  ['geo_strf_dyn_height_pc_p_mid', ""],
390  ['rho_ice', ""],
391  ['alpha_wrt_t_ice', ""],
392  ['specvol_ice', ""],
393  ['pressure_coefficient_ice', ""],
394  ['sound_speed_ice', ""],
395  ['kappa_ice', ""],
396  ['kappa_const_t_ice', ""],
397  ['internal_energy_ice', ""],
398  ['enthalpy_ice', ""],
399  ['entropy_ice', ""],
400  ['cp_ice', ""],
401  ['chem_potential_water_ice', ""],
402  ['Helmholtz_energy_ice', ""],
403  ['adiabatic_lapse_rate_ice', ""],
404  ['pt0_from_t_ice', ""],
405  ['pt_from_t_ice', ""],
406  ['t_from_pt0_ice', ""],
407  ['pot_enthalpy_from_pt_ice', ""],
408  ['pt_from_pot_enthalpy_ice', ""],
409  ['pot_enthalpy_from_pt_ice_poly', ""],
410  ['pt_from_pot_enthalpy_ice_poly', ""],
411  ['pressure_freezing_CT', ""],
412  ['melting_ice_SA_CT_ratio', ""],
413  ['melting_ice_SA_CT_ratio_poly', ""],
414  ['melting_ice_equilibrium_SA_CT_ratio', ""],
415  ['melting_ice_equilibrium_SA_CT_ratio_poly', ""],
416  ['melting_ice_into_seawater_SA_final', ""],
417  ['melting_ice_into_seawater_CT_final', ""],
418  ['ice_fraction_to_freeze_seawater_SA_freeze', ""],
419  ['ice_fraction_to_freeze_seawater_CT_freeze', ""],
420  ['ice_fraction_to_freeze_seawater_w_Ih', ""],
421  ['dSA_dCT_frazil', ""],
422  ['dSA_dP_frazil', ""],
423  ['dCT_dP_frazil', ""],
424  ['dSA_dCT_frazil_poly', ""],
425  ['dSA_dP_frazil_poly', ""],
426  ['dCT_dP_frazil_poly', ""],
427  ['frazil_properties_potential_SA_final', ""],
428  ['frazil_properties_potential_CT_final', ""],
429  ['frazil_properties_potential_w_Ih_final', ""],
430  ['frazil_properties_potential_poly_SA_final', ""],
431  ['frazil_properties_potential_poly_CT_final', ""],
432  ['frazil_properties_potential_poly_w_Ih_final', ""],
433  ['frazil_properties_SA_final', ""],
434  ['frazil_properties_CT_final', ""],
435  ['frazil_properties_w_Ih_final', ""],
436  ['melting_seaice_SA_CT_ratio', ""],
437  ['melting_seaice_SA_CT_ratio_poly', ""],
438  ['melting_seaice_equilibrium_SA_CT_ratio', ""],
439  ['melting_seaice_equilibrium_SA_CT_ratio_poly', ""],
440  ['melting_seaice_into_seawater_SA_final', ""],
441  ['melting_seaice_into_seawater_CT_final', ""],
442  ['seaice_fraction_to_freeze_seawater_SA_freeze', ""],
443  ['seaice_fraction_to_freeze_seawater_CT_freeze', ""],
444  ['seaice_fraction_to_freeze_seawater_w_Ih', ""]
445 ]
446 rootgrp = Dataset('gsw_data_v3_0.nc', 'r')
447 v = rootgrp.variables
448 d = rootgrp.dimensions
449 
450 version_date = rootgrp.version_date
451 version_number = rootgrp.version_number
452 try:
453  fd = os.open("gsw_mod_check_data.f90", os.O_CREAT|os.O_EXCL|os.O_RDWR, 0644)
454 except:
455  print str(sys.exc_info()[1])
456  print "Will not overwrite gsw_mod_check_data.f90 - exiting."
457  sys.exit(1)
458 out = os.fdopen(fd, "w")
459 out.write("""
460 !
461 !** $Id$
462 !** Extracted from gsw_data_v3_0.nc
463 !
464 !==========================================================================
465 module gsw_mod_check_data
466 !==========================================================================
467 
468 use gsw_mod_kinds
469 
470 implicit none
471 
472 """)
473 
474 dim_format = "integer, parameter :: %s = %d\n"
475 for key, value in work_dims.items():
476  if key != "":
477  out.write(dim_format % (value[1], len(d[key])))
478  out.write(dim_format % (value[2], len(d[value[0]])))
479 
480 out.write("""
481 type gsw_result
482  character (50) :: variable_name
483  real (r8) :: computation_accuracy
484  real (r8), dimension(cast_m,cast_n) :: values
485 end type gsw_result
486 
487 type gsw_result_ice
488  character (50) :: variable_name
489  real (r8) :: computation_accuracy
490  real (r8), dimension(cast_ice_m,cast_ice_n) :: values
491 end type gsw_result_ice
492 
493 type gsw_result_mpres
494  character (50) :: variable_name
495  real (r8) :: computation_accuracy
496  real (r8), dimension(cast_mpres_m,cast_mpres_n) :: values
497 end type gsw_result_mpres
498 
499 type gsw_result_cast
500  character (50) :: variable_name
501  real (r8) :: computation_accuracy
502  real (r8), dimension(cast_n) :: values
503 end type gsw_result_cast
504 
505 """)
506 
507 for var_label, var_name in [var for var in work_vars]:
508  if not var_name:
509  var_name = var_label
510  dims = [len(d[dname]) for dname in v[var_name].dimensions]
511  write_variable(var_label.lower(), dims, v[var_name])
512 
513 for var_label, var_name in [var for var in vars]:
514  if not var_name:
515  var_name = var_label
516  dims = [len(d[dname]) for dname in v[var_name].dimensions]
517  write_structure(var_label, dims, v[var_name])
518 
519 out.write("""
520 end module
521 !--------------------------------------------------------------------------
522 """)
523 out.close()
524 sys.exit(0)
def float2string(val, sformat, addcomma)
str
Definition: c2f.py:15
def write_variable(var_name, dims, v)
def write_structure(var_name, dims, v)