def _s2_aerosol(self, ): self.s2_logger.propagate = False self.s2_logger.info('Start to retrieve atmospheric parameters.') self.s2 = read_s2(self.s2_toa_dir, self.s2_tile, self.year, self.month, self.day, self.s2_u_bands) self.s2_logger.info('Reading in TOA reflectance.') selected_img = self.s2.get_s2_toa() self.s2_file_dir = self.s2.s2_file_dir self.s2.get_s2_cloud() self.s2_logger.info( 'Find corresponding pixels between S2 and MODIS tiles') tiles = Find_corresponding_pixels(self.s2.s2_file_dir + '/B04.jp2', destination_res=500) if len(tiles.keys()) > 1: self.s2_logger.info('This sentinel 2 tile covers %d MODIS tile.' % len(tiles.keys())) self.mcd43_files = [] szas, vzas, saas, vaas, raas = [], [], [], [], [] boas, boa_qas, brdf_stds, Hxs, Hys = [], [], [], [], [] for key in tiles.keys(): #h,v = int(key[1:3]), int(key[-2:]) self.s2_logger.info('Getting BOA from MODIS tile: %s.' % key) mcd43_file = glob(self.mcd43_tmp % (self.mcd43_dir, self.year, self.doy, key))[0] self.mcd43_files.append(mcd43_file) self.H_inds, self.L_inds = tiles[key] Lx, Ly = self.L_inds Hx, Hy = self.H_inds Hxs.append(Hx) Hys.append(Hy) self.s2_logger.info( 'Getting the angles and simulated surface reflectance.') self.s2.get_s2_angles(self.reconstruct_s2_angle) self.s2_angles = np.zeros((4, 6, len(Hx))) for j, band in enumerate(self.s2_u_bands[:-2]): self.s2_angles[[0,2],j,:] = self.s2.angles['vza'][band][Hx, Hy], \ self.s2.angles['vaa'][band][Hx, Hy] self.s2_angles[[1,3],j,:] = self.s2.angles['sza'][Hx, Hy], \ self.s2.angles['saa'][Hx, Hy] #use mean value to fill bad values for i in range(4): mask = ~np.isfinite(self.s2_angles[i]) if mask.sum() > 0: self.s2_angles[i][mask] = np.interp(np.flatnonzero(mask), \ np.flatnonzero(~mask), self.s2_angles[i][~mask]) # simple interpolation vza, sza = self.s2_angles[:2] vaa, saa = self.s2_angles[2:] raa = vaa - saa szas.append(sza) vzas.append(vza) raas.append(raa) vaas.append(vaa) saas.append(saa) # get the simulated surface reflectance s2_boa, s2_boa_qa, brdf_std = get_brdf_six(mcd43_file, angles=[vza, sza, raa],\ bands=(3,4,1,2,6,7), Linds= [Lx, Ly]) boas.append(s2_boa) boa_qas.append(s2_boa_qa) brdf_stds.append(brdf_std) self.s2_boa = np.hstack(boas) self.s2_boa_qa = np.hstack(boa_qas) self.brdf_stds = np.hstack(brdf_stds) self.Hx = np.hstack(Hxs) self.Hy = np.hstack(Hys) vza = np.hstack(vzas) sza = np.hstack(szas) vaa = np.hstack(vaas) saa = np.hstack(saas) raa = np.hstack(raas) self.s2_angles = np.array([vza, sza, vaa, saa]) #self.s2_boa, self.s2_boa_qa = self.s2_boa.flatten(), self.s2_boa_qa.flatten() self.s2_logger.info('Applying spectral transform.') self.s2_boa = self.s2_boa*np.array(self.s2_spectral_transform)[0,:-1][...,None] + \ np.array(self.s2_spectral_transform)[1,:-1][...,None] self.s2_logger.info('Getting elevation.') ele_data = reproject_data(self.global_dem, self.s2.s2_file_dir + '/B04.jp2', outputType=gdal.GDT_Float32).data mask = ~np.isfinite(ele_data) ele_data = np.ma.array(ele_data, mask=mask) / 1000. self.elevation = ele_data[self.Hx, self.Hy] self.s2_logger.info('Getting pripors from ECMWF forcasts.') sen_time_str = json.load( open(self.s2.s2_file_dir + '/tileInfo.json', 'r'))['timestamp'] self.sen_time = datetime.datetime.strptime(sen_time_str, u'%Y-%m-%dT%H:%M:%S.%fZ') example_file = self.s2.s2_file_dir + '/B04.jp2' aod, tcwv, tco3 = np.array(self._read_cams(example_file))[:, self.Hx, self.Hy] self.s2_aod550 = aod #* (1-0.14) # validation of +14% biase self.s2_tco3 = tco3 * 46.698 #* (1 - 0.05) tcwv = tcwv / 10. self.s2_tco3_unc = np.ones(self.s2_tco3.shape) * 0.2 self.s2_aod550_unc = np.ones(self.s2_aod550.shape) * 0.5 self.s2_logger.info( 'Trying to get the tcwv from the emulation of sen2cor look up table.' ) #try: self._get_tcwv(selected_img, vza, sza, raa, ele_data) #except: # self.s2_logger.warning('Getting tcwv from the emulation of sen2cor look up table failed, ECMWF data used.') # self.s2_tcwv = tcwv # self.s2_tcwv_unc = np.ones(self.s2_tcwv.shape) * 0.2 self.s2_logger.info('Trying to get the aod from ddv method.') try: solved = self._get_ddv_aot(self.s2.angles, example_file, self.s2_tcwv, ele_data, selected_img) if solved[0] < 0: self.s2_logger.warning( 'DDV failed and only cams data used for the prior.') else: self.s2_logger.info( 'DDV solved aod is %.02f, and it will used as the mean value of cams prediction.' % solved[0]) self.s2_aod550 += (solved[0] - self.s2_aod550.mean()) except: self.s2_logger.warning('Getting aod from ddv failed.') self.s2_logger.info('Applying PSF model.') if self.s2_psf is None: self.s2_logger.info('No PSF parameters specified, start solving.') high_img = np.repeat( np.repeat(selected_img['B11'], 2, axis=0), 2, axis=1) * 0.0001 high_indexs = self.Hx, self.Hy low_img = self.s2_boa[4] qa, cloud = self.s2_boa_qa[4], self.s2.cloud psf = psf_optimize(high_img, high_indexs, low_img, qa, cloud, 2) xs, ys = psf.fire_shift_optimize() xstd, ystd = 29.75, 39 ang = 0 self.s2_logger.info('Solved PSF parameters are: %.02f, %.02f, %d, %d, %d, and the correlation is: %f.' \ %(xstd, ystd, 0, xs, ys, 1-psf.costs.min())) else: xstd, ystd, ang, xs, ys = self.s2_psf # apply psf shifts without going out of the image extend shifted_mask = np.logical_and.reduce( ((self.Hx + int(xs) >= 0), (self.Hx + int(xs) < self.s2_full_res[0]), (self.Hy + int(ys) >= 0), (self.Hy + int(ys) < self.s2_full_res[0]))) self.Hx, self.Hy = self.Hx[shifted_mask] + int( xs), self.Hy[shifted_mask] + int(ys) #self.Lx, self.Ly = self.Lx[shifted_mask], self.Ly[shifted_mask] self.s2_boa = self.s2_boa[:, shifted_mask] self.s2_boa_qa = self.s2_boa_qa[:, shifted_mask] self.s2_angles = self.s2_angles[:, :, shifted_mask] self.elevation = self.elevation[shifted_mask] self.s2_aod550 = self.s2_aod550[shifted_mask] self.s2_tcwv = self.s2_tcwv[shifted_mask] self.s2_tco3 = self.s2_tco3[shifted_mask] self.s2_aod550_unc = self.s2_aod550_unc[shifted_mask] self.s2_tcwv_unc = self.s2_tcwv_unc[shifted_mask] self.s2_tco3_unc = self.s2_tco3_unc[shifted_mask] self.brdf_stds = self.brdf_stds[:, shifted_mask] self.s2_logger.info('Getting the convolved TOA reflectance.') self.valid_pixs = sum( shifted_mask) # count how many pixels is still within the s2 tile ker_size = 2 * int(round(max(1.96 * xstd, 1.96 * ystd))) self.bad_pixs = np.zeros(self.valid_pixs).astype(bool) imgs = [] for i, band in enumerate(self.s2_u_bands[:-2]): if selected_img[band].shape != self.s2_full_res: selected_img[band] = self.repeat_extend(selected_img[band], shape=self.s2_full_res) else: pass selected_img[band][0, :] = -9999 selected_img[band][-1, :] = -9999 selected_img[band][:, 0] = -9999 selected_img[band][:, -1] = -9999 imgs.append(selected_img[band]) # filter out the bad pixels self.bad_pixs |= cloud_dilation(self.s2.cloud |\ (selected_img[band] <= 0) | \ (selected_img[band] >= 10000),\ iteration= ker_size/2)[self.Hx, self.Hy] del selected_img del self.s2.selected_img del high_img del self.s2.angles del self.s2.sza del self.s2.saa del self.s2 ker = self.gaussian(xstd, ystd, ang) f = lambda img: signal.fftconvolve(img, ker, mode='same')[self.Hx, self .Hy] * 0.0001 half = parmap(f, imgs[:3]) self.s2_toa = np.array(half + parmap(f, imgs[3:])) #self.s2_toa = np.array(parmap(f,imgs)) del imgs # get the valid value masks qua_mask = np.all(self.s2_boa_qa <= self.qa_thresh, axis=0) boa_mask = np.all(~self.s2_boa.mask,axis = 0 ) &\ np.all(self.s2_boa > 0, axis = 0) &\ np.all(self.s2_boa < 1, axis = 0) toa_mask = (~self.bad_pixs) &\ np.all(self.s2_toa > 0, axis = 0) &\ np.all(self.s2_toa < 1, axis = 0) self.s2_mask = boa_mask & toa_mask & qua_mask & (~self.elevation.mask) self.s2_AEE, self.s2_bounds = self._load_emus(self.s2_sensor)
f_dat[mask] = np.nan unc_dat[mask] = np.nan return f_dat, unc_dat if __name__ == '__main__': example_file = '/store/S2_data/50/S/LH/2017/2/24/0/B04.jp2' mcd43_dir = '/data/selene/ucfajlg/Hebei/MCD43/' bands = [3, 4, 1, 2, 6, 7] va_files = [ '/'.join(example_file.split('/')[:-1]) + '/angles/VAA_VZA_B%02d.img' % i for i in [2, 3, 4, 8, 11, 12] ] sza = np.zeros((10980, 10980)) saa = sza.copy() from grab_s2_toa import read_s2 s2 = read_s2('/store/S2_data/', '50SLH', 2017, 2, 24, bands=['B02', 'B03', 'B04', 'B08', 'B11', 'B12']) s2.get_s2_angles() sa_files = [s2.angles['saa'], s2.angles['sza']] f_data, unc_data = MCD43_SurRef(mcd43_dir, example_file, 2017, 55, [va_files, sa_files], sun_view_ang_scale=[1., 0.01], bands=bands)
def atmospheric_correction(self, ): self.logger.propagate = False self.s2_sensor = 'msi' self.logger.info('Loading emulators.') #self.s2_inv_AEE = self._load_inverse_emus(self.s2_sensor) self._load_xa_xb_xc_emus() self.s2 = read_s2(self.s2_toa_dir, self.s2_tile, \ self.year, self.month, self.day, bands=None) self.logger.info('Reading in the reflectance.') all_refs = self.s2.get_s2_toa() self.logger.info('Reading in the angles') self.s2.get_s2_angles(self.reconstruct_s2_angle) self.sza, self.saa = self.s2.angles['sza'], self.s2.angles['saa'] self.logger.info('Doing 10 meter bands') self._10meter_ref = np.array([all_refs[band].astype(float)/10000. for band \ in ['B02', 'B03', 'B04', 'B08']]) self._10meter_vza = np.array([ self.s2.angles['vza'][band] for band in ['B02', 'B03', 'B04', 'B08'] ]) self._10meter_vaa = np.array([ self.s2.angles['vaa'][band] for band in ['B02', 'B03', 'B04', 'B08'] ]) self.logger.info('Getting control variables for 10 meters bands.') self._10meter_aod, self._10meter_tcwv, self._10meter_tco3,\ self._10meter_ele = self.get_control_variables('B04') self._block_size = 3660 self._num_blocks = 10980 / self._block_size self._mean_size = 60 self._10meter_band_indexs = [1, 2, 3, 7] self.rsr = [PredefinedWavelengths.S2A_MSI_02, PredefinedWavelengths.S2A_MSI_03, \ PredefinedWavelengths.S2A_MSI_04, PredefinedWavelengths.S2A_MSI_08 ] self.logger.info('Fire correction and splited into %d blocks.' % self._num_blocks**2) self.fire_correction(self._10meter_ref, self.sza, self._10meter_vza,\ self.saa, self._10meter_vaa, self._10meter_aod,\ self._10meter_tcwv, self._10meter_tco3, self._10meter_ele,\ self._10meter_band_indexs) self.toa_rgb = clip( self._10meter_ref[[2, 1, 0], ...].transpose(1, 2, 0) * 255 / 0.255, 0., 255.).astype(uint8) self.boa_rgb = clip( self.boa[[2, 1, 0], ...].transpose(1, 2, 0) * 255 / 0.255, 0., 255.).astype(uint8) self._save_rgb(self.toa_rgb, 'TOA_RGB.tif', self.s2.s2_file_dir + '/B04.jp2') self._save_rgb(self.boa_rgb, 'BOA_RGB.tif', self.s2.s2_file_dir + '/B04.jp2') del self._10meter_ref del self._10meter_vza del self._10meter_vaa del self._10meter_aod \ del self._10meter_tcwv del self._10meter_tco3 del self._10meter_ele #self.sur_refs.update(dict(zip(['B02', 'B03', 'B04', 'B08'], self.boa))) self._save_img(self.boa, ['B02', 'B03', 'B04', 'B08']) del self.boa self.logger.info('Doing 20 meter bands') self._20meter_ref = np.array([all_refs[band].astype(float)/10000. for band \ in ['B05', 'B06', 'B07', 'B8A', 'B11', 'B12']]) self._20meter_vza = np.array([self.s2.angles['vza'][band] for band \ in ['B05', 'B06', 'B07', 'B8A', 'B11', 'B12']]).reshape(6, 5490, 2, 5490, 2).mean(axis=(4,2)) self._20meter_vaa = np.array([self.s2.angles['vaa'][band] for band \ in ['B05', 'B06', 'B07', 'B8A', 'B11', 'B12']]).reshape(6, 5490, 2, 5490, 2).mean(axis=(4,2)) self._20meter_sza = self.sza.reshape(5490, 2, 5490, 2).mean(axis=(3, 1)) self._20meter_saa = self.saa.reshape(5490, 2, 5490, 2).mean(axis=(3, 1)) self.logger.info('Getting control variables for 20 meters bands.') self._20meter_aod, self._20meter_tcwv, self._20meter_tco3,\ self._20meter_ele = self.get_control_variables('B05') self._block_size = 1830 self._num_blocks = 5490 / self._block_size self._mean_size = 30 self._20meter_band_indexs = [4, 5, 6, 8, 11, 12] self.rsr = [PredefinedWavelengths.S2A_MSI_05, PredefinedWavelengths.S2A_MSI_06, \ PredefinedWavelengths.S2A_MSI_07, PredefinedWavelengths.S2A_MSI_09, \ PredefinedWavelengths.S2A_MSI_12, PredefinedWavelengths.S2A_MSI_13] self.logger.info('Fire correction and splited into %d blocks.' % self._num_blocks**2) self.fire_correction(self._20meter_ref, self._20meter_sza, self._20meter_vza,\ self._20meter_saa, self._20meter_vaa, self._20meter_aod,\ self._20meter_tcwv, self._20meter_tco3, self._20meter_ele,\ self._20meter_band_indexs) del self._20meter_ref del self._20meter_vza del self._20meter_vaa del self._20meter_sza del self._20meter_saa del self._20meter_aod del self._20meter_tcwv del self._20meter_tco3 del self._20meter_ele #self.sur_refs.update(dict(zip(['B05', 'B06', 'B07', 'B8A', 'B11', 'B12'], self.boa))) self._save_img(self.boa, ['B05', 'B06', 'B07', 'B8A', 'B11', 'B12']) del self.boa self.logger.info('Doing 60 meter bands') self._60meter_ref = np.array([all_refs[band].astype(float)/10000. for band \ in ['B01', 'B09', 'B10']]) self._60meter_vza = np.array([self.s2.angles['vza'][band] for band \ in ['B01', 'B09', 'B10']]).reshape(3, 1830, 6, 1830, 6).mean(axis=(4, 2)) self._60meter_vaa = np.array([self.s2.angles['vaa'][band] for band \ in ['B01', 'B09', 'B10']]).reshape(3, 1830, 6, 1830, 6).mean(axis=(4, 2)) self._60meter_sza = self.sza.reshape(1830, 6, 1830, 6).mean(axis=(3, 1)) self._60meter_saa = self.saa.reshape(1830, 6, 1830, 6).mean(axis=(3, 1)) self.logger.info('Getting control variables for 60 meters bands.') self._60meter_aod, self._60meter_tcwv, self._60meter_tco3,\ self._60meter_ele = self.get_control_variables('B09') self._block_size = 610 self._num_blocks = 1830 / self._block_size self._mean_size = 10 self._60meter_band_indexs = [0, 9, 10] self.rsr = [ PredefinedWavelengths.S2A_MSI_01, PredefinedWavelengths.S2A_MSI_10, PredefinedWavelengths.S2A_MSI_11 ] self.logger.info('Fire correction and splited into %d blocks.' % self._num_blocks**2) self.fire_correction(self._60meter_ref, self._60meter_sza, self._60meter_vza,\ self._60meter_saa, self._60meter_vaa, self._60meter_aod,\ self._60meter_tcwv, self._60meter_tco3, self._60meter_ele,\ self._60meter_band_indexs) del self._60meter_ref del self._60meter_vza del self._60meter_vaa del self._60meter_sza del self._60meter_saa del self._60meter_aod del self._60meter_tcwv del self._60meter_tco3 del self._60meter_ele #self.sur_refs.update(dict(zip(['B01', 'B09', 'B10'], self.boa))) self._save_img(self.boa, ['B01', 'B09', 'B10']) del self.boa del all_refs del self.s2.selected_img del self.s2.angles self.logger.info('Done!')
def _s2_aerosol(self, ): self.s2_logger.propagate = False self.s2_logger.info('Start to retrieve atmospheric parameters.') self.s2 = read_s2(self.s2_toa_dir, self.s2_tile, self.year, self.month, self.day, self.s2_u_bands) self.s2_logger.info('Reading in TOA reflectance.') selected_img = self.s2.get_s2_toa() self.s2_file_dir = self.s2.s2_file_dir self.s2.get_s2_cloud() self.s2_logger.info('Loading emulators.') self._load_xa_xb_xc_emus() self.s2_logger.info( 'Find corresponding pixels between S2 and MODIS tiles') tiles = Find_corresponding_pixels(self.s2.s2_file_dir + '/B04.jp2', destination_res=500) if len(tiles.keys()) > 1: self.s2_logger.info('This sentinel 2 tile covers %d MODIS tile.' % len(tiles.keys())) self.mcd43_files = [] boas, boa_qas, brdf_stds, Hxs, Hys = [], [], [], [], [] self.s2_logger.info( 'Getting the angles and simulated surface reflectance.') for key in tiles.keys(): self.s2_logger.info('Getting BOA from MODIS tile: %s.' % key) mcd43_file = glob(self.mcd43_tmp % (self.mcd43_dir, self.year, self.doy, key))[0] self.mcd43_files.append(mcd43_file) self.H_inds, self.L_inds = tiles[key] Lx, Ly = self.L_inds Hx, Hy = self.H_inds Hxs.append(Hx) Hys.append(Hy) self.s2.get_s2_angles(self.reconstruct_s2_angle) self.s2_angles = np.zeros((4, 6, len(Hx))) for j, band in enumerate(self.s2_u_bands[:-2]): self.s2_angles[[0,2],j,:] = (self.s2.angles['vza'][band])[Hx, Hy], \ (self.s2.angles['vaa'][band])[Hx, Hy] self.s2_angles[[1,3],j,:] = self.s2.angles['sza'][Hx, Hy], \ self.s2.angles['saa'][Hx, Hy] #use mean value to fill bad values for i in range(4): mask = ~np.isfinite(self.s2_angles[i]) if mask.sum() > 0: self.s2_angles[i][mask] = np.interp(np.flatnonzero(mask), \ np.flatnonzero(~mask), \ self.s2_angles[i][~mask]) # simple interpolation vza, sza = self.s2_angles[:2] vaa, saa = self.s2_angles[2:] raa = vaa - saa # get the simulated surface reflectance s2_boa, s2_boa_qa, brdf_std = get_brdf_six(mcd43_file, angles=[vza, sza, raa],\ bands=(3,4,1,2,6,7), Linds= [Lx, Ly]) boas.append(s2_boa) boa_qas.append(s2_boa_qa) brdf_stds.append(brdf_std) self.s2_boa = np.hstack(boas) self.s2_boa_qa = np.hstack(boa_qas) self.brdf_stds = np.hstack(brdf_stds) self.s2_logger.info('Applying spectral transform.') self.s2_boa = self.s2_boa*np.array(self.s2_spectral_transform)[0,:-1][...,None] + \ np.array(self.s2_spectral_transform)[1,:-1][...,None] self.Hx = np.hstack(Hxs) self.Hy = np.hstack(Hys) del sza del vza del saa del vaa del raa del mask del boas del boa_qas del brdf_stds del Hxs del Hys shape = (self.num_blocks, self.s2.angles['sza'].shape[0] / self.num_blocks, \ self.num_blocks, self.s2.angles['sza'].shape[1] / self.num_blocks) self.sza = self.s2.angles['sza'].reshape(shape).mean(axis=(3, 1)) self.saa = self.s2.angles['saa'].reshape(shape).mean(axis=(3, 1)) self.vza = [] self.vaa = [] for band in self.s2_u_bands[:-2]: self.vza.append( self.s2.angles['vza'][band].reshape(shape).mean(axis=(3, 1))) self.vaa.append( self.s2.angles['vaa'][band].reshape(shape).mean(axis=(3, 1))) self.vza = np.array(self.vza) self.vaa = np.array(self.vaa) self.raa = self.saa[None, ...] - self.vaa self.s2_logger.info('Getting elevation.') example_file = self.s2.s2_file_dir + '/B04.jp2' ele_data = reproject_data(self.global_dem, example_file, outputType=gdal.GDT_Float32).data mask = ~np.isfinite(ele_data) ele_data = np.ma.array(ele_data, mask=mask) / 1000. self.elevation = ele_data.reshape((self.num_blocks, ele_data.shape[0] / self.num_blocks, \ self.num_blocks, ele_data.shape[1] / self.num_blocks)).mean(axis=(3,1)) self.s2_logger.info('Getting pripors from ECMWF forcasts.') sen_time_str = json.load( open(self.s2.s2_file_dir + '/tileInfo.json', 'r'))['timestamp'] self.sen_time = datetime.datetime.strptime(sen_time_str, u'%Y-%m-%dT%H:%M:%S.%fZ') aot, tcwv, tco3 = np.array(self._read_cams(example_file)).reshape((3, self.num_blocks, \ self.block_size, self.num_blocks, self.block_size)).mean(axis=(4, 2)) self.aot = aot #* (1-0.14) # validation of +14% biase self.tco3 = tco3 * 46.698 #* (1 - 0.05) tcwv = tcwv / 10. self.tco3_unc = np.ones(self.tco3.shape) * 0.2 self.aot_unc = np.ones(self.aot.shape) * 0.5 self.s2_logger.info( 'Trying to get the tcwv from the emulation of sen2cor look up table.' ) try: self._get_tcwv(selected_img, self.s2.angles['vza'], self.s2.angles['vaa'], self.s2.angles['sza'], self.s2.angles['saa'], ele_data) except: self.s2_logger.warning( 'Getting tcwv from the emulation of sen2cor look up table failed, ECMWF data used.' ) self.tcwv = tcwv self.tcwv_unc = np.ones(self.tcwv.shape) * 0.2 self.s2_logger.info('Trying to get the aot from ddv method.') try: solved = self._get_ddv_aot(selected_img) if solved[0] < 0: self.s2_logger.warning( 'DDV failed and only cams data used for the prior.') else: self.s2_logger.info( 'DDV solved aot is %.02f, and it will used as the mean value of cams prediction.' % solved[0]) self.aot += (solved[0] - self.aot.mean()) except: self.s2_logger.warning('Getting aot from ddv failed.') self.s2_logger.info('Applying PSF model.') if self.s2_psf is None: xstd, ystd, ang, xs, ys = self._get_psf(selected_img) else: xstd, ystd, ang, xs, ys = self.s2_psf # apply psf shifts without going out of the image extend shifted_mask = np.logical_and.reduce( ((self.Hx + int(xs) >= 0), (self.Hx + int(xs) < self.full_res[0]), (self.Hy + int(ys) >= 0), (self.Hy + int(ys) < self.full_res[0]))) self.Hx, self.Hy = self.Hx[shifted_mask] + int( xs), self.Hy[shifted_mask] + int(ys) #self.Lx, self.Ly = self.Lx[shifted_mask], self.Ly[shifted_mask] self.s2_boa = self.s2_boa[:, shifted_mask] self.s2_boa_qa = self.s2_boa_qa[:, shifted_mask] self.brdf_stds = self.brdf_stds[:, shifted_mask] self.s2_logger.info('Getting the convolved TOA reflectance.') self.valid_pixs = sum( shifted_mask) # count how many pixels is still within the s2 tile ker_size = 2 * int(round(max(1.96 * xstd, 1.96 * ystd))) self.bad_pixs = np.zeros(self.valid_pixs).astype(bool) imgs = [] for i, band in enumerate(self.s2_u_bands[:-2]): if selected_img[band].shape != self.full_res: imgs.append( self.repeat_extend(selected_img[band], shape=self.full_res)) else: imgs.append(selected_img[band]) border_mask = np.zeros(self.full_res).astype(bool) border_mask[[0, -1], :] = True border_mask[:, [0, -1]] = True self.bad_pixs = cloud_dilation(self.s2.cloud | border_mask, iteration=ker_size / 2)[self.Hx, self.Hy] del selected_img del self.s2.selected_img del self.s2.angles['vza'] del self.s2.angles['vaa'] del self.s2.angles['sza'] del self.s2.angles['saa'] del self.s2.sza del self.s2.saa del self.s2 ker = self.gaussian(xstd, ystd, ang) f = lambda img: signal.fftconvolve(img, ker, mode='same')[self.Hx, self .Hy] * 0.0001 half = parmap(f, imgs[:3]) self.s2_toa = np.array(half + parmap(f, imgs[3:])) del imgs # get the valid value masks qua_mask = np.all(self.s2_boa_qa <= self.qa_thresh, axis=0) boa_mask = np.all(~self.s2_boa.mask,axis = 0 ) &\ np.all(self.s2_boa > 0, axis = 0) &\ np.all(self.s2_boa < 1, axis = 0) toa_mask = (~self.bad_pixs) &\ np.all(self.s2_toa > 0, axis = 0) &\ np.all(self.s2_toa < 1, axis = 0) self.s2_mask = boa_mask & toa_mask & qua_mask self.Hx = self.Hx[self.s2_mask] self.Hy = self.Hy[self.s2_mask] self.s2_toa = self.s2_toa[:, self.s2_mask] self.s2_boa = self.s2_boa[:, self.s2_mask] self.s2_boa_qa = self.s2_boa_qa[:, self.s2_mask] self.brdf_stds = self.brdf_stds[:, self.s2_mask] self.s2_boa_unc = grab_uncertainty(self.s2_boa, self.boa_bands, self.s2_boa_qa, self.brdf_stds).get_boa_unc() self.s2_logger.info('Solving...') self.aero = solving_atmo_paras( self.s2_boa, self.s2_toa, self.sza, self.vza, self.saa, self.vaa, self.aot, self.tcwv, self.tco3, self.elevation, self.aot_unc, self.tcwv_unc, self.tco3_unc, self.s2_boa_unc, self.Hx, self.Hy, self.full_res, self.aero_res, self.emus, self.band_indexs, self.boa_bands) solved = self.aero._optimization() return solved
def _s2_aerosol(self, ): self.s2_logger.propagate = False self.s2_logger.info('Start to retrieve atmospheric parameters.') self.s2 = read_s2(self.s2_toa_dir, self.s2_tile, self.year, self.month, self.day, self.s2_u_bands) self.s2_logger.info('Reading in TOA reflectance.') selected_img = self.s2.get_s2_toa() self.s2_file_dir = self.s2.s2_file_dir self.example_file = self.s2.s2_file_dir + '/B04.jp2' self.s2.get_s2_cloud() self.s2_logger.info('Loading emulators.') self._load_xa_xb_xc_emus() self.s2_logger.info( 'Getting the angles and simulated surface reflectance.') self.s2.get_s2_angles() sa_files = [self.s2.angles['saa'], self.s2.angles['sza']] if os.path.exists(self.s2_file_dir + '/angles/'): va_files = [ self.s2_file_dir + '/angles/VAA_VZA_B%02d.img' % i for i in [2, 3, 4, 8, 11, 12] ] else: va_files = [ np.array( [self.s2.angles['vaa'][band], self.s2.angles['vza'][band]]) for band in self.s2_u_bands[:-2] ] if len(glob(self.s2_file_dir + '/MCD43.npz')) == 0: boa, unc, hx, hy, lx, ly, flist = MCD43_SurRef(self.mcd43_dir, self.example_file, \ self.year, self.doy, [sa_files, va_files], sun_view_ang_scale=[1, 0.01], bands = [3,4,1,2,6,7], tolz=0.001, reproject=False) np.savez(self.s2_file_dir + '/MCD43.npz', boa=boa, unc=unc, hx=hx, hy=hy, lx=lx, ly=ly, flist=flist) else: f = np.load(self.s2_file_dir + '/MCD43.npz') boa, unc, hx, hy, lx, ly, flist = f['boa'], f['unc'], f['hx'], f[ 'hy'], f['lx'], f['ly'], f['flist'] self.Hx, self.Hy = hx, hy self.s2_logger.info('Update cloud mask.') flist = [ f.split('/')[0] + self.mcd43_dir + '/' + f.split('/')[-1] for f in flist ] self._mcd43_cloud(flist, lx, ly, self.example_file, boa, selected_img['B12']) self.s2_logger.info('Applying spectral transform.') self.s2_boa_qa = np.ma.array(unc) self.s2_boa = np.ma.array(boa)*np.array(self.s2_spectral_transform)[0,:-1][...,None] + \ np.array(self.s2_spectral_transform)[1,:-1][...,None] shape = (self.num_blocks, self.s2.angles['sza'].shape[0] / self.num_blocks, \ self.num_blocks, self.s2.angles['sza'].shape[1] / self.num_blocks) self.sza = self.s2.angles['sza'].reshape(shape).mean(axis=(3, 1)) self.saa = self.s2.angles['saa'].reshape(shape).mean(axis=(3, 1)) self.vza = [] self.vaa = [] for band in self.s2_u_bands[:-2]: self.vza.append( self.s2.angles['vza'][band].reshape(shape).mean(axis=(3, 1))) self.vaa.append( self.s2.angles['vaa'][band].reshape(shape).mean(axis=(3, 1))) self.vza = np.array(self.vza) self.vaa = np.array(self.vaa) self.raa = self.saa[None, ...] - self.vaa self.s2_logger.info('Getting elevation.') ele_data = reproject_data(self.global_dem, self.example_file, outputType=gdal.GDT_Float32).data mask = ~np.isfinite(ele_data) ele_data = np.ma.array(ele_data, mask=mask) / 1000. self.elevation = ele_data.reshape((self.num_blocks, ele_data.shape[0] / self.num_blocks, \ self.num_blocks, ele_data.shape[1] / self.num_blocks)).mean(axis=(3,1)) self.s2_logger.info('Getting pripors from ECMWF forcasts.') sen_time_str = json.load( open(self.s2.s2_file_dir + '/tileInfo.json', 'r'))['timestamp'] self.sen_time = datetime.datetime.strptime(sen_time_str, u'%Y-%m-%dT%H:%M:%S.%fZ') aot, tcwv, tco3 = np.array(self._read_cams(self.example_file)).reshape((3, self.num_blocks, \ self.block_size, self.num_blocks, self.block_size)).mean(axis=(4, 2)) mod08_aot = self._mod08_aot() #if np.isnan(mod08_aot): self.aot = aot - (aot.mean() - np.nanmean([mod08_aot, aot.mean()])) #else: # temp = np.zeros_like(aot) # temp[:] = mod08_aot # self.aot = temp self.tco3 = tco3 * 46.698 tcwv = tcwv / 10. self.tco3_unc = np.ones(self.tco3.shape) * 0.2 self.aot_unc = np.ones(self.aot.shape) * 2. self.s2_logger.info( 'Trying to get the tcwv from the emulation of sen2cor look up table.' ) try: self._get_tcwv(selected_img, self.s2.angles['vza'], self.s2.angles['vaa'], self.s2.angles['sza'], self.s2.angles['saa'], ele_data) except: self.s2_logger.warning( 'Getting tcwv from the emulation of sen2cor look up table failed, ECMWF data used.' ) self.tcwv = tcwv self.tcwv_unc = np.ones(self.tcwv.shape) * 0.2 ''' self.s2_logger.info('Trying to get the aot from ddv method.') try: solved = self._get_ddv_aot(selected_img) if solved[0] < 0: self.s2_logger.warning('DDV failed and only cams data used for the prior.') else: self.s2_logger.info('DDV solved aot is %.02f, and it will used as the mean value of cams prediction.'%solved[0]) self.aot[:] = solved[0] #self.aot + (solved[0]-self.aot.mean()) except: self.s2_logger.warning('Getting aot from ddv failed.') ''' self.s2_logger.info( 'Mean values for priors are: %.02f, %.02f, %.02f and mod08 aot is %.02f' % (aot.mean(), self.tcwv.mean(), self.tco3.mean(), mod08_aot)) self.s2_logger.info('Applying PSF model.') if self.s2_psf is None: xstd, ystd, ang, xs, ys = self._get_psf(selected_img) else: xstd, ystd, ang, xs, ys = self.s2_psf # apply psf shifts without going out of the image extend shifted_mask = np.logical_and.reduce( ((self.Hx + int(xs) >= 0), (self.Hx + int(xs) < self.full_res[0]), (self.Hy + int(ys) >= 0), (self.Hy + int(ys) < self.full_res[0]))) self.Hx, self.Hy = self.Hx[shifted_mask] + int( xs), self.Hy[shifted_mask] + int(ys) #self.Lx, self.Ly = self.Lx[shifted_mask], self.Ly[shifted_mask] self.s2_boa = self.s2_boa[:, shifted_mask] self.s2_boa_qa = self.s2_boa_qa[:, shifted_mask] self.s2_logger.info('Getting the convolved TOA reflectance.') #self.valid_pixs = sum(shifted_mask) # count how many pixels is still within the s2 tile ker_size = 2 * int(round(max(1.96 * xstd, 1.96 * ystd))) #self.bad_pixs = np.zeros(self.valid_pixs).astype(bool) imgs = [] for i, band in enumerate(self.s2_u_bands[:-2]): if selected_img[band].shape != self.full_res: imgs.append( self.repeat_extend(selected_img[band], shape=self.full_res)) else: imgs.append(selected_img[band]) border_mask = np.zeros(self.full_res).astype(bool) border_mask[[0, -1], :] = True border_mask[:, [0, -1]] = True self.dcloud = binary_dilation(self.cloud | border_mask, structure=np.ones((3, 3)).astype(bool), iterations=ker_size / 2).astype(bool) self.bad_pixs = self.dcloud[self.Hx, self.Hy] del selected_img del self.s2.selected_img del self.s2.angles['vza'] del self.s2.angles['vaa'] del self.s2.angles['sza'] del self.s2.angles['saa'] del self.s2.sza del self.s2.saa del self.s2 ker = self.gaussian(xstd, ystd, ang) f = lambda img: signal.fftconvolve(img, ker, mode='same')[self.Hx, self .Hy] * 0.0001 half = parmap(f, imgs[:3]) self.s2_toa = np.array(half + parmap(f, imgs[3:])) del imgs # get the valid value masks qua_mask = np.all(self.s2_boa_qa <= self.qa_thresh, axis=0) boa_mask = np.all(~self.s2_boa.mask,axis = 0 ) &\ np.all(self.s2_boa >= 0.001, axis = 0) &\ np.all(self.s2_boa < 1, axis = 0) toa_mask = (~self.bad_pixs) &\ np.all(self.s2_toa >= 0.0001, axis = 0) &\ np.all(self.s2_toa < 1., axis = 0) self.s2_mask = boa_mask & toa_mask & qua_mask self.Hx = self.Hx[self.s2_mask] self.Hy = self.Hy[self.s2_mask] self.s2_toa = self.s2_toa[:, self.s2_mask] self.s2_boa = self.s2_boa[:, self.s2_mask] self.s2_boa_unc = self.s2_boa_qa[:, self.s2_mask] self.s2_logger.info('Solving...') tempm = np.zeros(self.full_res) tempm[self.Hx, self.Hy] = 1 tempm = tempm.reshape(self.num_blocks, self.block_size, \ self.num_blocks, self.block_size).astype(int).sum(axis=(3,1)) mask = ~self.dcloud self.mask = mask.reshape(self.num_blocks, self.block_size, \ self.num_blocks, self.block_size).astype(int).sum(axis=(3,1)) self.mask = ((self.mask / ((1. * self.block_size)**2)) >= 0.5) & ( (tempm / ((self.aero_res / 500.)**2)) >= 0.5) self.mask = binary_erosion(self.mask, structure=np.ones((3, 3)).astype(bool)) self.aero = solving_atmo_paras( self.s2_boa, self.s2_toa, self.sza, self.vza, self.saa, self.vaa, self.aot, self.tcwv, self.tco3, self.elevation, self.aot_unc, self.tcwv_unc, self.tco3_unc, self.s2_boa_unc, self.Hx, self.Hy, self.mask, self.full_res, self.aero_res, self.emus, self.band_indexs, self.boa_bands) solved = self.aero._optimization() return solved
from datetime import datetime example_file = '/store/S2_data/50/S/MG/2016/1/24/0/B04.jp2' date = datetime.strptime('/'.join(example_file.split('/')[-5:-2]), '%Y/%m/%d') doy = date.timetuple().tm_yday mcd43_dir = '/data/selene/ucfajlg/Hebei/MCD43/' bands = [3, 4, 1, 2, 6, 7] va_files = [ '/'.join(example_file.split('/')[:-1]) + '/angles/VAA_VZA_B%02d.img' % i for i in [2, 3, 4, 8, 11, 12] ] sza = np.zeros((10980, 10980)) saa = sza.copy() from grab_s2_toa import read_s2 tile = ''.join(example_file.split('/')[-8:-5]) s2 = read_s2('/store/S2_data/', tile, date.year, date.month, date.day, bands=['B02', 'B03', 'B04', 'B08', 'B11', 'B12']) s2.get_s2_angles() sa_files = [s2.angles['saa'], s2.angles['sza']] ret = MCD43_SurRef(mcd43_dir, example_file, date.year, doy, [sa_files, va_files], sun_view_ang_scale=[1., 0.01], bands=bands, reproject=False)