LAI estimations

Hi all
I am python based. I have used NDVI stats quite successfully, but the LAI estimation I use does not seem to be very accurate - it has a few negative values. So I am now looking for more “accurate” LAI estimation algos.
I tried custom-scripts/script.js at master · sentinel-hub/custom-scripts · GitHub, but got stuck with the need to provide a dataMask. Has anyone used this algo in the python env. if so, can you share the request structure please?

Karthik

Hi Karthik, the script that you have linked to here is an evalscript that is a piece of Javascript that is only part of your Sentinel Hub request. Therefore, there should be no issue whether using this with either python or a curl request.

Can you give some more information on the python code you are using to run your request and I can help you with your structure. :slight_smile:

As for the LAI algorithm itself; you can read more in this previous post which may help you understand the outputs better.

Hi William
Apologies for the delay. I think the problem I am having is, I do not know what this script is returning and so unable to craft a request accordingly. I am using the following request which expects a json for another script (https://docs.sentinel-hub.com/api/latest/api/statistical/examples/#statistics-of-maximum-monthly-ndvi-for-a-parcel-in-2020); but that is not working for the lai one.

stats_request = {
        "input": {
            "bounds": {
                "bbox": bbox
            },
            "data": [
                {
                    "type": collection_id,
                    "dataFilter": {}
                }
            ]
        },
        "aggregation": {
            "timeRange": {
                "from": start_date + "T00:00:00Z",
                "to": end_date + "T23:59:59Z"
            },
            "aggregationInterval": {
               "of": "P5D"
            },
            "evalscript": evalscript_lai,
            "width": 512,
            "height": 529.328
        },
        "calculations": {
            "default": {}
        }
    }

evalscript_lai is set to the js. When using above, I get the following error. Can you point me to a sample json request I can use for this lai.js?

“error”:{“type”:“BAD_REQUEST”,“message”:“Failed to evaluate script!\nundefined:1134: evaluatePixel must return an object containing arrays\n throw “evaluatePixel must return an object containing arrays”;\n ^\n”

Many thanks
Karthik

Hi Karthik,

As you were using Statistical API, there were two things you were required to change so that it works correctly with Statistical API.

Firstly, in the setup function you are required to use the dataMask as an input and an output. In addition, the outputs of your evalscript need to be explicitly defined separately. Secondly, you also need to define these two outputs in the evaluatePixel function. This is explained in the documentation too.

Below are the adapted setup() function and the evaluatePixel() functions that you can insert into the evalscript. Remember this isn’t the whole evalscript for LAI!

function setup() {
  return {
    input: [{
      bands: [
          "B03",
          "B04",
          "B05",
          "B06",
          "B07",
          "B8A",
          "B11",
          "B12",
          "viewZenithMean",
          "viewAzimuthMean",
          "sunZenithAngles",
          "sunAzimuthAngles",
          "dataMask"
      ]
    }],
    output: [
        {
          id: "default",
          sampleType: "AUTO",
          bands: 1
        },
        {
        id: "dataMask",
        bands: 1
      }
    ]
  }
}

function evaluatePixel(sample, scene, metadata, customData, outputMetadata) {
  const result = evaluatePixelOrig([sample], [scene], metadata, customData, outputMetadata);
  lai_result = result[Object.keys(result)[0]];

  return {
        default: [lai_result],
        dataMask: [sample.dataMask]
    }
}

If this isn’t clear, then don’t hesitate to ask for additional clarification.

Hi William
Awesome. This seems to work. But can you please keep this open a bit longer in case I run into issues?
Thank you very much for your help.
I did not have evaluatePixel() set correctly.
Best
Karthik

Hi William
I am seeing some interesting variations in the LAI values… quite a few unexpected variations, since the crop in that area is in good growth. Importantly, we will be manually measuring LAI periodically but on a sample set of plants in that area.

  1. Has any validation been done using the algorithm?
  2. I have implemented a polynomial derivation of LAI based on NDVI (https://www.tucson.ars.ag.gov/unit/publications/PDFfiles/1153.pdf). I pull NDVI using CLM from sentinel 2. This approach has given us lesser data points, but this matches better with the manual measurement. Data set is small though.

How do you propose we narrow down the gaps? What would you like from me?
Best
Karthik

Hi Karthik,

We use the algorithm that is present in the SNAP Toolbox application. The script was ported from SNAP software and can be used in general. It is region agnostic so will work relatively well in most regions but if you require something more precise then you would want to calculate it differently.

On your second question, I’m not sure I have the knowledge to help you adjust and improve your approach to measuring LAI, as this is quite an advanced and specialised subject. However, If you wish to contribute your variation of LAI to the custom scripts repository that would be great!

Yup, understood.
From Agriculture, looks like Sentinel 2 is the “preferred” satellite “mission”? I am using Sentinel-2 L2A… should I use some other collection?
Thanks
Karthik