├── .gitignore ├── BAR.py ├── BARfunctions.py ├── LICENSE ├── README.md ├── granuleFiles └── info.txt └── models ├── AOD └── info.txt ├── ApproximationError └── approximationerror.json ├── FMF └── info.txt ├── LUT └── LUTinformation.txt └── SurfaceReflectance └── 2014 └── info.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | Albedo*.png 7 | *.nc 8 | *.hdf 9 | 10 | -------------------------------------------------------------------------------- /BAR.py: -------------------------------------------------------------------------------- 1 | """ 2 | Bayesian Aerosol Retrieval algorithm 3 | version 1.01 (12 August 2020) 4 | 5 | For the most recent version of the codes, please see https://github.com/TUT-ISI/BARalgorithm 6 | 7 | Reference: 8 | Lipponen, A., Mielonen, T., Pitkänen, M. R. A., Levy, R. C., Sawyer, V. R., Romakkaniemi, S., Kolehmainen, V., and Arola, A.: 9 | Bayesian Aerosol Retrieval Algorithm for MODIS AOD retrieval over land, Atmos. Meas. Tech., 11, 1529–1547, 2018. 10 | https://doi.org/10.5194/amt-11-1529-2018. 11 | 12 | Contact information: 13 | Antti Lipponen 14 | Finnish Meteorological Institute 15 | antti.lipponen@fmi.fi 16 | 17 | ---- 18 | 19 | Copyright 2018-2020 Antti Lipponen / Finnish Meteorological Institute 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 22 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 23 | modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 24 | Software is furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 27 | 28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 29 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 30 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 31 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | 33 | """ 34 | 35 | import os 36 | import json 37 | from scipy.interpolate import RegularGridInterpolator 38 | from netCDF4 import Dataset 39 | import numpy as np 40 | from scipy.sparse import diags, csr_matrix 41 | import sys 42 | from datetime import datetime 43 | # BAR functions 44 | from BARfunctions import loadGranule, prepareModels, loadSurfaceReflectancePrior, combinePolyLookupList, BARretrieve 45 | 46 | 47 | def printUse(): 48 | print('Use: "python BAR.py INPUT [OUTPUT] [-quantifyuncertainty] [-nospatialcorrelation] [-noapproximationerror]"\nExample: "python BAR.py MOD04_L2.A2015101.1155.006.2015104000600.hdf"') 49 | print('\nCommand line options:\n-quantifyuncertainty: Quantify the uncertainties related to retrieval and save the uncertainty estimates into the outputfile') 50 | print('-nospatialcorrelation: Do not use spatial correlation model') 51 | print('-noapproximationerror: Do not use approximation error model\n') 52 | 53 | 54 | # Read granule to be retrieved 55 | if len(sys.argv) < 2: 56 | print('\nMODIS M(O|Y)D04_L2 granule filename needed.') 57 | printUse() 58 | sys.exit(0) 59 | 60 | dataFile = sys.argv[1] 61 | inputFilePath, inputFileName = os.path.split(dataFile) 62 | print('\nBayesian Aerosol Retrieval (BAR) algorithm version 1.01 (12 August 2020).\n\n ---------------------\n Reference:\n Lipponen, A., Mielonen, T., Pitkänen, M. R. A., Levy, R. C., Sawyer, V. R., Romakkaniemi, S., Kolehmainen, V., and Arola, A.:\n Bayesian Aerosol Retrieval Algorithm for MODIS AOD retrieval over land, Atmos. Meas. Tech., 11, 1529–1547, 2018. https://doi.org/10.5194/amt-11-1529-2018\n ---------------------\n Contact information:\n Antti Lipponen, Finnish Meteorological Institute\n antti.lipponen@fmi.fi\n ---------------------\n') 63 | print(' Retrieving MODIS granule file: {}'.format(inputFileName)) 64 | 65 | if len(sys.argv) >= 3 and sys.argv[2][0] != '-': 66 | outputFilePath, outputFileName = os.path.split(sys.argv[2]) 67 | else: 68 | outputFilePath, outputFileName = inputFilePath, 'BAR_' + '.'.join(os.path.split(dataFile)[1].split('.')[:-1]) + '.nc' 69 | 70 | if not os.path.isfile(os.path.join(inputFilePath, inputFileName)): 71 | print('\nMODIS granule file "{}" not found.\n'.format(os.path.join(inputFilePath, inputFileName))) 72 | sys.exit(1) 73 | 74 | # Define areas, prior models & settings 75 | areas = { 76 | # East North America 77 | 'ENA': {'min_lat': 25.0, 'max_lat': 90.0, 'min_lon': -100.0, 'max_lon': -30.0}, 78 | # West North America 79 | 'WNA': {'min_lat': 25.0, 'max_lat': 90.0, 'min_lon': -180.0, 'max_lon': -100.0}, 80 | # Central and South America 81 | 'CSA': {'min_lat': -90.0, 'max_lat': 25.0, 'min_lon': -180.0, 'max_lon': -30.0}, 82 | # Europe 83 | 'EUR': {'min_lat': 35.0, 'max_lat': 90.0, 'min_lon': -30.0, 'max_lon': 60.0}, 84 | # North Africa and Middle East 85 | 'NAME': {'min_lat': 0.0, 'max_lat': 35.0, 'min_lon': -30.0, 'max_lon': 60.0}, 86 | # South Africa 87 | 'SA': {'min_lat': -90.0, 'max_lat': 0.0, 'min_lon': -30.0, 'max_lon': 60.0}, 88 | # Northeast Asia 89 | 'NEA': {'min_lat': 35.0, 'max_lat': 90.0, 'min_lon': 60.0, 'max_lon': 180.0}, 90 | # Southeast Asia 91 | 'SEA': {'min_lat': 0.0, 'max_lat': 35.0, 'min_lon': 60.0, 'max_lon': 180.0}, 92 | # Oceania 93 | 'OCE': {'min_lat': -90.0, 'max_lat': 0.0, 'min_lon': 60.0, 'max_lon': 180.0} 94 | } 95 | 96 | settings = { 97 | 'max_pixels_per_part': 3000, # max number of pixels to be retrieved at once 98 | 'BFGSftol': 1.0e-6, # iteration parameter 99 | 'BFGSgtol': 1.0e-6, # iteration parameter 100 | 'BFGSmaxiter': 5000, # iteration parameter 101 | 'N_processes': 4, # number of processes for retrieval (if computer has 4 CPU cores, 4 should result in optimal performance) 102 | 'surfacePriorYear': 2014, # year of surface reflectance prior model 103 | 'useApproximationErrorModel': True, # should we use the (precomputed) approximation error model 104 | 'useSpatialCorrelations': True, # should we use the spatial correlation models for aerosol properties 105 | 'quantifyUncertainty': False, # should we quantify the uncertainties, BAR can provide pixel-level uncertainty estimates but by default these are not saved to save time and disc space 106 | } 107 | 108 | AODprior = { 109 | 'range': 50.0, # correlation length (km) 110 | 'p': 1.5, # p parameter (defines smoothness of the field) 111 | 'sill': 0.10, # variance for the spatially correlated component 112 | 'nugget': 0.0025, # local variance 113 | } 114 | 115 | FMFprior = { 116 | 'range': 50.0, # correlation length (km) 117 | 'p': 1.5, # p parameter (defines smoothness of the field) 118 | 'sill': 0.25, # variance for the spatially correlated component 119 | 'nugget': 0.0100, # local variance 120 | } 121 | 122 | surfacePriorModifier = { 123 | 'meancoef': 1.0, # surface prior model expected values are multiplied by this number, > 1.0 brighten surface reflectance assumptions, < 1.0 darken surface reflectance assumptions 124 | 'stdcoef': 1.0, # surface prior model standard deviations are multiplied by this number, > 1.0 adds uncertainty to surface prior, < 1.0 reduces uncertainty 125 | } 126 | 127 | # parse command line options 128 | for option in sys.argv: 129 | if option[0] != '-': 130 | continue 131 | 132 | if option.lower() == '-quantifyuncertainty': 133 | settings['quantifyUncertainty'] = True 134 | print(' Uncertainty quantification enabled') 135 | elif option.lower() == '-nospatialcorrelation': 136 | settings['useSpatialCorrelations'] = False 137 | print(' Spatial correlation models disabled') 138 | elif option.lower() == '-noapproximationerror': 139 | settings['useApproximationErrorModel'] = False 140 | print(' Approximation error models disabled') 141 | elif option.lower()[:10] == '-aodprior=': 142 | print(' Using custom AOD prior parameters') 143 | try: 144 | l = json.loads(option[10:]) 145 | for k, v in l.items(): 146 | print(' {}: {}'.format(k, v)) 147 | if k not in AODprior: 148 | print('\n{} is not AOD prior parameter\n'.format(k)) 149 | sys.exit(1) 150 | AODprior[k] = v 151 | except: 152 | print('\nAOD prior parameter JSON is not valid.\n') 153 | sys.exit(1) 154 | elif option.lower()[:10] == '-fmfprior=': 155 | print(' Using custom FMF prior parameters') 156 | try: 157 | l = json.loads(option[10:]) 158 | for k, v in l.items(): 159 | print(' {}: {}'.format(k, v)) 160 | if k not in FMFprior: 161 | print('\n{} is not FMF prior parameter\n'.format(k)) 162 | sys.exit(1) 163 | FMFprior[k] = v 164 | except: 165 | print('\nFMF prior parameter JSON is not valid.\n') 166 | sys.exit(1) 167 | elif option.lower()[:14] == '-surfaceprior=': 168 | print(' Modifying surface reflectance prior') 169 | try: 170 | l = json.loads(option[14:]) 171 | for k, v in l.items(): 172 | print(' {}: {}'.format(k, v)) 173 | if k not in surfacePriorModifier: 174 | print('\n{} is not surface reflectance prior parameter\n'.format(k)) 175 | sys.exit(1) 176 | surfacePriorModifier[k] = v 177 | except: 178 | print('\nSurface reflectance prior modifier JSON is not valid.\n') 179 | sys.exit(1) 180 | else: 181 | print('\nUnknown command line option "{}"\n'.format(option)) 182 | printUse() 183 | sys.exit(1) 184 | 185 | # load approximation error model 186 | try: 187 | with open(os.path.join('models', 'ApproximationError', 'approximationerror.json'), 'rt') as f: 188 | approximationErrorModel = json.load(f) 189 | except: 190 | print('\nApproximation error file not found. This data should be included with the codes and data. Please check everything is correct.\n') 191 | sys.exit(1) 192 | 193 | # load FMF prior model expected value (the file is not provided with the code, please see the readme for information how to download the file) 194 | try: 195 | FMFpriorFile = os.path.join('models', 'FMF', 'gt_ff_0550nm.nc') 196 | f = Dataset(FMFpriorFile, 'r', format='NETCDF4') 197 | fmfMonth, fmfLat, fmfLon, fmfValues = np.arange(1, 13), f['lat'][:], f['lon'][:], f['aer_data'][:] 198 | f.close() 199 | except: 200 | print('\nFMF prior model data file ({}) not found. This is an external file that needs to be downloaded before the code can be run.\nYou can download the file from: ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_ff_0550nm.nc\nPlease see README.txt for more information.\n'.format(FMFpriorFile)) 201 | sys.exit(1) 202 | 203 | # load AOD prior model expected value (the file is not provided with the code, please see the readme for information how to download the file) 204 | try: 205 | AODpriorFile = os.path.join('models', 'AOD', 'gt_t_00550nm.nc') 206 | f = Dataset(AODpriorFile, 'r', format='NETCDF4') 207 | aodMonth, aodLat, aodLon, aodValues = np.arange(1, 13), f['lat'][:], f['lon'][:], f['aod'][:] 208 | f.close() 209 | except: 210 | print('\nAOD prior model data file ({}) not found. This is an external file that needs to be downloaded before the code can be run.\nYou can download the file from: ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_t_00550nm.nc\nPlease see README.txt for more information.\n'.format(AODpriorFile)) 211 | sys.exit(1) 212 | 213 | # construct an interpolator for the expected values 214 | AODFMFMeanIntpolator = { 215 | 'AOD': RegularGridInterpolator((aodMonth, aodLat[::-1], aodLon), aodValues[:, ::-1, :]), 216 | 'FMF': RegularGridInterpolator((fmfMonth, fmfLat[::-1], fmfLon), fmfValues[:, ::-1, :]) 217 | } 218 | 219 | # load MODIS granule file 220 | try: 221 | modisData = loadGranule(dataFile) 222 | except: 223 | print('\nError loading datafile "{}". The file should be a valid MODIS MOD04_L2 or MYD04_L2 product file.\n'.format(dataFile)) 224 | sys.exit(1) 225 | 226 | granuleMonth, granuleYear = modisData['scantime'].month, modisData['scantime'].year 227 | print(' Granule date and time: {}'.format(modisData['scantime'].strftime('%d %b %Y %H:%MZ (doy: %j)'))) 228 | 229 | try: 230 | granuleCenterPoint = [np.mean(modisData['lon']), np.mean(modisData['lat'])] 231 | print(' Granule center point: LAT: {:.2f} LON: {:.2f}'.format(granuleCenterPoint[1], granuleCenterPoint[0])) 232 | area = list(filter(lambda x: x[1]['min_lat'] <= granuleCenterPoint[1] and 233 | x[1]['max_lat'] >= granuleCenterPoint[1] and 234 | x[1]['min_lon'] <= granuleCenterPoint[0] and 235 | x[1]['max_lon'] >= granuleCenterPoint[0], areas.items()))[0][0] 236 | print(' Area to be used for retrieval: {}'.format(area)) 237 | except: 238 | print('\nERROR in finding the area.\n') 239 | sys.exit(1) 240 | 241 | 242 | # load surface reflectance prior model 243 | try: 244 | surfacePrior = loadSurfaceReflectancePrior(granuleMonth, granuleYear, surfacePriorModifier, settings) 245 | except: 246 | print('\nError loading surface prior.\n') 247 | sys.exit(1) 248 | 249 | # prepare radiative transfer models 250 | polynomialLookups, granuleMASK_full, allpartsData, gFull, aerosolmap = prepareModels(modisData, settings) 251 | if len(allpartsData) > 1: 252 | print(' Retrieval will be run in {} parts'.format(len(allpartsData))) 253 | 254 | savedata = { 255 | 'BAR_AOD': -9.999 * np.ones(gFull.shape[0]), 256 | 'BAR_AOD466': -9.999 * np.ones(gFull.shape[0]), 257 | 'BAR_AOD644': -9.999 * np.ones(gFull.shape[0]), 258 | 'BAR_AOD_percentile_2.5': -9.999 * np.ones(gFull.shape[0]), 259 | 'BAR_AOD_percentile_5.0': -9.999 * np.ones(gFull.shape[0]), 260 | 'BAR_AOD_percentile_16.0': -9.999 * np.ones(gFull.shape[0]), 261 | 'BAR_AOD_percentile_84.0': -9.999 * np.ones(gFull.shape[0]), 262 | 'BAR_AOD_percentile_95.0': -9.999 * np.ones(gFull.shape[0]), 263 | 'BAR_AOD_percentile_97.5': -9.999 * np.ones(gFull.shape[0]), 264 | 'BAR_FMF': -9.999 * np.ones(gFull.shape[0]), 265 | 'BAR_FMF_percentile_2.5': -9.999 * np.ones(gFull.shape[0]), 266 | 'BAR_FMF_percentile_5.0': -9.999 * np.ones(gFull.shape[0]), 267 | 'BAR_FMF_percentile_16.0': -9.999 * np.ones(gFull.shape[0]), 268 | 'BAR_FMF_percentile_84.0': -9.999 * np.ones(gFull.shape[0]), 269 | 'BAR_FMF_percentile_95.0': -9.999 * np.ones(gFull.shape[0]), 270 | 'BAR_FMF_percentile_97.5': -9.999 * np.ones(gFull.shape[0]), 271 | 'BAR_rhos466': -9.999 * np.ones(gFull.shape[0]), 272 | 'BAR_rhos553': -9.999 * np.ones(gFull.shape[0]), 273 | 'BAR_rhos644': -9.999 * np.ones(gFull.shape[0]), 274 | 'BAR_rhos211': -9.999 * np.ones(gFull.shape[0]), 275 | 'BAR_logAODplus1': -9.999 * np.ones(gFull.shape[0]), 276 | 'BAR_logAODplus1_std': -9.999 * np.ones(gFull.shape[0]), 277 | 'BAR_FMF_std': -9.999 * np.ones(gFull.shape[0]), 278 | 'BAR_rhos466_std': -9.999 * np.ones(gFull.shape[0]), 279 | 'BAR_rhos553_std': -9.999 * np.ones(gFull.shape[0]), 280 | 'BAR_rhos644_std': -9.999 * np.ones(gFull.shape[0]), 281 | 'BAR_rhos211_std': -9.999 * np.ones(gFull.shape[0]), 282 | 'lon': gFull[:, 0], 283 | 'lat': gFull[:, 1], 284 | 'DarkTarget_AOD': modisData['Corrected_Optical_Depth_Land553'], 285 | 'DarkTarget_FMF': modisData['Optical_Depth_Ratio_Small_Land'], 286 | } 287 | 288 | if not settings['quantifyUncertainty']: 289 | savedata = {k: savedata[k] for k in savedata if k.find('percentile') < 0 and k.find('_std') < 0} 290 | 291 | for iPart, partData in enumerate(allpartsData): 292 | if len(allpartsData) == 1: 293 | print(' Running retrieval...') 294 | else: 295 | print(' Running retrieval... (part {:d}/{:d})'.format(iPart + 1, len(allpartsData))) 296 | 297 | # preparing masks & coordinates 298 | MASKl, MASKf = partData['MASKl'], partData['MASKf'] 299 | g = gFull[MASKf, :] 300 | 301 | # preparing surface reflectance prior for this granule 302 | indices = surfacePrior['kNNmean'].kneighbors(g, return_distance=False) 303 | indicesstd = surfacePrior['kNNstd'].kneighbors(g, return_distance=False) 304 | 305 | granuleSurfacePrior = { 306 | 'mean466': surfacePrior['surfprior466'][indices].mean(axis=1), 307 | 'mean550': surfacePrior['surfprior550'][indices].mean(axis=1), 308 | 'mean644': surfacePrior['surfprior644'][indices].mean(axis=1), 309 | 'mean211': surfacePrior['surfprior211'][indices].mean(axis=1), 310 | 'std466': np.sqrt(np.clip(surfacePrior['surfprior466'][indices].std(axis=1), a_min=1.0e-6, a_max=1.0)**2 + np.mean(surfacePrior['surfprior466std'][indicesstd]**2, axis=1)), 311 | 'std550': np.sqrt(np.clip(surfacePrior['surfprior550'][indices].std(axis=1), a_min=1.0e-6, a_max=1.0)**2 + np.mean(surfacePrior['surfprior550std'][indicesstd]**2, axis=1)), 312 | 'std644': np.sqrt(np.clip(surfacePrior['surfprior644'][indices].std(axis=1), a_min=1.0e-6, a_max=1.0)**2 + np.mean(surfacePrior['surfprior644std'][indicesstd]**2, axis=1)), 313 | 'std211': np.sqrt(np.clip(surfacePrior['surfprior211'][indices].std(axis=1), a_min=1.0e-6, a_max=1.0)**2 + np.mean(surfacePrior['surfprior211std'][indicesstd]**2, axis=1)), 314 | } 315 | Nvars = g.shape[0] 316 | 317 | # preparing observed data 318 | REFW466 = modisData['rho466'][MASKl] 319 | STDREFW466 = modisData['stdrho466'][MASKl] 320 | REFW553 = modisData['rho550'][MASKl] 321 | STDREFW553 = modisData['stdrho550'][MASKl] 322 | REFW644 = modisData['rho644'][MASKl] 323 | STDREFW644 = modisData['stdrho644'][MASKl] 324 | REFW2113 = modisData['rho211'][MASKl] 325 | STDREFW2113 = modisData['stdrho211'][MASKl] 326 | MeasData = np.concatenate((REFW466, REFW553, REFW644, REFW2113)) 327 | MeasDataStd = np.concatenate((STDREFW466, STDREFW553, STDREFW644, STDREFW2113)) 328 | 329 | # bounds for AOD & FMF (& surface reflectance) 330 | min_AOD, max_AOD = np.log(0.0 + 1.0), np.log(5.0 + 1.0) 331 | min_FMF, max_FMF = 0.0, 1.0 332 | bounds = np.array([[min_AOD, max_AOD], [min_FMF, max_FMF], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0], [0.0, 1.0]]) 333 | 334 | # load approximation error model 335 | if settings['useApproximationErrorModel']: 336 | print(' Using approximation error model {}/month {}'.format(area, granuleMonth)) 337 | MeasNoiseVar = (1.0 / (1.0 + MeasData) * MeasDataStd)**2 # LOGSCALE RHOS 338 | Nwavelengths = 4 339 | icov_ii, icov_jj, icov_vv = np.zeros(Nwavelengths**2 * Nvars, dtype=int), np.zeros(Nwavelengths**2 * Nvars, dtype=int), np.zeros(Nwavelengths**2 * Nvars) 340 | for ii in range(Nvars): 341 | local_cov = np.array(np.array(approximationErrorModel[area][str(granuleMonth)]['cov']).reshape((Nwavelengths, Nwavelengths)) + diags([MeasNoiseVar[ii], MeasNoiseVar[ii + 1 * Nvars], MeasNoiseVar[ii + 2 * Nvars], MeasNoiseVar[ii + 3 * Nvars]], 0)) 342 | local_icov = np.linalg.inv(local_cov) 343 | icov_ii[ii * Nwavelengths**2:(ii + 1) * Nwavelengths**2] = np.concatenate([[ii + 0 * Nvars] * Nwavelengths, [ii + 1 * Nvars] * Nwavelengths, [ii + 2 * Nvars] * Nwavelengths, [ii + 3 * Nvars] * Nwavelengths]) 344 | icov_jj[ii * Nwavelengths**2:(ii + 1) * Nwavelengths**2] = np.concatenate([[ii + 0 * Nvars, ii + 1 * Nvars, ii + 2 * Nvars, ii + 3 * Nvars] * Nwavelengths]) 345 | icov_vv[ii * Nwavelengths**2:(ii + 1) * Nwavelengths**2] = local_icov.ravel() 346 | 347 | MeasNoiseiCov = csr_matrix((icov_vv, (icov_ii, icov_jj)), shape=(Nwavelengths * Nvars, Nwavelengths * Nvars)) 348 | MeasNoiseE = np.tile(np.array(approximationErrorModel[area][str(granuleMonth)]['E'])[:, np.newaxis], (1, Nvars)).ravel() 349 | else: 350 | MeasNoiseCov = diags((1.0 / (1.0 + MeasData) * MeasDataStd)**2, 0) # LOGSCALE RHOS 351 | MeasNoiseiCov = diags(1.0 / MeasNoiseCov.diagonal(), 0) 352 | MeasNoiseE = 0.0 353 | # switch to log-scale measurement data (TOA reflectances) 354 | MeasData = np.log(MeasData + 1.0) 355 | 356 | # Initial values for retrieval 357 | AOD0 = AODFMFMeanIntpolator['AOD'](np.array([[granuleMonth, gg[1], gg[0]] for gg in np.clip(g, a_min=[-179.5, -89.5], a_max=[179.5, 89.5])])) 358 | FMF0 = AODFMFMeanIntpolator['FMF'](np.array([[granuleMonth, gg[1], gg[0]] for gg in np.clip(g, a_min=[-179.5, -89.5], a_max=[179.5, 89.5])])) 359 | 360 | # prepare the lookup-tables to final form 361 | polynomiallookupMatrices_fine = combinePolyLookupList(polynomialLookups[MASKl]) 362 | polynomiallookupMatrices_coarse = combinePolyLookupList(polynomialLookups[MASKl], 4) 363 | BARresults = BARretrieve(g, AOD0, FMF0, AODprior, FMFprior, granuleSurfacePrior, 364 | polynomiallookupMatrices_fine, 365 | polynomiallookupMatrices_coarse, 366 | MeasData, MeasNoiseiCov, MeasNoiseE, MASKf, bounds, settings) 367 | 368 | for k, v in BARresults.items(): 369 | savedata[k][MASKf] = v 370 | 371 | outputfile = os.path.join(outputFilePath, outputFileName) 372 | print(' Saving results to {}'.format(outputfile)) 373 | nc = Dataset(outputfile, 'w') 374 | nc.AODprior = str(AODprior).replace('\'', '') 375 | nc.FMFprior = str(FMFprior).replace('\'', '') 376 | nc.surfacePriorModifier = str(surfacePriorModifier).replace('\'', '') 377 | nc.retrievalsettings = str(settings).replace('\'', '') 378 | nc.inputfilename = inputFileName 379 | nc.granuleTime = modisData['scantime'].strftime('%d-%m-%Y %H:%MZ') 380 | nc.retrievalTime = datetime.utcnow().strftime('%d-%m-%Y %H:%MZ') 381 | nX, nY = modisData['nX'], modisData['nY'] 382 | ncX = nc.createDimension('X', nX) 383 | ncY = nc.createDimension('Y', nY) 384 | var = nc.createVariable('latitude', 'f4', ('X', 'Y')) 385 | var[:] = savedata['lat'].reshape((nX, nY)) 386 | var = nc.createVariable('longitude', 'f4', ('X', 'Y')) 387 | var[:] = savedata['lon'].reshape((nX, nY)) 388 | for key in savedata.keys(): 389 | if not (key[:3] == 'BAR' or key[:10] == 'DarkTarget'): 390 | continue 391 | var = nc.createVariable(key, 'f4', ('X', 'Y')) 392 | varToBeSaved = savedata[key] 393 | if key.find('AOD') >= 0: 394 | var.vmin = -0.1 395 | var.vmax = 5.0 396 | else: 397 | var.vmin = 0.0 398 | var.vmax = 1.0 399 | varToBeSaved[np.logical_or(varToBeSaved < var.vmin, varToBeSaved > var.vmax)] = np.nan 400 | var[:] = varToBeSaved.reshape((nX, nY)) 401 | nc.close() 402 | print('***** ALL DONE FOR THIS GRANULE *****\n\nThanks for using Bayesian Aerosol Retrieval!\n') 403 | -------------------------------------------------------------------------------- /BARfunctions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Bayesian Aerosol Retrieval algorithm function file 3 | version 1.01 (12 August 2020) 4 | 5 | For the most recent version of the codes, please see https://github.com/TUT-ISI/BARalgorithm 6 | 7 | Reference: 8 | Lipponen, A., Mielonen, T., Pitkänen, M. R. A., Levy, R. C., Sawyer, V. R., Romakkaniemi, S., Kolehmainen, V., and Arola, A.: 9 | Bayesian Aerosol Retrieval Algorithm for MODIS AOD retrieval over land, Atmos. Meas. Tech., 11, 1529–1547, 2018. 10 | https://doi.org/10.5194/amt-11-1529-2018. 11 | 12 | Contact information: 13 | Antti Lipponen 14 | Finnish Meteorological Institute 15 | antti.lipponen@fmi.fi 16 | 17 | ---- 18 | 19 | Copyright 2018-2020 Antti Lipponen / Finnish Meteorological Institute 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 22 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 23 | modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 24 | Software is furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 27 | 28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 29 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 30 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 31 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 32 | 33 | """ 34 | 35 | import numpy as np 36 | from pyhdf.SD import SD 37 | from netCDF4 import Dataset 38 | from datetime import datetime, timedelta 39 | from multiprocessing import Pool # use multiprocessing to make things faster 40 | import copy 41 | from scipy.interpolate import interp1d, RegularGridInterpolator 42 | from imageio import imread 43 | from sklearn.neighbors import KNeighborsRegressor 44 | import os 45 | from scipy.optimize import minimize 46 | from scipy.sparse import diags 47 | from scipy.linalg import block_diag 48 | from scipy.stats import norm 49 | 50 | 51 | def loadGranule(filename): 52 | dataFields = [ 53 | 'Latitude', 54 | 'Longitude', 55 | 'Mean_Reflectance_Land', 56 | 'STD_Reflectance_Land', 57 | 'Surface_Reflectance_Land', 58 | 'Solar_Azimuth', 59 | 'Sensor_Azimuth', 60 | 'Solar_Zenith', 61 | 'Sensor_Zenith', 62 | 'Topographic_Altitude_Land', 63 | 'Scan_Start_Time', 64 | 'Optical_Depth_Ratio_Small_Land', 65 | 'Corrected_Optical_Depth_Land', 66 | 'Land_Ocean_Quality_Flag', 67 | 'Aerosol_Type_Land', 68 | ] 69 | 70 | hdfData = {} 71 | hdfFile = SD(filename) 72 | for dataField in dataFields: 73 | q = hdfFile.select(dataField) 74 | qAttributes = q.attributes() 75 | qData = q.get() 76 | hdfData[dataField] = qData * qAttributes['scale_factor'] 77 | hdfFile.end() 78 | 79 | nX, nY = hdfData['Latitude'].shape[0], hdfData['Latitude'].shape[1] 80 | Latitude, Longitude = hdfData['Latitude'].ravel(), hdfData['Longitude'].ravel() 81 | Mean_Reflectance_Land = hdfData['Mean_Reflectance_Land'].reshape((10, -1)) 82 | STD_Reflectance_Land = hdfData['STD_Reflectance_Land'].reshape((10, -1)) 83 | 84 | Solar_Azimuth = hdfData['Solar_Azimuth'].ravel() 85 | Sensor_Azimuth = hdfData['Sensor_Azimuth'].ravel() 86 | Solar_Zenith = hdfData['Solar_Zenith'].ravel() 87 | Sensor_Zenith = hdfData['Sensor_Zenith'].ravel() 88 | Topographic_Altitude_Land = hdfData['Topographic_Altitude_Land'].ravel() 89 | 90 | Scan_Start_Time = hdfData['Scan_Start_Time'][0, 0] 91 | 92 | Optical_Depth_Ratio_Small_Land = hdfData['Optical_Depth_Ratio_Small_Land'].ravel() 93 | Corrected_Optical_Depth_Land466 = hdfData['Corrected_Optical_Depth_Land'][0, :].ravel() 94 | Corrected_Optical_Depth_Land553 = hdfData['Corrected_Optical_Depth_Land'][1, :].ravel() 95 | Corrected_Optical_Depth_Land644 = hdfData['Corrected_Optical_Depth_Land'][2, :].ravel() 96 | Land_Ocean_Quality_Flag = hdfData['Land_Ocean_Quality_Flag'].astype(int).ravel() 97 | 98 | Aerosol_Type_Land = hdfData['Aerosol_Type_Land'].astype(int).ravel() 99 | 100 | MASK = np.logical_and(np.sum(Mean_Reflectance_Land > -0.1, axis=0) == 10, Corrected_Optical_Depth_Land553 > -0.1) 101 | 102 | theta0, phi0 = Solar_Zenith[MASK], Solar_Azimuth[MASK] 103 | theta, phi = Sensor_Zenith[MASK], Sensor_Azimuth[MASK] 104 | mhght = Topographic_Altitude_Land[MASK] 105 | 106 | rho466, rho553, rho644, rho211 = Mean_Reflectance_Land[0, MASK], Mean_Reflectance_Land[1, MASK], Mean_Reflectance_Land[2, MASK], Mean_Reflectance_Land[6, MASK] 107 | stdrho466, stdrho553, stdrho644, stdrho211 = STD_Reflectance_Land[0, MASK], STD_Reflectance_Land[1, MASK], STD_Reflectance_Land[2, MASK], STD_Reflectance_Land[6, MASK] 108 | 109 | Npixels = MASK.sum() 110 | scantime = datetime(1993, 1, 1) + timedelta(seconds=Scan_Start_Time) 111 | 112 | return { 113 | 'Corrected_Optical_Depth_Land553': Corrected_Optical_Depth_Land553, 114 | 'Corrected_Optical_Depth_Land466': Corrected_Optical_Depth_Land466, 115 | 'Corrected_Optical_Depth_Land644': Corrected_Optical_Depth_Land644, 116 | 'Land_Ocean_Quality_Flag': Land_Ocean_Quality_Flag, 117 | 'Optical_Depth_Ratio_Small_Land': Optical_Depth_Ratio_Small_Land, 118 | 'Aerosol_Type_Land': Aerosol_Type_Land[MASK] - 1, 119 | 'MASK': MASK, 120 | 'theta0': theta0, 121 | 'phi0': phi0, 122 | 'theta': theta, 123 | 'phi': phi, 124 | 'mhght': mhght, 125 | 'lat': Latitude, 126 | 'lon': Longitude, 127 | 'rho466': rho466, 128 | 'stdrho466': stdrho466, 129 | 'rho550': rho553, 130 | 'stdrho550': stdrho553, 131 | 'rho644': rho644, 132 | 'stdrho644': stdrho644, 133 | 'rho211': rho211, 134 | 'stdrho211': stdrho211, 135 | 'Npixels': Npixels, 136 | 'scantime': scantime, 137 | 'nX': nX, 138 | 'nY': nY 139 | } 140 | 141 | 142 | def loadSurfaceReflectancePrior(granuleMonth, granuleYear, surfacePriorModifier, settings): 143 | print(' Loading surface reflectance prior model {}/{}'.format(granuleMonth, settings['surfacePriorYear'])) 144 | surflats, surflons = np.meshgrid((np.arange(-90.0, 90.0, 0.05))[::-1] + 0.05 / 2, (np.arange(-180.0, 180.0, 0.05)) + 0.05 / 2) 145 | surflats, surflons = surflats.T.ravel(), surflons.T.ravel() 146 | 147 | surfacePriorYear = settings['surfacePriorYear'] 148 | 149 | surfprior466 = 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band3_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band3_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() 150 | surfprior466std = np.sqrt(0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band3_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2 + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band3_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2) 151 | 152 | surfprior550 = 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band4_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band4_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() 153 | surfprior550std = np.sqrt(0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band4_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2 + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band4_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2) 154 | 155 | surfprior644 = 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band1_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band1_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() 156 | surfprior644std = np.sqrt(0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band1_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2 + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band1_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2) 157 | 158 | surfprior211 = 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band7_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band7_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel() 159 | surfprior211std = np.sqrt(0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_BSA_Band7_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2 + 0.5 * (imread(os.path.join('models', 'SurfaceReflectance', str(surfacePriorYear), 'Albedo_WSA_Band7_std_{}_{:02d}.png'.format(str(surfacePriorYear), granuleMonth))) / 65535.0).ravel()**2) 160 | 161 | surfmask = (surfprior466 > 0.0) 162 | surfstdmask = (surfprior466std > 0.0) 163 | 164 | surfacePrior = { 165 | 'surfprior466': surfprior466[surfmask] * surfacePriorModifier['meancoef'], 166 | 'surfprior550': surfprior550[surfmask] * surfacePriorModifier['meancoef'], 167 | 'surfprior644': surfprior644[surfmask] * surfacePriorModifier['meancoef'], 168 | 'surfprior211': surfprior211[surfmask] * surfacePriorModifier['meancoef'], 169 | 'lat': surflats[surfmask], 170 | 'lon': surflons[surfmask], 171 | 'surfprior466std': surfprior466std[surfstdmask] * surfacePriorModifier['stdcoef'], 172 | 'surfprior550std': surfprior550std[surfstdmask] * surfacePriorModifier['stdcoef'], 173 | 'surfprior644std': surfprior644std[surfstdmask] * surfacePriorModifier['stdcoef'], 174 | 'surfprior211std': surfprior211std[surfstdmask] * surfacePriorModifier['stdcoef'], 175 | 'latstd': surflats[surfstdmask], 176 | 'lonstd': surflons[surfstdmask], 177 | 'kNNmean': KNeighborsRegressor(n_neighbors=3, leaf_size=50000, n_jobs=-1).fit(np.hstack((surflons[surfmask][:, np.newaxis], surflats[surfmask][:, np.newaxis])), np.zeros_like(surfprior466[surfmask])[:, np.newaxis]), 178 | 'kNNstd': KNeighborsRegressor(n_neighbors=3, leaf_size=50000, n_jobs=-1).fit(np.hstack((surflons[surfstdmask][:, np.newaxis], surflats[surfstdmask][:, np.newaxis])), np.zeros_like(surfprior466[surfstdmask])[:, np.newaxis]), 179 | } 180 | return surfacePrior 181 | 182 | 183 | def prepareFcn(data): 184 | geometry, LUTdata = data['geometry'], data['LUTdata'] 185 | lookups = interpolateToGeometry(geometry, LUTdata) 186 | return lookupToPolynomial(lookups) 187 | 188 | 189 | def interpolateToGeometry(geometry, lutdata): 190 | 191 | theta, theta0, phi, phi0, mhght = geometry['theta'], geometry['theta0'], geometry['phi'], geometry['phi0'], geometry['mhght'] 192 | 193 | lutInterpolatedData = copy.deepcopy(lutdata) 194 | del lutInterpolatedData['INT_NL0'] 195 | del lutInterpolatedData['Fd_NL0'] 196 | del lutInterpolatedData['SBAR_NL0'] 197 | del lutInterpolatedData['T_NL0'] 198 | del lutInterpolatedData['OPTH_NL0'] 199 | lutInterpolatedData['OPTH_NL'] = lutdata['OPTH_NL0'].copy() 200 | 201 | mdphi = np.abs(phi0 - phi - 180.0) 202 | if mdphi > 360.0: 203 | mdphi = np.mod(mdphi, 360.0) 204 | if mdphi > 180.0: 205 | mdphi = 360.0 - mdphi 206 | 207 | NLTAU = len(lutdata['axisTau']) 208 | NLWAV = len(lutdata['axisWav']) 209 | NLAEROSOLMODEL = len(lutdata['axisAerosolModel']) 210 | 211 | coordsINT_NL0 = np.array(list(map(lambda x: x.ravel(), np.meshgrid(mdphi, theta, theta0, lutdata['axisTau'], lutdata['axisWav'], lutdata['axisAerosolModel'])))).T 212 | INT_NL_vector = RegularGridInterpolator((lutInterpolatedData['axisPhi'], lutInterpolatedData['axisTheta'], lutInterpolatedData['axisTheta0'], lutInterpolatedData['axisTau'], lutInterpolatedData['axisWav'], lutInterpolatedData['axisAerosolModel']), lutdata['INT_NL0'])(coordsINT_NL0) 213 | lutInterpolatedData['INT_NL'] = INT_NL_vector.reshape((NLTAU, NLWAV, NLAEROSOLMODEL)) 214 | 215 | coordsSBAR_NL0 = np.array(list(map(lambda x: x.ravel(), np.meshgrid(theta0, lutdata['axisTau'], lutdata['axisWav'], lutdata['axisAerosolModel'])))).T 216 | SBAR_NL_vector = RegularGridInterpolator((lutInterpolatedData['axisTheta0'], lutInterpolatedData['axisTau'], lutInterpolatedData['axisWav'], lutInterpolatedData['axisAerosolModel']), lutdata['SBAR_NL0'])(coordsSBAR_NL0) 217 | lutInterpolatedData['SBAR_NL'] = SBAR_NL_vector.reshape((NLTAU, NLWAV, NLAEROSOLMODEL)) 218 | 219 | coordsFd_NL0 = np.array(list(map(lambda x: x.ravel(), np.meshgrid(theta0, lutdata['axisTau'], lutdata['axisWav'], lutdata['axisAerosolModel'])))).T 220 | Fd_NL_vector = RegularGridInterpolator((lutInterpolatedData['axisTheta0'], lutInterpolatedData['axisTau'], lutInterpolatedData['axisWav'], lutInterpolatedData['axisAerosolModel']), lutdata['Fd_NL0'])(coordsFd_NL0) 221 | coordsT_NL0 = np.array(list(map(lambda x: x.ravel(), np.meshgrid(theta, theta0, lutdata['axisTau'], lutdata['axisWav'], lutdata['axisAerosolModel'])))).T 222 | T_NL_vector = RegularGridInterpolator((lutInterpolatedData['axisTheta'], lutInterpolatedData['axisTheta0'], lutInterpolatedData['axisTau'], lutInterpolatedData['axisWav'], lutInterpolatedData['axisAerosolModel']), lutdata['T_NL0'])(coordsT_NL0) 223 | 224 | lutInterpolatedData['FdT_NL'] = Fd_NL_vector.reshape((NLTAU, NLWAV, NLAEROSOLMODEL)) * T_NL_vector.reshape((NLTAU, NLWAV, NLAEROSOLMODEL)) 225 | 226 | EQWAV_HGHT = [ 227 | np.interp(mhght, lutInterpolatedData['axisHeight'], lutInterpolatedData['EQWAV'][0, :]), 228 | np.interp(mhght, lutInterpolatedData['axisHeight'], lutInterpolatedData['EQWAV'][1, :]), 229 | np.interp(mhght, lutInterpolatedData['axisHeight'], lutInterpolatedData['EQWAV'][2, :]), 230 | ] 231 | 232 | INT_NL_height = (lutInterpolatedData['INT_NL']).copy() 233 | SBAR_NL_height = (lutInterpolatedData['SBAR_NL']).copy() 234 | FdT_NL_height = (lutInterpolatedData['FdT_NL']).copy() 235 | OPTH_NL_height = (lutInterpolatedData['OPTH_NL']).copy() 236 | 237 | for iiWav in range(3): # only for 466, 553 and 645nm 238 | INT_NL_height[:, iiWav, :] = interp1d(lutInterpolatedData['axisWav'], lutInterpolatedData['INT_NL'], axis=1, fill_value='extrapolate', bounds_error=False)(EQWAV_HGHT[iiWav]) 239 | SBAR_NL_height[:, iiWav, :] = interp1d(lutInterpolatedData['axisWav'], lutInterpolatedData['SBAR_NL'], axis=1, fill_value='extrapolate', bounds_error=False)(EQWAV_HGHT[iiWav]) 240 | FdT_NL_height[:, iiWav, :] = interp1d(lutInterpolatedData['axisWav'], lutInterpolatedData['FdT_NL'], axis=1, fill_value='extrapolate', bounds_error=False)(EQWAV_HGHT[iiWav]) 241 | OPTH_NL_height[:, iiWav, :] = interp1d(lutInterpolatedData['axisWav'], lutInterpolatedData['OPTH_NL'], axis=1, fill_value='extrapolate', bounds_error=False)(EQWAV_HGHT[iiWav]) 242 | 243 | return { 244 | 'fine_aerosol_model': geometry['fine_aerosol_model'], 245 | 'INT_NL': INT_NL_height, 246 | 'SBAR_NL': SBAR_NL_height, 247 | 'FdT_NL': FdT_NL_height, 248 | 'OPTH_NL': OPTH_NL_height, 249 | 'EXTNORM_NL': (lutInterpolatedData['EXTNORM_NL0']).copy() 250 | } 251 | 252 | 253 | def lookupToPolynomial(lookupdata): 254 | 255 | thetas_INT_NL = np.zeros((5, 4, 6)) 256 | thetas_SBAR_NL = np.zeros((5, 4, 6)) 257 | thetas_FdT_NL = np.zeros((5, 4, 6)) 258 | 259 | INT_NL = lookupdata['INT_NL'] 260 | SBAR_NL = lookupdata['SBAR_NL'] 261 | FdT_NL = lookupdata['FdT_NL'] 262 | OPTH_NL = lookupdata['OPTH_NL'] 263 | EXTNORM_NL = lookupdata['EXTNORM_NL'] 264 | 265 | for ii in range(5): # aerosol model 266 | x = np.log(OPTH_NL[:, 1, ii] + 1.0) # AOD @ 550nm 267 | A = np.vstack([x**5, x**4, x**3, x**2, x, np.ones(len(x))]).T 268 | 269 | iHtHHt = np.linalg.inv(A.T.dot(A)).dot(A.T) 270 | 271 | for jj in range(4): 272 | y = np.log(INT_NL[:, jj, ii] + 1.0) 273 | thetas_INT_NL[ii, jj, :] = iHtHHt.dot(y) 274 | 275 | y = np.log(SBAR_NL[:, jj, ii] + 1.0) 276 | thetas_SBAR_NL[ii, jj, :] = iHtHHt.dot(y) 277 | 278 | y = np.log(FdT_NL[:, jj, ii] + 1.0) 279 | thetas_FdT_NL[ii, jj, :] = iHtHHt.dot(y) 280 | 281 | return { 282 | 'thetas_INT_NL': thetas_INT_NL, 283 | 'thetas_SBAR_NL': thetas_SBAR_NL, 284 | 'thetas_FdT_NL': thetas_FdT_NL, 285 | 'OPTH_NL': OPTH_NL, 286 | 'EXTNORM_NL': EXTNORM_NL, 287 | 'fine_aerosol_model': lookupdata['fine_aerosol_model'], 288 | } 289 | 290 | 291 | def prepareModels(modisData, settings): 292 | 293 | Npixels = modisData['Npixels'] 294 | month = modisData['scantime'].month 295 | 296 | print(' Number of pixels to be retrieved: {}'.format(Npixels)) 297 | print(' Loading radiative transfer lookup-tables') 298 | 299 | # The LUT is based on NASA's Dark Target over land lookup tables (https://darktarget.gsfc.nasa.gov/reference/code) 300 | nc = Dataset('models/LUT/DarkTargetLUT.nc', 'r') 301 | LUTdata = { 302 | 'aerosolmap': getattr(nc['LUTdata'], 'aerosolmapmonth{:02d}'.format(month)), 303 | 'axisHeight': getattr(nc['LUTdata'], 'axisHeight'), 304 | 'axisTheta': getattr(nc['LUTdata'], 'axisTheta'), 305 | 'axisTheta0': getattr(nc['LUTdata'], 'axisTheta0'), 306 | 'axisPhi': getattr(nc['LUTdata'], 'axisPhi'), 307 | 'axisWav': getattr(nc['LUTdata'], 'axisWav'), 308 | 'axisAerosolModel': getattr(nc['LUTdata'], 'axisAerosolModel'), 309 | 'axisTau': getattr(nc['LUTdata'], 'axisTau') 310 | } 311 | N_Height, N_Theta, N_Theta0, N_Phi = len(LUTdata['axisHeight']), len(LUTdata['axisTheta']), len(LUTdata['axisTheta0']), len(LUTdata['axisPhi']) 312 | N_Wav, N_AerosolModel, N_Tau = len(LUTdata['axisWav']), len(LUTdata['axisAerosolModel']), len(LUTdata['axisTau']) 313 | LUTdata['EQWAV'] = getattr(nc['LUTdata'], 'EQWAV').reshape((3, N_Height)) 314 | LUTdata['INT_NL0'] = getattr(nc['LUTdata'], 'INT_NL0').reshape((N_Phi, N_Theta, N_Theta0, N_Tau, N_Wav, N_AerosolModel)) 315 | LUTdata['Fd_NL0'] = getattr(nc['LUTdata'], 'Fd_NL0').reshape((N_Theta0, N_Tau, N_Wav, N_AerosolModel)) 316 | LUTdata['SBAR_NL0'] = getattr(nc['LUTdata'], 'SBAR_NL0').reshape((N_Theta0, N_Tau, N_Wav, N_AerosolModel)) 317 | LUTdata['T_NL0'] = getattr(nc['LUTdata'], 'T_NL0').reshape((N_Theta, N_Theta0, N_Tau, N_Wav, N_AerosolModel)) 318 | LUTdata['OPTH_NL0'] = getattr(nc['LUTdata'], 'OPTH_NL0').reshape((N_Tau, N_Wav, N_AerosolModel)) 319 | LUTdata['EXTNORM_NL0'] = getattr(nc['LUTdata'], 'EXTNORM_NL0').reshape((N_Tau, N_Wav, N_AerosolModel)) 320 | nc.close() 321 | 322 | print(' Preparing radiative transfer lookup-tables') 323 | lonsvec, latsvec = modisData['lon'].ravel(), modisData['lat'].ravel() 324 | gFull = np.hstack((lonsvec[:, np.newaxis], latsvec[:, np.newaxis])) 325 | 326 | MASK_FULL = modisData['MASK'] 327 | MASK_FULL_true_pos = np.where(MASK_FULL)[0] 328 | 329 | N_parts = int(np.ceil(Npixels / float(settings['max_pixels_per_part']))) 330 | part_indices = np.linspace(0, Npixels - 1, N_parts + 1, dtype=int) 331 | 332 | partData = [] 333 | for iPart in range(1, N_parts + 1): 334 | 335 | iStart, iEnd = MASK_FULL_true_pos[part_indices[iPart - 1]], MASK_FULL_true_pos[part_indices[iPart]] 336 | 337 | MASKl = np.zeros(Npixels, dtype=bool) 338 | if iPart < N_parts: 339 | MASKl[np.arange(part_indices[iPart - 1], part_indices[iPart])] = True 340 | else: 341 | MASKl[np.arange(part_indices[iPart - 1], part_indices[iPart] + 1)] = True 342 | 343 | MASKf = MASK_FULL.copy() 344 | MASKf[:iStart] = False 345 | if iPart < N_parts: 346 | MASKf[iEnd:] = False 347 | 348 | partData.append({ 349 | 'MASKl': MASKl, 350 | 'MASKf': MASKf 351 | }) 352 | 353 | data = [] 354 | for ii in range(Npixels): 355 | geometry = { 356 | 'theta': modisData['theta'][ii], 357 | 'theta0': modisData['theta0'][ii], 358 | 'phi': modisData['phi'][ii], 359 | 'phi0': modisData['phi0'][ii], 360 | 'mhght': modisData['mhght'][ii], 361 | 'fine_aerosol_model': modisData['Aerosol_Type_Land'][ii], 362 | } 363 | data.append({'geometry': geometry, 'LUTdata': LUTdata}) 364 | 365 | # prepare models in parallel 366 | p = Pool(settings['N_processes']) 367 | polylookups = np.array(p.map(prepareFcn, data)) 368 | p.close() 369 | p.join() 370 | return polylookups, MASK_FULL, partData, gFull, LUTdata['aerosolmap'] 371 | 372 | 373 | def combinePolyLookupList(polylookuplist, aerosolmodelindex=None): 374 | 375 | POLYORDER = polylookuplist[0]['thetas_INT_NL'].shape[2] 376 | NLWAV = 4 377 | 378 | if aerosolmodelindex is not None: 379 | EXTNORM_NL_matrix = np.array(list(map(lambda x: x['EXTNORM_NL'][:, :, aerosolmodelindex], polylookuplist))) 380 | OPTH_NL_matrix = np.array(list(map(lambda x: x['OPTH_NL'][:, :, aerosolmodelindex], polylookuplist))) 381 | 382 | INT_NL_matrix = np.array(list(map(lambda x: x['thetas_INT_NL'][aerosolmodelindex, :, :], polylookuplist))).reshape((-1, POLYORDER)) 383 | SBAR_NL_matrix = np.array(list(map(lambda x: x['thetas_SBAR_NL'][aerosolmodelindex, :, :], polylookuplist))).reshape((-1, POLYORDER)) 384 | FdT_NL_matrix = np.array(list(map(lambda x: x['thetas_FdT_NL'][aerosolmodelindex, :, :], polylookuplist))).reshape((-1, POLYORDER)) 385 | else: 386 | EXTNORM_NL_matrix = np.array(list(map(lambda x: x['EXTNORM_NL'][:, :, x['fine_aerosol_model']], polylookuplist))) 387 | OPTH_NL_matrix = np.array(list(map(lambda x: x['OPTH_NL'][:, :, x['fine_aerosol_model']], polylookuplist))) 388 | 389 | INT_NL_matrix = np.array(list(map(lambda x: x['thetas_INT_NL'][x['fine_aerosol_model'], :, :], polylookuplist))).reshape((-1, POLYORDER)) 390 | SBAR_NL_matrix = np.array(list(map(lambda x: x['thetas_SBAR_NL'][x['fine_aerosol_model'], :, :], polylookuplist))).reshape((-1, POLYORDER)) 391 | FdT_NL_matrix = np.array(list(map(lambda x: x['thetas_FdT_NL'][x['fine_aerosol_model'], :, :], polylookuplist))).reshape((-1, POLYORDER)) 392 | INT_NL_matrix = np.vstack([INT_NL_matrix[0::NLWAV, :], INT_NL_matrix[1::NLWAV, :], INT_NL_matrix[2::NLWAV, :], INT_NL_matrix[3::NLWAV, :]]) 393 | SBAR_NL_matrix = np.vstack([SBAR_NL_matrix[0::NLWAV, :], SBAR_NL_matrix[1::NLWAV, :], SBAR_NL_matrix[2::NLWAV, :], SBAR_NL_matrix[3::NLWAV, :]]) 394 | FdT_NL_matrix = np.vstack([FdT_NL_matrix[0::NLWAV, :], FdT_NL_matrix[1::NLWAV, :], FdT_NL_matrix[2::NLWAV, :], FdT_NL_matrix[3::NLWAV, :]]) 395 | 396 | return {'INT_NL': INT_NL_matrix, 'SBAR_NL': SBAR_NL_matrix, 'FdT_NL': FdT_NL_matrix, 'EXTNORM_NL': EXTNORM_NL_matrix, 'OPTH_NL': OPTH_NL_matrix} 397 | 398 | 399 | def constructPriors(logaodPlus1, fmf, aodPrior, fmfPrior, surfPrior): 400 | priorAOD = {'mean': logaodPlus1, 401 | 'sill': aodPrior['sill'], 402 | 'range': aodPrior['range'], 403 | 'nugget': aodPrior['nugget'], 404 | 'p': aodPrior['p'] 405 | } 406 | priorFMF = {'mean': fmf, 407 | 'sill': fmfPrior['sill'], 408 | 'range': fmfPrior['range'], 409 | 'nugget': fmfPrior['nugget'], 410 | 'p': fmfPrior['p'] 411 | } 412 | priorRhos2113 = { 413 | 'mean': surfPrior['mean211'], 414 | 'std': surfPrior['std211'], 415 | } 416 | priorRhos644 = { 417 | 'mean': surfPrior['mean644'], 418 | 'std': surfPrior['std644'], 419 | } 420 | priorRhos553 = { 421 | 'mean': surfPrior['mean550'], 422 | 'std': surfPrior['std550'], 423 | } 424 | priorRhos466 = { 425 | 'mean': surfPrior['mean466'], 426 | 'std': surfPrior['std466'], 427 | } 428 | return priorAOD, priorFMF, priorRhos466, priorRhos553, priorRhos644, priorRhos2113 429 | 430 | 431 | def covariance_function(d, pr_sill, pr_range, pr_nugget, pr_p=1.0): 432 | c = pr_sill * np.exp(-3.0 * (d / pr_range)**pr_p) 433 | c[d == 0] += pr_nugget 434 | return c 435 | 436 | 437 | def dist(lat1, lon1, lat2, lon2): 438 | lat1R, lat2R, lon1R, lon2R = np.deg2rad(lat1), np.deg2rad(lat2), np.deg2rad(lon1), np.deg2rad(lon2) 439 | dlon = lon2R - lon1R 440 | dlat = lat2R - lat1R 441 | R = 6378.1 442 | a = (np.sin(dlat / 2.0))**2 + np.cos(lat1R) * np.cos(lat2R) * (np.sin(dlon / 2.0))**2 443 | c = 2.0 * np.arctan2(np.sqrt(a), np.sqrt(1.0 - a)) 444 | d = R * c 445 | return d 446 | 447 | 448 | class InverseProblem(object): 449 | def __init__(self, gGranule, polylookupMats_fine, polylookupMats_coarse, priorLogAODPlus1, priorFMF, 450 | priorRhos466, priorRhos553, priorRhos644, priorRhos2113, 451 | observations, noiseiCov, noiseE, mask, settings): 452 | self.g = gGranule 453 | self.Ng = self.g.shape[0] 454 | self.polylookupMats_fine = polylookupMats_fine 455 | self.polylookupMats_coarse = polylookupMats_coarse 456 | self.simuData = None 457 | self.invnoiseCov = noiseiCov 458 | self.noiseE = noiseE 459 | self.obs = observations 460 | self.mask = mask 461 | self.priorLogAODPlus1 = priorLogAODPlus1.copy() 462 | self.priorFMF = priorFMF.copy() 463 | self.priorRhos466 = priorRhos466.copy() 464 | self.priorRhos553 = priorRhos553.copy() 465 | self.priorRhos644 = priorRhos644.copy() 466 | self.priorRhos2113 = priorRhos2113.copy() 467 | self.settings = settings 468 | self.Nmodels = mask.sum() 469 | self.priorLogAODPlus1['cov'] = np.zeros((self.Ng, self.Ng)) 470 | self.priorFMF['cov'] = np.zeros((self.Ng, self.Ng)) 471 | 472 | for ii in range(self.Ng): 473 | distanceinKm = dist(self.g[:, 1], self.g[:, 0], self.g[ii, 1], self.g[ii, 0]) 474 | self.priorLogAODPlus1['cov'][ii, :] = covariance_function(distanceinKm, priorLogAODPlus1['sill'], priorLogAODPlus1['range'], priorLogAODPlus1['nugget'], priorLogAODPlus1['p']) 475 | self.priorFMF['cov'][ii, :] = covariance_function(distanceinKm, priorFMF['sill'], priorFMF['range'], priorFMF['nugget'], priorFMF['p']) 476 | 477 | self.priorRhos = { 478 | 'iCov': diags(np.concatenate((1.0 / self.priorRhos466['std']**2, 1.0 / self.priorRhos553['std']**2, 479 | 1.0 / self.priorRhos644['std']**2, 1.0 / self.priorRhos2113['std']**2)), 0), 480 | 'mean': np.concatenate((self.priorRhos466['mean'], self.priorRhos553['mean'], self.priorRhos644['mean'], self.priorRhos2113['mean'])) 481 | } 482 | 483 | print(" Inverting prior covariances") 484 | if settings['useSpatialCorrelations']: 485 | self.priorLogAODPlus1['iCov'] = np.linalg.inv(self.priorLogAODPlus1['cov']) 486 | self.priorFMF['iCov'] = np.linalg.inv(self.priorFMF['cov']) 487 | else: 488 | self.priorLogAODPlus1['iCov'] = diags(1.0 / self.priorLogAODPlus1['cov'].diagonal(), 0) 489 | self.priorFMF['iCov'] = diags(1.0 / self.priorFMF['cov'].diagonal(), 0) 490 | 491 | def functional_prior_val_and_Jac(self, priorX, X): 492 | dX = (X - priorX['mean'])[:, np.newaxis] 493 | iCovXdX = priorX['iCov'].dot(dX) 494 | return np.asarray(dX.T.dot(iCovXdX))[0, 0], 2.0 * np.asarray(iCovXdX).ravel() 495 | 496 | def functional_value_and_Jacobian_logscalemeas(self, x): 497 | logaodplus1, fmf, rho_s = x[0 * self.Ng:1 * self.Ng], x[1 * self.Ng:2 * self.Ng], x[2 * self.Ng:6 * self.Ng] 498 | fval_logaodplus1, J_fval_logaodplus1 = self.functional_prior_val_and_Jac(self.priorLogAODPlus1, logaodplus1) 499 | fval_fmf, J_fval_fmf = self.functional_prior_val_and_Jac(self.priorFMF, fmf) 500 | fval_rhos, J_fval_rhos = self.functional_prior_val_and_Jac(self.priorRhos, rho_s) 501 | rhostar_fine, J_rhostar_logaodplus1_fine, J_rhostar_rhos_fine = self.simulate(logaodplus1, rho_s, self.polylookupMats_fine, True) 502 | rhostar_coarse, J_rhostar_logaodplus1_coarse, J_rhostar_rhos_coarse = self.simulate(logaodplus1, rho_s, self.polylookupMats_coarse, True) 503 | rhostar = np.tile(fmf, (4,)) * rhostar_fine + (1.0 - np.tile(fmf, (4,))) * rhostar_coarse 504 | J_rhostar_logaodplus1 = np.tile(fmf, (4,)) * J_rhostar_logaodplus1_fine + (1.0 - np.tile(fmf, (4,))) * J_rhostar_logaodplus1_coarse 505 | J_rhostar_fmf = rhostar_fine - rhostar_coarse 506 | J_rhostar_logaodplus1 = 1.0 / (1.0 + rhostar) * J_rhostar_logaodplus1 507 | J_rhostar_fmf = 1.0 / (1.0 + rhostar) * J_rhostar_fmf 508 | d_rho_TOA_d_rhos = np.tile(fmf, (4,)) * J_rhostar_rhos_fine + (1.0 - np.tile(fmf, (4,))) * J_rhostar_rhos_coarse 509 | dObs = (np.log(rhostar + 1.0) + self.noiseE - self.obs)[:, np.newaxis] 510 | iNdObs = self.invnoiseCov.dot(dObs) 511 | func_val = (dObs.T.dot(iNdObs))[0, 0] + fval_logaodplus1 + fval_fmf + fval_rhos 512 | J = np.zeros(len(x)) 513 | J[0 * self.Ng:1 * self.Ng] = (2.0 * iNdObs.ravel() * J_rhostar_logaodplus1).reshape((-1, self.Ng)).sum(axis=0) + J_fval_logaodplus1 514 | J[1 * self.Ng:2 * self.Ng] = (2.0 * iNdObs.ravel() * J_rhostar_fmf).reshape((-1, self.Ng)).sum(axis=0) + J_fval_fmf 515 | J[2 * self.Ng:6 * self.Ng] = (2.0 * iNdObs.ravel() * d_rho_TOA_d_rhos) + J_fval_rhos 516 | return func_val, J 517 | 518 | def Jacobian_aod_fmf_rhos(self, x): 519 | logaodplus1, fmf, rho_s = x[0 * self.Ng:1 * self.Ng], x[1 * self.Ng:2 * self.Ng], x[2 * self.Ng:6 * self.Ng] 520 | fval_logaodplus1, J_fval_logaodplus1 = self.functional_prior_val_and_Jac(self.priorLogAODPlus1, logaodplus1) 521 | fval_fmf, J_fval_fmf = self.functional_prior_val_and_Jac(self.priorFMF, fmf) 522 | fval_rhos, J_fval_rhos = self.functional_prior_val_and_Jac(self.priorRhos, rho_s) 523 | rhostar_fine, J_rhostar_logaodplus1_fine, J_rhostar_rhos_fine = self.simulate(logaodplus1, rho_s, self.polylookupMats_fine, True) 524 | rhostar_coarse, J_rhostar_logaodplus1_coarse, J_rhostar_rhos_coarse = self.simulate(logaodplus1, rho_s, self.polylookupMats_coarse, True) 525 | rhostar = np.tile(fmf, (4,)) * rhostar_fine + (1.0 - np.tile(fmf, (4,))) * rhostar_coarse 526 | J_rhostar_logaodplus1 = np.tile(fmf, (4,)) * J_rhostar_logaodplus1_fine + (1.0 - np.tile(fmf, (4,))) * J_rhostar_logaodplus1_coarse 527 | J_rhostar_fmf = rhostar_fine - rhostar_coarse 528 | J_rhostar_logaodplus1 = 1.0 / (1.0 + rhostar) * J_rhostar_logaodplus1 529 | J_rhostar_fmf = 1.0 / (1.0 + rhostar) * J_rhostar_fmf 530 | d_rho_TOA_d_rhos = np.tile(fmf, (4,)) * J_rhostar_rhos_fine + (1.0 - np.tile(fmf, (4,))) * J_rhostar_rhos_coarse 531 | return J_rhostar_logaodplus1, J_rhostar_fmf, d_rho_TOA_d_rhos 532 | 533 | def simulate(self, logaodplus1, rhos, lookupMatrices, derivatives=True): 534 | NLWAV = 4 535 | logaodplus1Matrix = np.hstack((logaodplus1[:, np.newaxis]**5, 536 | logaodplus1[:, np.newaxis]**4, 537 | logaodplus1[:, np.newaxis]**3, 538 | logaodplus1[:, np.newaxis]**2, 539 | logaodplus1[:, np.newaxis], 540 | np.ones_like(logaodplus1[:, np.newaxis]))) 541 | 542 | INT_NL = np.exp((lookupMatrices['INT_NL'] * np.tile(logaodplus1Matrix, (NLWAV, 1))).sum(axis=1)) - 1.0 543 | SBAR_NL = np.exp((lookupMatrices['SBAR_NL'] * np.tile(logaodplus1Matrix, (NLWAV, 1))).sum(axis=1)) - 1.0 544 | FdT_NL = np.exp((lookupMatrices['FdT_NL'] * np.tile(logaodplus1Matrix, (NLWAV, 1))).sum(axis=1)) - 1.0 545 | rhostar = INT_NL + (FdT_NL * rhos) / (1.0 - SBAR_NL * rhos) 546 | if derivatives: 547 | logaodplus1stacked = np.tile(logaodplus1, (NLWAV,)) 548 | 549 | d_INT_NL_d_logaodplus1 = (INT_NL + 1.0) * (5.0 * lookupMatrices['INT_NL'][:, 0] * logaodplus1stacked**4 + 550 | 4.0 * lookupMatrices['INT_NL'][:, 1] * logaodplus1stacked**3 + 551 | 3.0 * lookupMatrices['INT_NL'][:, 2] * logaodplus1stacked**2 + 552 | 2.0 * lookupMatrices['INT_NL'][:, 3] * logaodplus1stacked + 553 | lookupMatrices['INT_NL'][:, 4]) 554 | d_SBAR_NL_d_logaodplus1 = (SBAR_NL + 1.0) * (5.0 * lookupMatrices['SBAR_NL'][:, 0] * logaodplus1stacked**4 + 555 | 4.0 * lookupMatrices['SBAR_NL'][:, 1] * logaodplus1stacked**3 + 556 | 3.0 * lookupMatrices['SBAR_NL'][:, 2] * logaodplus1stacked**2 + 557 | 2.0 * lookupMatrices['SBAR_NL'][:, 3] * logaodplus1stacked + 558 | lookupMatrices['SBAR_NL'][:, 4]) 559 | d_FdT_NL_d_logaodplus1 = (FdT_NL + 1.0) * (5.0 * lookupMatrices['FdT_NL'][:, 0] * logaodplus1stacked**4 + 560 | 4.0 * lookupMatrices['FdT_NL'][:, 1] * logaodplus1stacked**3 + 561 | 3.0 * lookupMatrices['FdT_NL'][:, 2] * logaodplus1stacked**2 + 562 | 2.0 * lookupMatrices['FdT_NL'][:, 3] * logaodplus1stacked + 563 | lookupMatrices['FdT_NL'][:, 4]) 564 | 565 | J_rhostar_logaodplus1 = d_INT_NL_d_logaodplus1 + (d_FdT_NL_d_logaodplus1 * rhos * (1.0 - SBAR_NL * rhos) + 566 | (FdT_NL * rhos) * (d_SBAR_NL_d_logaodplus1 * rhos)) / (1.0 - SBAR_NL * rhos)**2 567 | J_rhostar_rhos = (FdT_NL * (1.0 - SBAR_NL * rhos) + FdT_NL * rhos * SBAR_NL) / (1.0 - SBAR_NL * rhos)**2 568 | return rhostar, J_rhostar_logaodplus1, J_rhostar_rhos 569 | else: 570 | return rhostar 571 | 572 | 573 | def BARretrieve(g, AOD0, FMF0, AODprior, FMFprior, surfPrior, polylookupMats_fine, polylookupMats_coarse, MeasData, MeasNoiseiCov, MeasNoiseE, MASK, bounds, settings): 574 | 575 | logAODPlus1 = np.log(AOD0 + 1.0) 576 | priorLogAODPlus1, priorFMF, priorRhos466, priorRhos553, priorRhos644, priorRhos2113 = constructPriors(logAODPlus1, FMF0, AODprior, FMFprior, surfPrior) 577 | 578 | # the inverse problem 579 | IP = InverseProblem(g, polylookupMats_fine, polylookupMats_coarse, priorLogAODPlus1, priorFMF, priorRhos466, priorRhos553, priorRhos644, priorRhos2113, 580 | MeasData, MeasNoiseiCov, MeasNoiseE, MASK, settings) 581 | 582 | # AOD, ETA, rhos466, rhos644 583 | x0 = np.concatenate((priorLogAODPlus1['mean'], priorFMF['mean'], priorRhos466['mean'], priorRhos553['mean'], priorRhos644['mean'], priorRhos2113['mean'])) 584 | 585 | BFGSbounds = np.vstack((np.tile(bounds[0, :], (IP.Ng, 1)), 586 | np.tile(bounds[1, :], (IP.Ng, 1)), 587 | np.tile(bounds[2, :], (IP.Ng, 1)), 588 | np.tile(bounds[3, :], (IP.Ng, 1)), 589 | np.tile(bounds[4, :], (IP.Ng, 1)), 590 | np.tile(bounds[5, :], (IP.Ng, 1)))) 591 | 592 | print(' Retrieving...', end='', flush=True) 593 | res = minimize(IP.functional_value_and_Jacobian_logscalemeas, x0, method='L-BFGS-B', bounds=BFGSbounds, jac=True, 594 | options={ 595 | 'ftol': settings['BFGSftol'], 596 | 'gtol': settings['BFGSgtol'], 597 | 'disp': False, 598 | 'maxcor': 10, 599 | 'maxls': 100, 600 | 'maxiter': settings['BFGSmaxiter'] 601 | }) 602 | print('Done! (# iterations: {}, status message from L-BFGS-B: "{}")'.format(res.nit, res.message.decode('utf-8'))) 603 | 604 | logaodPlus1, fmf, rhos466, rhos553, rhos644, rhos2113 = res.x[:IP.Ng], res.x[IP.Ng:2 * IP.Ng], res.x[2 * IP.Ng:3 * IP.Ng], res.x[3 * IP.Ng:4 * IP.Ng], res.x[4 * IP.Ng:5 * IP.Ng], res.x[5 * IP.Ng:6 * IP.Ng] 605 | aod550 = np.exp(logaodPlus1) - 1.0 606 | aod550_fine = fmf * aod550 607 | aod550_coarse = (1.0 - fmf) * aod550 608 | 609 | OPTH = polylookupMats_fine['OPTH_NL'][:, :, 1] # 1 = AOD @ 550nm 610 | EXTNORM466f = polylookupMats_fine['EXTNORM_NL'][:, :, 0] 611 | EXTNORM644f = polylookupMats_fine['EXTNORM_NL'][:, :, 2] 612 | EXTNORM466c = polylookupMats_coarse['EXTNORM_NL'][:, :, 0] 613 | EXTNORM644c = polylookupMats_coarse['EXTNORM_NL'][:, :, 2] 614 | 615 | aod466, aod644 = -9.999 * np.ones_like(aod550), -9.999 * np.ones_like(aod550) 616 | for ii in range(len(aod550)): 617 | aod466_fine = np.interp(aod550_fine[ii], OPTH[ii, :], EXTNORM466f[ii, :]) * aod550_fine[ii] 618 | aod466_coarse = np.interp(aod550_coarse[ii], OPTH[ii, :], EXTNORM466c[ii, :]) * aod550_coarse[ii] 619 | aod466[ii] = aod466_fine + aod466_coarse 620 | aod644_fine = np.interp(aod550_fine[ii], OPTH[ii, :], EXTNORM644f[ii, :]) * aod550_fine[ii] 621 | aod644_coarse = np.interp(aod550_coarse[ii], OPTH[ii, :], EXTNORM644c[ii, :]) * aod550_coarse[ii] 622 | aod644[ii] = aod644_fine + aod644_coarse 623 | 624 | if settings['quantifyUncertainty']: 625 | print(' Quantifying uncertainties...', end='', flush=True) 626 | if IP.invnoiseCov is None: 627 | variance_X = np.concatenate((IP.priorLogAODPlus1['cov'].diagonal(), IP.priorFMF['cov'].diagonal())) 628 | else: 629 | J_AODPlus1, J_FMF, d_rho_TOA_d_rhos = IP.Jacobian_aod_fmf_rhos(res.x) 630 | J_AODPlus1 = J_AODPlus1.reshape((-1, IP.Ng)) 631 | J_FMF = J_FMF.reshape((-1, IP.Ng)) 632 | d_rho_TOA_d_rhos = d_rho_TOA_d_rhos.reshape((-1, IP.Ng)) 633 | J = np.zeros((4 * IP.Ng, 6 * IP.Ng)) 634 | for ii in range(IP.Ng): 635 | J[0 * IP.Ng + ii, 0 * IP.Ng + ii] = J_AODPlus1[0, ii] 636 | J[1 * IP.Ng + ii, 0 * IP.Ng + ii] = J_AODPlus1[1, ii] 637 | J[2 * IP.Ng + ii, 0 * IP.Ng + ii] = J_AODPlus1[2, ii] 638 | J[3 * IP.Ng + ii, 0 * IP.Ng + ii] = J_AODPlus1[3, ii] 639 | J[0 * IP.Ng + ii, 1 * IP.Ng + ii] = J_FMF[0, ii] 640 | J[1 * IP.Ng + ii, 1 * IP.Ng + ii] = J_FMF[1, ii] 641 | J[2 * IP.Ng + ii, 1 * IP.Ng + ii] = J_FMF[2, ii] 642 | J[3 * IP.Ng + ii, 1 * IP.Ng + ii] = J_FMF[3, ii] 643 | J[0 * IP.Ng + ii, 2 * IP.Ng + ii] = d_rho_TOA_d_rhos[0, ii] 644 | J[1 * IP.Ng + ii, 3 * IP.Ng + ii] = d_rho_TOA_d_rhos[1, ii] 645 | J[2 * IP.Ng + ii, 4 * IP.Ng + ii] = d_rho_TOA_d_rhos[2, ii] 646 | J[3 * IP.Ng + ii, 5 * IP.Ng + ii] = d_rho_TOA_d_rhos[3, ii] 647 | if settings['useSpatialCorrelations']: 648 | inv_Cov_LogAODPlus1FMF = (J.T.dot(IP.invnoiseCov.dot(J))) + np.linalg.inv(block_diag(IP.priorLogAODPlus1['cov'], IP.priorFMF['cov'], np.array(diags(np.concatenate((IP.priorRhos466['std']**2, IP.priorRhos553['std']**2, IP.priorRhos644['std']**2, IP.priorRhos2113['std']**2)), 0).todense()))) 649 | else: 650 | inv_Cov_LogAODPlus1FMF = (J.T.dot(IP.invnoiseCov.dot(J))) + diags(np.concatenate((IP.priorLogAODPlus1['iCov'].diagonal(), IP.priorFMF['iCov'].diagonal(), IP.priorRhos466['std']**2, IP.priorRhos553['std']**2, IP.priorRhos644['std']**2, IP.priorRhos2113['std']**2)), 0) 651 | cov_LogAODPlus1FMF = np.linalg.inv(inv_Cov_LogAODPlus1FMF) 652 | variance_X = np.array(cov_LogAODPlus1FMF.diagonal()).ravel() 653 | 654 | std_logaodPlus1, std_fmf, std_rhos = np.sqrt(variance_X[:IP.Ng]), np.sqrt(variance_X[IP.Ng:2 * IP.Ng]), np.sqrt(variance_X[2 * IP.Ng:]) 655 | print('Done!') 656 | 657 | AODinterval68 = np.clip(np.exp(norm.interval(0.68, loc=logaodPlus1, scale=std_logaodPlus1)) - 1.0, a_min=0.0, a_max=np.inf) 658 | AODinterval90 = np.clip(np.exp(norm.interval(0.90, loc=logaodPlus1, scale=std_logaodPlus1)) - 1.0, a_min=0.0, a_max=np.inf) 659 | AODinterval95 = np.clip(np.exp(norm.interval(0.95, loc=logaodPlus1, scale=std_logaodPlus1)) - 1.0, a_min=0.0, a_max=np.inf) 660 | FMFinterval68 = np.clip(norm.interval(0.68, loc=fmf, scale=std_fmf), a_min=0.0, a_max=1.0) 661 | FMFinterval90 = np.clip(norm.interval(0.90, loc=fmf, scale=std_fmf), a_min=0.0, a_max=1.0) 662 | FMFinterval95 = np.clip(norm.interval(0.95, loc=fmf, scale=std_fmf), a_min=0.0, a_max=1.0) 663 | BARresult = { 664 | 'BAR_AOD': aod550, 665 | 'BAR_logAODplus1': logaodPlus1, 666 | 'BAR_logAODplus1_std': std_logaodPlus1, 667 | 'BAR_AOD466': aod466, 668 | 'BAR_AOD644': aod644, 669 | 'BAR_AOD_percentile_2.5': AODinterval95[0], 670 | 'BAR_AOD_percentile_5.0': AODinterval90[0], 671 | 'BAR_AOD_percentile_16.0': AODinterval68[0], 672 | 'BAR_AOD_percentile_84.0': AODinterval68[1], 673 | 'BAR_AOD_percentile_95.0': AODinterval90[1], 674 | 'BAR_AOD_percentile_97.5': AODinterval95[1], 675 | 'BAR_FMF': fmf, 676 | 'BAR_FMF_std': std_fmf, 677 | 'BAR_FMF_percentile_2.5': FMFinterval68[0], 678 | 'BAR_FMF_percentile_5.0': FMFinterval90[0], 679 | 'BAR_FMF_percentile_16.0': FMFinterval95[0], 680 | 'BAR_FMF_percentile_84.0': FMFinterval68[1], 681 | 'BAR_FMF_percentile_95.0': FMFinterval90[1], 682 | 'BAR_FMF_percentile_97.5': FMFinterval95[1], 683 | 'BAR_rhos466': rhos466, 684 | 'BAR_rhos553': rhos553, 685 | 'BAR_rhos644': rhos644, 686 | 'BAR_rhos211': rhos2113, 687 | 'BAR_rhos466_std': std_rhos[0 * IP.Ng:1 * IP.Ng], 688 | 'BAR_rhos553_std': std_rhos[1 * IP.Ng:2 * IP.Ng], 689 | 'BAR_rhos644_std': std_rhos[2 * IP.Ng:3 * IP.Ng], 690 | 'BAR_rhos211_std': std_rhos[3 * IP.Ng:4 * IP.Ng], 691 | } 692 | else: 693 | BARresult = { 694 | 'BAR_AOD': aod550, 695 | 'BAR_logAODplus1': logaodPlus1, 696 | 'BAR_AOD466': aod466, 697 | 'BAR_AOD644': aod644, 698 | 'BAR_FMF': fmf, 699 | 'BAR_rhos466': rhos466, 700 | 'BAR_rhos553': rhos553, 701 | 'BAR_rhos644': rhos644, 702 | 'BAR_rhos211': rhos2113, 703 | } 704 | 705 | return BARresult 706 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2018 Antti Lipponen / Finnish Meteorological Institute 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BARalgorithm 2 | Bayesian Aerosol Retrieval algorithm 3 | version 1.01 (12 August 2020) 4 | 5 | This experimental code and data is meant for testing purposes only. 6 | As some of the models distributed with the code represent year 2014 7 | it should be noted that it is possible that the algorithm does 8 | not produce optimal estimates for data acquired long before or 9 | after year 2014. 10 | In all cases, the user should consult the author of the code 11 | before drawing any conclusions. The code is licensed under the 12 | MIT licence (found below). 13 | 14 | For the most recent version of the codes, please see https://github.com/TUT-ISI/BARalgorithm 15 | 16 | ## MODELS 17 | 18 | The models directory contains model files needed to run the code and some of the files are not available at Github. 19 | To download the LUT model (models/LUT directory) and surface reflectance prior model (models/SurfaceReflectance/2014) 20 | please download the code package from Zenodo (https://doi.org/10.5281/zenodo.1182939) and copy the 21 | contents of these two directories of the Zenodo package to corresponding BARalgorithm folders. 22 | 23 | --- 24 | 25 | **Reference:** 26 | Lipponen, A., Mielonen, T., Pitkänen, M. R. A., Levy, R. C., Sawyer, V. R., Romakkaniemi, S., Kolehmainen, V., and Arola, A.: 27 | Bayesian Aerosol Retrieval Algorithm for MODIS AOD retrieval over land, Atmos. Meas. Tech., 11, 1529–1547, 2018. 28 | https://doi.org/10.5194/amt-11-1529-2018. 29 | 30 | Contact information: 31 | Antti Lipponen 32 | Finnish Meteorological Institute 33 | antti.lipponen@fmi.fi 34 | 35 | --- 36 | 37 | Copyright 2018-2020 Antti Lipponen / Finnish Meteorological Institute 38 | 39 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 40 | files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, 41 | modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 42 | Software is furnished to do so, subject to the following conditions: 43 | 44 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 47 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 48 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 49 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 50 | 51 | --- 52 | 53 | 54 | ## 1) Bayesian Aerosol Retrieval (BAR) algorithm 55 | 56 | Bayesian Aerosol Retrieval (BAR) algorithm is a statistical aerosol retrieval algorithm and this 57 | code runs BAR algorithm using MODIS data over land. 58 | All technical details can be found from the article published in the Atmospheric Measurement Techniques 59 | (https://doi.org/10.5194/amt-11-1529-2018). The BAR algorithm is strongly based on NASA's Dark Target 60 | aerosol retrieval algorithm (https://darktarget.gsfc.nasa.gov/) and, for example, the radiative transfer 61 | simulation lookup-tables (LUTs) are based on the Dark Target LUTs distributed with the Dark 62 | Target stand-alone land code (https://darktarget.gsfc.nasa.gov/reference/code). 63 | 64 | 65 | ## 2) Requirements to run the code 66 | 67 | The code is written for Python 3 and it requires some packages and datafiles to run. 68 | The code has been tested on Linux/Ubuntu environment and it may or may not run on other operating systems. 69 | The code depends on, at least, the following packages and libraries: 70 | * NumPy 71 | * Scipy 72 | * netcdf4 73 | * pyhdf 74 | * scikit-learn 75 | 76 | We recommend the Anaconda Python (https://www.anaconda.com/download) to run the code (Python version >= 3.6). 77 | Please see the next sections for the instructions to download the required external data (Models), and 78 | install all required packages and libraries (Installation). 79 | 80 | ## 3) Models 81 | 82 | To run the BAR algorithm, you need certain model data files, some of the data files are included with the code 83 | and some of them you need to download before you can start using the algorithm code. All data files for models 84 | are located in the 'models' directory. 85 | There are 5 different models in BAR algorithm: 86 | AOD 87 | This is the expected value for AOD prior model. The expected value is based on MAC-V2 aerosol climatology 88 | (https://doi.org/10.1002/jame.20035 or https://doi.org/10.5194/gmd-10-433-2017) and the filename should be 'gt_t_00550nm.nc'. 89 | You can download the file from: 90 | ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_t_00550nm.nc 91 | If you want to download it from the command line, type: 92 | wget -O "models/AOD/gt_t_00550nm.nc" "ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_t_00550nm.nc" 93 | 94 | FMF 95 | This is the expected value for FMF prior model. The expected value is based on MAC-V2 aerosol climatology 96 | (https://doi.org/10.1002/jame.20035 or https://doi.org/10.5194/gmd-10-433-2017) and the filename should be 'gt_ff_0550nm.nc'. 97 | You can download the file from: 98 | ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_ff_0550nm.nc 99 | If you want to download it from the command line, type: 100 | wget -O "models/FMF/gt_ff_0550nm.nc" "ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_ff_0550nm.nc" 101 | 102 | ApproximationError 103 | The approximation error model is based on 2014 AERONET data and the required file 'approximationerror.json' is included with the code. 104 | 105 | LUT 106 | LUT directory includes the radiative transfer model lookup-tables. The lookup-tables are included with the code 107 | and are based on NASA's Dark Target over land algorithm (https://darktarget.gsfc.nasa.gov/). The original lookup-tables 108 | are distributed with the Dark Target over land stand-alone code (https://darktarget.gsfc.nasa.gov/reference/code). 109 | 110 | SurfaceReflectance 111 | SurfaceReflectance directory includes the prior model files corresponding to year 2014 for MODIS bands 1, 3, 4, and 7. 112 | The surface reflectance prior models are based on MODIS MCD43C3 data products 113 | (https://lpdaac.usgs.gov/dataset_discovery/modis/modis_products_table/mcd43c3). 114 | 115 | 116 | ## 4) Installation 117 | 118 | (These instructions are tested in Linux/Ubuntu and OS X environment) 119 | We recommend Anaconda Python and its environments to be used to run the BAR algorithm. 120 | To check if Anaconda is correctly installed type 'conda' and you should get information about the conda manager. 121 | 122 | Some of the packages may only be available the 'conda-forge' repository (https://conda-forge.org/). 123 | Start the installation by adding the conda-forge to your conda by typing: 124 | conda config --add channels conda-forge 125 | 126 | Creating an environment is recommended so you can install all the necessary packages and they won't 127 | disturb your regular/default Python environment. To create environment 'BARenv' for BAR and install the necessary 128 | Python packages type: 129 | conda create -n BARenv python=3.6 numpy scipy netcdf4 pyhdf scikit-learn imageio 130 | 131 | Now activate the 'BARenv' environment by typing: 132 | source activate BARenv 133 | 134 | If everything is OK you should now see the name of the environment in your command prompt. While the environment 135 | is active you can navigate to your BAR algorithm folder and start running the code. 136 | 137 | When you are done with your computations you can return back to your default Python configuration by 138 | deactivating the environment. The deactivation is done by typing: 139 | source deactivate 140 | 141 | 142 | ## 5) Use 143 | 144 | You can now run the retrieval by typing: 145 | python BAR.py INPUTFILENAME [OUTPUTFILENAME] 146 | 147 | INPUTFILENAME = path to MODIS MOD04_L2/MYD04_L2 granule hdf file 148 | OUTPUTFILENAME (optional) = the netCDF file to be used to save the results 149 | 150 | You can also give the following command line options: 151 | -quantifyuncertainty: Quantify the uncertainties related to retrieval and save the uncertainty estimates into the outputfile 152 | -nospatialcorrelation: Do not use spatial correlation model 153 | -noapproximationerror: Do not use approximation error model 154 | 155 | Also the AOD, FMF, and surface reflectance prior model parameters can be tuned from the command line using the commands -AODprior, -FMFprior, and -surfaceprior 156 | Examples: 157 | -AODprior='{"range": 250, "p": 2.0, "sill": 0.5, "nugget": 0.001}' 158 | -FMFprior='{"range": 75, "p": 1.25, "sill": 0.1, "nugget": 0.01}' 159 | -surfaceprior='{"meancoef": 1.05, "stdcoef": 1.5}' 160 | 161 | 162 | ## 6) Example 163 | 164 | In this example, a MODIS MOD04_L2 datafile is first downloaded and then 165 | the BAR algorithm is run to retrieve the AOD and FMF 166 | (one easy way to download single granules of data is to use the 167 | NASA Worldview https://worldview.earthdata.nasa.gov/). 168 | The resulting file will be in netCDF format and can be viewed 169 | for example with the Panoply Data Viewer (https://www.giss.nasa.gov/tools/panoply/). 170 | 171 | In this example case we will retrieve the aerosol properties over Finland 172 | in 2010 during a heavy smoke event from the fires in Russia. 173 | The example case can be viewed in NASA Worldview at: https://go.nasa.gov/2FfsNuG 174 | 175 | Download the data: 176 | wget --no-check-certificate -O "granuleFiles/MOD04_L2.A2010210.0950.006.2015046201421.hdf" "https://ladsweb.modaps.eosdis.nasa.gov/archive/allData/6/MOD04_L2/2010/210/MOD04_L2.A2010210.0950.006.2015046201421.hdf" 177 | 178 | Run the retrieval: 179 | source activate BARenv 180 | python BAR.py granuleFiles/MOD04_L2.A2010210.0950.006.2015046201421.hdf granuleFiles/Finland20100729.nc 181 | source deactivate 182 | 183 | Now the results are stored in the netCDF file 'granuleFiles/Finland20100729.nc'. 184 | 185 | --- 186 | 187 | ## Questions/Requests/Collaboration: antti.lipponen@fmi.fi 188 | 189 | --- 190 | 191 | ## Installation and test commands without explanation: 192 | 193 | ``` 194 | wget -O "models/AOD/gt_t_00550nm.nc" "ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_t_00550nm.nc" 195 | wget -O "models/FMF/gt_ff_0550nm.nc" "ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_ff_0550nm.nc" 196 | conda config --add channels conda-forge 197 | conda create -n BARenv python=3.6 numpy scipy netcdf4 pyhdf scikit-learn imageio 198 | source activate BARenv 199 | wget --no-check-certificate -O "granuleFiles/MOD04_L2.A2010210.0950.006.2015046201421.hdf" "https://ladsweb.modaps.eosdis.nasa.gov/archive/allData/6/MOD04_L2/2010/210/MOD04_L2.A2010210.0950.006.2015046201421.hdf" 200 | python BAR.py granuleFiles/MOD04_L2.A2010210.0950.006.2015046201421.hdf granuleFiles/Finland20100729.nc 201 | source deactivate 202 | ``` 203 | -------------------------------------------------------------------------------- /granuleFiles/info.txt: -------------------------------------------------------------------------------- 1 | This is a directory for granules to be retrieved. 2 | -------------------------------------------------------------------------------- /models/AOD/info.txt: -------------------------------------------------------------------------------- 1 | There should be file 'gt_t_00550nm.nc' in this directory. 2 | You can download the file from: ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_t_00550nm.nc 3 | -------------------------------------------------------------------------------- /models/ApproximationError/approximationerror.json: -------------------------------------------------------------------------------- 1 | {"EUR": {"1": {"cov": [8.953475050276286e-05, 0.00010950210379095781, 0.00012832488995506944, 0.00015328280351170306, 0.00010950210379095781, 0.0002076011852018236, 0.0002549441566895653, 0.0003695467348046041, 0.00012832488995506944, 0.0002549441566895653, 0.00033445414565569083, 0.0004986418915646365, 0.00015328280351170306, 0.0003695467348046041, 0.0004986418915646365, 0.0008850386616879555], "E": [-0.005029372242980695, -0.013212894710106948, -0.018436993782343883, -0.021383705083725585]}, "2": {"cov": [7.555401139859702e-05, 9.66335928103032e-05, 0.00011129067947025426, 0.00014011447176792293, 9.66335928103032e-05, 0.00019006029947829346, 0.00022389047425369778, 0.00034470822824716346, 0.00011129067947025426, 0.00022389047425369778, 0.00028375615724042486, 0.00044111623012699024, 0.00014011447176792293, 0.00034470822824716346, 0.00044111623012699024, 0.0008292060141353695], "E": [-0.00453211642151484, -0.010517997676914727, -0.014042229156001326, -0.014603241761674657]}, "3": {"cov": [5.274954763820077e-05, 7.204998912902263e-05, 8.289264996486981e-05, 0.00011145935761518282, 7.204998912902263e-05, 0.00013972494069146456, 0.00015734538131482762, 0.0002462387167641424, 8.289264996486981e-05, 0.00015734538131482762, 0.0001934637342390925, 0.0003116215360995374, 0.00011145935761518282, 0.0002462387167641424, 0.0003116215360995374, 0.0006226077033805805], "E": [-0.0018015047420959565, -0.0076457003570724325, -0.008977514039756357, -0.0023694996013895187]}, "4": {"cov": [5.7883410781144344e-05, 8.224137288160252e-05, 9.900619136253425e-05, 0.00013486383282823488, 8.224137288160252e-05, 0.0001632205338769666, 0.0001853317849102863, 0.0002767267209846418, 9.900619136253425e-05, 0.0001853317849102863, 0.00023604749765124316, 0.0003647137673277278, 0.00013486383282823488, 0.0002767267209846418, 0.0003647137673277278, 0.000667894539457628], "E": [-0.002910289190069311, -0.00601929878478695, -0.009819502947412365, -0.005213860003270995]}, "5": {"cov": [6.179458159454977e-05, 9.211253969462122e-05, 0.00011151744094735983, 0.00014633681594690518, 9.211253969462122e-05, 0.0001831382181703205, 0.00021184109533128607, 0.00029514927726921364, 0.00011151744094735983, 0.00021184109533128607, 0.00028221959201661927, 0.00040126454371225813, 0.00014633681594690518, 0.00029514927726921364, 0.00040126454371225813, 0.0007001799872579637], "E": [-0.002729113291962737, -0.0046023445296360654, -0.009196438575702966, -0.005777786046614594]}, "6": {"cov": [6.954812966750759e-05, 0.00010100403386120759, 0.00012245920336672567, 0.0001677824126766651, 0.00010100403386120759, 0.0001968586856347067, 0.00023767858029116352, 0.0003504675944137518, 0.00012245920336672567, 0.00023767858029116352, 0.00032001416737304433, 0.0004717600765906915, 0.0001677824126766651, 0.0003504675944137518, 0.0004717600765906915, 0.000833460035584448], "E": [-0.0024181670861490936, -0.0029887901914231046, -0.005739729525358766, -7.753803793652397e-05]}, "7": {"cov": [7.027982952318188e-05, 0.00010102586205895183, 0.00012239059067378161, 0.00015969299317378178, 0.00010102586205895183, 0.00019574275072354268, 0.00023915470871539, 0.0003478885697885483, 0.00012239059067378161, 0.00023915470871539, 0.00031522652997731344, 0.00045644736440019515, 0.00015969299317378178, 0.0003478885697885483, 0.00045644736440019515, 0.0007967735174289879], "E": [-0.0016893301379236753, -0.0032554669917729956, -0.00630203447618384, -0.0004598926878249393]}, "8": {"cov": [7.22037940344033e-05, 0.00010541557483868901, 0.00013026705245253143, 0.0001768275879018402, 0.00010541557483868901, 0.0002020594855253632, 0.00025437929354129213, 0.0003829118123515228, 0.00013026705245253143, 0.00025437929354129213, 0.0003454876777110887, 0.0005300641714997982, 0.0001768275879018402, 0.0003829118123515228, 0.0005300641714997982, 0.0009321959935968953], "E": [-0.0020149315083470287, -0.003929572152443175, -0.007327152668000998, -0.003277122890462808]}, "9": {"cov": [6.642302532851699e-05, 9.244729440269105e-05, 0.00011123676359684331, 0.0001453081687793022, 9.244729440269105e-05, 0.00017423038016017126, 0.00020980067489453734, 0.000313092435447303, 0.00011123676359684331, 0.00020980067489453734, 0.0002747543611002876, 0.0004112537573315059, 0.0001453081687793022, 0.000313092435447303, 0.0004112537573315059, 0.0007380504261900012], "E": [-0.0038166519369890878, -0.008054739642409672, -0.010926893494653176, -0.009285616488464345]}, "10": {"cov": [7.226108554444957e-05, 9.097844913054254e-05, 0.00010937615220048247, 0.0001396852365591922, 9.097844913054254e-05, 0.00017904961797994957, 0.00021894166556409258, 0.00032510134849911526, 0.00010937615220048247, 0.00021894166556409258, 0.0002906140977772867, 0.0004369070909871734, 0.0001396852365591922, 0.00032510134849911526, 0.0004369070909871734, 0.0008087200382060621], "E": [-0.005319811864697953, -0.011122304281558429, -0.015236495058533327, -0.014862650861616325]}, "11": {"cov": [8.39418171476615e-05, 9.924826309407223e-05, 0.00012092160573983446, 0.0001545258672186593, 9.924826309407223e-05, 0.00020582377581371053, 0.0002550256138902496, 0.0003975258393557331, 0.00012092160573983446, 0.0002550256138902496, 0.0003373727627557539, 0.0005369618559557506, 0.0001545258672186593, 0.0003975258393557331, 0.0005369618559557506, 0.00101830135722965], "E": [-0.005629399292050925, -0.012616157263232695, -0.015901714063376003, -0.018026407628282184]}, "12": {"cov": [7.661414225660894e-05, 8.60610650552703e-05, 0.00010580869438741485, 0.00013784634378478654, 8.60610650552703e-05, 0.00019913182903246677, 0.0002469949971193473, 0.0003866402675186968, 0.00010580869438741485, 0.0002469949971193473, 0.0003296989424383077, 0.0005303410184512202, 0.00013784634378478654, 0.0003866402675186968, 0.0005303410184512202, 0.0010144385141144588], "E": [-0.004342068674324379, -0.012915428266336473, -0.018987152457144753, -0.021929004024298232]}}, "WNA": {"1": {"cov": [8.948852398804068e-05, 0.00013179519768568182, 0.00017417802915129337, 0.00020342931742696913, 0.00013179519768568182, 0.00024453432454383714, 0.0003276127243876442, 0.0004307743021078163, 0.00017417802915129337, 0.0003276127243876442, 0.00045802807329452813, 0.000613411190732715, 0.00020342931742696913, 0.0004307743021078163, 0.000613411190732715, 0.0010236782179145706], "E": [-0.004684809683151325, -0.01203285240423524, -0.0173453725069434, -0.019147066942913807]}, "2": {"cov": [0.00013245743361913254, 0.000197411121699676, 0.0002597709936551726, 0.0003400662071065646, 0.000197411121699676, 0.0003255810858016449, 0.0004317630808721515, 0.0006029491343224262, 0.0002597709936551726, 0.0004317630808721515, 0.0005915251908462109, 0.0008388665366226136, 0.0003400662071065646, 0.0006029491343224262, 0.0008388665366226136, 0.0013850204954925283], "E": [-0.004966883075282064, -0.012514130268747536, -0.019114140220607076, -0.018091561650773497]}, "3": {"cov": [0.00014260547448153714, 0.0002125868330845081, 0.0002757580382874525, 0.0003551725653356075, 0.0002125868330845081, 0.0003400645552210273, 0.0004417044569248807, 0.0005948883158374226, 0.0002757580382874525, 0.0004417044569248807, 0.0005956887481809128, 0.0008187346605940245, 0.0003551725653356075, 0.0005948883158374226, 0.0008187346605940245, 0.0012863169496858747], "E": [-0.004186867355464016, -0.010328119873233399, -0.016271659572608524, -0.013940911527380445]}, "4": {"cov": [0.00013201790665519673, 0.00018492870943537994, 0.0002341981905987285, 0.00030087883049788295, 0.00018492870943537994, 0.00029223617331318273, 0.00036859417806027397, 0.0004982456596607646, 0.0002341981905987285, 0.00036859417806027397, 0.00048285955050573706, 0.0006663622140442691, 0.00030087883049788295, 0.0004982456596607646, 0.0006663622140442691, 0.0011069035108662272], "E": [-0.0011995690145284177, -0.005183824811828552, -0.009891914987135222, -0.004383140298829302]}, "5": {"cov": [0.00014355223622155894, 0.000195223365046799, 0.00024234027054145557, 0.0002948458766629861, 0.000195223365046799, 0.0003056795659604615, 0.00037195558892820957, 0.00047788998569809243, 0.00024234027054145557, 0.00037195558892820957, 0.000482752656309795, 0.0006430116195244394, 0.0002948458766629861, 0.00047788998569809243, 0.0006430116195244394, 0.0010520940348463016], "E": [-0.0022697094214563784, -0.0059549397551825825, -0.009125773423260014, -0.0014712994528369577]}, "6": {"cov": [0.00013726036207431803, 0.00018810126599173746, 0.00022267671369422616, 0.0002590559237900261, 0.00018810126599173746, 0.00029280111150357973, 0.0003451844392955669, 0.00043763477392459905, 0.00022267671369422616, 0.0003451844392955669, 0.00043879457340004766, 0.0005710978118053954, 0.0002590559237900261, 0.00043763477392459905, 0.0005710978118053954, 0.0009692057546741508], "E": [-0.0032598597854287953, -0.004456420426516457, -0.008188064400615369, -0.0012186101639278107]}, "7": {"cov": [0.0001355958084757075, 0.00017355144315609746, 0.00021182147405992015, 0.0002306289626094091, 0.00017355144315609746, 0.0002635388025490023, 0.0003220872670153359, 0.00038987005032623044, 0.00021182147405992015, 0.0003220872670153359, 0.0004293577728258611, 0.0005417056336479997, 0.0002306289626094091, 0.00038987005032623044, 0.0005417056336479997, 0.000927779101215503], "E": [-0.0010521613684729009, -0.0015773004094301046, -0.005529338989178144, -0.0014690307740106573]}, "8": {"cov": [0.0001284726590407441, 0.0001589033145819631, 0.00018704484897298442, 0.00021176332667886553, 0.0001589033145819631, 0.0002348537985019885, 0.0002819649584672656, 0.00036018145135463043, 0.00018704484897298442, 0.0002819649584672656, 0.0003666944044444807, 0.00048569417123591705, 0.00021176332667886553, 0.00036018145135463043, 0.00048569417123591705, 0.0008628208945943847], "E": [-0.0024959695171667823, -0.004364718646459972, -0.008394102710141328, -0.00498053797520271]}, "9": {"cov": [8.57260977277244e-05, 0.00011611325933961653, 0.00014371142364858725, 0.0001769713140444254, 0.00011611325933961653, 0.00020175831853458395, 0.00024275812701484586, 0.00033098485057212883, 0.00014371142364858725, 0.00024275812701484586, 0.00032679041030674017, 0.0004490356348958236, 0.0001769713140444254, 0.00033098485057212883, 0.0004490356348958236, 0.0007915376561975913], "E": [-0.005230387224544802, -0.008808601278651351, -0.011783452486308632, -0.007708695322760251]}, "10": {"cov": [7.836196935719185e-05, 0.00011673104892997016, 0.00014619523749667001, 0.0001869457684901854, 0.00011673104892997016, 0.00021440617762401103, 0.00027120118044993884, 0.0003740621024440235, 0.00014619523749667001, 0.00027120118044993884, 0.0003654751989504634, 0.0005153329972272436, 0.0001869457684901854, 0.0003740621024440235, 0.0005153329972272436, 0.0008892636815621291], "E": [-0.006178128129503621, -0.012147067875250467, -0.01734311714220574, -0.013586574865535009]}, "11": {"cov": [7.745701934983608e-05, 0.00010769883335279902, 0.00013841322126078058, 0.0001754880393232803, 0.00010769883335279902, 0.00020217240380682609, 0.0002634760790494456, 0.00036900845871884783, 0.00013841322126078058, 0.0002634760790494456, 0.0003624998690663402, 0.0005109651292408516, 0.0001754880393232803, 0.00036900845871884783, 0.0005109651292408516, 0.0008957784766901516], "E": [-0.004525143153943284, -0.012596014393293178, -0.01892115228951491, -0.018110870621336733]}, "12": {"cov": [9.131290531282126e-05, 0.00011864925879177934, 0.00014976300654089662, 0.00017242589312185257, 0.00011864925879177934, 0.00022217449139697734, 0.0002824434845161017, 0.00037834774809281037, 0.00014976300654089662, 0.0002824434845161017, 0.0003776888464867109, 0.0005222958575756019, 0.00017242589312185257, 0.00037834774809281037, 0.0005222958575756019, 0.0009566018131157988], "E": [-0.0056114729698205496, -0.013309018015061722, -0.020119242265447368, -0.01936419527016478]}}, "ENA": {"1": {"cov": [4.04123634524758e-05, 4.90745432087314e-05, 5.761767079237148e-05, 6.730053732570278e-05, 4.90745432087314e-05, 9.799097582166428e-05, 0.00011585566838994545, 0.00017778263567425594, 5.761767079237148e-05, 0.00011585566838994545, 0.00014628876013817683, 0.00024053399613506104, 6.730053732570278e-05, 0.00017778263567425594, 0.00024053399613506104, 0.0005807058616477815], "E": [-0.0015007001048587681, -0.008109653676895173, -0.011105725972657257, -0.010903358131789276]}, "2": {"cov": [4.106010528392173e-05, 5.1424827129855656e-05, 5.822897211277774e-05, 6.119745860039529e-05, 5.1424827129855656e-05, 8.700561062392532e-05, 0.00010095401872627637, 0.00014983500134903852, 5.822897211277774e-05, 0.00010095401872627637, 0.00012304742772903545, 0.0001881958298224044, 6.119745860039529e-05, 0.00014983500134903852, 0.0001881958298224044, 0.000488336168526483], "E": [-0.0003321739434537785, -0.0051952704373237485, -0.007375951938283762, -0.007537028715808608]}, "3": {"cov": [5.9172262860714635e-05, 7.131963310786581e-05, 7.908910861539856e-05, 7.09774842393771e-05, 7.131963310786581e-05, 0.00010724003404939051, 0.00011966195579444255, 0.0001509268594698714, 7.908910861539856e-05, 0.00011966195579444255, 0.00014538157940960995, 0.00020582315447448493, 7.09774842393771e-05, 0.0001509268594698714, 0.00020582315447448493, 0.0005248729872465585], "E": [0.0008131059124513937, -0.0027129606415669874, -0.0024442632062535857, 0.0051410898304876385]}, "4": {"cov": [4.673758691782819e-05, 5.266962864220426e-05, 7.254532626011578e-05, 9.544319081230011e-05, 5.266962864220426e-05, 9.656702118537108e-05, 0.00010449980401900346, 0.00015018537226790435, 7.254532626011578e-05, 0.00010449980401900346, 0.00015413395644506267, 0.00025275193481451443, 9.544319081230011e-05, 0.00015018537226790435, 0.00025275193481451443, 0.0006058744896550913], "E": [0.0007143132524936036, -0.0013742113375558376, -0.002516213942216808, 0.004344155303895536]}, "5": {"cov": [4.478658112434297e-05, 5.343754533416507e-05, 7.233128931849169e-05, 0.00010860978061463342, 5.343754533416507e-05, 0.00010536448679947374, 0.00010506391004388767, 0.00017509314156867041, 7.233128931849169e-05, 0.00010506391004388767, 0.00015667685251331882, 0.0002615446174602318, 0.00010860978061463342, 0.00017509314156867041, 0.0002615446174602318, 0.0005534551443729544], "E": [-0.00020876679964448863, 0.0025883773705503432, -0.004231131932878926, -0.0006560343271276303]}, "6": {"cov": [6.479877501726544e-05, 7.303573173295473e-05, 7.955906527120984e-05, 9.750755737504368e-05, 7.303573173295473e-05, 0.00013604931047615838, 0.00012772327635574894, 0.00017211004440387655, 7.955906527120984e-05, 0.00012772327635574894, 0.00014930327046894796, 0.00021366648358347168, 9.750755737504368e-05, 0.00017211004440387655, 0.00021366648358347168, 0.0004979209061289198], "E": [-1.802530598224439e-05, 0.0009668264167365936, -0.00394108796542289, 0.0010974986233183298]}, "7": {"cov": [7.821654185428464e-05, 9.745351430475856e-05, 9.650791971054889e-05, 7.197683399355757e-05, 9.745351430475856e-05, 0.0001702615099540873, 0.0001705902008514883, 0.00018645197976496178, 9.650791971054889e-05, 0.0001705902008514883, 0.00018964532019527438, 0.00022360012794800667, 7.197683399355757e-05, 0.00018645197976496178, 0.00022360012794800667, 0.0005071717574422619], "E": [0.0007426914259935843, -6.140344006511783e-05, -0.004278338483968573, -0.0011561556884801469]}, "8": {"cov": [5.737657706391018e-05, 7.388374494477681e-05, 7.404049133450104e-05, 7.420794544867434e-05, 7.388374494477681e-05, 0.00012771820298220315, 0.00012775819772825413, 0.00016753070061623337, 7.404049133450104e-05, 0.00012775819772825413, 0.00014312431281018957, 0.0001958353508216778, 7.420794544867434e-05, 0.00016753070061623337, 0.0001958353508216778, 0.0004284194448711808], "E": [-3.975820633541488e-05, -0.0017482040772208718, -0.005368174129483795, -0.004125215180614365]}, "9": {"cov": [3.8715672469018104e-05, 5.4831585491149775e-05, 6.369099960932799e-05, 8.342006986095736e-05, 5.4831585491149775e-05, 0.00011118474007713805, 0.00011860849913702228, 0.0001777968792369081, 6.369099960932799e-05, 0.00011860849913702228, 0.00015667359524514156, 0.0002266049952979765, 8.342006986095736e-05, 0.0001777968792369081, 0.0002266049952979765, 0.000413898919977956], "E": [-0.002466504403669467, -0.004144198699216228, -0.0072065504708234696, -0.007799723437406439]}, "10": {"cov": [4.0326679451555e-05, 5.433146724260705e-05, 6.314894466486452e-05, 7.516213946312796e-05, 5.433146724260705e-05, 0.00011150939507646652, 0.00012152502416626115, 0.0001713575432716509, 6.314894466486452e-05, 0.00012152502416626115, 0.00015006100646529477, 0.00021813435912419317, 7.516213946312796e-05, 0.0001713575432716509, 0.00021813435912419317, 0.0004225866168044165], "E": [-0.0032732821610255355, -0.007371466874225817, -0.009362751895726482, -0.008993254904401188]}, "11": {"cov": [4.560004473799762e-05, 4.755653452843547e-05, 5.715282336263725e-05, 7.188464365548521e-05, 4.755653452843547e-05, 9.697925895813434e-05, 0.00011518884875040916, 0.00016631044354611097, 5.715282336263725e-05, 0.00011518884875040916, 0.00015314814146925691, 0.00023193330667394853, 7.188464365548521e-05, 0.00016631044354611097, 0.00023193330667394853, 0.0004850002343046866], "E": [-0.001386842330247412, -0.00715967224900195, -0.0084816071519844, -0.008423502534173774]}, "12": {"cov": [5.151236071734249e-05, 4.965013261918479e-05, 5.722727513685328e-05, 6.31668411760947e-05, 4.965013261918479e-05, 9.548059999280423e-05, 0.00011275146468016131, 0.00017781912116002847, 5.722727513685328e-05, 0.00011275146468016131, 0.00014462335256635128, 0.00024423145184314686, 6.31668411760947e-05, 0.00017781912116002847, 0.00024423145184314686, 0.0005932242861661824], "E": [-0.0019829150515047814, -0.008643826754185242, -0.01169755222683089, -0.013061053454500027]}}, "CSA": {"1": {"cov": [0.00012626682542947907, 0.0001578220177370821, 0.00019275871812711345, 0.00024073565812004924, 0.0001578220177370821, 0.0002516413899296245, 0.00030341556153117114, 0.0004187478549024227, 0.00019275871812711345, 0.00030341556153117114, 0.00040992331600389273, 0.0005578057112352486, 0.00024073565812004924, 0.0004187478549024227, 0.0005578057112352486, 0.0009554530118841813], "E": [-0.0018688044228243328, -0.004681035243631046, -0.008696131082538944, -0.003082098612221945]}, "2": {"cov": [0.00014541089209148055, 0.00018150975441266802, 0.0002294720039595309, 0.0002948982434111529, 0.00018150975441266802, 0.0002761995832643128, 0.00035322475294053616, 0.000490586937041114, 0.0002294720039595309, 0.00035322475294053616, 0.0004938067080066826, 0.0006916164319894594, 0.0002948982434111529, 0.000490586937041114, 0.0006916164319894594, 0.0011561735804201147], "E": [-0.002861985943874712, -0.0050512761871942535, -0.009520867888123105, -0.0019586911193166523]}, "3": {"cov": [0.00011445695052707632, 0.00013924705797798822, 0.00017396026676118497, 0.0002377403668621724, 0.00013924705797798822, 0.00021519205636763255, 0.0002653854869142049, 0.00038427656453510184, 0.00017396026676118497, 0.0002653854869142049, 0.00036601505215038733, 0.000511253528141107, 0.0002377403668621724, 0.00038427656453510184, 0.000511253528141107, 0.0009852922653244744], "E": [-0.0016706705377239062, -0.004710609315168111, -0.007520391936145815, -0.001026290654548831]}, "4": {"cov": [8.448453394428078e-05, 0.0001079294957747768, 0.00012683976143129238, 0.00016806058863559848, 0.0001079294957747768, 0.00018600631275011236, 0.00021363606758072662, 0.00030998889156631874, 0.00012683976143129238, 0.00021363606758072662, 0.0002786564659399856, 0.00038449862750256346, 0.00016806058863559848, 0.00030998889156631874, 0.00038449862750256346, 0.0008022530074883195], "E": [-0.0013884824839751411, -0.006163049290412802, -0.009940702879527655, -0.006701673380000106]}, "5": {"cov": [8.411807855192272e-05, 0.00010372518458049932, 0.00012225418870822705, 0.00016488156917849968, 0.00010372518458049932, 0.00018931261148494543, 0.00021601553602556325, 0.00033737820588075276, 0.00012225418870822705, 0.00021601553602556325, 0.0002716834533874688, 0.0004162343028465497, 0.00016488156917849968, 0.00033737820588075276, 0.0004162343028465497, 0.0008034755064853305], "E": [-0.0015921870335099952, -0.006840686129410439, -0.01060954873143835, -0.01098729248085259]}, "6": {"cov": [5.734747292957152e-05, 6.704911393399793e-05, 7.60136027521063e-05, 0.00010087763730370951, 6.704911393399793e-05, 0.0001351642518139565, 0.00015012051244704257, 0.0002356023458189976, 7.60136027521063e-05, 0.00015012051244704257, 0.00018567566647332689, 0.00027805367046280117, 0.00010087763730370951, 0.0002356023458189976, 0.00027805367046280117, 0.0005720852358248343], "E": [-0.0020295461776530174, -0.006822172250691622, -0.010455981920841535, -0.010814452816138437]}, "7": {"cov": [5.918726853445026e-05, 6.961253245441802e-05, 8.090433996612178e-05, 0.00011007545528764713, 6.961253245441802e-05, 0.00013407732620273268, 0.00015077978463496697, 0.00024059909374500216, 8.090433996612178e-05, 0.00015077978463496697, 0.00019126345137177684, 0.0002941985045482761, 0.00011007545528764713, 0.00024059909374500216, 0.0002941985045482761, 0.0005887139970409252], "E": [-0.0013074610198905712, -0.004957708939886271, -0.008001269215940809, -0.006036667691388754]}, "8": {"cov": [6.8715813597716e-05, 8.384698655529499e-05, 9.794209519671689e-05, 0.00012659837651754675, 8.384698655529499e-05, 0.00014552291154492999, 0.00016412067758383284, 0.00025487001812731885, 9.794209519671689e-05, 0.00016412067758383284, 0.00020613634007891972, 0.00031131237427529815, 0.00012659837651754675, 0.00025487001812731885, 0.00031131237427529815, 0.0006642341728980737], "E": [-0.00044847377894285945, -0.0034763783242894586, -0.005857071052377115, -0.002698827924734637]}, "9": {"cov": [7.778840088616016e-05, 9.163884440616591e-05, 0.00010816577370415008, 0.0001391151854586563, 9.163884440616591e-05, 0.00015006448957024293, 0.00016644086638149282, 0.00025183873120687776, 0.00010816577370415008, 0.00016644086638149282, 0.0002088481281252327, 0.00031424246959624205, 0.0001391151854586563, 0.00025183873120687776, 0.00031424246959624205, 0.0006500330332688438], "E": [0.0012518381598404515, -0.00016683531078129366, -0.0032724169631851846, 0.0014325325942615708]}, "10": {"cov": [9.73561502968065e-05, 0.00011554158425160792, 0.00013545310712957507, 0.00016941290168506962, 0.00011554158425160792, 0.00018002809929641283, 0.00020451887551335726, 0.0002959379531453065, 0.00013545310712957507, 0.00020451887551335726, 0.0002555029129850177, 0.000367109503451341, 0.00016941290168506962, 0.0002959379531453065, 0.000367109503451341, 0.0007519281787745344], "E": [0.001472918070168902, 0.0005618904473594366, -0.0031628287109770337, 0.0022463526843483628]}, "11": {"cov": [0.00010372470016624176, 0.00013637230166699596, 0.0001605522948917251, 0.00021035203823435152, 0.00013637230166699596, 0.00022829293201956903, 0.00025960973632386684, 0.00037229923555038533, 0.0001605522948917251, 0.00025960973632386684, 0.00032640437701157975, 0.0004507838964252811, 0.00021035203823435152, 0.00037229923555038533, 0.0004507838964252811, 0.0007994902928322653], "E": [0.0007496614200479534, 0.0012108444801768037, -0.0019085472617183658, 0.006047569979593492]}, "12": {"cov": [0.00010393115053277966, 0.00013288483091566393, 0.00015580192650794053, 0.0001971701739380518, 0.00013288483091566393, 0.00021763325582430958, 0.0002500275484483726, 0.00034470336447386, 0.00015580192650794053, 0.0002500275484483726, 0.00032105439721393924, 0.0004205704987976784, 0.0001971701739380518, 0.00034470336447386, 0.0004205704987976784, 0.0007638866106051427], "E": [0.0002720309230303253, 0.0009829466277472554, -0.0032743739569748645, 0.002863978365050146]}}, "NAME": {"1": {"cov": [0.0001630083600139199, 0.00018755326862679398, 0.00021543187526038528, 0.00027864572430468453, 0.00018755326862679398, 0.0002787822732714594, 0.00034915537710547144, 0.0005262000214861996, 0.00021543187526038528, 0.00034915537710547144, 0.0005026961975299941, 0.0008188023481182487, 0.00027864572430468453, 0.0005262000214861996, 0.0008188023481182487, 0.0015969973781268633], "E": [-0.009798608899609346, -0.013481102055005523, -0.014600749229949486, -0.0048333658750016675]}, "2": {"cov": [8.66037165434853e-05, 0.00011560888851139474, 0.00014461375203208714, 0.00019280367276749567, 0.00011560888851139474, 0.00020241345913225452, 0.00026989448640584406, 0.0004045016819299802, 0.00014461375203208714, 0.00026989448640584406, 0.00041067026932984323, 0.0006247555070771415, 0.00019280367276749567, 0.0004045016819299802, 0.0006247555070771415, 0.0011655558628858064], "E": [-0.006137381884723708, -0.009157752510452338, -0.01144968450048589, -0.007638710234588703]}, "3": {"cov": [0.00015377671098609183, 0.0002078475762013043, 0.0002686687689876016, 0.00039632297729599885, 0.0002078475762013043, 0.0003573808757644757, 0.0004781028259360438, 0.0006775293329714612, 0.0002686687689876016, 0.0004781028259360438, 0.0006829129385744724, 0.0009557219163850725, 0.00039632297729599885, 0.0006775293329714612, 0.0009557219163850725, 0.0015568130699360366], "E": [-0.0048665642442287105, -0.0038950937543821285, -0.009659428098859571, -0.012330456354410352]}, "4": {"cov": [0.00016773907470677977, 0.00024310569137151762, 0.00031813331932269167, 0.0004458232801529331, 0.00024310569137151762, 0.0004216145364129911, 0.000545108952299593, 0.0007947154398248325, 0.00031813331932269167, 0.000545108952299593, 0.0007570138707117524, 0.0011016992299285868, 0.0004458232801529331, 0.0007947154398248325, 0.0011016992299285868, 0.0017391898174228344], "E": [-0.00413677162354216, -0.0038027979870601733, -0.007979643498931432, -0.0023453127498600165]}, "5": {"cov": [0.00020290673776391518, 0.00028622570291468146, 0.00035494208171960647, 0.0005058615690480714, 0.00028622570291468146, 0.00046758611939407197, 0.000592914662319222, 0.0008683788680750157, 0.00035494208171960647, 0.000592914662319222, 0.0007945129904461081, 0.0011682817568352127, 0.0005058615690480714, 0.0008683788680750157, 0.0011682817568352127, 0.0018387751788646344], "E": [-0.0023022341329507964, -0.002004928365307218, -0.004475156462748493, 0.0028614395192214787]}, "6": {"cov": [0.00021523422992499847, 0.00029469278090141237, 0.00037369527292846006, 0.0005159035823018246, 0.00029469278090141237, 0.0004730014447137139, 0.0006205837365827486, 0.000879102428114602, 0.00037369527292846006, 0.0006205837365827486, 0.0008620711635423647, 0.0012192958834316224, 0.0005159035823018246, 0.000879102428114602, 0.0012192958834316224, 0.0018735880611850588], "E": [-0.0027384310472420015, -0.0017880136368925575, -0.0039570128952401765, 0.0020724784134842494]}, "7": {"cov": [0.00024076894997738754, 0.0003358878504727759, 0.0004565913960030624, 0.0006236460367530313, 0.0003358878504727759, 0.0005455322707653642, 0.0007565541428123814, 0.0010744802543529732, 0.0004565913960030624, 0.0007565541428123814, 0.0010853400999886308, 0.0015434956025572124, 0.0006236460367530313, 0.0010744802543529732, 0.0015434956025572124, 0.0023533829859666206], "E": [-0.002226849138219883, -0.0016270166377786374, -0.004371346659399811, 0.0015650213526746462]}, "8": {"cov": [0.00021598640142854155, 0.0002984646788550096, 0.0004000691844059636, 0.0005601288351428267, 0.0002984646788550096, 0.00048004404639697903, 0.0006568823301138918, 0.0009431242760814905, 0.0004000691844059636, 0.0006568823301138918, 0.0009298220766858973, 0.0013450827644476558, 0.0005601288351428267, 0.0009431242760814905, 0.0013450827644476558, 0.002089671348215613], "E": [-0.0038413222749725112, -0.004684966153581174, -0.008440465722002022, -0.0028463578721743404]}, "9": {"cov": [0.00020462013102311315, 0.0002813236919160746, 0.00038406784016540283, 0.0005414019116650915, 0.0002813236919160746, 0.0004520129453716759, 0.0006264350192709964, 0.0009027693216173408, 0.00038406784016540283, 0.0006264350192709964, 0.0008954352403044846, 0.0012928279541049132, 0.0005414019116650915, 0.0009027693216173408, 0.0012928279541049132, 0.001980423963135566], "E": [-0.0032437910762863897, -0.0049720219402494825, -0.008152971227564698, -0.007669998774353232]}, "10": {"cov": [0.00016435153898091835, 0.0002462459703290938, 0.0003618292542723693, 0.0005072022278872614, 0.0002462459703290938, 0.00043162213420457535, 0.0006393440243168941, 0.0009307054387486988, 0.0003618292542723693, 0.0006393440243168941, 0.0009915885718395562, 0.0014632356736721298, 0.0005072022278872614, 0.0009307054387486988, 0.0014632356736721298, 0.0022840110561520525], "E": [-0.004193975126879607, -0.009308718083427286, -0.013769311073799972, -0.013691314726480386]}, "11": {"cov": [0.00012361568165788242, 0.0001851730103513981, 0.0002687413415361949, 0.00041383867076776325, 0.0001851730103513981, 0.0003458078335337833, 0.0005132627677705234, 0.0008298426572101071, 0.0002687413415361949, 0.0005132627677705234, 0.0008370620135591131, 0.0013938415115651128, 0.00041383867076776325, 0.0008298426572101071, 0.0013938415115651128, 0.0025055169049348967], "E": [-0.00433486909275374, -0.012638421290124685, -0.017260521330194442, -0.020545226097905517]}, "12": {"cov": [0.00025786483934086234, 0.00031374902972121447, 0.00038808319008830594, 0.0004595563376440693, 0.00031374902972121447, 0.00047469059405368433, 0.0006146255386674866, 0.0007972623854020358, 0.00038808319008830594, 0.0006146255386674866, 0.0008500021243940807, 0.0011362964713393566, 0.0004595563376440693, 0.0007972623854020358, 0.0011362964713393566, 0.0017134582853663499], "E": [-0.007083803716049802, -0.014170564540380098, -0.024599629932830124, -0.03020941155959353]}}, "SA": {"1": {"cov": [7.583574668810677e-05, 0.00011045908183047953, 0.00011804489717909616, 8.724628459979506e-05, 0.00011045908183047953, 0.00021963337084016194, 0.00022921189535616516, 0.00024404475428254334, 0.00011804489717909616, 0.00022921189535616516, 0.0002816361948534306, 0.0003868173645390216, 8.724628459979506e-05, 0.00024404475428254334, 0.0003868173645390216, 0.0012655082896832724], "E": [-0.001026555351750169, 0.005092284101806649, 0.003914543716121363, 0.025973804065113786]}, "2": {"cov": [9.276270619931871e-05, 0.00011109520378347486, 0.00012014263872750232, 0.00011056737991021926, 0.00011109520378347486, 0.00020040895154157276, 0.0002200995396421935, 0.0003092387564040571, 0.00012014263872750232, 0.0002200995396421935, 0.00029493907510854463, 0.0005456697695420488, 0.00011056737991021926, 0.0003092387564040571, 0.0005456697695420488, 0.0017455481312838798], "E": [-0.0030821730853806822, 0.0002819695035470443, 0.0012495243621673674, 0.02085123954651663]}, "3": {"cov": [7.64994639544446e-05, 0.00011162805115622441, 0.0001418890189649539, 0.00021688734770478437, 0.00011162805115622441, 0.0002319693943608602, 0.0002748261443456303, 0.0004602572116350845, 0.0001418890189649539, 0.0002748261443456303, 0.00039478538149722366, 0.0007847442564996309, 0.00021688734770478437, 0.0004602572116350845, 0.0007847442564996309, 0.0021856144894389657], "E": [0.0007995362903591777, 0.001827274627562346, 0.0011164769050857823, 0.014402615174728989]}, "4": {"cov": [4.159023788467439e-05, 5.889413706229625e-05, 6.163718584268902e-05, 8.488700769869292e-05, 5.889413706229625e-05, 0.0001505761952952779, 0.00015010281173467638, 0.00026567776740754785, 6.163718584268902e-05, 0.00015010281173467638, 0.00017267620758993252, 0.000315869110163597, 8.488700769869292e-05, 0.00026567776740754785, 0.000315869110163597, 0.0008443764575714743], "E": [-0.0028622151853787137, -0.005963985108584494, -0.009160390106479455, -0.006258946705690743]}, "5": {"cov": [4.123267604476567e-05, 5.849552738209009e-05, 6.437040305130537e-05, 8.937980291639014e-05, 5.849552738209009e-05, 0.00012182264578617253, 0.00013569716420526898, 0.00021934986974058161, 6.437040305130537e-05, 0.00013569716420526898, 0.00016683421484844674, 0.0002834709757512807, 8.937980291639014e-05, 0.00021934986974058161, 0.0002834709757512807, 0.0005803343112306659], "E": [-0.0052268875796581266, -0.00811219636334487, -0.01182732802569364, -0.008257908972653702]}, "6": {"cov": [5.418966390699047e-05, 6.63890762219998e-05, 7.624320955600204e-05, 9.646733974864538e-05, 6.63890762219998e-05, 0.0001258167169716775, 0.0001526834230570763, 0.00024111557518331585, 7.624320955600204e-05, 0.0001526834230570763, 0.0002001869194911514, 0.00032324033103038597, 9.646733974864538e-05, 0.00024111557518331585, 0.00032324033103038597, 0.0006497428569143845], "E": [-0.006136558799817282, -0.008359905290589123, -0.010259956162333897, -0.004801639255840845]}, "7": {"cov": [5.874820606598904e-05, 6.444362538042307e-05, 7.481086692170288e-05, 8.863374166618419e-05, 6.444362538042307e-05, 0.00011161319574469235, 0.00014005822192116437, 0.00022985408207778656, 7.481086692170288e-05, 0.00014005822192116437, 0.00019004938142143737, 0.0003395764939590073, 8.863374166618419e-05, 0.00022985408207778656, 0.0003395764939590073, 0.0008301941598944574], "E": [-0.0061910644253810945, -0.00767709145440057, -0.008474456290087785, 4.255949929498487e-05]}, "8": {"cov": [5.2278502526291186e-05, 6.193856545715525e-05, 7.261257522589731e-05, 0.00010560139262460443, 6.193856545715525e-05, 9.331630009451761e-05, 0.00011673091574171621, 0.00019014538399334164, 7.261257522589731e-05, 0.00011673091574171621, 0.000157821228143878, 0.0002737872873432288, 0.00010560139262460443, 0.00019014538399334164, 0.0002737872873432288, 0.0006391220395489474], "E": [-0.0063554851295547915, -0.005840166840917663, -0.007126558766756268, 0.0025545462713832817]}, "9": {"cov": [5.296272529511597e-05, 6.45788202727645e-05, 7.324086726969387e-05, 9.281776423641972e-05, 6.45788202727645e-05, 0.00010532304537586445, 0.00012746655529237663, 0.00020893718598230908, 7.324086726969387e-05, 0.00012746655529237663, 0.00016830085910427397, 0.0002971395745149518, 9.281776423641972e-05, 0.00020893718598230908, 0.0002971395745149518, 0.0007370808767698039], "E": [-0.0028005768391388547, -0.0007478404541103947, -0.0018174635202156467, 0.008669066071398154]}, "10": {"cov": [4.792163357287587e-05, 5.7428354944431614e-05, 5.931344738180909e-05, 6.914520531477641e-05, 5.7428354944431614e-05, 0.00010062032091164941, 0.00011217634583973945, 0.00016703749109279027, 5.931344738180909e-05, 0.00011217634583973945, 0.00013958664100217037, 0.00022962106224388943, 6.914520531477641e-05, 0.00016703749109279027, 0.00022962106224388943, 0.0005206014674408254], "E": [0.0010942053334347945, 0.0016840852962694969, -0.0008510739437755516, 0.00779563326145466]}, "11": {"cov": [5.2949229070463916e-05, 7.83154688771659e-05, 9.876787774057922e-05, 0.0001527593431010032, 7.83154688771659e-05, 0.00016464804884149306, 0.0001915136052990748, 0.0002999818717979241, 9.876787774057922e-05, 0.0001915136052990748, 0.0002652383590484727, 0.00042125387105014733, 0.0001527593431010032, 0.0002999818717979241, 0.00042125387105014733, 0.000779855864933291], "E": [0.0041883507188853475, 0.00612430471164313, 0.004345012410639865, 0.02338274796023737]}, "12": {"cov": [5.323414971084344e-05, 8.931388423340135e-05, 9.540077869509335e-05, 0.00017325539722393555, 8.931388423340135e-05, 0.00020198283540945897, 0.00019089049214357983, 0.0003444310436834646, 9.540077869509335e-05, 0.00019089049214357983, 0.00022283220410784918, 0.00040940927573846565, 0.00017325539722393555, 0.0003444310436834646, 0.00040940927573846565, 0.0008471875318647136], "E": [0.0029533357897985058, 0.008274823231677428, -0.0033091366137721345, 0.008643514302555194]}}, "SEA": {"1": {"cov": [0.00014725265919836734, 0.00014680005252174316, 0.00014970350743858025, 0.0001331232689011559, 0.00014680005252174316, 0.00017516771990302153, 0.00018863862415907632, 0.00023548570686189124, 0.00014970350743858025, 0.00018863862415907632, 0.00022680984884045034, 0.000315573113167694, 0.0001331232689011559, 0.00023548570686189124, 0.000315573113167694, 0.0007568185667249767], "E": [-0.01085835814199726, -0.013029149500205506, -0.017368108226803916, -0.01629142965058486]}, "2": {"cov": [0.00012758423296222569, 0.0001336225352118144, 0.000143962028666555, 0.0001591681756981573, 0.0001336225352118144, 0.000169268314933323, 0.00018953855177867475, 0.00026152047452220734, 0.000143962028666555, 0.00018953855177867475, 0.00023827134532488313, 0.0003486983485934307, 0.0001591681756981573, 0.00026152047452220734, 0.0003486983485934307, 0.000747937022060162], "E": [-0.00920113497350715, -0.010315158989460463, -0.015311649582956464, -0.013080058503290401]}, "3": {"cov": [0.00014826178052483485, 0.00014848292154438688, 0.00015954539321250976, 0.0001524160622593289, 0.00014848292154438688, 0.00017666763068571547, 0.0001965528428519765, 0.000245738541134208, 0.00015954539321250976, 0.0001965528428519765, 0.00024253591051006016, 0.0003389680359448662, 0.0001524160622593289, 0.000245738541134208, 0.0003389680359448662, 0.0008331853927810118], "E": [-0.006040816780091787, -0.005360383688369774, -0.007994915115199341, -0.002970397228063165]}, "4": {"cov": [0.00013088727792709477, 0.00013809903903407126, 0.0001399918165255625, 0.0001481360734534987, 0.00013809903903407126, 0.00017998254911911286, 0.000187113802800157, 0.00025642207378805137, 0.0001399918165255625, 0.000187113802800157, 0.00022391075455594072, 0.00033275493983584076, 0.0001481360734534987, 0.00025642207378805137, 0.00033275493983584076, 0.0008266772994383085], "E": [-0.005644289295161337, -0.003590805930934249, -0.005571467908558669, 0.005804492076371598]}, "5": {"cov": [0.00010416482680137654, 0.00011482245795234696, 0.0001261663455505966, 0.00014942394335213028, 0.00011482245795234696, 0.0001702979030843958, 0.0001797898030368393, 0.0002734908696030544, 0.0001261663455505966, 0.0001797898030368393, 0.0002200977092208945, 0.0003470086072677977, 0.00014942394335213028, 0.0002734908696030544, 0.0003470086072677977, 0.000795518343312656], "E": [-0.004699703989077916, -0.0023047805898772644, -0.0049556585808995385, 0.0044181921094658405]}, "6": {"cov": [0.0001344829043088175, 0.0001383615089370697, 0.000139993988986619, 0.00016487266771674948, 0.0001383615089370697, 0.00017471977250511987, 0.000177206146815398, 0.0002412620234405377, 0.000139993988986619, 0.000177206146815398, 0.0002090565100871489, 0.0003055536859565442, 0.00016487266771674948, 0.0002412620234405377, 0.0003055536859565442, 0.0007254789066994693], "E": [-0.0035884884202487255, -0.0015532353630857976, -0.00325664549069285, 0.0050077149623969225]}, "7": {"cov": [0.00016461748811064832, 0.00016491107480463404, 0.00016530563102226233, 0.00014881221526321064, 0.00016491107480463404, 0.00021752851382051652, 0.00022598947532672143, 0.00027035283680706, 0.00016530563102226233, 0.00022598947532672143, 0.00027034122876120015, 0.0003457147737346456, 0.00014881221526321064, 0.00027035283680706, 0.0003457147737346456, 0.0007687585822421578], "E": [-0.0002912459942883, 0.0008485548390226583, -0.0024318621614338037, 0.001899663214076669]}, "8": {"cov": [0.00019450765369616674, 0.00020590167741423422, 0.00022177185491208538, 0.0001978082063387848, 0.00020590167741423422, 0.0002593334161364615, 0.00028131002035640656, 0.000313646158459395, 0.00022177185491208538, 0.00028131002035640656, 0.0003290116120668416, 0.0003889511396052844, 0.0001978082063387848, 0.000313646158459395, 0.0003889511396052844, 0.000755617795079498], "E": [-0.0041258685634646824, -0.0028091689270944853, -0.00710316122876118, -0.005231812019836107]}, "9": {"cov": [0.00021438115047887294, 0.00023722993036666128, 0.0002619509989542971, 0.00025829554887660976, 0.00023722993036666128, 0.000299816311103688, 0.00032798815842448884, 0.0003774070151898125, 0.0002619509989542971, 0.00032798815842448884, 0.0003839784855631859, 0.00044106005753171286, 0.00025829554887660976, 0.0003774070151898125, 0.00044106005753171286, 0.0007215728262100218], "E": [-0.005448782905178626, -0.0055096354795471925, -0.009857465048871902, -0.005139269765413394]}, "10": {"cov": [0.0001583561904034455, 0.00017066437928500922, 0.00018193782702831656, 0.00014862803147762903, 0.00017066437928500922, 0.00021302891078657407, 0.00022249483157948155, 0.00022619029496556543, 0.00018193782702831656, 0.00022249483157948155, 0.00025582565984013674, 0.0002619700259056647, 0.00014862803147762903, 0.00022619029496556543, 0.0002619700259056647, 0.0005758664320101], "E": [-0.004427801113429622, -0.005568671212264058, -0.009760496806952203, -0.007009419322796504]}, "11": {"cov": [0.0001972064556568658, 0.00021082095450504452, 0.0002176437100921876, 0.00015209100385553712, 0.00021082095450504452, 0.00025827631605634076, 0.0002655535668404375, 0.00024147033235578447, 0.0002176437100921876, 0.0002655535668404375, 0.00030224891473497773, 0.0002872608651828329, 0.00015209100385553712, 0.00024147033235578447, 0.0002872608651828329, 0.0006440162444361975], "E": [-0.008115458682000476, -0.011195750257015934, -0.012932940213594521, -0.009252209655656651]}, "12": {"cov": [0.00014699491635295124, 0.00015977915862173, 0.00016482684235581135, 0.00011198304780266062, 0.00015977915862173, 0.00020823588336827688, 0.00022087627478533178, 0.00021530527596799414, 0.00016482684235581135, 0.00022087627478533178, 0.0002601890399138882, 0.00029337454159122743, 0.00011198304780266062, 0.00021530527596799414, 0.00029337454159122743, 0.0008180859005928094], "E": [-0.0076631093110374054, -0.011320947005818004, -0.014673116573513334, -0.011878481511042031]}}, "NEA": {"1": {"cov": [9.595420629016278e-05, 0.00010905750300289764, 0.000124155536312874, 0.00011414764980745958, 0.00010905750300289764, 0.00016613159476298303, 0.00019720638865236011, 0.000246541356115502, 0.000124155536312874, 0.00019720638865236011, 0.0002446134360996498, 0.0003251742551336183, 0.00011414764980745958, 0.000246541356115502, 0.0003251742551336183, 0.000617916689724204], "E": [-0.005473010911895809, -0.01094074896362418, -0.014323878059365941, -0.008059966134755583]}, "2": {"cov": [0.00010979762931174309, 0.00013343844957410244, 0.00013972235520170266, 0.00010387321933726199, 0.00013343844957410244, 0.00018123497454176806, 0.00019604076787416746, 0.00019410924260637963, 0.00013972235520170266, 0.00019604076787416746, 0.00021934238952187813, 0.00024107099358007108, 0.00010387321933726199, 0.00019410924260637963, 0.00024107099358007108, 0.00048108282308386634], "E": [-0.0029272683444763886, -0.010461907447165977, -0.014384372794208622, -0.015969855145700033]}, "3": {"cov": [7.304181575831124e-05, 8.860169465728328e-05, 9.691561722294355e-05, 9.469276819875254e-05, 8.860169465728328e-05, 0.00013120528535768406, 0.00015023272800170117, 0.00018645849149001497, 9.691561722294355e-05, 0.00015023272800170117, 0.00018513660513208216, 0.00025868193621183047, 9.469276819875254e-05, 0.00018645849149001497, 0.00025868193621183047, 0.0005740483463152562], "E": [-0.002734704545509878, -0.0069216005603151, -0.007378811624778804, 0.002512136353419292]}, "4": {"cov": [6.508322786251132e-05, 6.389807718635056e-05, 7.449158843831162e-05, 7.71194780362113e-05, 6.389807718635056e-05, 9.297297829132804e-05, 0.00010407370155747972, 0.00013420074213963136, 7.449158843831162e-05, 0.00010407370155747972, 0.00015610221003515586, 0.0002664414354464118, 7.71194780362113e-05, 0.00013420074213963136, 0.0002664414354464118, 0.0007288091309520131], "E": [-2.1264576772137e-06, -0.0031710909586324595, -0.005506039086872375, -0.00030808821008408704]}, "5": {"cov": [7.896988966004428e-05, 7.494080025600724e-05, 0.00010205962900400247, 0.00011919916978513983, 7.494080025600724e-05, 0.0001238542870103607, 0.0001300515802938824, 0.00015499626594442535, 0.00010205962900400247, 0.0001300515802938824, 0.00018610575926841783, 0.00025759821923160335, 0.00011919916978513983, 0.00015499626594442535, 0.00025759821923160335, 0.0005741162534371042], "E": [0.00020024802923646057, -0.00048406184033764066, -0.002863109808414463, 0.0018449086822235894]}, "6": {"cov": [7.627841533211153e-05, 8.406747702016812e-05, 9.876935991160767e-05, 0.0001112550245100161, 8.406747702016812e-05, 0.00012864528383373184, 0.00014107322700907896, 0.00019613264111569605, 9.876935991160767e-05, 0.00014107322700907896, 0.00019073264818448844, 0.0002793811556432539, 0.0001112550245100161, 0.00019613264111569605, 0.0002793811556432539, 0.0005810576529316201], "E": [-0.0007399432415924889, 4.923913871843211e-05, -0.006781458857584702, -0.00635924446485004]}, "7": {"cov": [0.0001462198099485023, 0.00014747185341003002, 0.00014844276097095523, 7.50969630610511e-05, 0.00014747185341003002, 0.00019187352929584414, 0.00019942559520202326, 0.00018246798071641648, 0.00014844276097095523, 0.00019942559520202326, 0.00023265003501494238, 0.00023638779534185893, 7.50969630610511e-05, 0.00018246798071641648, 0.00023638779534185893, 0.0005509438596204418], "E": [-0.001083547232164181, -0.003019938928541563, -0.007950853371760089, -0.00674300380050066]}, "8": {"cov": [0.0001361105058165792, 0.0001337638448952651, 0.00013384656393895127, 5.8896629540560476e-05, 0.0001337638448952651, 0.00016542916691818192, 0.00017175829866696962, 0.00014547412822671395, 0.00013384656393895127, 0.00017175829866696962, 0.00019641751065625193, 0.00018892424469677622, 5.8896629540560476e-05, 0.00014547412822671395, 0.00018892424469677622, 0.00043912662069687765], "E": [-0.0022915900473463036, -0.004668641617334907, -0.010089971925233573, -0.009789447936231363]}, "9": {"cov": [9.005290892106313e-05, 0.00010670057962363769, 0.0001149437939905057, 0.00010321466228377085, 0.00010670057962363769, 0.0001633244610471664, 0.00017596802833379644, 0.00020173139999357052, 0.0001149437939905057, 0.00017596802833379644, 0.00021968360865119824, 0.0002692864929765143, 0.00010321466228377085, 0.00020173139999357052, 0.0002692864929765143, 0.0005388170118583867], "E": [-0.0057172993499936264, -0.00780510744334649, -0.012229913207428417, -0.012247076432969087]}, "10": {"cov": [8.560966865540227e-05, 0.00010501986154196957, 0.00013422299377674414, 0.0001685780326068506, 0.00010501986154196957, 0.00017387230527690065, 0.00021566881325590936, 0.00029593853223050287, 0.00013422299377674414, 0.00021566881325590936, 0.00029743804149263156, 0.00042509661155633777, 0.0001685780326068506, 0.00029593853223050287, 0.00042509661155633777, 0.0007487858735497112], "E": [-0.00455182193126949, -0.009645803920650828, -0.012923027320137434, -0.01392601069770625]}, "11": {"cov": [7.144398535812703e-05, 7.645762755419275e-05, 8.680296786439346e-05, 9.979064178470279e-05, 7.645762755419275e-05, 0.00013675253078461168, 0.00017070435431833144, 0.00024651661483547643, 8.680296786439346e-05, 0.00017070435431833144, 0.0002352843130138795, 0.0003588454589841933, 9.979064178470279e-05, 0.00024651661483547643, 0.0003588454589841933, 0.0006785391421130198], "E": [-0.005800209783566768, -0.012467480701303588, -0.01615386369954387, -0.015045015669940237]}, "12": {"cov": [4.4044788464562575e-05, 4.015058260569332e-05, 3.9201792856583026e-05, 3.1168938522789246e-05, 4.015058260569332e-05, 8.053105969788034e-05, 9.041803398179612e-05, 0.00011966479742372511, 3.9201792856583026e-05, 9.041803398179612e-05, 0.00011291648435686084, 0.00016070438889969368, 3.1168938522789246e-05, 0.00011966479742372511, 0.00016070438889969368, 0.00032278963947202777], "E": [-0.004917671205216495, -0.014209979355515531, -0.01844633248630005, -0.015507590138466573]}}, "OCE": {"1": {"cov": [0.000134180497719243, 0.00018622026468410885, 0.0002505639669200435, 0.00024086863423125544, 0.00018622026468410885, 0.0002942838635718185, 0.0003899459015918655, 0.00040443636234201716, 0.0002505639669200435, 0.0003899459015918655, 0.0005520126137441356, 0.0006085810286288995, 0.00024086863423125544, 0.00040443636234201716, 0.0006085810286288995, 0.0012002176448229667], "E": [-0.000199816606626331, -0.0007687895464043373, -0.001328070044677783, 0.00774071103303265]}, "2": {"cov": [0.00026895013347743186, 0.00036342597365331933, 0.00048071239289371507, 0.00021682666238775311, 0.00036342597365331933, 0.0005424628187707665, 0.0007053217181920092, 0.00038385233076627966, 0.00048071239289371507, 0.0007053217181920092, 0.0009639902890936044, 0.0005592082255130623, 0.00021682666238775311, 0.00038385233076627966, 0.0005592082255130623, 0.0012223356427106037], "E": [0.0002789067482655769, -0.003131417477790076, -0.0033413465410394375, 0.005696054576396964]}, "3": {"cov": [0.0002569579354430727, 0.0003467640390028045, 0.0004181752298025202, 0.00015119471950653113, 0.0003467640390028045, 0.0005373771441845232, 0.0006504181432447318, 0.00035340419840924073, 0.0004181752298025202, 0.0006504181432447318, 0.0008535949654926921, 0.0005342514217338899, 0.00015119471950653113, 0.00035340419840924073, 0.0005342514217338899, 0.001037082466159978], "E": [0.0014134653788622775, -0.0006676214651127749, -0.0018335655926236816, 0.0096351642479853]}, "4": {"cov": [0.00041715944842544235, 0.0005635314643340565, 0.0007052809771494328, 0.00025141514305109533, 0.0005635314643340565, 0.0008223548346778469, 0.001038821085923969, 0.0005048868510735262, 0.0007052809771494328, 0.001038821085923969, 0.0013637020441044651, 0.0007615600946008545, 0.00025141514305109533, 0.0005048868510735262, 0.0007615600946008545, 0.0011227431197362587], "E": [0.0009793618812517918, -0.0013735234010658487, -0.0010011021687159512, 0.010741714437060575]}, "5": {"cov": [0.00022220507505477693, 0.00027988820397907755, 0.00032326227394549926, -4.790697941295676e-05, 0.00027988820397907755, 0.0003923863780923982, 0.000455042350451909, -1.7469441845045088e-06, 0.00032326227394549926, 0.000455042350451909, 0.0006341605583088453, 0.00012482346235377067, -4.790697941295676e-05, -1.7469441845045088e-06, 0.00012482346235377067, 0.0005285058963300424], "E": [-0.0034885050140176857, -0.007738156513314401, -0.007380603950246919, -0.0029828644506018492]}, "6": {"cov": [0.0002412803398025987, 0.00028908131255077135, 0.0003398647112051173, 7.086667668991062e-06, 0.00028908131255077135, 0.00039525982129346696, 0.0004972009464270424, 0.00014031778901107608, 0.0003398647112051173, 0.0004972009464270424, 0.0007493031896263155, 0.00043458553435813497, 7.086667668991062e-06, 0.00014031778901107608, 0.00043458553435813497, 0.0009959314008141722], "E": [-0.0012378422486822374, -0.005682230227561667, -0.006773204292045608, -0.0030853616443949072]}, "7": {"cov": [0.00021125861648225777, 0.0002643247539688794, 0.0003168522724232801, 3.943072681647999e-05, 0.0002643247539688794, 0.0003691352556049736, 0.0004633569678549672, 0.00015121305036042913, 0.0003168522724232801, 0.0004633569678549672, 0.0006600048366618016, 0.0003635917297490849, 3.943072681647999e-05, 0.00015121305036042913, 0.0003635917297490849, 0.0007651480314765249], "E": [-0.0017706038015762732, -0.006696228686677845, -0.007324406971114368, -0.0015271521205341906]}, "8": {"cov": [0.00017192509511082535, 0.00021816644934994102, 0.0002727843427544211, 0.0001280166036146038, 0.00021816644934994102, 0.0003272690361842399, 0.00043597472242962567, 0.00031473102734084563, 0.0002727843427544211, 0.00043597472242962567, 0.0006620573108077997, 0.0006201741003317354, 0.0001280166036146038, 0.00031473102734084563, 0.0006201741003317354, 0.0011265245889200085], "E": [-0.0009682398273239412, -0.004743513163620483, -0.004332577884151978, 0.005059128235624599]}, "9": {"cov": [0.00022591399469629547, 0.0002773348278449622, 0.000343217060148922, 0.00019243742326671042, 0.0002773348278449622, 0.000384714848855549, 0.0005044459038010173, 0.0003698869961752964, 0.000343217060148922, 0.0005044459038010173, 0.0007542847006432573, 0.0007019672720975436, 0.00019243742326671042, 0.0003698869961752964, 0.0007019672720975436, 0.0012377384088203835], "E": [-0.0006289174858750413, -0.0011806080707603556, -0.0006442373041335367, 0.011486779167665842]}, "10": {"cov": [0.00019250175836708867, 0.00024907947169033065, 0.0003130537745119289, 0.00022133297735736412, 0.00024907947169033065, 0.0003789123332685371, 0.0005099278835241425, 0.0004632157123818842, 0.0003130537745119289, 0.0005099278835241425, 0.0007876661602461957, 0.0008429302861961513, 0.00022133297735736412, 0.0004632157123818842, 0.0008429302861961513, 0.001530111680508485], "E": [-0.00012559476640977563, -8.654330503918284e-05, 0.0009246229117164245, 0.015036245028609882]}, "11": {"cov": [0.0001266619653561041, 0.00015860671361933031, 0.00018236974288028825, 0.00018476046729551382, 0.00015860671361933031, 0.0002524475454040994, 0.00032999253192501514, 0.0004332779266157224, 0.00018236974288028825, 0.00032999253192501514, 0.000522916322057793, 0.0007803898270233489, 0.00018476046729551382, 0.0004332779266157224, 0.0007803898270233489, 0.001521643031873588], "E": [0.002751027330110359, 0.003106605943475435, 0.006388043147487338, 0.01890812058089797]}, "12": {"cov": [0.00010535447455500557, 0.00016051997608195688, 0.00021438651998818655, 0.00029396700173446984, 0.00016051997608195688, 0.00028493642304291007, 0.0003878384665562965, 0.0005559026664483023, 0.00021438651998818655, 0.0003878384665562965, 0.0005732875274054295, 0.0008566820958852823, 0.00029396700173446984, 0.0005559026664483023, 0.0008566820958852823, 0.0014801757384759326], "E": [0.003209745677676623, 0.002889536534942949, 0.0018326001385482876, 0.013865318529628412]}}} -------------------------------------------------------------------------------- /models/FMF/info.txt: -------------------------------------------------------------------------------- 1 | There should be file 'gt_ff_0550nm.nc' in this directory. 2 | You can download the file from: ftp://ftp-projects.zmaw.de/aerocom/climatology/MACv2_2017/550nm_2005/gt_ff_0550nm.nc 3 | -------------------------------------------------------------------------------- /models/LUT/LUTinformation.txt: -------------------------------------------------------------------------------- 1 | The LUT data is based on NASA's Dark Target over land lookup tables (https://darktarget.gsfc.nasa.gov/reference/code). 2 | 3 | To download the LUT model (models/LUT directory) and surface reflectance prior model (models/SurfaceReflectance/2014) 4 | please download the code package from Zenodo (https://doi.org/10.5281/zenodo.1182939) and copy the 5 | contents of these two model directories in the Zenodo package to corresponding BARalgorithm folders. -------------------------------------------------------------------------------- /models/SurfaceReflectance/2014/info.txt: -------------------------------------------------------------------------------- 1 | Surface reflectance prior model is located in this directory. 2 | 3 | To download the LUT model (models/LUT directory) and surface reflectance prior model (models/SurfaceReflectance/2014) 4 | please download the code package from Zenodo (https://doi.org/10.5281/zenodo.1182939) and copy the 5 | contents of these two model directories in the Zenodo package to corresponding BARalgorithm folders. 6 | --------------------------------------------------------------------------------