Created
April 16, 2015 08:02
-
-
Save mraspaud/9a0964cca1ca375d97b4 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Copyright (c) 2013, 2014, 2015 Martin Raspaud | |
# Author(s): | |
# Martin Raspaud <[email protected]> | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
"""Apply reflectance correction (rayleigh effect removal) | |
MODIS only at the moment. | |
Shamelessly translated from the crefl1.7.1.c. | |
TODO: | |
- Interpolation of heights and angle data maybe ? | |
- cleanup, optimize | |
""" | |
import numpy as np | |
import logging | |
logger = logging.getLogger(__name__) | |
aH2O = np.array( | |
[-5.60723, -5.25251, 0, 0, -6.29824, -7.70944, -3.91877, 0, 0, 0, 0, 0, 0, 0, 0, 0]) | |
bH2O = np.array([0.820175, 0.725159, 0, 0, 0.865732, 0.966947, | |
0.745342, 0, 0, 0, 0, 0, 0, 0, 0, 0]) | |
#/*const float aO3[Nbands]={ 0.0711, 0.00313, 0.0104, 0.0930, 0, 0, 0, 0.00244, 0.00383, 0.0225, 0.0663, 0.0836, 0.0485, 0.0395, 0.0119, 0.00263};*/ | |
aO3 = np.array([0.0715289, 0, 0.00743232, 0.089691, 0, 0, 0, 0.001, | |
0.00383, 0.0225, 0.0663, 0.0836, 0.0485, 0.0395, 0.0119, 0.00263]) | |
#/*const float taur0[Nbands] = { 0.0507, 0.0164, 0.1915, 0.0948, 0.0036, 0.0012, 0.0004, 0.3109, 0.2375, 0.1596, 0.1131, 0.0994, 0.0446, 0.0416, 0.0286, 0.0155};*/ | |
taur0 = np.array([0.05100, 0.01631, 0.19325, 0.09536, 0.00366, 0.00123, 0.00043, | |
0.3139, 0.2375, 0.1596, 0.1131, 0.0994, 0.0446, 0.0416, 0.0286, 0.0155]) | |
UO3 = 0.319 | |
UH2O = 2.93 | |
def show(data): | |
"""Show the stetched data. | |
""" | |
import Image as pil | |
img = pil.fromarray(np.array((data - data.min()) * 255.0 / | |
(data.max() - data.min()), np.uint8)) | |
img.show() | |
def fintexp1(tau): | |
a = [-.57721566, 0.99999193, -0.24991055, | |
0.05519968, -0.00976004, 0.00107857] | |
a.reverse() | |
return np.polyval(a, tau) - np.log(tau) | |
def fintexp3(tau): | |
return (np.exp(-tau) * (1 - tau) + tau * tau * fintexp1(tau)) / 2.0 | |
def csalbr(tau): | |
return ((3 * tau - fintexp3(tau) * (4 + 2 * tau) + 2 * np.exp(-tau)) / | |
(4 + 3 * tau)) | |
def init_lut(): | |
vals = np.arange(4000) * 0.0001 | |
vals[0] = 0.0001 | |
sphalb = csalbr(vals) | |
sphalb[0] = 0 | |
return sphalb | |
def chand(phi, muv, mus, taur): | |
xfd = 0.958725775 | |
xbeta2 = 0.5 | |
musn = mus[:, :, np.newaxis] | |
muvn = muv[:, :, np.newaxis] | |
phios = phi + np.pi | |
xcos1 = 1.0 | |
xcos2 = np.cos(phios)[:, :, np.newaxis] | |
xcos3 = np.cos(2 * phios)[:, :, np.newaxis] | |
xph1 = 1 + (3 * musn * musn - 1) * (3 * muvn * muvn - 1) * xfd / 8 | |
xph2 = -xfd * xbeta2 * 1.5 * musn * muvn * \ | |
np.sqrt(1 - musn * musn) * np.sqrt(1 - muvn * muvn) | |
xph3 = xfd * xbeta2 * 0.375 * (1 - musn * musn) * (1 - muvn * muvn) | |
p = np.array([np.ones_like(mus), mus + muv, muv * mus, | |
mus * mus + muv * muv, mus * mus * muv * muv]) | |
as01 = np.array( | |
[0.33243832, 0.16285370, -0.30924818, -0.10324388, 0.11493334]) | |
as02 = np.array( | |
[-6.777104e-02, 1.577425e-03, -1.240906e-02, 3.241678e-02, -3.503695e-02]) | |
as01 = as01[:, np.newaxis, np.newaxis] | |
as02 = as02[:, np.newaxis, np.newaxis] | |
fs01 = np.sum(p * as01, axis=0)[:, :, np.newaxis] | |
fs02 = np.sum(p * as02, axis=0)[:, :, np.newaxis] | |
xlntaur = np.log(taur) | |
fs0 = fs01 + fs02 * xlntaur | |
as1 = np.array([0.19666292, -5.439061e-02]) | |
as2 = np.array([0.14545937, -2.910845e-02]) | |
fs1 = as1[0] + xlntaur * as1[1] | |
fs2 = as2[0] + xlntaur * as2[1] | |
trdown = np.exp(-taur / musn) | |
trup = np.exp(-taur / muvn) | |
xitm1 = (1 - trdown * trup) / 4 / (musn + muvn) | |
xitm2 = (1 - trdown) * (1 - trup) | |
xitot1 = xph1 * (xitm1 + xitm2 * fs0) | |
xitot2 = xph2 * (xitm1 + xitm2 * fs1) | |
xitot3 = xph3 * (xitm1 + xitm2 * fs2) | |
rhoray = xitot1 * xcos1 + xitot2 * xcos2 * 2 + xitot3 * xcos3 * 2 | |
return rhoray, trdown, trup | |
MAXAIRMASS = 18 | |
SCALEHEIGHT = 8000 | |
def compute_atm_variables(mus, muv, phi, height): | |
sphalb0 = init_lut() | |
print sphalb0 | |
musn = mus[:, :, np.newaxis] | |
muvn = muv[:, :, np.newaxis] | |
m = np.ma.masked_greater(1 / musn + 1 / muvn, MAXAIRMASS) | |
psurfratio = np.exp(-height / SCALEHEIGHT) | |
taur = taur0[np.newaxis, np.newaxis, :] * psurfratio[:, :, np.newaxis] | |
rhoray, trdown, trup = chand(phi, muv, mus, taur) | |
logger.debug("rhoray: " + str((rhoray.max(), rhoray.min()))) | |
sphalb = sphalb0[(taur / 0.0001 + 0.5).astype(int)] | |
sphalb = np.ma.masked_greater_equal(taur, 4000 * 0.0001) | |
Ttotrayu = ((2 / 3.0 + muvn) + (2 / 3.0 - muvn) * trup) / (4 / 3.0 + taur) | |
Ttotrayd = ((2 / 3.0 + musn) + (2 / 3.0 - musn) * trdown) / \ | |
(4 / 3.0 + taur) | |
tO3 = np.exp(-m * UO3 * aO3) | |
tO3[:, :, aO3 == 0] = 1 | |
tH2O = np.exp(-np.exp(aH2O + bH2O * np.log(m * UH2O))) | |
tH2O[:, :, bH2O == 0] = 1 | |
TtotraytH2O = np.ma.masked_invalid(Ttotrayu * Ttotrayd * tH2O) | |
# tO2 = np.exp(-m *aO2) | |
tO2 = 1 | |
tOG = np.ma.masked_invalid(tO3 * tO2) | |
return sphalb, rhoray, TtotraytH2O, tOG | |
def correct_refl(refl, sphalb, rhoray, TtotraytH2O, tOG): | |
corr_refl = (refl / tOG - rhoray) / TtotraytH2O | |
corr_refl /= (1 + corr_refl * sphalb) | |
return corr_refl | |
if __name__ == '__main__': | |
from mpop.satellites import PolarFactory | |
from datetime import datetime | |
from mpop.utils import debug_on | |
debug_on() | |
t = datetime(2012, 12, 10, 10, 29, 35) | |
g = PolarFactory.create_scene("terra", "", "modis", t) | |
g.load(["1", "2", "3", "4"], resolution=1000) | |
l = g.project("spain") | |
img1 = l.image.truecolor() | |
img1.save("before.png") | |
height = g.hdfeos_l1b_reader.get_height()[:] | |
sunz = (g.hdfeos_l1b_reader.get_sunz()[:] * | |
g.hdfeos_l1b_reader.get_sunz().attributes()["scale_factor"]) | |
satz = g.hdfeos_l1b_reader.get_satz( | |
)[:] * g.hdfeos_l1b_reader.get_satz().attributes()["scale_factor"] | |
suna = g.hdfeos_l1b_reader.get_suna( | |
)[:] * g.hdfeos_l1b_reader.get_suna().attributes()["scale_factor"] | |
sata = g.hdfeos_l1b_reader.get_sata( | |
)[:] * g.hdfeos_l1b_reader.get_sata().attributes()["scale_factor"] | |
sunz = np.ma.masked_outside(sunz, -89, 89) | |
phi = np.deg2rad(suna - sata) | |
sphalb, rhoray, TtotraytH2O, tOG = compute_atm_variables(np.cos(np.deg2rad(sunz)), | |
np.cos( | |
np.deg2rad(satz)), | |
phi, | |
height) | |
#refl = np.dstack([g["1"].data, g["2"].data, g["3"].data, g["4"].data])[2::5, 2::5, :] / 400 | |
#corr_refl = (refl / tOG[:, :, :4] - rhoray[:, :, :4]) / TtotraytH2O[:, :, :4] | |
#corr_refl /= (1 + corr_refl * sphalb[:, :, :4]) | |
from geotiepoints.interpolator import generic_modis5kmto1km | |
chans = ["1", "2", "3", "4"] | |
refl = np.dstack( | |
[g["1"].data, g["2"].data, g["3"].data, g["4"].data]) / 400 | |
mus = generic_modis5kmto1km(np.cos(np.deg2rad(sunz)))[0][:, :, np.newaxis] | |
refl /= mus | |
print "interpolation" | |
for num, chan in enumerate(chans): | |
print chan | |
sph, tog, rho, th2o = generic_modis5kmto1km(sphalb[:, :, num], rhoray[:, :, num], | |
tOG[:, :, num], TtotraytH2O[:, :, num]) | |
g[chan].data = correct_refl(refl[:, :, num], sph, tog, rho, th2o) | |
l = g.project("spain") | |
img = l.image.truecolor() | |
img.save("after.png") | |
img.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment