import ee
import warnings
from box import Box
def _get_expression_map(img, platformDict):
'''Gets the dictionary required for the map parameter in ee.Image.expression() method.
Parameters
----------
img : ee.Image
Image to get the dictionary from.
platformDict : dict
Dictionary retrieved from the _get_platform() method.
Returns
-------
dict
Map dictionary for ee.Image.expression.
'''
def lookupS2(img):
return {
'A': img.select('B1'),
'B': img.select('B2'),
'G': img.select('B3'),
'R': img.select('B4'),
'RE1': img.select('B5'),
'RE2': img.select('B6'),
'RE3': img.select('B7'),
'N' : img.select('B8'),
'RE4': img.select('B8A'),
'WV' : img.select('B9'),
'S1': img.select('B11'),
'S2': img.select('B12')
}
def lookupL8(img):
return {
'A': img.select('B1'),
'B': img.select('B2'),
'G': img.select('B3'),
'R': img.select('B4'),
'N': img.select('B5'),
'S1': img.select('B6'),
'S2': img.select('B7'),
'T1' : img.select('B10'),
'T2': img.select('B11')
}
def lookupL457(img):
return {
'B': img.select('B1'),
'G': img.select('B2'),
'R': img.select('B3'),
'N': img.select('B4'),
'S1': img.select('B5'),
'T1': img.select('B6'),
'S2': img.select('B7')
}
def lookupMOD09GQ(img):
return {
'R': img.select('sur_refl_b01'),
'N': img.select('sur_refl_b02')
}
def lookupMOD09GA(img):
return {
'B': img.select('sur_refl_b03'),
'G': img.select('sur_refl_b04'),
'R': img.select('sur_refl_b01'),
'N': img.select('sur_refl_b02'),
'S1': img.select('sur_refl_b06'),
'S2': img.select('sur_refl_b07')
}
def lookupMCD43A4(img):
return {
'B': img.select('Nadir_Reflectance_Band3'),
'G': img.select('Nadir_Reflectance_Band4'),
'R': img.select('Nadir_Reflectance_Band1'),
'N': img.select('Nadir_Reflectance_Band2'),
'S1': img.select('Nadir_Reflectance_Band6'),
'S2': img.select('Nadir_Reflectance_Band7')
}
lookupPlatform = {
'COPERNICUS/S2': lookupS2,
'LANDSAT/LC08': lookupL8,
'LANDSAT/LE07': lookupL457,
'LANDSAT/LT05': lookupL457,
'LANDSAT/LT04': lookupL457,
'MODIS/006/MOD09GQ': lookupMOD09GQ,
'MODIS/006/MYD09GQ': lookupMOD09GQ,
'MODIS/006/MOD09GA': lookupMOD09GA,
'MODIS/006/MYD09GA': lookupMOD09GA,
'MODIS/006/MOD09Q1': lookupMOD09GQ,
'MODIS/006/MYD09Q1': lookupMOD09GQ,
'MODIS/006/MOD09A1': lookupMOD09GA,
'MODIS/006/MYD09A1': lookupMOD09GA,
'MODIS/006/MCD43A4': lookupMCD43A4
}
if platformDict['platform'] not in list(lookupPlatform.keys()):
raise Exception("Sorry, satellite platform not supported for index computation!")
return lookupPlatform[platformDict['platform']](img)
def _get_indices():
'''Retrieves the dictionary of indices used for the index() method in ee.Image and ee.ImageCollection classes.
Returns
-------
dict
Indices.
'''
vegetationIndices = {
'BNDVI' : {
'formula' : '(N - B)/(N + B)',
'description' : 'Blue Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','B'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=135',
'contributor' : 'davemlz'
},
'CIG' : {
'formula' : '(N / G) - 1.0',
'description' : 'Blue Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','G'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=128',
'contributor' : 'davemlz'
},
'CVI' : {
'formula' : '(N * R) / (G ** 2.0)',
'description' : 'Chlorophyll Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','R','G'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=391',
'contributor' : 'davemlz'
},
'EVI' : {
'formula' : 'g * (N - R) / (N + C1 * R - C2 * B + L)',
'description' : 'Enhanced Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','g','R','C1','C2','B','L'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=16',
'contributor' : 'davemlz'
},
'EVI2' : {
'formula' : 'g * (N - R) / (N + 2.4 * R + L)',
'description' : 'Two-Band Enhanced Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','g','R','L'],
'reference' : 'https://doi.org/10.1016/j.rse.2008.06.006',
'contributor' : 'davemlz'
},
'GARI' : {
'formula' : '(N - (G - (B - R))) / (N - (G + (B - R)))',
'description' : 'Green Atmospherically Resistant Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','G','B','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=363',
'contributor' : 'davemlz'
},
'GBNDVI' : {
'formula' : '(N - (G + B))/(N + (G + B))',
'description' : 'Green-Blue Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','B','G'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=186',
'contributor' : 'davemlz'
},
'GEMI' : {
'formula' : '((2.0*((N ** 2.0)-(R ** 2.0)) + 1.5*N + 0.5*R)/(N + R + 0.5))*(1.0 - 0.25*((2.0 * ((N ** 2.0) - (R ** 2)) + 1.5 * N + 0.5 * R)/(N + R + 0.5)))-((R - 0.125)/(1 - R))',
'description' : 'Global Environment Monitoring Index',
'type' : 'vegetation',
'requires' : ['N','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=25',
'contributor' : 'davemlz'
},
'GLI' : {
'formula' : '(2.0 * G - R - B) / (2.0 * G + R + B)',
'description' : 'Green Leaf Index',
'type' : 'vegetation',
'requires' : ['G','B','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=375',
'contributor' : 'davemlz'
},
'GNDVI' : {
'formula' : '(N - G)/(N + G)',
'description' : 'Green Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','G'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=401',
'contributor' : 'davemlz'
},
'GRNDVI' : {
'formula' : '(N - (G + R))/(N + (G + R))',
'description' : 'Green-Red Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','G','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=185',
'contributor' : 'davemlz'
},
'GVMI' : {
'formula' : '((N + 0.1) - (S2 + 0.02)) / ((N + 0.1) + (S2 + 0.02))',
'description' : 'Global Vegetation Moisture Index',
'type' : 'vegetation',
'requires' : ['N','S2'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=372',
'contributor' : 'davemlz'
},
'MNDVI' : {
'formula' : '(N - S2)/(N + S2)',
'description' : 'Modified Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','S2'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=245',
'contributor' : 'davemlz'
},
'NDVI' : {
'formula' : '(N - R)/(N + R)',
'description' : 'Normalized Difference Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=58',
'contributor' : 'davemlz'
},
'NGRDI' : {
'formula' : '(G - R) / (G + R)',
'description' : 'Normalized Green Red Difference Index',
'type' : 'vegetation',
'requires' : ['G','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=390',
'contributor' : 'davemlz'
},
'RVI' : {
'formula' : 'N / R',
'description' : 'Ratio Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','R'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=72',
'contributor' : 'davemlz'
},
'SAVI' : {
'formula' : '(1.0 + L) * (N - R) / (N + R + L)',
'description' : 'Soil-Adjusted Vegetation Index',
'type' : 'vegetation',
'requires' : ['N','R','L'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=87',
'contributor' : 'davemlz'
},
'VARI' : {
'formula' : '(G - R) / (G + R - B)',
'description' : 'Visible Atmospherically Resistant Index',
'type' : 'vegetation',
'requires' : ['G','R','B'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=356',
'contributor' : 'davemlz'
},
}
burnIndices = {
'BAI' : {
'formula' : '1.0 / ((0.1 - R) ** 2.0 + (0.06 - N) ** 2.0)',
'description' : 'Burned Area Index',
'type' : 'burn',
'requires' : ['N','R'],
'reference' : 'https://digital.csic.es/bitstream/10261/6426/1/Martin_Isabel_Serie_Geografica.pdf',
'contributor' : 'davemlz'
},
'BAIS2' : {
'formula' : '(1.0 - ((RE2 * RE3 * RE4) / R) ** 0.5) * (((S2 - RE4)/(S2 + RE4) ** 0.5) + 1.0)',
'description' : 'Burned Area Index for Sentinel 2',
'type' : 'burn',
'requires' : ['RE2','RE3','RE4','R','S2'],
'reference' : 'https://doi.org/10.3390/ecrs-2-05177',
'contributor' : 'davemlz'
},
'CSIT' : {
'formula' : 'N / (S2 * T1 / 10000.0)',
'description' : 'Char Soil Index Thermal',
'type' : 'burn',
'requires' : ['N','S2','T1'],
'reference' : 'https://doi.org/10.1080/01431160600954704',
'contributor' : 'davemlz'
},
'NBR' : {
'formula' : '(N - S2) / (N + S2)',
'description' : 'Normalized Burn Ratio',
'type' : 'burn',
'requires' : ['N','S2'],
'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=53',
'contributor' : 'davemlz'
},
'NBRT' : {
'formula' : '(N - (S2 * T1 / 10000.0)) / (N + (S2 * T1 / 10000.0))',
'description' : 'Normalized Burn Ratio Thermal',
'type' : 'burn',
'requires' : ['N','S2','T1'],
'reference' : 'https://doi.org/10.1080/01431160500239008',
'contributor' : 'davemlz'
},
'NDVIT' : {
'formula' : '(N - (R * T1 / 10000.0))/(N + (R * T1 / 10000.0))',
'description' : 'Normalized Difference Vegetation Index Thermal',
'type' : 'burn',
'requires' : ['N','R','T1'],
'reference' : 'https://doi.org/10.1080/01431160600954704',
'contributor' : 'davemlz'
},
'SAVIT' : {
'formula' : '(1.0 + L) * (N - (R * T1 / 10000.0)) / (N + (R * T1 / 10000.0) + L)',
'description' : 'Soil-Adjusted Vegetation Index Thermal',
'type' : 'burn',
'requires' : ['N','R','L','T1'],
'reference' : 'https://doi.org/10.1080/01431160600954704',
'contributor' : 'davemlz'
},
}
waterIndices = {
'MNDWI' : {
'formula' : '(G - S1) / (G + S1)',
'description' : 'Modified Normalized Difference Water Index',
'type' : 'water',
'requires' : ['G','S1'],
'reference' : 'https://doi.org/10.1080/01431160600589179',
'contributor' : 'davemlz'
},
'NDWI' : {
'formula' : '(G - N) / (G + N)',
'description' : 'Normalized Difference Water Index',
'type' : 'water',
'requires' : ['G','N'],
'reference' : 'https://doi.org/10.1080/01431169608948714',
'contributor' : 'davemlz'
},
}
snowIndices = {
'NDSI' : {
'formula' : '(G - S1) / (G + S1)',
'description' : 'Normalized Difference Snow Index',
'type' : 'snow',
'requires' : ['G','S1'],
'reference' : 'https://doi.org/10.1109/IGARSS.1994.399618',
'contributor' : 'davemlz'
},
}
droughtIndices = {
'NDDI' : {
'formula' : '(((N - R)/(N + R)) - ((G - N)/(G + N)))/(((N - R)/(N + R)) + ((G - N)/(G + N)))',
'description' : 'Normalized Difference Drought Index',
'type' : 'drought',
'requires' : ['N','R','G'],
'reference' : 'https://doi.org/10.1029/2006GL029127',
'contributor' : 'davemlz'
},
}
kernelIndices = {
'kEVI' : {
'formula' : 'g * (kNN - kNR) / (kNN + C1 * kNR - C2 * kNB + kNL)',
'description' : 'Kernel Enhanced Vegetation Index',
'type' : 'kernel',
'requires' : ['kNN','g','kNR','C1','C2','kNB','kNL'],
'reference' : 'https://doi.org/10.1126/sciadv.abc7447',
'contributor' : 'davemlz'
},
'kNDVI' : {
'formula' : '(kNN - kNR)/(kNN + kNR)',
'description' : 'Kernel Normalized Difference Vegetation Index',
'type' : 'kernel',
'requires' : ['kNN','kNR'],
'reference' : 'https://doi.org/10.1126/sciadv.abc7447',
'contributor' : 'davemlz'
},
'kRVI' : {
'formula' : 'kNN / kNR',
'description' : 'Kernel Ratio Vegetation Index',
'type' : 'kernel',
'requires' : ['kNN','kNR'],
'reference' : 'https://doi.org/10.1126/sciadv.abc7447',
'contributor' : 'davemlz'
},
'kVARI' : {
'formula' : '(kGG - kGR) / (kGG + kGR - kGB)',
'description' : 'Kernel Visible Atmospherically Resistant Index',
'type' : 'kernel',
'requires' : ['kGG','kGR','kGB'],
'reference' : 'https://doi.org/10.1126/sciadv.abc7447',
'contributor' : 'davemlz'
},
}
indices = {**vegetationIndices, **burnIndices, **waterIndices, **snowIndices, **droughtIndices, **kernelIndices}
return indices
def _get_kernel_image(img,lookup,kernel,sigma,a,b):
'''Creates an ee.Image representing a kernel computed on bands [a] and [b].
Parameters
----------
img : ee.Image
Image to compute the kernel on.
lookup : dict
Dictionary retrieved from _get_expression_map().
kernel : str
Kernel to use.
sigma : str | float
Length-scale parameter. Used for kernel = 'RBF'.
a : str
Key of the first band to use.
b : str
Key of the second band to use.
Returns
-------
ee.Image
Kernel image.
'''
if a not in list(lookup.keys()) or b not in list(lookup.keys()):
return None
else:
lookupab = {
'a': lookup[a],
'b': lookup[b]
}
if isinstance(sigma,str):
lookup = {**lookup, **lookupab, 'sigma': img.expression(sigma,lookupab)}
else:
lookup = {**lookup, **lookupab, 'sigma': sigma}
kernels = {
'linear' : 'a * b',
'RBF': 'exp((-1.0 * (a - b) ** 2.0)/(2.0 * sigma ** 2.0))',
'poly': '((a * b) + c) ** p',
}
return img.expression(kernels[kernel],lookup)
def _remove_none_dict(dictionary):
'''Removes elements from a dictionary with None values.
Parameters
----------
dictionary : dict
Returns
-------
dict
Curated dictionary.
'''
newDictionary = dict(dictionary)
for key in dictionary.keys():
if dictionary[key] is None:
del newDictionary[key]
return newDictionary
def _get_kernel_parameters(img,lookup,kernel,sigma):
'''Gets the additional kernel parameters to compute kernel indices.
Parameters
----------
img : ee.Image
Image to compute the kernel parameters on.
lookup : dict
Dictionary retrieved from _get_expression_map().
kernel : str
Kernel to use.
sigma : str | float
Length-scale parameter. Used for kernel = 'RBF'.
Returns
-------
dict
Kernel parameters.
'''
kernelParameters = {
'kNN' : _get_kernel_image(img,lookup,kernel,sigma,'N','N'),
'kNR' : _get_kernel_image(img,lookup,kernel,sigma,'N','R'),
'kNB' : _get_kernel_image(img,lookup,kernel,sigma,'N','B'),
'kNL' : _get_kernel_image(img,lookup,kernel,sigma,'N','L'),
'kGG' : _get_kernel_image(img,lookup,kernel,sigma,'G','G'),
'kGR' : _get_kernel_image(img,lookup,kernel,sigma,'G','R'),
'kGB' : _get_kernel_image(img,lookup,kernel,sigma,'G','B'),
}
return kernelParameters
def _index(self,index,G,C1,C2,L,kernel,sigma,p,c):
'''Computes one or more spectral indices (indices are added as bands) for an image oir image collection.
Parameters
----------
self : ee.Image | ee.ImageCollection
Image to compute indices on. Must be scaled to [0,1]. Check the supported platforms in User Guide > Spectral Indices > Supported Platforms.
index : string | list[string]
Index or list of indices to compute.
G : float
Gain factor. Used just for index = 'EVI'.
C1 : float
Coefficient 1 for the aerosol resistance term. Used just for index = 'EVI'.
C2 : float
Coefficient 2 for the aerosol resistance term. Used just for index = 'EVI'.
L : float
Canopy background adjustment. Used just for index = ['EVI','SAVI'].
kernel : str
Kernel used for kernel indices.
sigma : str | float
Length-scale parameter. Used for kernel = 'RBF'. If str, this must be an expression including 'a' and 'b'. If numeric, this must be positive.
p : float
Kernel degree. Used for kernel = 'poly'.
c : float
Free parameter that trades off the influence of higher-order versus lower-order terms. Used for kernel = 'poly'. This must be greater than or equal to 0.
Returns
-------
ee.Image | ee.ImageCollection
Image (or Image Collection) with the computed spectral index, or indices, as new bands.
'''
platformDict = _get_platform(self)
if isinstance(sigma,int) or isinstance(sigma,float):
if sigma < 0:
raise Exception('[sigma] must be positive!')
if p <= 0 or c < 0:
raise Exception('[p] and [c] must be positive!')
additionalParameters = {
'g': float(G),
'C1': float(C1),
'C2': float(C2),
'L': float(L),
'p': float(p),
'c': float(c)
}
spectralIndices = _get_indices()
indicesNames = list(spectralIndices.keys())
if not isinstance(index, list):
if index == 'all':
index = list(spectralIndices.keys())
elif index in ['vegetation','burn','water','snow','drought','kernel']:
temporalListOfIndices = []
for idx in indicesNames:
if spectralIndices[idx]['type'] == index:
temporalListOfIndices.append(idx)
index = temporalListOfIndices
else:
index = [index]
for idx in index:
if idx not in list(spectralIndices.keys()):
warnings.warn("Index " + idx + " is not a built-in index and it won't be computed!",Warning)
else:
def temporalIndex(img):
lookupDic = _get_expression_map(img, platformDict)
lookupDic = {**lookupDic, **additionalParameters}
kernelParameters = _get_kernel_parameters(img,lookupDic,kernel,sigma)
lookupDic = {**lookupDic, **kernelParameters}
lookupDicCurated = _remove_none_dict(lookupDic)
if all(band in list(lookupDicCurated.keys()) for band in spectralIndices[idx]['requires']):
return img.addBands(img.expression(spectralIndices[idx]['formula'],lookupDicCurated).rename(idx))
else:
warnings.warn("This platform doesn't have the required bands for " + idx + " computation!",Warning)
return img
if isinstance(self,ee.imagecollection.ImageCollection):
self = self.map(temporalIndex)
elif isinstance(self,ee.image.Image):
self = temporalIndex(self)
return self
[docs]def indices():
'''Gets the dictionary of available indices as a Box object.
Returns
-------
Box
Dictionary of available indices. For each index, the keys 'description', 'formula', 'requires', 'reference' and 'contributor' can be checked.
Examples
--------
>>> import eemont
>>> indices = eemont.indices()
>>> indices.BAIS2.description
'Burned Area Index for Sentinel 2'
>>> indices.BAIS2.formula
'(1.0 - ((RE2 * RE3 * RE4) / R) ** 0.5) * (((S2 - RE4)/(S2 + RE4) ** 0.5) + 1.0)'
>>> indices.BAIS2.reference
'https://doi.org/10.3390/ecrs-2-05177'
'''
return Box(_get_indices(),frozen_box = True)
[docs]def listIndices():
'''Gets the list of available indices.
Returns
-------
list
List of available indices.
Examples
--------
>>> import eemont
>>> eemont.listIndices()
['BNDVI','CIG','CVI','EVI','EVI2','GBNDVI','GNDVI',...]
'''
return list(_get_indices().keys())
def _get_platform(args):
'''Gets the platform (satellite) of an image (or image collection) and wheter if it is a Surface Reflectance product.
Parameters
----------
args : ee.Image | ee.ImageCollection
Image to get platform.
Returns
-------
dict
Platform and product of the image (or image collection).
'''
platforms = [
'COPERNICUS/S3',
'COPERNICUS/S2',
'LANDSAT/LC08',
'LANDSAT/LE07',
'LANDSAT/LT05',
'LANDSAT/LT04',
'MODIS/006/MCD43A4',
'MODIS/006/MCD43A3',
'MODIS/006/MOD09GQ',
'MODIS/006/MOD10A1',
'MODIS/006/MOD11A1',
'MODIS/006/MOD09GA',
'MODIS/006/MODOCGA',
'MODIS/006/MOD14A1',
'MODIS/006/MCD43A1',
'MODIS/006/MCD15A3H',
'MODIS/006/MOD09Q1',
'MODIS/006/MOD09A1',
'MODIS/006/MOD11A2',
'MODIS/006/MOD17A2H',
'MODIS/006/MOD16A2',
'MODIS/006/MOD13Q1',
'MODIS/006/MOD13A1',
'MODIS/006/MOD13A2',
'MODIS/061/MOD08_M3',
'MODIS/006/MOD17A3HGF',
'MODIS/006/MYD09GQ',
'MODIS/006/MYD10A1',
'MODIS/006/MYD11A1',
'MODIS/006/MYD09GA',
'MODIS/006/MYDOCGA',
'MODIS/006/MYD14A1',
'MODIS/006/MYD09Q1',
'MODIS/006/MYD09A1',
'MODIS/006/MYD11A2',
'MODIS/006/MYD17A2H',
'MODIS/006/MYD13Q1',
'MODIS/006/MYD13A1',
'MODIS/006/MYD13A2',
'MODIS/061/MYD08_M3',
'MODIS/006/MYD17A3HGF'
]
if isinstance(args, ee.imagecollection.ImageCollection):
imgID = args.first().get('system:id').getInfo()
elif isinstance(args, ee.image.Image):
imgID = args.get('system:id').getInfo()
else:
raise Exception("Sorry, just ee.Image or ee.ImageCollection classes supported!")
plt = None
for platform in platforms:
if platform in imgID:
plt = platform
if '_SR' in imgID:
platformDict = {'platform': plt, 'sr': True}
else:
platformDict = {'platform': plt, 'sr': False}
if plt is None:
raise Exception("Sorry, satellite platform not supported!")
return platformDict
def _get_scale_method(platformDict):
'''Gets the scale algorithms for the scale() method in ee.Imge and ee.ImageCollection.
Parameters
----------
platformDict : dict
Dictionary retrieved from the _get_platform() method.
Returns
-------
dict
Lookup dictionary for scale algorithms.
'''
def S3(img):
scalars = [
0.0139465,
0.0133873,
0.0121481,
0.0115198,
0.0100953,
0.0123538,
0.00879161,
0.00876539,
0.0095103,
0.00773378,
0.00675523,
0.0071996,
0.00749684,
0.0086512,
0.00526779,
0.00530267,
0.00493004,
0.00549962,
0.00502847,
0.00326378,
0.00324118
]
scaled = img.select(['Oa.*']).multiply(scalars).addBands(img.select('quality_flags'))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def S2(img):
scaled = img.select(['B.*']).divide(1e4)
scaled = scaled.addBands(img.select(['Q.*']))
if platformDict['sr']:
scaled = scaled.addBands(img.select(['AOT','WVP']).divide(1e3))
scaled = scaled.addBands(img.select(['T.*']))
scaled = scaled.addBands(img.select('SCL'))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def L8(img):
if platformDict['sr']:
scaled = img.select(['B[1-9]']).divide(1e4)
scaled = scaled.addBands(img.select(['B10','B11']).divide(10))
scaled = scaled.addBands(img.select(['sr_aerosol','pixel_qa','radsat_qa']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
else:
warnings.warn("TOA reflectance for Landsat 8 is already scaled!",Warning)
pass
def L457(img):
if platformDict['sr']:
scaled = img.select(['B[1-5]','B7']).divide(1e4)
scaled = scaled.addBands(img.select(['B6']).divide(10))
scaled = scaled.addBands(img.select(['sr_atmos_opacity']).divide(1e3))
scaled = scaled.addBands(img.select(['sr_cloud_qa','pixel_qa','radsat_qa']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
else:
warnings.warn("TOA reflectance for Landsat 4, 5 and 7 is already scaled!",Warning)
pass
def MCD43A4(img):
scaled = img.select(['Nadir.*']).divide(1e4)
scaled = scaled.addBands(img.select(['BRDF.*']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MCD43A3(img):
scaled = img.select(['Albedo.*']).divide(1e3)
scaled = scaled.addBands(img.select(['BRDF.*']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD09GQ(img):
scaled = img.select(['sur.*']).divide(1e4)
scaled = scaled.addBands(img.select(['obscov']).divide(100))
scaled = scaled.addBands(img.select(['num_observations','QC_250m','iobs_res','orbit_pnt','granule_pnt']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD10A1(img):
scaled = img.select(['NDSI']).divide(1e4)
scaled = scaled.addBands(img.select(['NDSI_Snow.*']))
scaled = scaled.addBands(img.select(['Snow.*']))
scaled = scaled.addBands(img.select(['orbit_pnt','granule_pnt']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD11A1(img):
scaled = img.select(['LST.*']).multiply(0.02)
scaled = scaled.addBands(img.select(['Day_view_time','Night_view_time']).multiply(0.1))
scaled = scaled.addBands(img.select(['Emis.*']).multiply(0.002))
scaled = scaled.addBands(img.select(['Clear.*']).multiply(0.0005))
scaled = scaled.addBands(img.select(['QC_Day','Day_view_angle','QC_Night','Night_view_angle']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD09GA(img):
scaled = img.select(['sur.*']).multiply(0.0001)
scaled = scaled.addBands(img.select(['Sensor.*']).multiply(0.01))
scaled = scaled.addBands(img.select(['Solar.*']).multiply(0.01))
scaled = scaled.addBands(img.select(['Range']).multiply(25))
scaled = scaled.addBands(img.select(['num_observations_1km','state_1km','gflags','orbit_pnt','granule_pnt','num_observations_500m','QC_500m','obscov_500m','iobs_res','q_scan']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MODOCGA(img):
scaled = img.select(['sur.*']).multiply(0.0001)
scaled = scaled.addBands(img.select(['num_observations','orbit_pnt','granule_pnt']))
scaled = scaled.addBands(img.select(['QC.*']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD14A1(img):
scaled = img.select(['MaxFRP']).multiply(0.1)
scaled = scaled.addBands(img.select(['FireMask','sample','QA']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MCD43A1(img):
scaled = img.select(['BRDF_Albedo_Parameters.*']).multiply(0.001)
scaled = scaled.addBands(img.select(['BRDF_Albedo_Band.*']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MCD15A3H(img):
scaled = img.select(['Fpar','FparStdDev']).multiply(0.01)
scaled = scaled.addBands(img.select(['Lai','LaiStdDev']).multiply(0.1))
scaled = scaled.addBands(img.select(['FparLai_QC','FparExtra_QC']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD09Q1(img):
scaled = img.select(['sur.*']).divide(1e4)
scaled = scaled.addBands(img.select(['State','QA']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD09A1(img):
scaled = img.select(['sur.*']).divide(1e4)
scaled = scaled.addBands(img.select(['SolarZenith','ViewZenith','RelativeAzimuth']).multiply(0.01))
scaled = scaled.addBands(img.select(['QA','StateQA','DayOfYear']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD11A2(img):
scaled = img.select(['LST.*']).multiply(0.02)
scaled = scaled.addBands(img.select(['Day_view_time','Night_view_time']).multiply(0.1))
scaled = scaled.addBands(img.select(['Emis.*']).multiply(0.002).add(0.49))
scaled = scaled.addBands(img.select(['Day_view_angl','Night_view_angl']).subtract(65))
scaled = scaled.addBands(img.select(['QC_Day','QC_Night','Clear_sky_days','Clear_sky_nights']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD17A2H(img):
scaled = img.select(['Gpp','PsnNet']).multiply(0.0001)
scaled = scaled.addBands(img.select(['Psn_QC']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD16A2(img):
scaled = img.select(['ET','PET']).multiply(0.1)
scaled = scaled.addBands(img.select(['LE','PLE']).multiply(0.0001))
scaled = scaled.addBands(img.select(['ET_QC']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD13Q1(img):
scaled = img.select(['NDVI','EVI']).multiply(0.0001)
scaled = scaled.addBands(img.select(['sur.*']).multiply(0.0001))
scaled = scaled.addBands(img.select(['ViewZenith','SolarZenith','RelativeAzimuth']).multiply(0.01))
scaled = scaled.addBands(img.select(['DetailedQA','DayOfYear','SummaryQA']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD13A1(img):
scaled = img.select(['NDVI','EVI']).multiply(0.0001)
scaled = scaled.addBands(img.select(['sur.*']).multiply(0.0001))
scaled = scaled.addBands(img.select(['ViewZenith','SolarZenith','RelativeAzimuth']).multiply(0.01))
scaled = scaled.addBands(img.select(['DetailedQA','DayOfYear','SummaryQA']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD13A2(img):
scaled = img.select(['NDVI','EVI']).multiply(0.0001)
scaled = scaled.addBands(img.select(['sur.*']).multiply(0.0001))
scaled = scaled.addBands(img.select(['ViewZenith','SolarZenith','RelativeAzimuth']).multiply(0.01))
scaled = scaled.addBands(img.select(['DetailedQA','DayOfYear','SummaryQA']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD08_M3(img):
scaled = img.select(['Aerosol.*']).multiply(0.001)
scaled = scaled.addBands(img.select(['Cirrus.*']).multiply(0.0001))
scaled = scaled.addBands(img.select(['Cloud_Optical_Thickness_Liquid_Log.*']).multiply(0.001))
scaled = scaled.addBands(img.select(['Cloud_Optical_Thickness_Liquid_Mean_Uncertainty']).multiply(0.01))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
def MOD17A3HGF(img):
scaled = img.select(['Npp']).multiply(0.0001)
scaled = scaled.addBands(img.select(['Npp_QC']))
return ee.Image(scaled.copyProperties(img,img.propertyNames()))
lookup = {
'COPERNICUS/S3': S3,
'COPERNICUS/S2': S2,
'LANDSAT/LC08': L8,
'LANDSAT/LE07': L457,
'LANDSAT/LT05': L457,
'LANDSAT/LT04': L457,
'MODIS/006/MCD43A4': MCD43A4,
'MODIS/006/MCD43A3': MCD43A3,
'MODIS/006/MOD09GQ': MOD09GQ,
'MODIS/006/MOD10A1': MOD10A1,
'MODIS/006/MOD11A1': MOD11A1,
'MODIS/006/MOD09GA': MOD09GA,
'MODIS/006/MODOCGA': MODOCGA,
'MODIS/006/MOD14A1': MOD14A1,
'MODIS/006/MCD43A1': MCD43A1,
'MODIS/006/MCD15A3H': MCD15A3H,
'MODIS/006/MOD09Q1': MOD09Q1,
'MODIS/006/MOD09A1': MOD09A1,
'MODIS/006/MOD11A2': MOD11A2,
'MODIS/006/MOD17A2H': MOD17A2H,
'MODIS/006/MOD16A2': MOD16A2,
'MODIS/006/MOD13Q1': MOD13Q1,
'MODIS/006/MOD13A1': MOD13A1,
'MODIS/006/MOD13A2': MOD13A2,
'MODIS/061/MOD08_M3': MOD08_M3,
'MODIS/006/MOD17A3HGF': MOD17A3HGF,
'MODIS/006/MYD09GQ': MOD09GQ,
'MODIS/006/MYD10A1': MOD10A1,
'MODIS/006/MYD11A1': MOD11A1,
'MODIS/006/MYD09GA': MOD09GA,
'MODIS/006/MYDOCGA': MODOCGA,
'MODIS/006/MYD14A1': MOD14A1,
'MODIS/006/MYD09Q1': MOD09Q1,
'MODIS/006/MYD09A1': MOD09A1,
'MODIS/006/MYD11A2': MOD11A2,
'MODIS/006/MYD17A2H': MOD17A2H,
'MODIS/006/MYD13Q1': MOD13Q1,
'MODIS/006/MYD13A1': MOD13A1,
'MODIS/006/MYD13A2': MOD13A2,
'MODIS/061/MYD08_M3': MOD08_M3,
'MODIS/006/MYD17A3HGF': MOD17A3HGF
}
return lookup