Skip to content

Commit d69ed24

Browse files
committed
Update interpolation funcs
1 parent 68bbe0b commit d69ed24

File tree

2 files changed

+46
-60
lines changed

2 files changed

+46
-60
lines changed

isobars2isentropes/metpy.py

+28-35
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,71 @@
11
#!/usr/bin/env python3
2-
#------------------------------------------------------------------------------#
32
# Interpolate to isentropic levels
4-
# NOTE: File cannot have any print statements! Need to capture output of
5-
# time command
6-
#------------------------------------------------------------------------------#
7-
# Imports
8-
# import cartopy.crs as ccrs
9-
# import cartopy.feature as cfeature
10-
# import matplotlib.pyplot as plt
3+
# NOTE: File cannot have any print statements! Need to capture output of time command.
114
import os
125
import sys
6+
137
import numpy as np
14-
import xarray as xr
8+
159
import metpy.calc as mcalc
10+
import xarray as xr
1611
from metpy.units import units
1712

1813
# File, with optional decoding
19-
if len(sys.argv)!=3:
14+
if len(sys.argv) != 3:
2015
raise ValueError('Require two input args.')
2116
filename = sys.argv[1]
2217
dir = filename.split('/')[0]
23-
nt = int(sys.argv[2]) # number of time chunks; 0 to disable chunking
24-
if nt: # 1 chunk per level
25-
N = 100000 # max chunk size for lon/lat dimensions; want to chunk each 2D slice separately
26-
# N = 1000 # this made no difference
27-
chunks = {'time':nt, 'plev':N, 'lat':N, 'lon':N} # one chunk per horizontal slice, works pretty well
18+
nt = int(sys.argv[2]) # number of time chunks; 0 to disable chunking
19+
if nt: # 1 chunk per level
20+
N = 100000 # max chunk size for space (want to chunk each timestep separately)
21+
chunks = {'time': nt, 'plev': N, 'lat': N, 'lon': N}
2822
data = xr.open_dataset(filename, chunks=chunks, decode_times=False)
2923
else:
3024
data = xr.open_dataset(filename, decode_times=False)
3125

3226
# Interpoland
33-
eps = 1
34-
# thlev = np.array([*range(260, 360, 10), *range(360, 400, 20), *range(400, 800, 50), *range(800, 1600, 200)])
3527
# thlev = np.array([*range(260, 360, 10), *range(360, 400, 20), *range(400, 800, 50)])
3628
# thlev = np.array([*range(300, 360, 10), *range(360, 400, 20)])
37-
# thlev = np.arange(240,400,20) # must be ascending!
38-
thlev = np.array([265, 275, 285, 300, 315, 330, 350, 370, 395, 430, 475, 530, 600, 700, 850])
29+
# thlev = np.arange(240,400,20) # must be ascending!
30+
thlev = [265, 275, 285, 300, 315, 330, 350, 370, 395, 430, 475, 530, 600, 700, 850]
31+
thlev = np.array(thlev)
32+
3933
# Coordinates
4034
time = data['time']
4135
plev = data['plev']
4236
lat = data['lat']
4337
lon = data['lon']
38+
4439
# Variables
45-
# u = data['u'][0]
4640
u = data['u']
4741
v = data['v']
4842
t = data['t']
49-
t = t*units.kelvin
50-
thlev = thlev.astype('float32')*units.kelvin # assign units to input arg
51-
plev = plev.values.astype('float32')*units.hectopascals
43+
t = t * units.kelvin
44+
thlev = thlev.astype('float32') * units.kelvin
45+
plev = plev.values.astype('float32') * units.hectopascals
5246

5347
# Interpolation
5448
# The returned 'p' are pressure along each isentrope
55-
# NOTE: If temps out of bounds get error:
56-
# raise ValueError('Input theta level out of data bounds')
57-
# This should just be a warning, or optionally disabled!
58-
p, t_th, u_th, v_th = mcalc.isentropic_interpolation(thlev, plev, t.values*units.kelvin, u.values, v.values, axis=1, tmpk_out=True) # output isentropes in Kelvin
49+
p, t_th, u_th, v_th = mcalc.isentropic_interpolation(
50+
thlev, plev, t.values * units.kelvin, u.values, v.values, axis=1, tmpk_out=True
51+
)
5952
dims = ('time', 'thlev', 'lat', 'lon')
60-
p = xr.Variable(dims, p.astype('float32'), {'long_name':'pressure', 'units':'hPa'})
53+
p = xr.Variable(dims, p.astype('float32'), {'long_name': 'pressure', 'units': 'hPa'})
6154
t_th = xr.Variable(dims, t_th.astype('float32'), t.attrs)
6255
u_th = xr.Variable(dims, u_th.astype('float32'), u.attrs)
6356
v_th = xr.Variable(dims, v_th.astype('float32'), v.attrs)
57+
6458
# Make dataset, add variables and coordinates
6559
# NOTE: Put coordinates in first, so they come first in ncdump
66-
thlev = xr.Variable('thlev', thlev, {'long_name':'potential_temperature', 'units':'K'})
67-
out = xr.Dataset({}, coords={'time':time, 'thlev':thlev, 'lat':lat, 'lon':lon})
68-
for name,data in zip(('p','t','u','v'),(p,t_th,u_th,v_th)):
60+
thlev = xr.Variable(
61+
'thlev', thlev, {'long_name': 'potential_temperature', 'units': 'K'}
62+
)
63+
out = xr.Dataset({}, coords={'time': time, 'thlev': thlev, 'lat': lat, 'lon': lon})
64+
for name, data in zip(('p', 't', 'u', 'v'), (p, t_th, u_th, v_th)):
6965
out[name] = data
70-
# out = xr.Dataset({'p':p, 't':t_th, 'u':u_th, 'v':v_th},
71-
# {'thlev':thlev, 'lon':lon, 'lat':lat})
7266

