12 import matplotlib.pyplot
as plt
13 import scipy.interpolate
as trp
37 print (
"Reading Deepblue LUT: " + lut_filepath)
42 self.
lut = np.zeros((NWL,NCHL,NWS,NFMF,NAOT,NRAA,NVZA,NSZA))
43 fmf_pts = np.zeros((NFMF))
45 self.
lut[W470][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m03']
46 self.
lut[W470][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m03']
47 self.
lut[W470][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m03']
48 self.
lut[W550][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m04']
49 self.
lut[W550][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m04']
50 self.
lut[W550][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m04']
51 self.
lut[W659][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m05']
52 self.
lut[W659][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m05']
53 self.
lut[W659][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m05']
54 self.
lut[W860][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m07']
55 self.
lut[W860][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m07']
56 self.
lut[W860][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m07']
57 self.
lut[W124][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m08']
58 self.
lut[W124][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m08']
59 self.
lut[W124][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m08']
60 self.
lut[W164][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m10']
61 self.
lut[W164][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m10']
62 self.
lut[W164][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m10']
63 self.
lut[W213][:,:,0:NF1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'IoverF_m11']
64 self.
lut[W213][:,:,NF1-1:NF2-1,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'IoverF_m11']
65 self.
lut[W213][:,:,NF2-2:NFMF,:,:,:,:]=xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'IoverF_m11']
66 self.
chl_lut = xr.load_dataset(lut_filepath,group=
'/LOG_CHL')[
'LOG_CHL']
67 raa_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Relative_Azimuth_Angle']
68 vza_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'View_Zenith_Angle']
69 sza_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Solar_Zenith_Angle']
70 wnd_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Wind_Speed']
71 chl_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Chl_Conc']
72 aot_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Aerosol_Optical_Depth_550']
73 fmf_pts[0:NF1] = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_DUST')[
'Fine_Mode_Fraction_550']
74 fmf_pts[NF1-1:NF2-1] = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Fine_Mode_Fraction_550']
75 fmf_pts[NF2-2:NFMF] = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_FINE')[
'Fine_Mode_Fraction_550']
76 self.
wl_pts = xr.load_dataset(lut_filepath,group=
'/OCEAN_AEROSOL_MIXED')[
'Band_Central_Wavelength']
77 self.
coef = np.array([0.06,0.06,0.04,0.04,0.07,0.06,0.1])
78 self.
pars = lm.Parameters()
79 self.
pars.add(name=
'fmf', value=0.5, min=0, max=1)
80 self.
pars.add(name=
'aot', value=1.0, min=0, max=100)
82 self.
rpts = (chl_pts, wnd_pts, raa_pts, vza_pts, sza_pts)
83 self.
mpts = (fmf_pts, aot_pts)
84 self.
lut = np.transpose(self.
lut, (1,2,5,6,7,3,4,0))
86 self.
rpts = (wnd_pts, raa_pts, vza_pts, sza_pts)
87 self.
mpts = (fmf_pts, aot_pts, chl_pts)
88 self.
lut = np.transpose(self.
lut, (2,5,6,7,3,4,1,0))
89 self.
pars.add(name=
'chl', value=-2.0, min=-10.0, max=2.0)
91 self.
rpts = (chl_pts, raa_pts, vza_pts, sza_pts)
92 self.
mpts = (fmf_pts, aot_pts, wnd_pts)
93 self.
lut = np.transpose(self.
lut, (1,5,6,7,3,4,2,0))
94 self.
pars.add(name=
'wnd', value=1.0, min=0, max=100)
96 self.
rpts = (raa_pts, vza_pts, sza_pts)
97 self.
mpts = (fmf_pts, aot_pts, chl_pts, wnd_pts)
98 self.
lut = np.transpose(self.
lut, (5,6,7,3,4,1,2,0))
99 self.
pars.add(name=
'chl', value=-2.0, min=-10.0, max=2.0)
100 self.
pars.add(name=
'wnd', value=1.0, min=0, max=100)
101 except Exception
as inst:
104 print (
"Unable to read LUT file ... exiting")
107 def minfun(self, pars, data, scale, rlut):
109 rxi = np.stack((pars[
'fmf'], pars[
'aot']))
111 rxi = np.stack((pars[
'fmf'], pars[
'aot'], pars[
'chl']))
113 rxi = np.stack((pars[
'fmf'], pars[
'aot'], pars[
'wnd']))
115 rxi = np.stack((pars[
'fmf'], pars[
'aot'], pars[
'chl'], pars[
'wnd']))
116 model = trp.interpn(self.
mpts,rlut,rxi,
117 bounds_error=
False,fill_value=
None )[0]
118 return (model - data)*scale
121 cosz = np.cos(sza*D2R)
126 xi = np.stack((chl, wnd, raa, vza, sza))
129 xi = np.stack((wnd, raa, vza, sza))
132 xi = np.stack((chl, raa, vza, sza))
134 xi = np.stack((raa, vza, sza))
135 tlut = trp.interpn(self.
rpts, self.
lut, xi)[0]
136 scale = 1.0/(self.
coef*(rfl + 0.00001))
137 mfit = lm.minimize(self.
minfun, self.
pars, args=(rfl, scale, tlut))
138 self.
fmf = mfit.params[
'fmf'].value
139 self.
aot = mfit.params[
'aot'].value
144 mxi = np.stack((self.
fmf,self.
aot))
147 self.
chl = mfit.params[
'chl'].value
148 mxi = np.stack((self.
fmf,self.
aot,self.
chl))
151 self.
wnd = mfit.params[
'wnd'].value
152 mxi = np.stack((self.
fmf,self.
aot,self.
wnd))
154 self.
chl = mfit.params[
'chl'].value
155 self.
wnd = mfit.params[
'wnd'].value
157 mrfl = trp.interpn(self.
mpts, tlut, mxi,
158 bounds_error=
False, fill_value=
None )[0]
163 self.
sse = np.dot(self.
rsd,self.
rsd)/(NWL-2)
169 plt.plot(self.
wl_pts, self.
rfl, marker=
'.', color=
'b', label=
'measured')
170 plt.plot(self.
wl_pts, self.
mrfl, marker=
'.', color=
'g', label=
'modeled')
171 plt.plot(self.
wl_pts, self.
rsd, marker=
'.', color=
'r', label=
'residual')
172 plt.xlabel(
'wavelength (nm)')
173 plt.ylabel(
'reflectance')
174 tstr =
"dbocean mode {3:d} -- y={4:}, x={5:} aot: {0:.3f} fmf: {1:.3f} sse: {2:.3}"
175 plt.title(tstr.format(self.
aot, self.
fmf, self.
sse, self.
mode, iy, ix))
176 plt.legend(loc=
'upper right')
184 print (
"Reading sensor data: " + self.
ifile)
186 self.
rfl[W470] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_490']
187 self.
rfl[W550] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_550']
188 self.
rfl[W659] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_670']
189 self.
rfl[W860] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_865']
190 self.
rfl[W124] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_1240']
191 self.
rfl[W164] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_1610']
192 self.
rfl[W213] = xr.load_dataset(l1b_filepath,group=
'/observations')[
'rhot_2250']
193 self.
sza = xr.load_dataset(l1b_filepath,group=
'/geolocation')[
'solar_zenith'].values
194 self.
vza = xr.load_dataset(l1b_filepath,group=
'/geolocation')[
'sensor_zenith'].values
195 self.
raa = xr.load_dataset(l1b_filepath,group=
'/geolocation')[
'relative_azimuth'].values
196 self.
lat = xr.load_dataset(l1b_filepath,group=
'/navigation_data')[
'latitude'].values
197 self.
lon = xr.load_dataset(l1b_filepath,group=
'/navigation_data')[
'longitude'].values
198 self.
cld = xr.load_dataset(l1b_filepath,group=
'/ancillary')[
'cloud_mask'].values
199 self.
wnd = xr.load_dataset(l1b_filepath,group=
'/ancillary')[
'wind_speed'].values
200 self.
chl = xr.load_dataset(l1b_filepath,group=
'/ancillary')[
'chlorophyll'].values
201 self.
rfl = np.transpose(self.
rfl, (1,2,0))
203 except Exception
as inst:
206 print (
"Unable to read from file ... exiting")
216 rfl = xr.DataArray(np.zeros((NWL,ydim,xdim)),dims=(
'wl',
'y',
'x'))
217 lat = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
218 lon = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
219 sza = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
220 vza = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
221 raa = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
222 wnd = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
223 chl = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
224 aot = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
225 fmf = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
226 sse = xr.DataArray(np.zeros((ydim,xdim)),dims=(
'y',
'x'))
227 self.
ds = xr.Dataset({
'rfl': rfl,
'lat': lat,
'lon': lon,
228 'sza': sza,
'vza': vza,
'raa': raa,
229 'wnd': wnd,
'chl': chl,
'aot': aot,
230 'fmf': fmf,
'sse': sse, })
231 except Exception
as inst:
234 print (
"Unable to initialize output file ... exiting")
238 print (
"Writing to file: " + self.
ofile)
243 parser = argparse.ArgumentParser()
244 parser.add_argument(
"-if",
"--ifile", type=argparse.FileType(
'r'),
245 help=
"input file", required=
True)
246 parser.add_argument(
"-of",
"--ofile", type=argparse.FileType(
'w'),
247 help=
"output file", required=
False)
248 parser.add_argument(
"-lf",
"--lut", type=argparse.FileType(
'r'),
249 help=
"lookup table file", required=
True)
250 parser.add_argument(
"-pf",
"--plot", type=bool, default=
False,
251 help=
"plot pixel data", required=
False)
252 parser.add_argument(
"-mf",
"--mode", type=int, default=0,
253 help=
"mode option", required=
False)
254 parser.add_argument(
"y", type=int, help=
"start line")
255 parser.add_argument(
"x", type=int, help=
"start pixel")
256 parser.add_argument(
"z", type=int, help=
"square side ")
258 args = parser.parse_args()
259 vin =
input(args.ifile.name)
266 vout =
output(args.ofile.name, dimy, dimx)
268 dbo =
dbocean(args.lut.name, args.mode)
270 print (
"Processing mode {0}".format(args.mode))
271 for iy
in range(args.y, args.y+dimy):
272 tic = time.perf_counter()
273 for ix
in range(args.x, args.x+dimx):
275 if(vin.cld[iy,ix]
or vin.chl[iy,ix]<-999):
276 fmf,aot,chl,wnd,sse = -999.9, -999.9, -999.9, -999.9, -999.9
279 fmf,aot,chl,wnd,sse = dbo.process(vin.rfl[iy,ix],vin.sza[iy,ix],
280 vin.vza[iy,ix],vin.raa[iy,ix],
281 vin.wnd[iy,ix],vin.chl[iy,ix])
282 except Exception
as inst:
285 print (
"processing error at pixel", iy, ix)
290 vout.ds.rfl[:,iy-args.y,ix-args.x] = vin.rfl[iy,ix]
291 vout.ds.lat[iy-args.y,ix-args.x] = vin.lat[iy,ix]
292 vout.ds.lon[iy-args.y,ix-args.x] = vin.lon[iy,ix]
293 vout.ds.sza[iy-args.y,ix-args.x] = vin.sza[iy,ix]
294 vout.ds.vza[iy-args.y,ix-args.x] = vin.vza[iy,ix]
295 vout.ds.raa[iy-args.y,ix-args.x] = vin.raa[iy,ix]
296 vout.ds.wnd[iy-args.y,ix-args.x] = wnd
297 vout.ds.chl[iy-args.y,ix-args.x] = chl
298 vout.ds.aot[iy-args.y,ix-args.x] = aot
299 vout.ds.fmf[iy-args.y,ix-args.x] = fmf
300 vout.ds.sse[iy-args.y,ix-args.x] = sse
302 toc = time.perf_counter()
305 print(iy, tpp, flush=
True)
309 if __name__ ==
"__main__":