MPAS-JEDI
modelsp_utils.py
Go to the documentation of this file.
1 from copy import deepcopy
2 import datetime as dt
3 from datetime import datetime, timedelta
4 from netCDF4 import Dataset
5 import netCDF4 as nc
6 import numpy as np
7 import os
8 import sys
9 
10 ncWriteFormat = 'NETCDF3_64BIT_OFFSET'
11 
12 fcHours = os.getenv('fcHours', '0')
13 intervalHours = os.getenv('intervalHours', '6')
14 fcNums = os.getenv('fcNums', '1')
15 initDate = os.getenv('start_init', '2018041500')
16 endDate = os.getenv('end_init', '2018051400')
17 diff2exp = os.getenv('diff2exp', 'False')
18 expDirectory = os.getenv('TOP_DIR','/glade/scratch/$user/pandac/')
19 
20 GFSANA_DIR = os.getenv('GFSANA_DIR', 'Please link GFSANA_DIR')
21 expLongNames = os.getenv('expLongNames', 'please set expLongNames')
22 expNames = os.getenv('expNames','please set expNames')
23 #for ci:
24 EXP_DIR1 = os.getenv('FCDIAG_WORK_DIR1','FC1DIAG DIR OR FC2DIAG DIR FOR CONTROL')
25 EXP_DIR2 = os.getenv('FCDIAG_WORK_DIR2','FC1DIAG DIR OR FC2DIAG DIR FOR CURRENT/target exp')
26 exp1Name = os.getenv('exp1Name','name for control expt')
27 exp2Name = os.getenv('exp2Name','name for current/target expt')
28 #
29 aggregatableFileStats = ['RMS','Mean'] #,'STD','MS', 'Min','Max']
30 allFileStats = aggregatableFileStats
31 expStats = 'expmgfs'
32 varNames2d = ['t2m','surface_pressure','q2','u10','v10']
33 varNames3d = ['theta','temperature','rho','pressure','uReconstructZonal','uReconstructMeridional','qv','w']
34 varNames = varNames2d + varNames3d
35 latBands = ['NXTro','Tro','SXTro']
36 latBandsBounds = [90.0, 30.0, -30.0, -90.0]
37 
38 inflationVariables = [
39  'temperature',
40  'uReconstructZonal',
41  'uReconstructMeridional',
42  'spechum',
43  'surface_pressure',
44  'qc',
45  'qi',
46  'qr',
47  'qs',
48  'qg',
49 #non-increment-variables in output stream
50  'qv',
51 ]
52 
53 
54 variableTraits = {
55  'temperature': {
56  'templateVar': '2D-c-c',
57  'units': 'K',
58  'long_name': 'temperature',
59  },
60  'uReconstructZonal': {
61  'templateVar': '2D-c-c',
62  'units': 'm s^{-1}',
63  'long_name': 'Zonal component of reconstructed horizontal velocity at cell centers',
64  },
65  'uReconstructMeridional': {
66  'templateVar': '2D-c-c',
67  'units': 'm s^{-1}',
68  'long_name': 'Meridional component of reconstructed horizontal velocity at cell centers',
69  },
70  'spechum': {
71  'templateVar': '2D-c-c',
72  'units': 'kg kg^{-1}',
73  'long_name': 'Specific humidity',
74  },
75  'surface_pressure': {
76  'templateVar': '1D-c',
77  'units': 'Pa',
78  'long_name': 'Diagnosed surface pressure',
79  },
80  'qc': {
81  'templateVar': '2D-c-c',
82  'units': 'kg kg^{-1}',
83  'long_name': 'Cloud water mixing ratio',
84  },
85  'qi': {
86  'templateVar': '2D-c-c',
87  'units': 'kg kg^{-1}',
88  'long_name': 'Ice mixing ratio',
89  },
90  'qr': {
91  'templateVar': '2D-c-c',
92  'units': 'kg kg^{-1}',
93  'long_name': 'Rain mixing ratio',
94  },
95  'qs': {
96  'templateVar': '2D-c-c',
97  'units': 'kg kg^{-1}',
98  'long_name': 'Snow mixing ratio',
99  },
100  'qg': {
101  'templateVar': '2D-c-c',
102  'units': 'kg kg^{-1}',
103  'long_name': 'Graupel mixing ratio',
104  },
105  'qv': {
106  'templateVar': '2D-c-c',
107  'units': 'kg kg^{-1}',
108  'long_name': 'Water vapor mixing ratio',
109  },
110 # 'pressure_base': '2D-c-c',
111 # 'pressure_p': '2D-c-c',
112 # 'theta': '2D-c-c',
113 # 'rho': '2D-c-c',
114 ## 'u': '2D-e-c',
115 # 'xice': '1D-c',
116 # 'snowc': '1D-c',
117 # 'skintemp': '1D-c',
118 # 'snowh': '1D-c',
119 # 'vegfra': '1D-c',
120 # 'u10': '1D-c',
121 # 'v10': '1D-c',
122 # 'lai': '1D-c',
123 # 'smois': '2D-c-s',
124 # 'tslb': '2D-c-s',
125 ## 'w': '2D-c-w',
126 # 're_cloud': '2D-c-c',
127 # 're_ice': '2D-c-c',
128 # 're_snow': '2D-c-c',
129 # 'cldfrac': '2D-c-c',
130 # TODO: replace template variables with actual dimensions?
131 # 'temperature': [nCells, nVertLevels],
132 # 'uReconstructZonal': [nCells, nVertLevels],
133 # 'uReconstructMeridional': [nCells, nVertLevels],
134 # 'spechum': [nCells, nVertLevels],
135 # 'surface_pressure': [nCells],
136 }
137 templateVariables = {
138  '1D-c': 'surface_pressure',
139  '2D-c-c': 'theta',
140 # '2D-c-w': 'w',
141 # '2D-e-c': 'u',
142 # '2D-c-s': 'smois',
143 }
144 
145 #setting for 120km res.:
146 nlevelSurface = 1
147 nlevels = 55
148 nlevelsP1 =56
149 ncells = 40962
150 
151 #
152 fcRange = int(fcHours)/24.
153 interval = int(intervalHours)/24
154 SDATE = datetime.strptime(initDate,'%Y%m%d%H')
155 EDATE = datetime.strptime(endDate,'%Y%m%d%H')
156 
157 DATEINC = dt.timedelta(days=interval)
158 expLongNames = expLongNames.split()
159 expNames = expNames.split()
160 nExp = len(expNames)
161 
162 def getGridFile(date = initDate, gfsAnaDir = GFSANA_DIR, nCells = 40962):
163  date = initDate
164  print(date)
165  d = datetime.strptime(date,'%Y%m%d%H')
166  filedate= d.strftime('%Y-%m-%d_%H.%M.%S')
167 
168  return gfsAnaDir+'/x1.'+str(nCells)+'.init.'+filedate+'.nc'
169 
170 def readGrid(date=initDate, gridFile=None, returnR=False):
171  if gridFile is None: gridFile = getGridFile(date)
172  ncData = Dataset(gridFile, 'r')
173  lats = np.array( ncData.variables['latCell'][:] ) * 180.0 / np.pi
174  lons = np.array( ncData.variables['lonCell'][:] ) * 180.0 / np.pi
175  R = ncData.__dict__['sphere_radius']
176  ncData.close()
177 
178  if returnR:
179  return (lats, lons, R)
180 
181  return (lats,lons)
182 
183 def hasVar(varName, ncFile):
184  ncData = Dataset(ncFile, 'r')
185  ncData.close()
186  return (varName in ncData.variables)
187 
188 def varDims(varName, ncFile):
189  src = Dataset(ncFile, 'r')
190  dims = deepcopy(src.variables[varName].dimensions)
191  src.close()
192  return dims
193 
194 def varAttrs(varName, ncFile):
195  src = Dataset(ncFile, 'r')
196  attrs = deepcopy(src[varName].__dict__)
197  src.close()
198  return attrs
199 
200 def varDatatype(varName, ncFile):
201  src = Dataset(ncFile, 'r')
202  datatype = src.variables[varName].datatype
203  src.close()
204  return datatype
205 
206 def getPressure(ncData):
207  pressure_p = np.array( ncData.variables['pressure_p'][0,:,:] )
208  pressure_base = np.array( ncData.variables['pressure_base'][0,:,:] )
209  pressure = pressure_p + pressure_base
210  return pressure
211 
212 def getTemperature(ncFile):
213  ncData = Dataset(ncFile, 'r')
214  rgas = 287.0
215  cp = 1004.5
216  pressure = getPressure(ncData)
217  theta = np.array(ncData.variables['theta'][0,:,:])
218  tmp1 = (1.e5 / pressure)**(rgas / cp)
219  temperature = np.subtract(np.divide(theta, tmp1), 273.15)
220 
221  ncData.close()
222 
223  return temperature
224 
225 def varRead(varName, ncFile):
226  if (varName == 'temperature'):
227  varVals = getTemperature(ncFile)
228  else:
229  ncData = Dataset(ncFile, 'r')
230  if (varName == 'pressure'):
231  varVals = getPressure(ncData)
232  elif varName in varNames3d:
233  varVals = np.array( ncData.variables[varName][0,:,:] )
234  else:
235  varVals = np.array( ncData.variables[varName][0,:] )
236 
237  if (varName == 'qv' or varName == 'rho' or varName == 'q2'):
238  varVals = varVals * 1000.
239 
240  ncData.close()
241 
242  return varVals
243 
244 def varWrite(varName, varVals, ncFile,
245  varAttrs,
246 # varUnits, varLongName, # could make these args optional
247  dims, datatype):
248  assert os.path.exists(ncFile), 'Only appending to existing file is enabled in varWrite!'
249 
250  dst = Dataset(ncFile, 'a', format=ncWriteFormat)
251  nDims = len(varVals.shape)
252 
253  if not hasVar(varName, ncFile):
254  dst.createVariable(varName, datatype, dims)
255 
256 # # create variable attributes
257 # assert isinstance(varUnits, str), 'varUnits required when adding a new variable'
258 # assert isinstance(varUnits, str), 'varLongName required when adding a new variable'
259 
260 # attrs = {
261 # 'units': varUnits,
262 # 'long_name': varLongName,
263 # }
264  dst[varName].setncatts(varAttrs)
265 
266  if 'Time' in dims:
267  if nDims == 1:
268  dst[varName][0,:] = np.asarray(varVals[:], dtype=datatype)
269  elif nDims == 2:
270  dst[varName][0,:,:] = np.asarray(varVals[:,:], dtype=datatype)
271  else:
272  if nDims == 1:
273  dst[varName][:] = np.asarray(varVals[:], dtype=datatype)
274  elif nDims == 2:
275  dst[varName][:,:] = np.asarray(varVals[:,:], dtype=datatype)
276 
277  dst.close()
278 
279 def createHeaderOnlyFile(infile, outfile, date):
280  assert os.path.exists(infile), 'infile must exist!'
281  src = Dataset(infile, 'r')
282  dst = Dataset(outfile, 'w', format=ncWriteFormat)
283 
284  # copy global attributes all at once via dictionary
285  dstatts = deepcopy(src.__dict__)
286 
287  d = datetime.strptime(date, '%Y%m%d%H')
288  confdate = d.strftime('%Y-%m-%d_%H:%M:%S')
289  dstatts['config_start_time'] = confdate
290  dstatts['config_stop_time'] = confdate
291  dst.setncatts(dstatts)
292 
293  # copy dimensions
294  for name, dimension in src.dimensions.items():
295  dst.createDimension(
296  name, (len(dimension) if not dimension.isunlimited() else None))
297 
298  requiredMetaVars = ['xtime']
299  for varname in requiredMetaVars:
300  srcvar = src.variables[varname]
301  # create variable in destination
302  dst.createVariable(
303  varname,
304  srcvar.datatype,
305  srcvar.dimensions)
306 
307  # copy variable attributes all at once via dictionary
308  dst[varname].setncatts(src[varname].__dict__)
309 
310  # finally copy variable data
311  if varname == 'xtime':
312  xtime_ = src[varname][0][:]
313  xtime = nc.stringtoarr(confdate, len(src[varname][0][:]))
314  dst[varname][0] = xtime
315  else:
316  if 'Time' in srcvar.dimensions:
317  dst[varname][0,:] = src[varname][0,:]
318  else:
319  dst[varname][:] = src[varname][:]
320 
321  src.close()
322  dst.close()
323 
324 def varDiff(varName, ncFile1, ncFile2):
325  var1 = varRead(varName, ncFile1)
326  var2 = varRead(varName, ncFile2)
327  return var2 - var1
328 
329 def main():
330  print ('This is not a runnable program.')
331  os._exit(0)
332 
333 if __name__ == '__main__': main()
334 
def varAttrs(varName, ncFile)
def hasVar(varName, ncFile)
def readGrid(date=initDate, gridFile=None, returnR=False)
def getGridFile(date=initDate, gfsAnaDir=GFSANA_DIR, nCells=40962)
def varDims(varName, ncFile)
def getTemperature(ncFile)
def varRead(varName, ncFile)
def varDatatype(varName, ncFile)
def createHeaderOnlyFile(infile, outfile, date)
def varDiff(varName, ncFile1, ncFile2)
def varWrite(varName, varVals, ncFile, varAttrs, dims, datatype)
def getPressure(ncData)