7367
# Save file
7468
outname = f'{dir}/isentropes_py{nt}.nc'
7569
if os.path.exists(outname):
7670
os.remove(outname)
77-
out.to_netcdf(outname, mode='w') # specify whether we did chunking
78-
71+
out.to_netcdf(outname, mode='w') # specify whether we did chunking

isobars2isentropes/ncl.ncl

+18-25
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
;------------------------------------------------------------------------------;
21
; Interpolate to isentropic levels
3-
;------------------------------------------------------------------------------;
4-
qq = integertochar(34) ; a double quote; only way to put inside string! yuck.
2+
qq = integertochar(34) ; a double quote
53
demo = "ncl 'filename=" + qq + "foobar" + qq + "' or " + qq + "filename=\" + qq + "foobar\" + qq + qq + "."
64
if (.not. isvar("filename")) then
75
print("fatal:File name must be passed as variable 'filename' as follows: " + demo)
8-
exit ; almost impossible to put double-quote in string
6+
exit
97
end if
108
if (.not. isvar("outname")) then
119
print("fatal:Output name must be passed as variable 'outname' as follows: " + demo)
12-
exit ; almost impossible to put double-quote in string
10+
exit
1311
end if
1412

1513
; Read file
1614
f = addfile(filename, "r") ; just read data from here
15+
1716
; Coordinates
1817
time = f->time
1918
plev = f->plev
@@ -24,18 +23,15 @@ lat@axis = "Y"
2423
lon@axis = "X"
2524

2625
; Get potential temp
27-
; p0 = 1013.25
2826
t = f->t
29-
p0 = 1000.0 ; more common to make this the reference pressure
27+
p0 = 1000.0
3028
kappa = 0.286
31-
theta = t*conform(t, (p0/plev)^kappa, (/1/)) ; calculate potential temperature
29+
theta = t * conform(t, (p0 / plev)^kappa, (/1/))
3230
delete(t)
3331

34-
; The theta coordinates
35-
; Should go in *same order* as pressure coordinates (pressure increasing,
36-
; so theta decreasing)
37-
; thlev = ispan(400,240,20)*1.0 ; specify desired isentropic levels
38-
thlev = (/265, 275, 285, 300, 315, 330, 350, 370, 395, 430, 475, 530, 600, 700, 850/)*1.0
32+
; The theta coordinates. Should go in *same order* as pressure coordinates.
33+
; thlev = ispan(400, 240, 20) *1.0 ; specify desired isentropic levels
34+
thlev = 1.0 * (/265, 275, 285, 300, 315, 330, 350, 370, 395, 430, 475, 530, 600, 700, 850/)
3935
thlev = thlev(::-1)
4036
thlev!0 = "thlev"
4137
thlev&thlev = thlev ; this is apparently necessary
@@ -46,46 +42,43 @@ thlev@axis = "Z"
4642
; Output file
4743
; Add coordinates so they appear first in order
4844
; TODO: Add coordinates and whatnot
49-
; dir = str_split(filename, "/")
50-
; dir := dir(0)
51-
; system("rm " + dir + "/isentropes_ncl.nc 2>/dev/null") ; remove file
52-
system("rm " + outname + " 2>/dev/null") ; remove file
53-
o = addfile(outname, "c") ; create new file; don't want to read old values or anything
54-
filedimdef(o, "time", -1, True) ; unlimited dimension
55-
; print(time)
56-
; print(lat)
57-
; print(thlev)
45+
system("rm " + outname + " 2>/dev/null") ; remove file
46+
o = addfile(outname, "c") ; create new file, don't want to read old values or anything
47+
filedimdef(o, "time", -1, True) ; unlimited dimension
5848
o->time = time
5949
o->thlev = thlev
6050
o->lat = lat
6151
o->lon = lon
6252

6353
; Interpolate
64-
; Don't need to save temperature of course, but would like pressure
6554
names = (/"p", "u", "v"/)
6655
do i=0,dimsizes(names)-1
6756
; Special consideration for p levs
6857
name = names(i)
6958
if (name .eq. "p") then
70-
var_orig = conform(f->t, plev, (/1/)) ; only dimension 1 matches
59+
var_orig = conform(f->t, plev, (/1/))
7160
var_orig@long_name = "pressure"
7261
var_orig@units = "hPa"
7362
else
7463
var_orig = f->$name$
7564
end if
65+
7666
; Interpolate to isentropes
7767
var = int2p_n(theta, var_orig, thlev, 0, 1)
68+
7869
; Dimensions
79-
var!0 = "time" ; name dimensions
70+
var!0 = "time"
8071
var!1 = "thlev"
8172
var!2 = "lat"
8273
var!3 = "lon"
74+
8375
; Coordinates
8476
var&time = time
8577
var&thlev = thlev
8678
var&lat = lat
8779
var&lon = lon
8880
copy_VarAtts(var_orig, var)
81+
8982
; Add to file
9083
o->$name$ = var
9184
delete(var)

0 commit comments

Comments
 (0)