Statiscal Batch API vs Request

Hi.

How can I convert the data from a ‘normal’ sentinel hub request for a geometry to the same format given by the statistical batch API returns?

For the same geometry’ I’ve seen distinct values from the two APIs.

I.E. for a given date and geometry in sentinel 2 batch statistical API, the band 08 has returned:
B08_B0_mean: 0.3256
When I get the same data with a standard SentinelHubRequest and average the values for the geometry pixels on band B08 I get:
Band 8 mean: 3273.40

The same issue happens for SAR data.
In the stats API:
VV_B0_mean 0.056809
VH_B0_mean 0.01612

In the request API (average over field geometry’ pixels):
VV: 11.31
VH: 3.21

Is the batch statistical returns normalized in some way?

Could you point me for the documentation or let me know how to convert the process api ‘normal’ returns to the same normalized format of the batch statistical api?

I am attaching the eval scripts for sentinel 2 below, for reference.

Batch Stats API:

evalscript = """
    //VERSION=3
    function setup() {
    return {
        input: [{
        bands: [
            "B02",   // Blue (10m)
            "B03",   // Green (10m)
            "B04",   // Red (10m)
            "B05",   // Vegetation Red Edge (20m)
            "B06",   // Vegetation Red Edge (20m)
            "B07",   // Vegetation Red Edge (20m)
            "B08",   // NIR (10m)
            "B8A",   // NIR Narrow (20m)
            "B11",   // SWIR (20m)
            "B12",   // SWIR (20m)
            "SCL",   // Scene Classification (20m) - used for cloud detection
            "AOT",   // Aerosol Optical Thickness (10m)
            "dataMask"  // Data mask (10m)
        ]
        }],
        output: [
        { id: "B02", bands: 1, sampleType: "FLOAT32" },  // Blue
        { id: "B03", bands: 1, sampleType: "FLOAT32" },  // Green
        { id: "B04", bands: 1, sampleType: "FLOAT32" },  // Red
        { id: "B05", bands: 1, sampleType: "FLOAT32" },  // Vegetation Red Edge
        { id: "B06", bands: 1, sampleType: "FLOAT32" },  // Vegetation Red Edge
        { id: "B07", bands: 1, sampleType: "FLOAT32" },  // Vegetation Red Edge
        { id: "B08", bands: 1, sampleType: "FLOAT32" },  // NIR
        { id: "B8A", bands: 1, sampleType: "FLOAT32" },  // NIR Narrow
        { id: "B11", bands: 1, sampleType: "FLOAT32" },  // SWIR
        { id: "B12", bands: 1, sampleType: "FLOAT32" },  // SWIR
        { id: "SCL", bands: 1 },                         // Scene Classification
        { id: "AOT", bands: 1 },                         // Aerosol Optical Thickness
        { id: "dataMask", bands: 1 },                    // Data Mask
        { id: "cloudCoverage", bands: 1, sampleType: "UINT8" }  // Cloud Coverage
        ]
    }
    }

    function evaluatePixel(samples) {
        // Determine cloud coverage based on SCL classes (classes 3, 8, 9, 10, 11 indicate clouds or shadows)
        let isCloud = (samples.SCL === 3 || samples.SCL === 8 || samples.SCL === 9 || samples.SCL === 10 || samples.SCL === 11) ? 1 : 0;

        return {
            B02: [samples.B02],    // Blue
            B03: [samples.B03],    // Green
            B04: [samples.B04],    // Red
            B05: [samples.B05],    // Vegetation Red Edge
            B06: [samples.B06],    // Vegetation Red Edge
            B07: [samples.B07],    // Vegetation Red Edge
            B08: [samples.B08],    // NIR
            B8A: [samples.B8A],    // NIR Narrow
            B11: [samples.B11],    // SWIR
            B12: [samples.B12],    // SWIR
            SCL: [samples.SCL],    // Scene Classification
            AOT: [samples.AOT],    // Aerosol Optical Thickness
            dataMask: [samples.dataMask],  // Data Mask
            cloudCoverage: [isCloud]  // Cloud coverage (0 for clear, 1 for cloud)
        }
    }
    """

    request_payload = {
        "input": {
        "features":{
            "s3": {
                "url": f"s3://{S3_BUCKET_BATCH_API}/{path_geopackage_s3}",
                "accessKey": AWS_ID,
                "secretAccessKey": AWS_SECRET
            }
        },
            "data": [
            {
                "type": "sentinel-2-l2a",
                "dataFilter": {
                    "mosaickingOrder": "leastCC"
                }
            }
            ]
        },
        "aggregation": {
            "timeRange": {
                    "from": f"{date_start}T00:00:00Z",
                    "to": f"{date_end}T00:00:00Z"
            },
            "aggregationInterval": {
                "of": interval
            },
            "evalscript": evalscript,
            "resx": resolution,
            "resy": resolution
        },
        "output": {
            "s3": {
                "url": f"s3://{S3_BUCKET_BATCH_API}/{path_output_s3}",
                "region": "eu-west-1", 
                "accessKey": AWS_ID,
                "secretAccessKey": AWS_SECRET
            }
        }
    }
    
    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }

    url = "https://services.sentinel-hub.com/api/v1/statistics/batch"

‘Normal’ pixel data Sentinel Request:

evalscript = """
    //VERSION=3
    function setup() {
      return {
        input: [{
          bands: ["B02", "B03", "B04", "B05", "B06", "B07", "B08", "B8A", "B11", "B12", "dataMask", "SCL", "AOT"],
          units: "DN"
        }],
        output: {
          id: "default",
          bands: 13,
          sampleType: SampleType.FLOAT32
        }
      }
    }
    function evaluatePixel(sample) {
        return [sample.B02, sample.B03, sample.B04, sample.B05, sample.B06, sample.B07, sample.B08, 
        sample.B8A, sample.B11, sample.B12, sample.dataMask, sample.SCL, sample.AOT]
    }
    """

    request = SentinelHubRequest(
        data_folder=_data_folder,
        evalscript=evalscript,
        input_data=[
            SentinelHubRequest.input_data(
                data_collection=DataCollection.SENTINEL2_L2A,
                time_interval=_time_interval,
                mosaicking_order='leastCC',
                other_args={"dataFilter": {"maxCloudCoverage": MAX_CC, "mosaickingOrder": "leastCC"}, "processing": {"upsampling": "BILINEAR"}}
            ),
        ],
        responses=[
            SentinelHubRequest.output_response('default', MimeType.TIFF),
        ],
        bbox=_bbox,
        geometry=geometry,
        size=size,
        config=config
    )

    try:
        response = request.get_data(save_data=True)
        filename_d = request.get_filename_list()
        return filename_d

    except Exception as e:
        print('Error getting sentinel imagery {0}'.format(e))        

Hi,

The difference between the two requests is that in the Statistical API request you are requesting Surface Reflectance (default) and in the Process API request you are requesting Digital Numbers. These have different data value ranges as documented here: Sentinel-2 L2A

Thanks for your answer. How about SAR, how can I get the same format in the Process API returns to the Batch Statistical API ?