-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Latest update of python scripts: 20-04-2020 ([email protected]) From Baptiste: - reorganized sice_lib.py - prevented code to crash when no pixels are suitable for retrieval
- Loading branch information
1 parent
c0c3ef7
commit 44f2cf2
Showing
2 changed files
with
265 additions
and
487 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,12 @@ | ||
# pySICEv1.2 | ||
# pySICEv1.3 | ||
# | ||
# from FORTRAN VERSION 5 | ||
# March 31, 2020 | ||
# | ||
# Update 16-04-2020 ([email protected]) | ||
# Latest update of python script: 20-04-2020 ([email protected]) | ||
# From Baptiste: | ||
#- prevented caluclation on nan values in snow_impurities function | ||
#- now use clean snow BBA caluclation for clear plluted pixels (isnow = 7) | ||
# From Alex's side: | ||
#- approximation of the bba clean snow | ||
#- reorganized sice_lib.py | ||
#- prevented code to crash when no pixels are suitable for retrieval | ||
# | ||
# BAV 10-10-2019 ([email protected]) | ||
# Changes: | ||
|
@@ -104,7 +102,7 @@ | |
|
||
start_time = time.process_time() | ||
|
||
InputFolder = sys.argv[1] + '/' | ||
InputFolder = sys.argv[1] + '/' | ||
|
||
#%% ========= input tif ================ | ||
Oa01 = rio.open(InputFolder+'r_TOA_01.tif') | ||
|
@@ -157,18 +155,18 @@ def WriteOutput(var,var_name,in_folder): | |
isnow[sza>75] = 100 | ||
isnow[toa_cor_o3[20, :,:] < 0.1] = 102 | ||
for i_channel in range(21): | ||
toa_cor_o3[i_channel, np.logical_not(np.isnan(isnow))] = np.nan | ||
toa_cor_o3[i_channel, ~np.isnan(isnow)] = np.nan | ||
|
||
vaa[np.logical_not(np.isnan(isnow))] = np.nan | ||
saa[np.logical_not(np.isnan(isnow))] = np.nan | ||
sza[np.logical_not(np.isnan(isnow))] = np.nan | ||
vza[np.logical_not(np.isnan(isnow))] = np.nan | ||
vaa[ ~np.isnan(isnow)] = np.nan | ||
saa[ ~np.isnan(isnow)] = np.nan | ||
sza[ ~np.isnan(isnow)] = np.nan | ||
vza[ ~np.isnan(isnow)] = np.nan | ||
height = height.astype(float) | ||
height[np.logical_not(np.isnan(isnow))] = np.nan | ||
height[ ~np.isnan(isnow)] = np.nan | ||
|
||
# =========== view geometry and atmosphere propeties ============== | ||
raa, am1, am2, ak1, ak2, amf, co = sl.view_geometry(vaa, saa, sza, vza, aot, height) | ||
tau, p, g = sl.aerosol_properties(aot, height, co) | ||
tau, p, g,gaer,taumol,tauaer = sl.aerosol_properties(aot, height, co) | ||
|
||
# =========== snow properties ==================================== | ||
D, area, al, r0, bal = sl.snow_properties(toa_cor_o3, ak1, ak2) | ||
|
@@ -189,7 +187,8 @@ def WriteOutput(var,var_name,in_folder): | |
# =========== clean snow ==================================== | ||
# for that we calculate the theoretical reflectance at band 1 of a surface with: | ||
# r0 = 1, a (albedo) = 1, ak1 = 1, ak2 = 1 | ||
t1, t2, ratm, r, astra, rms = sl.prepare_coef(tau, g, p, am1, am2, amf) | ||
# t1 and t2 are the backscattering fraction | ||
t1, t2, ratm, r, astra, rms = sl.prepare_coef(tau, g, p, am1, am2, amf,gaer,taumol,tauaer) | ||
rs_1 = sl.alb2rtoa(1, t1[0,:,:], t2[0,:,:], np.ones_like(r0), np.ones_like(ak1), | ||
np.ones_like(ak2), ratm[0,:,:], r[0,:,:]) | ||
|
||
|
@@ -202,12 +201,12 @@ def WriteOutput(var,var_name,in_folder): | |
def mult_channel(c,A): | ||
tmp = A.T*c | ||
return tmp.T | ||
|
||
alb_sph = np.exp(-np.sqrt(1000.*4.*np.pi* mult_channel(bai/w, np.tile(al,(21,1,1))))) | ||
alb_sph[alb_sph>0.999]=1 | ||
|
||
# ========== very dirty snow ==================================== | ||
ind_pol = toa_cor_o3[0,:,:] < rs_1 | ||
|
||
isnow[ind_pol] = 1 | ||
|
||
ind_very_dark = np.logical_and(toa_cor_o3[20]<0.4, ind_pol) | ||
|
@@ -228,75 +227,75 @@ def mult_channel(c,A): | |
|
||
# =========== polluted snow ==================================== | ||
ind_pol = np.logical_or(ind_very_dark, ind_pol) | ||
subs_pol = np.argwhere(ind_pol) | ||
|
||
# approximation of the transcendental equation allowing closed-from solution | ||
#alb_sph[:,ind_pol] = (toa_cor_o3[:,ind_pol] - r[:,ind_pol])/(t1[:,ind_pol]*t2[:,ind_pol]*r0[ind_pol] + ratm[:,ind_pol]*(toa_cor_o3[:,ind_pol] - r[:,ind_pol])) | ||
|
||
# solving iteratively the transcendental equation | ||
alb_sph[:,ind_pol] = 1 | ||
|
||
def solver_wrapper(toa_cor_o3,tau, t1, t2, r0, ak1, ak2, ratm, r): | ||
def func_solv(albedo): | ||
return toa_cor_o3 - sl.alb2rtoa(albedo, t1, t2, r0, ak1, ak2, ratm, r) | ||
# it is assumed that albedo is in the range 0.1-1.0 | ||
return sl.zbrent(func_solv, 0.1, 1, 100, 1.e-6) | ||
|
||
solver_wrapper_v = np.vectorize(solver_wrapper) | ||
|
||
# loop over all bands except band 19, 20 | ||
for i_channel in np.append(np.arange(18), [20]): | ||
alb_sph[i_channel,ind_pol] = solver_wrapper_v( | ||
toa_cor_o3[i_channel,ind_pol], | ||
tau[i_channel,ind_pol], | ||
t1[i_channel,ind_pol], | ||
t2[i_channel,ind_pol], | ||
r0[ind_pol], ak1[ind_pol], | ||
ak2[ind_pol], | ||
ratm[i_channel,ind_pol], | ||
r[i_channel,ind_pol]) | ||
if np.any(ind_pol): | ||
subs_pol = np.argwhere(ind_pol) | ||
|
||
ind_bad = alb_sph[i_channel,:,:]==-999 | ||
alb_sph[i_channel,ind_bad] = np.nan | ||
isnow[ind_bad]= -i_channel | ||
|
||
# INTERNal CHECK FOR CLEAN PIXELS | ||
# Are reprocessed as clean | ||
ind_clear_pol1 = np.logical_and(ind_pol, alb_sph[0,:,:]>0.98) | ||
ind_clear_pol2 = np.logical_and(ind_pol, alb_sph[1,:,:]>0.98) | ||
ind_clear_pol = np.logical_or(ind_clear_pol1, ind_clear_pol2) | ||
isnow[ind_clear_pol]= 7 | ||
for i_channel in range(21): | ||
alb_sph[i_channel,ind_clear_pol] = np.exp(-np.sqrt(4.*1000.*al[ind_clear_pol] * np.pi * bai[i_channel] / w[i_channel] )) | ||
# approximation of the transcendental equation allowing closed-from solution | ||
#alb_sph[:,ind_pol] = (toa_cor_o3[:,ind_pol] - r[:,ind_pol])/(t1[:,ind_pol]*t2[:,ind_pol]*r0[ind_pol] + ratm[:,ind_pol]*(toa_cor_o3[:,ind_pol] - r[:,ind_pol])) | ||
|
||
# solving iteratively the transcendental equation | ||
alb_sph[:,ind_pol] = 1 | ||
|
||
def solver_wrapper(toa_cor_o3,tau, t1, t2, r0, ak1, ak2, ratm, r): | ||
def func_solv(albedo): | ||
return toa_cor_o3 - sl.alb2rtoa(albedo, t1, t2, r0, ak1, ak2, ratm, r) | ||
# it is assumed that albedo is in the range 0.1-1.0 | ||
return sl.zbrent(func_solv, 0.1, 1, 100, 1.e-6) | ||
|
||
solver_wrapper_v = np.vectorize(solver_wrapper) | ||
# loop over all bands except band 19, 20 | ||
for i_channel in np.append(np.arange(18), [20]): | ||
alb_sph[i_channel,ind_pol] = solver_wrapper_v( | ||
toa_cor_o3[i_channel,ind_pol], | ||
tau[i_channel,ind_pol], | ||
t1[i_channel,ind_pol], | ||
t2[i_channel,ind_pol], | ||
r0[ind_pol], ak1[ind_pol], | ||
ak2[ind_pol], | ||
ratm[i_channel,ind_pol], | ||
r[i_channel,ind_pol]) | ||
|
||
ind_bad = alb_sph[i_channel,:,:]==-999 | ||
alb_sph[i_channel,ind_bad] = np.nan | ||
isnow[ind_bad]= -i_channel | ||
|
||
# INTERNal CHECK FOR CLEAN PIXELS | ||
# Are reprocessed as clean | ||
ind_clear_pol1 = np.logical_and(ind_pol, alb_sph[0,:,:]>0.98) | ||
ind_clear_pol2 = np.logical_and(ind_pol, alb_sph[1,:,:]>0.98) | ||
ind_clear_pol = np.logical_or(ind_clear_pol1, ind_clear_pol2) | ||
isnow[ind_clear_pol]= 7 | ||
for i_channel in range(21): | ||
alb_sph[i_channel,ind_clear_pol] = np.exp(-np.sqrt(4.*1000.*al[ind_clear_pol] * np.pi * bai[i_channel] / w[i_channel] )) | ||
|
||
# re-defining polluted pixels | ||
ind_pol = np.logical_or(isnow==6, isnow==1) | ||
|
||
# re-defining polluted pixels | ||
ind_pol = np.logical_or(isnow==6, isnow==1) | ||
|
||
#retrieving snow impurities | ||
ntype, bf, conc = sl.snow_impurities(alb_sph, bal) | ||
|
||
# alex 09.06.2019 | ||
# reprocessing of albedo to remove gaseous absorption using linear polynomial approximation in the range 753-778nm. | ||
# Meaning: alb_sph[12],alb_sph[13] and alb_sph[14] are replaced by a linear interpolation between alb_sph[11] and alb_sph[15] | ||
afirn=(alb_sph[15,ind_pol]-alb_sph[11,ind_pol])/(w[15]-w[11]) | ||
bfirn=alb_sph[15,ind_pol]-afirn*w[15] | ||
alb_sph[12,ind_pol] = bfirn + afirn*w[12] | ||
alb_sph[13,ind_pol] = bfirn + afirn*w[13] | ||
alb_sph[14,ind_pol] = bfirn + afirn*w[14] | ||
|
||
# BAV 09-02-2020: 0.5 to 0.35 | ||
# pixels that are clean enough in channels 18 19 20 and 21 are not affected by pollution, the analytical equation can then be used | ||
ind_ok = np.logical_and(ind_pol, toa_cor_o3[20,:,:]>0.35) | ||
for i_channel in range(17,21): | ||
alb_sph[i_channel,ind_ok] = np.exp(-np.sqrt(4.*1000.*al[ind_ok] * np.pi * bai[i_channel] / w[i_channel] )) | ||
# Alex, SEPTEMBER 26, 2019 | ||
# to avoid the influence of gaseous absorption (water vapor) we linearly interpolate in the range 885-1020nm for bare ice cases only (low toa[20]) | ||
# Meaning: alb_sph[18] and alb_sph[19] are replaced by a linear interpolation between alb_sph[17] and alb_sph[20] | ||
delx=w[20]-w[17] | ||
bcoef=(alb_sph[20,ind_pol]-alb_sph[17,ind_pol])/delx | ||
acoef=alb_sph[20,ind_pol]-bcoef*w[20] | ||
alb_sph[18,ind_pol] = acoef + bcoef*w[18] | ||
alb_sph[19,ind_pol] = acoef + bcoef*w[19] | ||
#retrieving snow impurities | ||
ntype, bf, conc = sl.snow_impurities(alb_sph, bal) | ||
|
||
# alex 09.06.2019 | ||
# reprocessing of albedo to remove gaseous absorption using linear polynomial approximation in the range 753-778nm. | ||
# Meaning: alb_sph[12],alb_sph[13] and alb_sph[14] are replaced by a linear interpolation between alb_sph[11] and alb_sph[15] | ||
afirn=(alb_sph[15,ind_pol]-alb_sph[11,ind_pol])/(w[15]-w[11]) | ||
bfirn=alb_sph[15,ind_pol]-afirn*w[15] | ||
alb_sph[12,ind_pol] = bfirn + afirn*w[12] | ||
alb_sph[13,ind_pol] = bfirn + afirn*w[13] | ||
alb_sph[14,ind_pol] = bfirn + afirn*w[14] | ||
|
||
# BAV 09-02-2020: 0.5 to 0.35 | ||
# pixels that are clean enough in channels 18 19 20 and 21 are not affected by pollution, the analytical equation can then be used | ||
ind_ok = np.logical_and(ind_pol, toa_cor_o3[20,:,:]>0.35) | ||
for i_channel in range(17,21): | ||
alb_sph[i_channel,ind_ok] = np.exp(-np.sqrt(4.*1000.*al[ind_ok] * np.pi * bai[i_channel] / w[i_channel] )) | ||
# Alex, SEPTEMBER 26, 2019 | ||
# to avoid the influence of gaseous absorption (water vapor) we linearly interpolate in the range 885-1020nm for bare ice cases only (low toa[20]) | ||
# Meaning: alb_sph[18] and alb_sph[19] are replaced by a linear interpolation between alb_sph[17] and alb_sph[20] | ||
delx=w[20]-w[17] | ||
bcoef=(alb_sph[20,ind_pol]-alb_sph[17,ind_pol])/delx | ||
acoef=alb_sph[20,ind_pol]-bcoef*w[20] | ||
alb_sph[18,ind_pol] = acoef + bcoef*w[18] | ||
alb_sph[19,ind_pol] = acoef + bcoef*w[19] | ||
|
||
# ========= derivation of plane albedo and reflectance =========== | ||
rp = np.power (alb_sph, ak1) | ||
|
@@ -356,4 +355,4 @@ def func_solv(albedo): | |
WriteOutput(rp[i,:,:], 'albedo_spectral_planar_'+str(i+1).zfill(2), InputFolder) | ||
WriteOutput(refl[i,:,:], 'rBRR_'+str(i+1).zfill(2), InputFolder) | ||
|
||
print("End SICE.py %s --- %s seconds ---" % (InputFolder, time.process_time() - start_time)) | ||
print("End SICE.py %s --- %s CPU seconds ---" % (InputFolder, time.process_time() - start_time)) |
Oops, something went wrong.