import numpy as np from scipy.special import eval_legendre from scipy import optimize # 所有提取方法均基于xarray数据,xarray数据的变量与波长、时间、光谱仪绑定 def cal_inside_bands_ave(data): ''' 根据多个光谱找出窗口内数据最低点对应波长 ''' sky_spec = data.sky.to_pandas().between_time('10:00:00', '15:00:00') veg_spec = data.veg.to_pandas().between_time('10:00:00', '15:00:00') sky_idxmin = sky_spec.idxmin(axis=1) veg_idxmin = veg_spec.idxmin(axis=1) wvl_inside_band_l = veg_idxmin.mean() wvl_inside_band_e = sky_idxmin.mean() return[wvl_inside_band_l, wvl_inside_band_e] def cal_outside_values_mean(data,outer): ''' 计算肩部窗口的均值 ''' _data = data.where((data.Wavelength>outer[0])&(data.Wavelengthwl_range[0])&(data.Wavelength outer[1]) & (data.Wavelength < outer[1] + 3), drop=True) [wvl_inside_band_l,wvl_inside_band_e]=cal_inside_bands_ave(data2) for i in range(0,nmeas_): _data = data.isel(Measures=i) veg_out,sky_out,_ = cal_outside_values_mean(_data,outer) veg_in = _data.veg.sel(Wavelength = wvl_inside_band_l,method='nearest').values sky_in = _data.sky.sel(Wavelength = wvl_inside_band_e,method='nearest').values _sif = (sky_out*veg_in - sky_in*veg_out)/(sky_out - sky_in) _refl = (veg_in - _sif)/ sky_in sif.append(_sif) refl.append(_refl) return[sif,refl] def fld3(data,wl_range,outer_left,outer_right): """ 3FLD (Huaize Feng) input: data,xarray dataset wl_range, a window around Fraunhofer lines position, [start,end] outer_*, a window outside the Fraunhofer lines, [start,end] outer_left, left window outside the Fraunhofer lines outer_right, left window outside the Fraunhofer lines return: list[sif,reflectance] """ sif = [] refl = [] nmeas_ = data.Measures.size data = data.where((data.Wavelength>wl_range[0])&(data.Wavelength outer_left[1]) & (data.Wavelength < outer_right[0]), drop=True) [wvl_inside_band_l,wvl_inside_band_e]=cal_inside_bands_ave(data2) # 应该局限到759-761 for i in range(0,nmeas_): _data = data.isel(Measures=i) veg_out_left,sky_out_left,wvl_outer_left = cal_outside_values_mean(_data,outer_left) veg_out_right,sky_out_right,wvl_outer_right = cal_outside_values_mean(_data,outer_right) veg_in = _data.veg.sel(Wavelength = wvl_inside_band_l,method='nearest').values sky_in = _data.sky.sel(Wavelength = wvl_inside_band_e,method='nearest').values # 根据离吸收峰的距离的反比进行赋权 wight_left = (wvl_outer_right - wvl_inside_band_e)/(wvl_outer_right - wvl_outer_left) wight_right = (wvl_inside_band_e - wvl_outer_left)/(wvl_outer_right - wvl_outer_left) _sif = (veg_in - (sky_in/((wight_left*sky_out_left) + (wight_right*sky_out_right))) * ((wight_left*veg_out_left) + (wight_right*veg_out_right))) / (1-(sky_in / ((wight_left*sky_out_left) + (wight_right*sky_out_right)))) _refl = (veg_in - _sif)/ sky_in sif.append(_sif) refl.append(_refl) return[sif,refl] def sfm(data,wl_range,band): """ Spectral Fitting Method (Huaize Feng) input: data, xarray dataset wl_range,[start,end] a window around Fraunhofer lines position, ,about 10 nm for fitting a ployniam or gussian function. band,float/int exact position of the Fraunhofer line return: list[sif,reflectance,rmse,B] sif, numpy array, sif at the Fraunhofer line for each measurement reflectance, numpy array rmse, RMSE B, numpy array, the parameters of the fitting equation [a,b,c,d,e,f]: a, b, c for polynimal refelectance d, float, MAX sif value [0,10] mw/m2/nm/sr e, position of MAX sif value - wl_range, [0,wavelength.size], nm f, full width at half maximum, [0,wavelength.size*5] """ sif,refl,rmse,B = [],[],[],[] data = data.where((data.Wavelength>wl_range[0])&(data.Wavelengthwl_range[0])&(data.Wavelengthwl_range[0])&(data.Wavelengthwl_range[0])&(data.Wavelength