Pixxel

Product Classification Layer

Overview

The Product Classification Layer (PCL) identifies surface and atmospheric conditions within the data product. It uses a bit mask approach to categorise individual pixels, which keeps the classification data compact and easy to query.

The PCL is delivered as part of every product package, as the file ..._PCL.tif. The file is a single-band GeoTIFF on the same grid as the image raster, with the same UTM projection, extent and pixel size. Each PCL pixel therefore corresponds directly to the pixel at the same row and column of the image raster.

Data Structure and Encoding

The classification data is encoded as a 16-bit unsigned integer (uint16). Within this integer, each bit position corresponds to a specific surface or atmospheric condition.

The values are additive: a single pixel value can represent several simultaneous conditions, because the individual flags are combined through bitwise operations.

Classification Flags

The PCL defines specific bit values for various conditions. The integer value 0 is reserved for pixels containing no valid data. It is also the no-data value of the GeoTIFF, and it coincides with the no-data pixels of the image raster.

NameBit ValueBit PositionDescription
NODATA0-Pixel contains no valid data
LAND10Pixel is classified as land
WATER21Pixel is classified as water
CLOUD42Pixel is covered by cloud
CLDSDW83Pixel is under cloud shadow1
CLDEDG164Pixel is at the edge of a cloud
-32 – 10245 – 10Reserved
SNWICE204811Pixel is covered by snow or ice

1 Cloud shadow is not detected by the classification model currently used for Firefly (FF01–FF03) images, so this flag is not set in their PCL.

Bits 5 to 10 are reserved for future use and are always 0 in the current product. Bits 12 to 15 are unused.

Derivation of the Flags

The flags are assigned in two stages.

Land and Water

Every valid pixel is first classified as either LAND or WATER. The classification uses a global vector database of land polygons, rasterised onto the product grid. Pixels inside a land polygon receive the LAND flag and all other valid pixels receive the WATER flag. If no land polygon intersects the scene, the entire scene is flagged as WATER.

Cloud, Cloud Edge and Snow/Ice

A deep learning segmentation model is then applied to the blue, green, red and NIR bands of the top-of-atmosphere (TOA) reflectance. Its output refines the classification as follows:

  • CLOUD: pixels classified by the model as cloud.
  • WATER: pixels classified by the model as water receive the WATER flag and lose the LAND flag. This captures water bodies, such as rivers, reservoirs and flooded areas, that the land polygon database does not resolve.
  • SNWICE: pixels classified by the model as snow or ice.
  • CLDEDG: a buffer of 5 pixels around every cloud. Pixels within this buffer that the model left unclassified are flagged as cloud edge. Cloud-edge pixels are not counted in the Cloud_Cover metadata field, but users who need conservative cloud screening should exclude them together with cloud pixels.

Combinations

Because of the two-stage derivation, each valid pixel carries exactly one of LAND or WATER. It also carries at most one of CLOUD, CLDSDW, CLDEDG or SNWICE. For example, a cloud over the sea has the value 6 (CLOUD + WATER). A snow-covered land pixel has the value 2049 (SNWICE + LAND).

Interpretation and Usage

Because the system uses bit masking, users must employ bitwise operations to query the presence of specific conditions rather than checking for simple integer equality.

Programmatic Implementation

To check if a specific condition exists within a pixel, a bitwise AND operation is performed between the pixel's value and the target flag. If the result is non-zero, the condition is present.

The following Python snippet demonstrates how to verify if a pixel contains a cloud:

# Check if cloud is present
is_cloud = (pcl & CLOUD) != 0

The following example reads the PCL of a product package with rasterio and builds a mask of clear land pixels. Clear means valid, flagged as LAND, and free of cloud, cloud edge, cloud shadow and snow/ice:

import rasterio

LAND, WATER, CLOUD, CLDSDW, CLDEDG, SNWICE = 1, 2, 4, 8, 16, 2048

with rasterio.open("FF01_20011230_00501045_0000021756_PCL.tif") as src:
    pcl = src.read(1)

valid = pcl != 0
obscured = (pcl & (CLOUD | CLDSDW | CLDEDG | SNWICE)) != 0
clear_land = valid & ((pcl & LAND) != 0) & ~obscured

The resulting mask can be applied directly to any band of the image raster in the same package, because both files share the same grid.

Examples of Multi-Condition Pixels

The additive nature of the bit mask allows for complex environmental descriptions within a single value.

Example A: Cloud Over Water

Consider a pixel with the integer value 6. In binary, this is represented as 00110. This value is the sum of two distinct flags:

  • CLOUD (value 4)
  • WATER (value 2)

Therefore, a value of 6 indicates the presence of both cloud and water simultaneously.

Example B: Cloud Edge Over Water

Consider a pixel with the bitmask value of 18 (10010). Decomposition of this value reveals:

  1. The bit corresponding to value 2 is set (bit 1), identifying the pixel as WATER.
  2. The bit corresponding to value 16 is set (bit 4), identifying the pixel as CLDEDG (cloud edge).

Example C: Snow or Ice Over Land

Consider a pixel with the bitmask value of 2049 (100000000001). Decomposition of this value reveals:

  1. The bit corresponding to value 1 is set (bit 0), identifying the pixel as LAND.
  2. The bit corresponding to value 2048 is set (bit 11), identifying the pixel as SNWICE (snow or ice).