Skip to content

Commit b454a2b

Browse files
author
Jing Feng
committed
fix stability issue
1 parent 0346518 commit b454a2b

8 files changed

Lines changed: 84220 additions & 99 deletions

File tree

cloud_rad_scheme/compute_rain.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55

66
from .optics import optics_var
77
from .spec_util import mie_coefficients, read_refractive_index, create_list
8+
from os.path import exists
89

9-
10-
def compute_rain(file_outres, file_lut, file_pade, a, wavenum_out, source, band_limit, re_range_lut,
10+
def compute_rain(file_outres, file_band, file_curvefit, file_pade, a, wavenum_out, source, band_limit,
1111
re_range_pade, re_ref_pade, thin_flag):
1212
rau = 996*10**3 # droplet density g/m**3
1313
cm_to_um = 10**4
1414
freq = cm_to_um/wavenum_out
1515
m = read_refractive_index(freq)
1616
nwav = len(wavenum_out)
1717

18-
r = create_list(0.1,re_range_lut[-1,-1]*3,5) # droplet dimension
18+
r = create_list(0.1,re_range_pade[-1,-1]*3,5) # droplet dimension
1919
nr = len(r)
2020
asy = np.zeros((nr,nwav))
2121
ext = np.zeros((nr,nwav))
@@ -39,20 +39,8 @@ def compute_rain(file_outres, file_lut, file_pade, a, wavenum_out, source, band_
3939
optics_band = optics_outres.thin_average(source,band_limit)
4040
else:
4141
optics_band = optics_outres.thick_average(source,band_limit)
42+
optics_band.write_lut_spectralpoints(file_band)
4243

43-
v_range = np.zeros(np.shape(re_range_lut))
44-
try:
45-
v_range[0,:] = interp1d(optics_band.r,optics_band.v**(1/3.0))(re_range_lut[0,:])**3
46-
except:
47-
print('WARNING: look-up-table size range re_range exceeds lower-limit at '+'{:4.1f}'.format(optics_band.r[0])+' microns')
48-
v_range[0,:] = interp1d(optics_band.r,optics_band.v**(1/3.0),fill_value="extrapolate")(re_range_lut[0,:])**3
49-
try:
50-
v_range[1,:] = interp1d(optics_band.r,optics_band.v**(1/3.0))(re_range_lut[1,:])**3
51-
except:
52-
print('WARNING: look-up-table size range re_range exceeds upper-limit at '+'{:4.1f}'.format(optics_band.r[-1])+' microns')
53-
v_range[1,:] = interp1d(optics_band.r,optics_band.v**(1/3.0),fill_value="extrapolate")(re_range_lut[1,:])**3
54-
# output parameterization netcdf file following piece-wise linear interpolation
55-
optics_band.create_lut_coeff(re_range_lut,v_range,file_lut)
5644
v_range = np.zeros(np.shape(re_range_pade))
5745
try:
5846
v_range[0,:] = interp1d(optics_band.r,optics_band.v**(1/3.0))(re_range_pade[0,:])**3

cloud_rad_scheme/compute_snow.py

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,44 @@
66
from .optics import optics_var
77
from .read_yang_ice_library import read_yang_ice_library
88

9-
def compute_snow(path_ori, habit, roughness, file_outres, file_lut, file_pade, a, wavenum_out, source,
9+
def compute_snow(path_ori, habit, roughness, file_outres, file_band, file_pade, a, wavenum_out, source,
1010
band_limit, re_range_lut, re_range_pade, re_ref_pade, thin_flag):
1111
rau = 917*10**3 # ice density g/m**3
1212
nwav = len(wavenum_out)
13-
r = create_list(1,10000)
13+
r = create_list(1,10000,20)
1414
nr = len(r)
15-
asy = np.zeros((nr,nwav))
16-
ext = np.zeros((nr,nwav))
17-
ssa = np.zeros((nr,nwav))
18-
sca = np.zeros((nr,nwav))
1915
r_out = np.zeros((nr,))
2016
v = np.zeros((nr,))
2117
s = np.zeros((nr,))
2218

2319
[wavenum_in, r_in, d_in, s_in, v_in, ext_cross_section_in, sca_cross_section_in, asy_in] =\
2420
read_yang_ice_library(path_ori, habit, roughness)
25-
21+
nwav = len(wavenum_in)
22+
asy = np.zeros((nr,nwav))
23+
ext = np.zeros((nr,nwav))
24+
ssa = np.zeros((nr,nwav))
25+
sca = np.zeros((nr,nwav))
26+
for i in range(nr):
27+
r_out[i], s[i], v[i], ext[i,:], sca[i,:], ssa[i,:], asy[i,:] = compute_Yang_singlesize(a,2.0*r[i],rau,wavenum_in,wavenum_in,d_in, s_in, v_in, ext_cross_section_in, sca_cross_section_in, asy_in)
28+
optics_outres=optics_var(r_out, s, v, ext, sca, ssa, asy, rau, wavenum=wavenum_in)
29+
optics_outres.write_lut_spectralpoints(file_outres)
30+
31+
nwav = len(wavenum_out)
32+
asy = np.zeros((nr,nwav))
33+
ext = np.zeros((nr,nwav))
34+
ssa = np.zeros((nr,nwav))
35+
sca = np.zeros((nr,nwav))
2636
# Mie Theory & integrate over gamma PSD
2737
for i in range(nr):
2838
r_out[i], s[i], v[i], ext[i,:], sca[i,:], ssa[i,:], asy[i,:] = compute_Yang_singlesize(a,2.0*r[i],rau,wavenum_out,wavenum_in,d_in, s_in, v_in, ext_cross_section_in, sca_cross_section_in, asy_in)
29-
3039
optics_outres=optics_var(r_out, s, v, ext, sca, ssa, asy, rau, wavenum=wavenum_out)
31-
optics_outres.write_lut_spectralpoints(file_outres)
40+
3241
if thin_flag==True:
3342
optics_band = optics_outres.thin_average(source,band_limit)
3443
else:
3544
optics_band = optics_outres.thick_average(source,band_limit)
45+
optics_band.write_lut_spectralpoints(file_band)
3646

37-
v_range = np.zeros(np.shape(re_range_lut))
38-
try:
39-
v_range[0,:] = interp1d(optics_band.r,optics_band.v**(1/3.0))(re_range_lut[0,:])**3
40-
except:
41-
print('WARNING: look-up-table size range re_range exceeds lower-limit at '+'{:4.1f}'.format(optics_band.r[0])+' microns')
42-
v_range[0,:] = interp1d(optics_band.r,optics_band.v**(1/3.0),fill_value="extrapolate")(re_range_lut[0,:])**3
43-
try:
44-
v_range[1,:] = interp1d(optics_band.r,optics_band.v**(1/3.0))(re_range_lut[1,:])**3
45-
except:
46-
print('WARNING: look-up-table size range re_range exceeds upper-limit at '+'{:4.1f}'.format(optics_band.r[-1])+' microns')
47-
v_range[1,:] = interp1d(optics_band.r,optics_band.v**(1/3.0),fill_value="extrapolate")(re_range_lut[1,:])**3
48-
# output parameterization netcdf file following piece-wise linear interpolation
49-
optics_band.create_lut_coeff(re_range_lut,v_range,file_lut)
5047
v_range = np.zeros(np.shape(re_range_pade))
5148
try:
5249
v_range[0,:] = interp1d(optics_band.r,optics_band.v**(1/3.0))(re_range_pade[0,:])**3
@@ -64,7 +61,7 @@ def compute_snow(path_ori, habit, roughness, file_outres, file_lut, file_pade, a
6461

6562
def compute_Yang_singlesize(a,d,rau,wavenum_out,wavenum_in,d_in, s_in, v_in, ext_cross_section_in, sca_cross_section_in, asy_in):
6663
nwav = len(wavenum_in)
67-
dr = d/10.0 # um, integrate step of particle size
64+
dr = min(d/100.0,1) # um, integrate step of particle size
6865
d_hres = np.append(np.array([]), np.arange(dr, d*3.5, dr)) # radius
6966
d = np.array([d])
7067

cloud_rad_scheme/optics.py

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import netCDF4 as nc
44
import numpy as np
55
from scipy.interpolate import CubicSpline
6+
from scipy.interpolate import interp1d
67
from scipy.optimize import curve_fit
78
from scipy.stats import gamma
89

@@ -53,18 +54,31 @@ def write_lut_spectralpoints(self,file_out):
5354
"""generate piecewise-linear fit coefficients and write to a given path
5455
write look-up-table parameterization
5556
"""
56-
nband = len(self.wavenum)
57+
try:
58+
nband = len(self.wavenum)
59+
except:
60+
nband = np.shape(self.band_limit)[0]
5761
nr = len(self.r)
5862
with nc.Dataset(file_out, mode='w', format='NETCDF4_CLASSIC') as ncfile:
5963
# create Dimension
6064
ncfile.createDimension('Band', nband)
6165
ncfile.createDimension('Re', nr)
6266
ncfile.createDimension('Constant', 1)
6367
# create Variable
64-
freq = ncfile.createVariable('freq', np.float32, ('Band'))
65-
freq.units = 'micrometer'
66-
wavenum = ncfile.createVariable('wavenum', np.float32, ('Band'))
67-
wavenum.units = 'cm-1'
68+
try:
69+
wavenum = ncfile.createVariable('wavenum', np.float32, ('Band'))
70+
wavenum.units = 'cm-1'
71+
freq = ncfile.createVariable('freq', np.float32, ('Band'))
72+
freq.units = 'micrometer'
73+
wavenum[:] = self.wavenum
74+
freq[:] = cm_to_um/wavenum[:]
75+
except:
76+
Band_limits_lwr = ncfile.createVariable('Band_limits_lwr', np.float32, ('Band',))
77+
Band_limits_lwr.units = 'cm-1'
78+
Band_limits_upr = ncfile.createVariable('Band_limits_upr', np.float32, ('Band',))
79+
Band_limits_upr.units = 'cm-1'
80+
Band_limits_lwr[:] = self.band_limit[:,0]
81+
Band_limits_upr[:] = self.band_limit[:,1]
6882
re = ncfile.createVariable('re', np.float32, ('Re'))
6983
re.units = 'micrometer'
7084
v = ncfile.createVariable('v', np.float32, ('Re'))
@@ -79,8 +93,6 @@ def write_lut_spectralpoints(self,file_out):
7993
asy.units = 'unitless'
8094
rau = ncfile.createVariable('rau', np.float32, ('Constant'))
8195
rau.units = 'g/m**3'
82-
wavenum[:] = self.wavenum
83-
freq[:] = cm_to_um/wavenum[:]
8496
re[:] = self.r
8597
v[:] = self.v
8698
s[:] = self.s
@@ -144,9 +156,9 @@ def interp_cloud_optics(self, wavenum_out):
144156
ssa_out = np.zeros((nsize, nwav))
145157
asy_out = np.zeros((nsize, nwav))
146158
for i in range(nsize):
147-
ext_out[i,:] = CubicSpline(self.wavenum, self.ext[i,:])(wavenum_out)
148-
ssa_out[i,:] = CubicSpline(self.wavenum, self.ssa[i,:])(wavenum_out)
149-
asy_out[i,:] = CubicSpline(self.wavenum, self.asy[i,:])(wavenum_out)
159+
ext_out[i,:] = interp1d(self.wavenum, self.ext[i,:],fill_value="extrapolate")(wavenum_out)
160+
ssa_out[i,:] = interp1d(self.wavenum, self.ext[i,:]*self.ssa[i,:],fill_value="extrapolate")(wavenum_out)/ext_out[i,:]
161+
asy_out[i,:] = interp1d(self.wavenum, self.ext[i,:]*self.ssa[i,:]*self.asy[i,:],fill_value="extrapolate")(wavenum_out)/ext_out[i,:]/ssa_out[i,:]
150162
sca_out = ssa_out * ext_out
151163
result = optics_var(self.r, self.s, self.v,
152164
ext_out, sca_out, ssa_out, asy_out,self.rau,
@@ -299,7 +311,6 @@ def create_lut_coeff(self,re_range,v_range,file_out):
299311
lut_asy_a[k,i] = f[1] # a + b*r
300312
lut_asy_b[k,i] = f[0]
301313

302-
303314
def create_pade_coeff(self,re_range,re_ref,v_range,file_out):
304315
"""generate Padé approximantsize coefficients and write to a given path
305316
write look-up-table parameterization
@@ -350,42 +361,64 @@ def create_pade_coeff(self,re_range,re_ref,v_range,file_out):
350361
Particle_Volume_limits_lwr[:] = v_range[0,:]
351362
Particle_Volume_limits_upr[:] = v_range[1,:]
352363

353-
def pade(x, p1, p2, p3, q1, q2, q3):
354-
return (p3 + p2*x + p1*x**2)/(q3 + q2*x + q1*x**2)
364+
re_range[0,0] = re_range[0,0]
355365

366+
def pade(x, p1, p2, p3, q1, q2, q3):
367+
return ((p3) + (p2)*x + (p1)*x**2)/((q3) + (q2)*x + (q1)*x**2)
368+
def pade_abs(x, p1, p2, p3, q1, q2, q3):
369+
return ((p3) + (p2)*x + (p1)*x**2)/(abs(q3)+ abs(q2)*x + abs(q1)*x**2)
370+
def pade_2p2q_abs(x, p2, p3, q2,q3):
371+
return (p3 + p2*x)/(abs(q3) + abs(q2)*x)
372+
def pade_2p2q(x, p2, p3, q2,q3):
373+
return (p3 + p2*x)/(q3+ q2*x)
374+
def piecewise(x,y):
375+
f1 = (y[-1]-y[0])/(x[-1]-x[0])
376+
f2 = y[0] - f1*x[0]
377+
return [f1,f2]
356378
for k in range(nr):
357379
for i in range(nband):
358380
id = np.where((self.r>=re_range[0,k]) & (self.r<re_range[1,k]))
359381
r_sample = self.r[id]
360382
try:
361-
tmp, cov = curve_fit(pade, r_sample-re_ref[k], np.squeeze(self.ext[id,i]))
362-
pade_ext_p[:,k,i] = tmp[:3]
363-
pade_ext_q[:,k,i] = tmp[3:]
383+
tmp, cov = curve_fit(pade_abs, r_sample-re_ref[k], np.squeeze(self.ext[id,i]))
384+
pade_ext_p[:,k,i] = (tmp[:3])
385+
pade_ext_q[:,k,i] = abs(tmp[3:])
364386
except:
365-
# too much degree-of-freedom. using linear fit instead
366-
f = np.polyfit(r_sample, np.squeeze(self.ext[id,i]), 1)
367-
pade_ext_p[:,k,i] = [0, f[0], f[1]] # a + b*r
368-
pade_ext_q[:,k,i] = [0, 0, 1]
387+
try:
388+
tmp, cov = curve_fit(pade, r_sample-re_ref[k], np.squeeze(self.ext[id,i]))
389+
pade_ext_p[:,k,i] = (tmp[:3])
390+
pade_ext_q[:,k,i] = (tmp[3:])
391+
except:
392+
tmp, cov = curve_fit(pade_2p2q_abs, r_sample-re_ref[k], np.squeeze(self.ext[id,i]))
393+
pade_ext_p[:,k,i] = [0, (tmp[0]), (tmp[1])]
394+
pade_ext_q[:,k,i] = [0, abs(tmp[2]), abs(tmp[3])]
395+
# too much degree-of-freedom. using linear fit instead
396+
#f = piecewise(r_sample, np.squeeze(self.ext[id,i]))
397+
#pade_ext_p[:,k,i] = [0, f[0], f[1]] # a + b*r
398+
#pade_ext_q[:,k,i] = [0, 0, 1]
369399

370400
try:
371-
tmp, cov = curve_fit(pade, r_sample-re_ref[k], np.squeeze(self.ssa[id,i]))
372-
pade_ssa_p[:,k,i] = tmp[:3]
373-
pade_ssa_q[:,k,i] = tmp[3:]
401+
tmp, cov = curve_fit(pade_abs, r_sample-re_ref[k], 1-np.squeeze(self.ssa[id,i]))
402+
pade_ssa_p[:,k,i] = abs(tmp[3:])-(tmp[:3])
403+
pade_ssa_q[:,k,i] = abs(tmp[3:])
374404
except:
375405
# too much degree-of-freedom. using linear fit instead
376-
f = np.polyfit(r_sample, np.squeeze(self.ssa[id,i]), 1)
406+
f = piecewise(r_sample, np.squeeze(self.ssa[id,i]))
377407
pade_ssa_p[:,k,i] = [0, f[0], f[1]] # a + b*r
378408
pade_ssa_q[:,k,i] = [0, 0, 1]
379409

380410
try:
381-
tmp, cov = curve_fit(pade, r_sample-re_ref[k], np.squeeze(self.asy[id,i]))
382-
pade_asy_p[:,k,i] = tmp[:3]
383-
pade_asy_q[:,k,i] = tmp[3:]
411+
tmp, cov = curve_fit(pade_abs, r_sample-re_ref[k], 1-np.squeeze(self.asy[id,i]))
412+
pade_asy_p[:,k,i] = abs(tmp[3:])-(tmp[:3])
413+
pade_asy_q[:,k,i] = abs(tmp[3:])
384414
except:
385415
# too much degree-of-freedom. using linear fit instead
386-
f = np.polyfit(r_sample,np.squeeze(self.asy[id,i]),1)
387-
pade_asy_p[:,k,i] = [0, f[0], f[1]] # a + b*r
388-
pade_asy_q[:,k,i] = [0, 0, 1]
416+
tmp, cov = curve_fit(pade_2p2q_abs, r_sample-re_ref[k], 1-np.squeeze(self.asy[id,i]))
417+
pade_asy_p[:,k,i] = [0, abs(tmp[2])-tmp[0], abs(tmp[3])-tmp[1]]
418+
pade_asy_q[:,k,i] = [0, abs(tmp[2]), abs(tmp[3])]
419+
#f = np.polyfit(r_sample,np.squeeze(self.asy[id,i]),1)
420+
#pade_asy_p[:,k,i] = [0, f[0], f[1]] # a + b*r
421+
#pade_asy_q[:,k,i] = [0, 0, 1]
389422

390423
def lognormpdf(x,mu,sigma):
391424
y = 1.0/x/sigma/math.sqrt(2*math.pi) * np.exp(-1.0/2.0*(np.log(x/mu)/sigma)**2)

0 commit comments

Comments
 (0)