@@ -75,11 +75,14 @@ def coarsegrain_reference_dataset(ds, resolution, operator):
75
75
operator = op .Operator2
76
76
elif operator == 'Operator4' :
77
77
operator = op .Operator4
78
+ elif operator == 'Operator5' :
79
+ operator = op .Operator5
78
80
else :
79
81
raise ValueError ('operator must be Operator1 or Operator2' )
80
82
81
83
dsf = xr .Dataset ()
82
84
for var in ['q' , 'u' , 'v' , 'psi' ]:
85
+ print (f'var={ var } ' )
83
86
dsf [var ] = operator (ds [var ], resolution )
84
87
85
88
# Coarsegrain spectral flux
@@ -191,22 +194,98 @@ def compute_Eflux(ds):
191
194
192
195
return normalized_differences , differences , scales
193
196
197
+ def dataset_statistics (ds , delta = 0.25 , ** kw_ispec ):
198
+ '''
199
+ If path is given, the dataset is returned as is
200
+ If dataset is given, statistics are computed
201
+ '''
202
+ if isinstance (ds , str ):
203
+ ds = xr .open_mfdataset (ds , combine = 'nested' , concat_dim = 'run' , decode_times = False , chunks = {'time' :1 , 'run' :1 })
204
+ if 'years' not in ds ['time' ].attrs :
205
+ ds ['time' ] = ds ['time' ] / 360
206
+ ds ['time' ].attrs = {'long_name' :'time [$years$]' }
207
+ return ds
208
+
209
+ def KE (ds ):
210
+ return (ds .u ** 2 + ds .v ** 2 ) * 0.5
211
+
212
+ def KE_time (ds ):
213
+ if 'run' in ds .dims :
214
+ dims = ['run' , 'x' , 'y' ]
215
+ else :
216
+ dims = ['x' , 'y' ]
217
+ return op .ave_lev (KE (ds ), delta = delta ).mean (dims )
218
+
219
+ stats = xr .Dataset ()
220
+
221
+ m = pyqg .QGModel (nx = len (ds .x ), log_level = 0 )
222
+ for key in ['APEflux' , 'APEgenspec' , 'Dissspec' , 'ENSDissspec' ,
223
+ 'ENSflux' , 'ENSfrictionspec' , 'ENSgenspec' , 'ENSparamspec' ,
224
+ 'Ensspec' , 'KEflux' , 'KEfrictionspec' , 'KEspec' , 'entspec' ,
225
+ 'paramspec' , 'paramspec_APEflux' , 'paramspec_KEflux' ]:
226
+ if key not in ds .keys ():
227
+ continue
228
+ var = ds [key ]
229
+ if 'run' in ds .dims :
230
+ var = var .mean (dim = 'run' )
231
+ if 'lev' in var .dims :
232
+ sps = []
233
+ for z in [0 ,1 ]:
234
+ k , sp = calc_ispec (m , var .isel (lev = z ).values , ** kw_ispec )
235
+ sps .append (sp )
236
+ sp = np .stack (sps , axis = 0 )
237
+ stats [key + 'r' ] = \
238
+ xr .DataArray (sp , dims = ['lev' , 'kr' ],
239
+ coords = [[1 ,2 ], coord (k , 'wavenumber, $m^{-1}$' )])
240
+
241
+ var_mean = op .ave_lev (var , delta )
242
+ k , sp = calc_ispec (m , var_mean .values , ** kw_ispec )
243
+ stats [key + 'r_mean' ] = \
244
+ xr .DataArray (sp , dims = ['kr' ],
245
+ coords = [coord (k , 'wavenumber, $m^{-1}$' )])
246
+ else :
247
+ k , sp = calc_ispec (m , var .values , ** kw_ispec )
248
+ stats [key + 'r' ] = \
249
+ xr .DataArray (sp , dims = ['kr' ],
250
+ coords = [coord (k , 'wavenumber, $m^{-1}$' )])
251
+
252
+ budget_sum = 0
253
+ for key in ['KEfluxr' , 'APEfluxr' , 'APEgenspecr' , 'KEfrictionspecr' ,
254
+ 'paramspec_APEfluxr' , 'paramspec_KEfluxr' ]:
255
+ if key in stats .keys ():
256
+ budget_sum += stats [key ]
257
+ stats ['Energysumr' ] = budget_sum
258
+
259
+ Eflux = 0
260
+ for key in ['KEfluxr' , 'APEfluxr' , 'paramspec_KEfluxr' , 'paramspec_APEfluxr' ]:
261
+ if key in stats .keys ():
262
+ Eflux = Eflux + stats [key ]
263
+ stats ['Efluxr' ] = Eflux
264
+
265
+ stats ['KE_time' ] = KE_time (ds )
266
+
267
+ if 'years' not in stats ['time' ].attrs :
268
+ stats ['time' ] = stats ['time' ] / 360
269
+ stats ['time' ].attrs = {'long_name' :'time [$years$]' }
270
+
271
+ return stats
272
+
194
273
def cache_path (path ):
195
274
dir = os .path .dirname (path )
196
275
files = os .path .basename (path )
197
276
#https://www.delftstack.com/howto/python/str-to-hex-python/
198
277
cachename = files .encode ('utf-8' ).hex () + '.cache_netcdf'
199
278
return os .path .join (dir ,cachename )
200
279
201
- def dataset_smart_read (path , delta = 0.25 , read_cache = True ):
280
+ def dataset_smart_read (path , delta = 0.25 , read_cache = True , compute_all = True ):
202
281
#print(path)
203
282
nfiles = len (glob .glob (path ))
204
283
#if nfiles < 10:
205
284
#print('Warning! Computations are unstable. Number of files is less than 10 and equal to', nfiles)
206
285
cache = cache_path (path )
207
286
if os .path .exists (cache ) and read_cache :
208
287
#print('Read cache ' + cache)
209
- ds1 = xr .open_mfdataset (path , combine = 'nested' , concat_dim = 'run' , decode_times = False )
288
+ ds1 = xr .open_mfdataset (path , combine = 'nested' , concat_dim = 'run' , decode_times = False , chunks = { 'time' : 1 , 'run' : 1 } )
210
289
ds2 = xr .open_dataset (cache )
211
290
ds1 ['time' ] = ds1 ['time' ] / 360
212
291
ds1 ['time' ].attrs = {'long_name' :'time [$years$]' }
@@ -216,7 +295,7 @@ def dataset_smart_read(path, delta=0.25, read_cache=True):
216
295
#print('Delete cache ' + cache)
217
296
os .remove (cache )
218
297
219
- ds = xr .open_mfdataset (path , combine = 'nested' , concat_dim = 'run' , decode_times = False )
298
+ ds = xr .open_mfdataset (path , combine = 'nested' , concat_dim = 'run' , decode_times = False , chunks = { 'time' : 1 , 'run' : 1 } )
220
299
ds ['time' ] = ds ['time' ] / 360
221
300
ds ['time' ].attrs = {'long_name' :'time [$years$]' }
222
301
@@ -238,13 +317,18 @@ def KE_time(ds):
238
317
def Vabs (ds ):
239
318
return np .sqrt (2 * KE (ds ))
240
319
241
- stats ['omega' ] = relative_vorticity (ds )
242
- stats ['KE' ] = KE (ds )
243
- stats ['Ens' ] = Ens (ds )
244
- stats ['Vabs' ] = Vabs (ds )
320
+ if compute_all :
321
+ stats ['omega' ] = relative_vorticity (ds )
322
+ stats ['KE' ] = KE (ds )
323
+ stats ['Ens' ] = Ens (ds )
324
+ stats ['Vabs' ] = Vabs (ds )
245
325
246
326
def PDF_var (ds , var , lev ):
247
- ds_ = ds .isel (time = AVERAGE_SLICE_ANDREW ).isel (lev = lev )
327
+ if compute_all :
328
+ time = AVERAGE_SLICE_ANDREW
329
+ else :
330
+ time = slice (- 1 , None )
331
+ ds_ = ds .isel (time = time ).isel (lev = lev )
248
332
if var == 'KE' :
249
333
values = KE (ds_ )
250
334
elif var == 'Ens' :
@@ -268,7 +352,12 @@ def PDF_var(ds, var, lev):
268
352
points , density = PDF_histogram (values , xmin = xmin , xmax = xmax )
269
353
return xr .DataArray (density , dims = f'{ var } _{ lev } ' , coords = [points ])
270
354
271
- for var in ['q' , 'u' , 'v' , 'KE' , 'Ens' ]:
355
+ if compute_all :
356
+ variables = ['q' , 'u' , 'v' , 'KE' , 'Ens' ]
357
+ else :
358
+ variables = ['q' , 'u' , 'v' , 'KE' ]
359
+
360
+ for var in variables :
272
361
for lev in [0 ,1 ]:
273
362
stats [f'PDF_{ var } { lev + 1 } ' ] = PDF_var (ds , var , lev )
274
363
0 commit comments