Scaling and Offsetting ANY RASTER DATASET From the GEE STAC
Tutorial created by **David Montero Loaiza**: GitHub | Twitter
GitHub Repo: https://github.com/davemlz/eemont
PyPI link: https://pypi.org/project/eemont/
Conda-forge: https://anaconda.org/conda-forge/eemont
Documentation: https://eemont.readthedocs.io/
More tutorials: https://github.com/davemlz/eemont/tree/master/docs/tutorials
Let’s start!
If required, please uncomment:
[1]:
#!pip install eemont
#!pip install geemap
Import the required packages.
[2]:
import ee, eemont, geemap
import geemap.colormaps as cm
Authenticate and Initialize Earth Engine and geemap.
[3]:
Map = geemap.Map()
Let’s define a point of interest:
[4]:
poi = ee.Geometry.PointFromQuery("Argel, Algeria",user_agent = "eemont-tutorial-015")
Let’s try 5 different datasets:
[5]:
S2 = ee.ImageCollection("COPERNICUS/S2_SR").filterBounds(poi)
L8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR").filterBounds(poi)
MOD11A2 = ee.ImageCollection("MODIS/006/MOD11A2").filterBounds(poi)
WAPOR_ET = ee.ImageCollection("FAO/WAPOR/2/L1_AETI_D").filterBounds(poi)
NOAA_OCEAN_SURF_TEMP = ee.ImageCollection("NOAA/CDR/OISST/V2_1").filterBounds(poi)
Check the SCALE parameters
In order to check the SCALE parameters of any raster dataset (ee.Image or ee.ImageCollection), use the getScaleParams:
[6]:
S2.getScaleParams()
[6]:
{'AOT': 0.001,
'B1': 0.0001,
'B11': 0.0001,
'B12': 0.0001,
'B2': 0.0001,
'B3': 0.0001,
'B4': 0.0001,
'B5': 0.0001,
'B6': 0.0001,
'B7': 0.0001,
'B8': 0.0001,
'B8A': 0.0001,
'B9': 0.0001,
'MSK_CLDPRB': 1.0,
'MSK_SNWPRB': 1.0,
'QA10': 1.0,
'QA20': 1.0,
'QA60': 1.0,
'SCL': 1.0,
'TCI_B': 1.0,
'TCI_G': 1.0,
'TCI_R': 1.0,
'WVP': 0.001}
The getScaleParams will retrieve a dictionary where each key is each of the bands of the datasets and the value is the scale factor for that band.
The getScaleParams method also works for ee.Image classes:
[7]:
S2.first().getScaleParams()
[7]:
{'AOT': 0.001,
'B1': 0.0001,
'B11': 0.0001,
'B12': 0.0001,
'B2': 0.0001,
'B3': 0.0001,
'B4': 0.0001,
'B5': 0.0001,
'B6': 0.0001,
'B7': 0.0001,
'B8': 0.0001,
'B8A': 0.0001,
'B9': 0.0001,
'MSK_CLDPRB': 1.0,
'MSK_SNWPRB': 1.0,
'QA10': 1.0,
'QA20': 1.0,
'QA60': 1.0,
'SCL': 1.0,
'TCI_B': 1.0,
'TCI_G': 1.0,
'TCI_R': 1.0,
'WVP': 0.001}
If a band doesn’t have a scale factor, this will be retrieved as 1.
Now, let’s check the scale parameters for the rest of the datasets:
[8]:
L8.getScaleParams()
[8]:
{'B1': 0.0001,
'B10': 0.1,
'B11': 0.1,
'B2': 0.0001,
'B3': 0.0001,
'B4': 0.0001,
'B5': 0.0001,
'B6': 0.0001,
'B7': 0.0001,
'pixel_qa': 1.0,
'radsat_qa': 1.0,
'sr_aerosol': 1.0}
[9]:
MOD11A2.getScaleParams()
[9]:
{'Clear_sky_days': 1.0,
'Clear_sky_nights': 1.0,
'Day_view_angl': 1.0,
'Day_view_time': 0.1,
'Emis_31': 0.002,
'Emis_32': 0.002,
'LST_Day_1km': 0.02,
'LST_Night_1km': 0.02,
'Night_view_angl': 1.0,
'Night_view_time': 0.1,
'QC_Day': 1.0,
'QC_Night': 1.0}
[10]:
WAPOR_ET.getScaleParams()
[10]:
{'L1_AETI_D': 0.1}
[11]:
NOAA_OCEAN_SURF_TEMP.getScaleParams()
[11]:
{'anom': 0.01, 'err': 0.01, 'ice': 0.01, 'sst': 0.01}
Check the OFFSET parameters
In order to check the OFFSET parameters of any raster dataset (ee.Image or ee.ImageCollection), use the getOffsetParams:
[12]:
S2.getOffsetParams()
[12]:
{'AOT': 0.0,
'B1': 0.0,
'B11': 0.0,
'B12': 0.0,
'B2': 0.0,
'B3': 0.0,
'B4': 0.0,
'B5': 0.0,
'B6': 0.0,
'B7': 0.0,
'B8': 0.0,
'B8A': 0.0,
'B9': 0.0,
'MSK_CLDPRB': 0.0,
'MSK_SNWPRB': 0.0,
'QA10': 0.0,
'QA20': 0.0,
'QA60': 0.0,
'SCL': 0.0,
'TCI_B': 0.0,
'TCI_G': 0.0,
'TCI_R': 0.0,
'WVP': 0.0}
The getOffsetParams will retrieve a dictionary where each key is each of the bands of the datasets and the value is the offset factor for that band.
The getOffsetParams method also works for ee.Image classes:
[13]:
S2.first().getOffsetParams()
[13]:
{'AOT': 0.0,
'B1': 0.0,
'B11': 0.0,
'B12': 0.0,
'B2': 0.0,
'B3': 0.0,
'B4': 0.0,
'B5': 0.0,
'B6': 0.0,
'B7': 0.0,
'B8': 0.0,
'B8A': 0.0,
'B9': 0.0,
'MSK_CLDPRB': 0.0,
'MSK_SNWPRB': 0.0,
'QA10': 0.0,
'QA20': 0.0,
'QA60': 0.0,
'SCL': 0.0,
'TCI_B': 0.0,
'TCI_G': 0.0,
'TCI_R': 0.0,
'WVP': 0.0}
If a band doesn’t have an offset factor, this will be retrieved as 0.
Now, let’s check the offset parameters for the rest of the datasets:
[14]:
L8.getOffsetParams()
[14]:
{'B1': 0.0,
'B10': 0.0,
'B11': 0.0,
'B2': 0.0,
'B3': 0.0,
'B4': 0.0,
'B5': 0.0,
'B6': 0.0,
'B7': 0.0,
'pixel_qa': 0.0,
'radsat_qa': 0.0,
'sr_aerosol': 0.0}
[15]:
MOD11A2.getOffsetParams()
[15]:
{'Clear_sky_days': 0.0,
'Clear_sky_nights': 0.0,
'Day_view_angl': -65.0,
'Day_view_time': 0.0,
'Emis_31': 0.49,
'Emis_32': 0.49,
'LST_Day_1km': 0.0,
'LST_Night_1km': 0.0,
'Night_view_angl': -65.0,
'Night_view_time': 0.0,
'QC_Day': 0.0,
'QC_Night': 0.0}
Most datasets have no offset factors, however, in some cases (e.g. MOD11A2), these can be found.
[16]:
WAPOR_ET.getOffsetParams()
[16]:
{'L1_AETI_D': 0.0}
[17]:
NOAA_OCEAN_SURF_TEMP.getOffsetParams()
[17]:
{'anom': 0.0, 'err': 0.0, 'ice': 0.0, 'sst': 0.0}
Automatic Scaling and Offsetting
The automatic scaling and offsetting can be achieved by running the scaleAndOffset method for ee.Image and ee.ImageCollection classes (This method replaces the scale method):
[18]:
S2 = S2.scaleAndOffset()
L8 = L8.scaleAndOffset()
MOD11A2 = MOD11A2.scaleAndOffset()
WAPOR_ET = WAPOR_ET.scaleAndOffset()
NOAA_OCEAN_SURF_TEMP = NOAA_OCEAN_SURF_TEMP.scaleAndOffset()
Visualization parameters:
[19]:
reflectance_RGB_vis = {
"min": 0,
"max": 0.3,
"bands": ["B4","B3","B2"]
}
Kelvin_LST_vis = {
"min": 280,
"max": 320,
"bands": "LST_Day_1km",
"palette": cm.palettes.inferno
}
mm_ET_vis = {
"min": 0,
"max": 5,
"bands": "L1_AETI_D",
"palette": cm.palettes.Blues
}
Celsius_OST_vis = {
"min": -1.8,
"max": 30,
"bands": "sst",
"palette": cm.palettes.inferno
}
Let’s visualize everything with geemap:
[20]:
Map = geemap.Map()
Map.addLayer(S2.first(),reflectance_RGB_vis,"S2 RGB (SR)")
Map.addLayer(L8.first(),reflectance_RGB_vis,"L8 RGB (SR)")
Map.addLayer(MOD11A2.first(),Kelvin_LST_vis,"MOD11A2 LST Day (Kelvin)")
Map.addLayer(WAPOR_ET.first(),mm_ET_vis,"WAPOR ET (mm)")
Map.addLayer(NOAA_OCEAN_SURF_TEMP.first(),Celsius_OST_vis,"NOAA OST (Celsius)")
Map.centerObject(poi,6)
Map