diff --git a/preprocess_thresholds.py b/preprocess_thresholds.py index 9c5b7ecf3cdcb49b65c798707e081928c38f753c..b0c96f7fa374254b322f4d24118fc5b299a692fc 100644 --- a/preprocess_thresholds.py +++ b/preprocess_thresholds.py @@ -266,21 +266,23 @@ def get_b1_thresholds(data, thresholds, scene_idx): return locut, midpt, hicut -def get_pn_thresholds(data, thresholds, scene, test_name): +def polar_night_thresholds(data, thresholds, scene, test_name, scene_idx): thresholds = thresholds[scene] if ((test_name == '4-12um_BTD_Thin_Cirrus_Test') and (scene in ['Land_Night', 'Night_Snow']) or (test_name == '7.3-11um_BTD_Mid_Level_Cloud_Test') and (scene == 'Land_Night')): - locut = thresholds[test_name]['thr'][0] * np.ones(data.M15.shape) - midpt = thresholds[test_name]['thr'][1] * np.ones(data.M15.shape) - hicut = thresholds[test_name]['thr'][2] * np.ones(data.M15.shape) - power = thresholds[test_name]['thr'][3] * np.ones(data.M15.shape) + locut = thresholds[test_name]['thr'][0] * np.ones(data.M15.values[scene_idx].ravel()) + midpt = thresholds[test_name]['thr'][1] * np.ones(data.M15.values[scene_idx].ravel()) + hicut = thresholds[test_name]['thr'][2] * np.ones(data.M15.values[scene_idx].ravel()) + power = thresholds[test_name]['thr'][3] * np.ones(data.M15.values[scene_idx].ravel()) - out_thr = xr.DataArray(data=np.dstack((locut, midpt, hicut, np.ones(data.ndvi.shape), power)), - dims=('number_of_lines', 'number_of_pixels', 'z')) - return out_thr + # out_thr = xr.DataArray(data=np.dstack((locut, midpt, hicut, np.ones(data.ndvi.shape), power)), + # dims=('number_of_lines', 'number_of_pixels', 'z')) + out_thr = np.dstack((locut, midpt, hicut, np.ones(locut.shape), power)) - rad = data.M15.values.reshape(data.M15.shape[0]*data.M15.shape[1]) + return out_thr.T + + rad = data.M15.values[scene_idx].ravel() bt_bounds = thresholds[test_name]['bt11_bounds'] locut, midpt = np.empty(rad.shape), np.empty(rad.shape) @@ -343,15 +345,16 @@ def get_pn_thresholds(data, thresholds, scene, test_name): hicut[idx] = midpt[idx] - conf_range[idx] locut[idx] = midpt[idx] + conf_range[idx] - locut = locut.reshape(data.M15.shape) - midpt = midpt.reshape(data.M15.shape) - hicut = hicut.reshape(data.M15.shape) - power = power.reshape(data.M15.shape) + # locut = locut.reshape(data.M15.shape) + # midpt = midpt.reshape(data.M15.shape) + # hicut = hicut.reshape(data.M15.shape) + # power = power.reshape(data.M15.shape) - out_thr = xr.DataArray(data=np.dstack((locut, midpt, hicut, np.ones(data.ndvi.shape), power)), - dims=('number_of_lines', 'number_of_pixels', 'z')) + # out_thr = xr.DataArray(data=np.dstack((locut, midpt, hicut, np.ones(data.ndvi.shape), power)), + # dims=('number_of_lines', 'number_of_pixels', 'z')) + out_thr = np.dstack((locut, midpt, hicut, np.ones(locut.shape), power)) - return out_thr + return out_thr.T def get_nl_thresholds(data, threshold): @@ -433,24 +436,23 @@ def vis_refl_thresholds(data, thresholds, scene, scene_idx): return np.squeeze(out_thr.T), out_rad -def GEMI_thresholds(data, thresholds, scene_name, scene_idx): - thresh = thresholds[scene_name]['GEMI_Test'] +def gemi_thresholds(data, thresholds, scene_name, scene_idx): ndvi = data.ndvi.values[scene_idx].ravel() gemi_thr = np.ones((ndvi.shape[0], 5)) idx = np.nonzero(ndvi < 0.1) - gemi_thr[idx, :3] = thresh['gemi0'][:3] - idx = np.nonzero((ndvi >= 0.1) & (data.ndvi < 0.2)) - gemi_thr[idx, :3] = thresh['gemi1'][:3] + gemi_thr[idx, :3] = thresholds['gemi0'][:3] + idx = np.nonzero((ndvi >= 0.1) & (ndvi < 0.2)) + gemi_thr[idx, :3] = thresholds['gemi1'][:3] idx = np.nonzero((ndvi >= 0.2) & (ndvi < 0.3)) - gemi_thr[idx, :3] = thresh['gemi2'][:3] + gemi_thr[idx, :3] = thresholds['gemi2'][:3] # thr_out = xr.DataArray(data=np.dstack((gemi_thr[:, :, 0], gemi_thr[:, :, 1], gemi_thr[:, :, 2], # np.ones(gemi_thr[:, :, 0].shape), # np.ones(gemi_thr[:, :, 0].shape))), # dims=('number_of_lines', 'number_of_pixels', 'z')) - return gemi_thr + return gemi_thr.T def bt11_4um_preproc(data, thresholds, scene_name): diff --git a/spectral_tests.py b/spectral_tests.py new file mode 100644 index 0000000000000000000000000000000000000000..7ee812f0e62301e398eacfa6cd712d10b93dd091 --- /dev/null +++ b/spectral_tests.py @@ -0,0 +1,569 @@ +import numpy as np +import xarray as xr + +# from numpy.lib.stride_tricks import sliding_window_view +from typing import Dict + +import functools + +# import utils +import conf +import conf_xr +import scene as scn +import preprocess_thresholds as preproc +import restoral + +import importlib + +_RTD = 180./np.pi +_DTR = np.pi/180 + +# this is used for testing, eventually we want to remove it +importlib.reload(preproc) +importlib.reload(conf) + + +class CloudTests(object): + + def __init__(self, + data: xr.Dataset, + scene_name: str, + thresholds: Dict) -> None: + self.data = data + self.scene_name = scene_name + self.thresholds = thresholds + self.scene_idx = tuple(np.nonzero(data[scene_name] == 1)) + if self.scene_idx[0].shape[0] == 0: + self.pixels_in_scene = False + else: + self.pixels_in_scene = True + + def run_if_test_exists_for_scene(func): + @functools.wraps(func) + def wrapper(self, *args, test_name, **kwargs): + if test_name not in self.thresholds[self.scene_name]: + # print('Not running test for this scene') + # returns cmin. This could be changed into a keyworded argument for readability + return args[-1] + return func(self, *args, test_name, **kwargs) + return wrapper + + @run_if_test_exists_for_scene + def test_11um(self, + band: str, + cmin: np.ndarray, + test_name: str = '11um_Test') -> np.ndarray: + confidence = np.ones(self.data[band].shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, threshold['thr']) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def surface_temperature_test(self, + band31: str, + band32: str, + cmin: np.ndarray, + test_name: str = 'Surface_Temperature_test') -> np.ndarray: + pass + + @run_if_test_exists_for_scene + def sst_test(self, + band31: str, + band32: str, + cmin: np.ndarray, + test_name: str = 'SST_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + m31 = self.data[band31].values - 273.16 + bt_diff = self.data[band31].values - self.data[band32].values + sst = self.data.geos_sfct.values - 273.16 + cosvza = np.cos(self.data.sensor_zenith.values*_DTR) + + c = threshold['coeffs'] + + modsst = 273.16 + c[0] + c[1]*m31 + c[2]*bt_diff*sst + c[3]*bt_diff*((1/cosvza) - 1) + sfcdif = self.data.geos_sfct.values - modsst + + print(f'Testing "{self.scene_name}"\n') + confidence[self.scene_idx] = conf.conf_test_new(sfcdif[self.scene_idx], threshold['thr']) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def bt_diff_86_11um(self, + band: str, + cmin: np.ndarray, + test_name: str = '8.6-11um_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, threshold['thr']) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def test_11_12um_diff(self, + band: str, + cmin: np.ndarray, + test_name: str = '11-12um_Cirrus_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + thr = preproc.thresholds_11_12um(self.data, threshold, self.scene_name, self.scene_idx) + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def oceanic_stratus_11_4um_test(self, + band: str, + cmin: np.ndarray, + test_name: str = '11-4um_Oceanic_Stratus_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + thr = threshold['thr'] + if self.scene_name in ['Land_Day_Desert', 'Land_Day_Desert_Coast', 'Polar_Day_Desert', + 'Polar_Day_Desert_Coast']: + confidence[self.scene_idx] = conf.conf_test_dble(rad, thr) + + # these scenes have not been implemented yet + elif self.scene_name in ['Land_Night', 'Polar_Night_Land', 'Polar_Day_Snow', 'Polar_Night_Snow', + 'Day_Snow', 'Night_Snow', 'Antarctic_Day']: + pass + else: + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def nir_reflectance_test(self, + band: str, + cmin: np.ndarray, + test_name: str = 'NIR_Reflectance_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + thr = preproc.thresholds_NIR(self.data, self.thresholds, self.scene_name, + test_name, self.scene_idx) + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def vis_nir_ratio_test(self, + band: str, + cmin: np.ndarray, + test_name: str = 'Vis/NIR_Reflectance_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + # I'm not using the self.scene_idx here because it messes up with the indexing of the + # confidence array and I don't want to think of a solution at the moment. I will need + # to figure out the logic to make it work once I'm at the stage where I want to optimize + # the code + rad = self.data[band].values # [self.scene_idx] + solar_zenith = self.data.solar_zenith.values # [self.scene_idx] + sensor_zenith = self.data.sensor_zenith.values # [self.scene_idx] + rel_azimuth = self.data.relative_azimuth.values # [self.scene_idx] + sunglint_angle = self.data.sunglint_angle.values # [self.scene_idx] + + cos_refang = np.sin(sensor_zenith*_DTR) * np.sin(solar_zenith*_DTR) * \ + np.cos(rel_azimuth*_DTR) + np.cos(sensor_zenith*_DTR) * np.cos(solar_zenith*_DTR) + refang = np.arccos(cos_refang) * _RTD + + idx = np.nonzero((solar_zenith <= 85) & (refang <= sunglint_angle)) + + thr_no_sunglint = np.array([threshold['thr'][i] for i in range(8)]) + thr_sunglint = np.array([self.thresholds['Sun_Glint']['snglnt'][i] for i in range(8)]) + + confidence = conf.conf_test_dble(rad, thr_no_sunglint) + confidence[idx] = conf.conf_test_dble(rad[idx], thr_sunglint) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def test_16_21um_Reflectance(self, + band: str, + cmin: np.ndarray, + test_name: str = '1.6_2.1um_NIR_Reflectance_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + thr = preproc.thresholds_NIR(self.data, self.thresholds, self.scene_name, + test_name, self.scene_idx) + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def visible_reflectance_test(self, + band: str, + cmin: np.ndarray, + test_name: str = 'Visible_Reflectance_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + print(f'Testing "{self.scene_name}"\n') + thr, rad = preproc.vis_refl_thresholds(self.data, self.thresholds, self.scene_name, + self.scene_idx) + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def gemi_test(self, + band: str, + cmin: np.ndarray, + test_name: str = 'GEMI_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + thr = preproc.gemi_thresholds(self.data, threshold, self.scene_name, + self.scene_idx) + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def test_1_38um_high_clouds(self, + band: str, + cmin: np.ndarray, + test_name: str = '1.38um_High_Cloud_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + if self.scene_name in ['Ocean_Day', 'Polar_Day_Ocean']: + thr = preproc.thresholds_1_38um_test(self.data, self.thresholds, self.scene_name, + self.scene_idx) + else: + thr = threshold['thr'] + + print(f'Testing "{self.scene_name}"\n') + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + @run_if_test_exists_for_scene + def thin_cirrus_4_12um_BTD_test(self, + band: str, + cmin: np.ndarray, + test_name: str = '4-12um_BTD_Thin_Cirrus_Test') -> np.ndarray: + + confidence = np.ones(self.data.M01.shape) + threshold = self.thresholds[self.scene_name][test_name] + + if (threshold['perform'] is True and self.pixels_in_scene is True): + thr = preproc.polar_night_thresholds(self.data, self.thresholds, self.scene_name, + test_name, self.scene_idx) + rad = self.data[band].values[self.scene_idx] + confidence[self.scene_idx] = conf.conf_test_new(rad, thr) + + cmin = np.fmin(cmin, confidence) + + return cmin + + def single_threshold_test(self, test_name, band, cmin): + + if band == 'bad_data': + return cmin + print(f'Running test "{test_name}" for "{self.scene_name}"') + + # preproc_thresholds() + if 'thr' in self.thresholds[self.scene_name][test_name]: + thr = np.array(self.thresholds[self.scene_name][test_name]['thr']) + else: + thr = np.array(self.thresholds[self.scene_name][test_name]) + thr_xr = xr.Dataset() + + if test_name == '11-12um_Cirrus_Test': + thr_xr['threshold'] = pt.preproc(self.data, self.thresholds[self.scene_name], self.scene_name) + thr = np.ones((5,)) # This is only temporary to force the logic of the code + # I need to find a better solution at some point + elif test_name == 'SST_Test': + thr_xr['threshold'] = (('number_of_lines', 'number_of_pixels', 'z'), + np.ones((self.data[band].shape[0], self.data[band].shape[1], 5))*thr) + elif test_name == '7.3-11um_BTD_Mid_Level_Cloud_Test': + thr_xr['threshold'] = pt.get_pn_thresholds(self.data, self.thresholds, self.scene_name, + '7.3-11um_BTD_Mid_Level_Cloud_Test') + thr = np.ones((5,)) + elif test_name == 'Surface_Temperature_Test': + thr_xr['threshold'] = pt.preproc_surf_temp(self.data, self.thresholds[self.scene_name]) + thr = np.ones((5,)) + elif (test_name == '11-4um_Oceanic_Stratus_Test' and + self.scene_name in ['Land_Day_Desert', 'Land_Day_Desert_Coast', 'Polar_Day_Desert', + 'Polar_Day_Desert_Coast']): + thr = np.array([self.thresholds[self.scene_name][test_name][i] for i in range(8)]) + elif test_name == 'NIR_Reflectance_Test': + corr_thr = pt.preproc_nir(self.data, self.thresholds, self.scene_name) + thr_xr['threshold'] = (('number_of_lines', 'number_of_pixels', 'z'), corr_thr) + elif test_name == 'Visible_Reflectance_Test': + thr_xr['threshold'], self.data['M128'] = pt.vis_refl_thresholds(self.data, + self.thresholds, + self.scene_name) + elif test_name == '1.6_2.1um_NIR_Reflectance_Test': + corr_thr = pt.nir_refl(self.data, self.thresholds, self.scene_name) + thr_xr['threshold'] = (('number_of_lines', 'number_of_pixels', 'z'), corr_thr) + thr = np.ones((5,)) + elif test_name == '4-12um_BTD_Thin_Cirrus_Test': + thr_xr['threshold'] = pt.get_pn_thresholds(self.data, self.thresholds, self.scene_name, + '4-12um_BTD_Thin_Cirrus_Test') + thr = np.ones((5,)) + elif test_name == 'GEMI_Test': + thr_xr['threshold'] = pt.GEMI_test(self.data, self.thresholds, self.scene_name) + thr = np.ones((5,)) + elif (test_name == '1.38um_High_Cloud_Test' and self.scene_name in ['Ocean_Day', 'Polar_Ocean_Day']): + thr_xr['threshold'] = pt.test_1_38um_preproc(self.data, self.thresholds, self.scene_name) + thr = np.ones((5,)) + else: + thr_xr['threshold'] = (('number_of_lines', 'number_of_pixels', 'z'), + np.ones((self.data[band].shape[0], self.data[band].shape[1], 5))*thr) + + data = xr.Dataset(self.data, coords=thr_xr) + + if test_name == 'SST_Test': + data['sfcdif'] = (('number_of_lines', 'number_of_pixels'), + pt.preproc_sst(data, self.thresholds[self.scene_name][test_name]).values) + band = 'sfcdif' + if test_name == '11um_Variability_Test': + var = pt.var_11um(self.data, self.thresholds) + data['11um_var'] = data.M15 + data['11um_var'].values[var != 9] = np.nan + + if thr[4] == 1: + print('test running...') + confidence = conf_xr.conf_test(data, band) + + cmin = np.fmin(cmin, confidence) + + return cmin + + def double_threshold_test(self, test_name, band, cmin): + data = self.data + if test_name == '11-4um_BT_Difference_Test': + thr = pt.bt11_4um_preproc(self.data, self.thresholds, self.scene_name) + print('test running...') + confidence = conf.conf_test_dble(data['M15-M13'].values, thr) + confidence = confidence.reshape(data.M01.shape) + + if test_name == 'Vis/NIR_Ratio_Test': + print('test running...') + thr_no_sunglint = np.array([self.thresholds[self.scene_name][test_name][i] for i in range(8)]) + thr_sunglint = np.array([self.thresholds['Sun_Glint']['snglnt'][i] for i in range(8)]) + vrat = data.M07.values/data.M05.values + _dtr = np.pi/180.0 + sza = data.sensor_zenith.values + raz = data.relative_azimuth.values + vza = data.sensor_zenith.values + cos_refang = np.sin(vza*_dtr) * np.sin(sza*_dtr) * np.cos(raz*_dtr) + \ + np.cos(vza*_dtr) * np.cos(sza*_dtr) + refang = np.arccos(cos_refang) * 180./np.pi + idx = np.nonzero((data.solar_zenith <= 85) & (refang <= data.sunglint_angle)) + + confidence = conf.conf_test_dble(vrat, thr_no_sunglint) + confidence = confidence.reshape(data.M01.shape) + confidence[idx] = conf.conf_test_dble(vrat[idx], thr_sunglint) + + confidence = confidence.reshape(data.M01.shape) + + if (test_name == '11-4um_Oceanic_Stratus_Test' and + self.scene_name in ['Land_Day_Desert', 'Land_Day_Desert_Coast', 'Polar_Day_Desert', + 'Polar_Day_Desert_Coast']): + thr = np.array([self.thresholds[self.scene_name][test_name][i] for i in range(8)]) + + print('test running...') + confidence = conf.conf_test_dble(data['M15-M16'].values, thr) + confidence = confidence.reshape(data.M01.shape) + + cmin = np.fmin(cmin, confidence) + + return cmin + + +class ComputeTests(CloudTests): + + def __init__(self, + data: xr.Dataset, + scene_name: str, + thresholds: Dict) -> None: + super().__init__(data, scene_name, thresholds) + + def run_tests(self): + cmin_G1 = np.ones(self.data.M01.shape) + cmin_G2 = np.ones(self.data.M01.shape) + cmin_G3 = np.ones(self.data.M01.shape) + cmin_G4 = np.ones(self.data.M01.shape) + cmin_G5 = np.ones(self.data.M01.shape) + + # Group 1 + cmin_G1 = self.test_11um('M15', cmin_G1, test_name='11um_Test') + cmin_G1 = self.sst_test('M15', 'M16', cmin_G1, test_name='SST_Test') + + # Group 2 + cmin_G2 = self.bt_diff_86_11um('M14-M15', cmin_G2, test_name='8.6-11um_Test') + cmin_G2 = self.test_11_12um_diff('M15-M16', cmin_G2, test_name='11-12um_Cirrus_Test') + cmin_G2 = self.oceanic_stratus_11_4um_test('M15-M13', cmin_G2, + test_name='11-4um_Oceanic_Stratus_Test') + + # Group 3 + cmin_G3 = self.nir_reflectance_test('M07', cmin_G3, test_name='NIR_Reflectance_Test') + cmin_G3 = self.vis_nir_ratio_test('M07M05ratio', cmin_G3, test_name='Vis/NIR_Ratio_Test') + cmin_G3 = self.nir_reflectance_test('M10', cmin_G3, test_name='1.6_2.1um_NIR_Reflectance_Test') + cmin_G3 = self.visible_reflectance_test('M128', cmin_G3, test_name='Visible_Reflectance_Test') + cmin_G3 = self.gemi_test('GEMI', cmin_G3, test_name='GEMI_Test') + + # Group 4 + cmin_G4 = self.test_1_38um_high_clouds('M09', cmin_G4, test_name='1.38um_High_Cloud_Test') + + # Group 5 + cmin_G5 = self.thin_cirrus_4_12um_BTD_test('M13-M16', cmin_G5, + test_name='4-12um_BTD_Thin_Cirrus_Test') + + cmin = cmin_G1 * cmin_G2 * cmin_G3 * cmin_G4 * cmin_G5 + + return cmin + + def clear_sky_restoral(self, + cmin: np.ndarray) -> np.ndarray: + + total_bit = np.full(self.data.M01.shape, 3) + sunglint_angle = self.thresholds['Sun_Glint']['bounds'][3] + scene_flags = scn.find_scene(self.data, sunglint_angle) + + idx = np.nonzero((scene_flags['water'] == 1) & (scene_flags['ice'] == 0) & + (scene_flags['uniform'] == 1) & (cmin <= 0.99) & (cmin >= 0.05)) + # cmin[idx] = restoral.spatial(self.data, self.thresholds['Sun_Glint'], scene_flags, cmin)[idx] + + idx = np.nonzero((scene_flags['water'] == 1) & (scene_flags['sunglint'] == 1) & + (scene_flags['uniform'] == 1) & (cmin <= 0.95)) + cmin[idx] = restoral.sunglint(self.data, self.thresholds['Sun_Glint'], total_bit, cmin)[idx] + + return cmin + + +def preproc_thresholds(thresholds, data): + thr = np.array(thresholds) + thr_xr = xr.Dataset() + thr_xr['tresholds'] = (('number_of_lines', 'number_of_pixels', 'z'), + np.ones((data['M01'].shape[0], data['M01'].shape[1], 5))*thr) + + nl_sfct1 = thresholds['Land_Night']['Surface_Temperature_Test'][0] +# nl_sfct2 = thresholds['Land_Night']['Surface_Temperature_Test'][1] +# nlsfct_pfm = thresholds['Land_Night']['Surface_Temperature_Test'][2] + nl_df1 = thresholds['Land_Night']['Surface_Temperature_Test_difference'][0:2] + nl_df2 = thresholds['Land_Night']['Surface_Temperature_Test_difference'][2:] + +# df1 = data.M15 - data.M16 +# df2 = data.M15 - data.M13 + thr_xr = thr_xr.where(data.desert != 1, nl_sfct1) + thr_xr = thr_xr.where((data['M15-M16'] > nl_df1[0]) | + ((data['M15-M16'] < nl_df1[0]) & + ((data['M15-M13'] <= nl_df2[0]) | (data['M15-M13'] >= nl_df2[1]))), + nl_sfct1[0]) + + data = xr.Dataset(data, coords=thr_xr) + + return data + + +def single_threshold_test(test, rad, threshold): + + radshape = rad.shape + rad = rad.reshape(np.prod(radshape)) + + thr = np.array(threshold[test]) + confidence = np.zeros(rad.shape) + + if thr[4] == 1: + print(f"{test} test running") + # the C code has the line below that I don't quite understand the purpose of. + # It seems to be setting the bit to 0 if the BT value is greater than the midpoint + # + # if (m31 >= dobt11[1]) (void) set_bit(13, pxout.testbits); + + # confidence = utils.conf_test(rad, thr) + confidence = conf.conf_test(rad, thr) + + return confidence.reshape(radshape) + + +def test(): + rad = np.random.randint(50, size=[4, 8]) + # coeffs = [5, 42, 20, 28, 15, 35, 1] + # coeffs = [20, 28, 5, 42, 15, 35, 1] + coeffs = [35, 15, 20, 1, 1] + # confidence = conf_test_dble(rad, coeffs) + confidence = test_11um(rad, coeffs) + print(rad) + print('\n') + print(confidence) + + +if __name__ == "__main__": + test() + + + + + + diff --git a/thresholds.mvcm.snpp.v0.0.1.yaml b/thresholds.mvcm.snpp.v0.0.1.yaml index 29cf81551a741c124f8a2a23ad5e6f05ca4bcb02..7c2565cddef859b779b751fcb488c3c673820bbc 100644 --- a/thresholds.mvcm.snpp.v0.0.1.yaml +++ b/thresholds.mvcm.snpp.v0.0.1.yaml @@ -10,7 +10,9 @@ Land_Day: adj: 1.25 perform: True dl_ref3_tpw : -10.00 - 11-4um_Oceanic_Stratus_Test: [-16.0, -14.0, -12.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-16.0, -14.0, -12.0, 1.0, 1.0] + perform: True CO2_High_Clouds_Test: [222.0, 224.0, 226.0, 1.0, 1.0] Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: @@ -34,6 +36,7 @@ Land_Night: perform: True 4-12um_BTD_Thin_Cirrus_Test: thr: [15.0, 10.0, 5.00, 1.0, 1.0] + perform: True CO2_High_Clouds_Test: [222.0, 224.0, 226.0, 1.0, 1.0] Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] 7.3-11um_BTD_Mid_Level_Cloud_Test: @@ -65,7 +68,9 @@ Land_Day_Coast: adj: 1.25 perform: True dl_ref3_tpw_t2 : -10.00 - 11-4um_Oceanic_Stratus_Test: [-16.0, -14.0, -12.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-16.0, -14.0, -12.0, 1.0, 1.0] + perform: True CO2_High_Clouds_Test: [222.0, 224.0, 226.0, 1.0, 1.0] Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: @@ -85,13 +90,11 @@ Land_Day_Desert: cmult: 0.3 adj: 1.25 perform: True - 11-4um_Oceanic_Stratus_Test: [-28.0, -26.0, -24.0, -2.0, 0.0, 2.0, 1.0, 1.0] # this replaces lds11_4hi and - # lds11_4lo. The values are - # sorted left to right so that - # they follow the scheme: - # Lo-Mid-Hi--Hi-Mid-Lo - # This is the opposite of - # Ocean_Day + 11-4um_Oceanic_Stratus_Test: + thr: [-28.0, -26.0, -24.0, -2.0, 0.0, 2.0, 1.0, 1.0] # this replaces lds11_4hi and lds11_4lo. The values + perform: True # are sorted left to right so that they follow the + # scheme: Lo-Mid-Hi--Hi-Mid-Lo This is the opposite + # of Ocean_Day # lds11_4hi : [2.0, 0.0, -2.0, 1.00, 1.0] # lds11_4lo : [-28.0, -26.0, -24.0, 1.00] CO2_High_Clouds_Test: [222.0, 224.0, 226.0, 1.0, 1.0] @@ -108,6 +111,7 @@ Land_Day_Desert: gemi0: [0.085, 0.095, 0.115, 1.00, 1.0] gemi1: [0.145, 0.170, 0.220, 1.00] gemi2: [0.310, 0.335, 0.360, 1.00] + perform: True lds_ref3_tpw : -10.00 ldsbt1 : 320.0 # lds11_12lcmult : 0.3 @@ -120,7 +124,9 @@ Land_Day_Desert_Coast: cmult: 0.3 adj: 1.25 perform: True - 11-4um_Oceanic_Stratus_Test: [-23.0, -21.0, -19.0, -2.0, 0.0, 2.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-23.0, -21.0, -19.0, -2.0, 0.0, 2.0, 1.0, 1.0] + perform: True CO2_High_Clouds_Test: [222.0, 224.0, 226.0, 1.0, 1.0] Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: @@ -152,7 +158,9 @@ Ocean_Day: cmult: 0.3 adj: 1.25 perform: True - 11-4um_Oceanic_Stratus_Test: [-11.0, -9.0, -7.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-11.0, -9.0, -7.0, 1.0, 1.0] + perform: True NIR_Reflectance_Test: thr: [0.062, 0.043, 0.029, 1.0, 1.0] coeffs: [1.7291, 0.0715, -0.0026, 0.000025889] @@ -205,7 +213,9 @@ Ocean_Night: cmult: 0.3 adj: 1.0 perform: True - 11-4um_Oceanic_Stratus_Test: [1.25, 1.00, 0.25, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [1.25, 1.0, 0.25, 1.0, 1.0] + perform: True CO2_High_Clouds_Test: [222.0, 224.0, 226.0, 1.0, 1.0] Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] no86_73 : [14.0, 15.0, 16.0, 1.0, 1.0] @@ -225,7 +235,9 @@ Polar_Day_Land: adj: 0.3 perform: True pdl_ref3_tpw : -10.00 - 11-4um_Oceanic_Stratus_Test: [-16.0, -14.0, -12.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-16.0, -14.0, -12.0, 1.0, 1.0] + perform: True pdlh20 : [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: thr: [0.207, 0.169, 0.132, 1.0, 1.0] @@ -268,6 +280,7 @@ Polar_Night_Land: mid3: [0.00, 0.00, 0.00, 0.0] high: [1.00, 0.70, 0.40, 1.0] bt11_bounds : [235.0, 000.0, 000.0, 265.0] + perform: True Polar_Day_Coast: 11-12um_Cirrus_Test: @@ -276,7 +289,9 @@ Polar_Day_Coast: adj: 0 # I NEED TO WORK ON THIS perform: True pdl_ref3_tpw_t2 : -10.00 - 11-4um_Oceanic_Stratus_Test: [-16.0, -14.0, -12.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-16.0, -14.0, -12.0, 1.0, 1.0] + perform: True Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: thr: [0.207, 0.169, 0.132, 1.0, 1.0] @@ -292,7 +307,9 @@ Polar_Day_Desert: cmult: 0 # I NEED TO WORK ON THIS adj: 0 # I NEED TO WORK ON THIS perform: True - 11-4um_Oceanic_Stratus_Test: [-22.0, -20.0, -18.0, -2.0, 0.0, 2.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-22.0, -20.0, -18.0, -2.0, 0.0, 2.0, 1.0, 1.0] + perform: True Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: thr: [0.326, 0.288, 0.250, 1.00, 1.0] @@ -305,6 +322,7 @@ Polar_Day_Desert: gemi0: [0.085, 0.110, 0.135, 1.00, 1.0] gemi1: [0.170, 0.220, 0.270, 1.00] gemi2: [0.310, 0.335, 0.360, 1.00] + perform: True pds_ref3_tpw : -10.00 pdsbt1 : 320.0 @@ -314,7 +332,9 @@ Polar_Day_Desert_Coast: cmult: 0 # I NEED TO WORK ON THIS adj: 0 # I NEED TO WORK ON THIS perform: True - 11-4um_Oceanic_Stratus_Test: [-23.0, -21.0, -19.0, -2.0, 0.0, 2.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-23.0, -21.0, -19.0, -2.0, 0.0, 2.0, 1.0, 1.0] + perform: True Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] Visible_Reflectance_Test: thr: [0.326, 0.288, 0.250, 1.00, 1.0] @@ -361,7 +381,7 @@ Polar_Night_Snow: mid3: [0.00, 0.00, 0.00, 0.0] # pn_4_12m3 high: [2.50, 2.00, 1.50, 1.0] # pn_4_12h bt11_bounds: [235.0, 0.0, 0.0, 265.0] # bt_11_bounds - pns_4_12_pfm : 1.0 + perform: True 7.3-11um_BTD_Mid_Level_Cloud_Test: low: [-1.00, 0.00, 1.00, 1.0, 1.0] # pn_7_11l mid1: [0.00, -4.50, -1.00, 1.0] # pn_7_11m1 @@ -426,7 +446,9 @@ Polar_Day_Ocean: locut_coeff: 0.0100 midpt_coeff: 0.0070 perform: True - 11-4um_Oceanic_Stratus_Test: [-11.0, -9.0, -7.0, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [-11.0, -9.0, -7.0, 1.0, 1.0] + perform: True Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] pdo_b26pfm : 1.0 pdo_b2bias_adj : 0.96 @@ -454,7 +476,9 @@ Polar_Night_Ocean: adj: 1.0 perform: True pnobt1 : 280.0 - 11-4um_Oceanic_Stratus_Test: [1.25, 1.00, 0.25, 1.0, 1.0] + 11-4um_Oceanic_Stratus_Test: + thr: [1.25, 1.0, 0.25, 1.0, 1.0] + perform: True Water_Vapor_High_Clouds_Test: [215.0, 220.0, 225.0, 1.0, 1.0] pno86_73 : [14.0, 15.0, 16.0, 1.0, 1.0] 11um_Variability_Test: [3.0, 6.0, 7.0, 1.0, 1.0] @@ -496,6 +520,7 @@ Night_Snow: ns11_4lo : [0.70, 0.60, 0.50, 1.0, 1.0] 4-12um_BTD_Thin_Cirrus_Test: thr: [4.50, 4.00, 3.50, 1.0, 1.0] + perform: True 7.3-11um_BTD_Mid_Level_Cloud_Test: low: [-1.00, 0.00, 1.00, 1.0, 1.0] # pn_7_11l mid1: [0.00, -4.50, -1.00, 1.0] # pn_7_11m1