colab Open in SageMaker Studio Lab Open in Planetary Computer

Scaling and Offsetting ANY RASTER DATASET From the GEE STAC

Tutorial created by **David Montero Loaiza**: GitHub | Twitter

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