Landsat 8 and 9 (from USGS)

Description

Landsat 8 and 9 images are optical and thermal images measured every 8 days, with a resolution of 30 meters. Supported images and levels are:

Optical

Thermal

Level 1

Level 2

These images are available to download here. Additional information can be found here and here for level 2 products and here for level 1 products.

Usage

To use these images as iota2 input two ways are available:

General sensor

The simplest way is to use one general sensor, called Landsat8USGS. It uses all provided images and processes them identically. chain.l8_usgs_path is the parameter to enable the use of Landsat 8 and 9 products by iota2.

chain:
{
    ...
    l8_usgs_path:"/absolute/path/to/Storage_directory"
    ...
}

Warning

While simpler to use, this method may introduce processing errors, due to the differing nature of the images: thermal images shouldn’t be processed exactly like optical images.

Differentiated sensors

The ideal way of dealing with Landsat 8 and 9 images is using multiple sensors, one for each type of supported images:

chain:
{
    ...
    l8_usgs_optical_path:"/absolute/path/to/Storage_directory_optical"
    l8_usgs_thermal_path:"/absolute/path/to/Storage_directory_thermal"
    l8_usgs_infrared_path:"/absolute/path/to/Storage_directory_infrared"
    ...
}

With:

Optical:

Level 2 optical products (bands 1 to 7): ["B1", "B2", "B3", "B4", "B5", "B6", "B7"]

Thermal:

Level 2 thermal product (band 10) and emissivity map: ["B10", "EMIS"]

Warning

The use of the emissivity is supported but not activated by default, as it doesn’t seem to add pertinent information.

Infrared:

Level 1 thermal products (bands 11 and 12): ["B10", "B11"]

Image files can be stored either across multiple different directories or within a single directory (much simpler solution):

└── Storage_directory
    ├── tile199029
    │   ├── LC08_L2SP_199029_20230309_20230320_02_T1
    │   │   ├── LC08_L2SP_199029_20230309_20230320_02_T1_SR_B1.TIF  # Level 2, band 1 (optical)
    │   │   ├── LC08_L2SP_199029_20230309_20230320_02_T1_ST_B10.TIF  # Level 2, band 10 (LST)
    │   │   ├── LC08_L1TP_199029_20230309_20230320_02_T1_B10.TIF  # Level 1, band 10 (infrared)
    │   │   ├── ...
    │   │   └── *.tif
    │   ├── LC08_L2SP_199029_20230325_20230404_02_T1
    │   │   └── *.tif
    │   └── ...
    ├── tile199030
    │   └── ...
    └── ...

Note

Each sensor has a dedicated section in the configuration file, each containing three parameters:

  • keep_bands: selects which band(s)/product(s) to use

  • enable_sensor_gapfilling: enables or disables temporal gapfilling (useful for thermal and IR images)

  • temporal_resolution: sets the resolution for the gapfilling

Example:

chain:
{
    ...
}
Landsat8_usgs_thermal:
{
    temporal_resolution = 16
    keep_bands = ["B2", "B3", "B4", "B7"]
    enable_sensor_gapfilling = True
}
Landsat8_usgs_thermal:
{
    temporal_resolution = 16
    keep_bands = ["B10", "EMIS"]
    enable_sensor_gapfilling = False
}
Landsat8_usgs_infrared:
{
    temporal_resolution = 16
    enable_sensor_gapfilling = False
}...

Required images

In order to run using a landsat 8 sensor, the chain also requires at least 3 masks (included in downloadable products):

  • Cloud mask, called QA_PIXEL (pixel quality assessment)

  • Saturation mask, called QA_RADSAT (radiometric saturation quality assessment)

  • Metadata file, called MTL

Usage with other sensors

It is also possible to use this (these) sensor(s) with other ones available in iota2 (i.e. Sentinel-2). Sentinel-2 and Landsat 8/9 data (provided by the USGS) use different tiling systems, so you first need to use a specific builder in order to re-tile one of the two datasets you are using. The process (for one tile) is the following:

  1. Download landsat and sentinel images

  2. Use iota2’s tiler builder (to the builder’s documentation for more details) with a first configuration file:

chain :
{
  output_path : '/path/to/tiled/images'
  first_step : 'tiler'
  last_step : 'tiler'
  proj : 'EPSG:2154'
  rasters_grid_path : '/path/to/reference/images'
  list_tile : 'T30TXQ'
  features_path : '/path/to/images/to/be/tiled/'
  spatial_resolution : 10 # mandatory but not used in this case. The output spatial resolution will be the one found in 'rasters_grid_path' directory.
}

builders:
{
  builders_class_name : ["I2FeaturesToGrid"]
}
  1. Place the images as expected by iota2. Images from different sensors don’t need to be in the same directory, but need to be in a directory with the same name, corresponding to the tile. For example:

├── landsat_data
│   └── T30TXQ # tile (common name for all sensors)
│       ├── LC08_L2SP_199029_20230309_20230320_02_T1 # date 1 directory
│       │   ├── LC08_L2SP_199029_20230309_20230320_02_T1_SR_B1.TIF
│       │   ├── LC08_L2SP_199029_20230309_20230320_02_T1_ST_B10.TIF
│       │   └── ...
│       ├── LC08_L2SP_199029_20230325_20230404_02_T1 # date 2 directory
│       │   └── *.tif
│       └── ...
└── sentinel_data
    └── T30TXQ # tile (common name for all sensors)
        ├── SENTINEL2A_20230217-110844-292_L2A_T30TXQ_D_V3-1 # date 1 directory
        │   ├── MASKS
        │   │   └──  SENTINEL2A_20230217-110844-292_L2A_T30TXQ_D_V3-1_*.tif
        │   ├── SENTINEL2A_20230217-110844-292_L2A_T30TXQ_D_V3-1_FRE_B*.tif
        │   ├── SENTINEL2A_20230217-110844-292_L2A_T30TXQ_D_V3-1_FRE_STACK.tif
        │   └── ...
        ├── SENTINEL2B_20230304-110849-778_L2A_T30TXQ_D_V3-1
        │   └── *.tif
        └── ...
  1. Run iota2 as usual, with two sensors. For example, in order to use thermal images from Landsat 8 and optical images from Sentinel-2:

chain :
{
  output_path : '/path/to/output/'
  remove_output_path : True
  nomenclature_path : '/path/to/file'
  list_tile : 'T30TXQ'
  l8_usgs_thermal_path = '/path/to/landsat/images/'
  s2_path : '/path/to/sentinel/images/'
  ground_truth : '/path/to/file'
  data_field : 'id'
  spatial_resolution : 10
  color_table : '/path/to/file'
  proj : 'EPSG:32630'
  first_step: "init"
  last_step: "validation"
}
arg_train :
{
  classifier : 'sharkrf'
  otb_classifier_options : {"classifier.sharkrf.nbtrees" : 100 }
  sample_selection: {"sampler": "random",
  "strategy": "percent",
  "strategy.percent.p": 0.1}
  random_seed: 1234
}
arg_classification :
{
  classif_mode : 'separate'
}
sensors_data_interpolation :
{
  write_outputs: False
}