BioPhysical parameters with Sentinel Toolbox Python bindings

Disclaimer

This notebook is a technology demonstration, none of the results are validated! This notebook shows how the 'snappy' Python module from the Sentinel toolbox. It can be tested inside the PROBA-V MEP notebook environment: https://proba-v-mep.esa.int/notebooks.

Goal

The goal of this notebook is to compute BioPhysical parameters using Sentinel 2 reflectance data. The input reflectance data has already been radiometrically and geometrically corrected, and can be found on the exploitation platform. This scenario is mainly used as a way to demonstrate how snappy can be used and configured inside a notebook, and how it integrates with Python libraries.

Known Limitations

  • Angle information is not taken into account when computing biophysical parameters.
  • When the snap process fails, it does not always provide clear error messages (I get a Java NullPointerException on some occasions, which is solved by running it again.)
  • I was not yet able to properly configure logging of the snap toolbox from within a notebook.

Table of contents

  1. Basic snappy configuration
  2. Load snappy
  3. Find input data
  4. Combine separate bands into a Sentinel 2 product
  5. Create empty bands for angles
  6. Resample bands to common resolution
  7. Subset
  8. Compute Biophysical parameters
  9. Save result
  10. Export to numpy, plot & Histogram

1. Basic snappy configuration

Before importing snappy, we write a config file into the working directory. Snappy will start a Java program in the background, and this config file allows us to modify some basic settings of this program, such as the amount of available memory.

In [1]:
snappy_ini = """
[DEFAULT]
snap_home = /usr/local/snap
# java_class_path: ./target/classes
# java_library_path: ./lib
# java_options: -Djava.awt.headless=false
java_max_mem: 512M
debug: True
"""
with open("snappy.ini", "w") as conf_file:
    conf_file.write(snappy_ini)

2. Load snappy

We now import snappy and check some basic settings. The userDir is important, as Snappy will use it to write various files. We check the location of this directory.

In [2]:
import snappy

config = snappy.EngineConfig.instance()
print(config.userDir())
print(snappy.EngineConfig.instance().storagePath())

userdir = snappy.EngineConfig.instance().userDir()
userdir.toUri().toString()
from snappy import ProductUtils,ProductData
/opt/rh/python27/root/usr/lib64/python2.7/site-packages/snappy: java_module_dirs = 
['/usr/local/snap/probavbox/modules',
 '/usr/local/snap/rstb/modules',
 '/usr/local/snap/s1tbx/modules',
 '/usr/local/snap/s3tbx/modules',
 '/usr/local/snap/s2tbx/modules',
 '/usr/local/snap/snap/modules']
/opt/rh/python27/root/usr/lib64/python2.7/site-packages/snappy: env =
({'GeographicLib-Java.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/net-sf-geographiclib/GeographicLib-Java.jar',
  'Jama.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/Jama/Jama.jar',
  'LibSVM.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/nz-ac-waikato-cms-weka/LibSVM.jar',
  'abdera-client.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-abdera/abdera-client.jar',
  'abdera-core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-abdera/abdera-core.jar',
  'abdera-i18n.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-abdera/abdera-i18n.jar',
  'abdera-parser.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-abdera/abdera-parser.jar',
  'ajt.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/be-abeel/ajt.jar',
  'animal-sniffer-annotations.jar': '/usr/local/snap/s1tbx/modules/ext/org.esa.s1tbx.s1tbx-io/org-codehaus-mojo/animal-sniffer-annotations.jar',
  'apache-mime4j-core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-james/apache-mime4j-core.jar',
  'arpack_combined_all.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/net-sourceforge-f2j/arpack_combined_all.jar',
  'axiom-api.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-ws-commons-axiom/axiom-api.jar',
  'axiom-impl.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-ws-commons-axiom/axiom-impl.jar',
  'bounce.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/nz-ac-waikato-cms-weka-thirdparty/bounce.jar',
  'c3p0.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/c3p0/c3p0.jar',
  'clibwrapper-jiio.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-jai/com-sun-media/clibwrapper-jiio.jar',
  'colt.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/colt/colt.jar',
  'common.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-eclipse-emf/common.jar',
  'commons-cli.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/commons-cli/commons-cli.jar',
  'commons-codec.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/commons-codec/commons-codec.jar',
  'commons-collections.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/commons-collections/commons-collections.jar',
  'commons-compress.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-commons/commons-compress.jar',
  'commons-httpclient.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/commons-httpclient/commons-httpclient.jar',
  'commons-io.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/commons-io/commons-io.jar',
  'commons-jxpath.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/commons-jxpath/commons-jxpath.jar',
  'commons-lang.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/commons-lang/commons-lang.jar',
  'commons-lang3.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/org-apache-commons/commons-lang3.jar',
  'commons-logging.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/commons-logging/commons-logging.jar',
  'commons-math3.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/org-apache-commons/commons-math3.jar',
  'commons-net.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/commons-net/commons-net.jar',
  'commons-pool.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/commons-pool/commons-pool.jar',
  'concurrent.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/concurrent/concurrent.jar',
  'core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/com-googlecode-efficient-java-matrix-library/core.jar',
  'derby.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-derby/derby.jar',
  'ecore.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-eclipse-emf/ecore.jar',
  'ehcache-core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/net-sf-ehcache/ehcache-core.jar',
  'error_prone_annotations.jar': '/usr/local/snap/s1tbx/modules/ext/org.esa.s1tbx.s1tbx-io/com-google-errorprone/error_prone_annotations.jar',
  'fastutil.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-grm/it-unimi-dsi/fastutil.jar',
  'gdal.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-gdal-reader/org-esa-s2tbx-gdal/gdal.jar',
  'geronimo-activation_1.1_spec.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-geronimo-specs/geronimo-activation_1.1_spec.jar',
  'geronimo-javamail_1.4_spec.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-geronimo-specs/geronimo-javamail_1.4_spec.jar',
  'geronimo-stax-api_1.0_spec.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-geronimo-specs/geronimo-stax-api_1.0_spec.jar',
  'gml-v_3_1_1-schema.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-commons/org-jvnet-ogc/gml-v_3_1_1-schema.jar',
  'gson.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/com-google-code-gson/gson.jar',
  'gt-api.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-api.jar',
  'gt-coverage.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-coverage.jar',
  'gt-cql.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-cql.jar',
  'gt-data.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-data.jar',
  'gt-epsg-hsql.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-epsg-hsql.jar',
  'gt-geotiff.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-geotiff.jar',
  'gt-graph.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-graph.jar',
  'gt-main.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-main.jar',
  'gt-metadata.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-metadata.jar',
  'gt-opengis.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-opengis.jar',
  'gt-referencing.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-referencing.jar',
  'gt-render.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-render.jar',
  'gt-shapefile.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-shapefile.jar',
  'gt-wms.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-wms.jar',
  'gt-xml.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools/gt-xml.jar',
  'gt-xsd-core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools-xsd/gt-xsd-core.jar',
  'gt-xsd-gml2.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools-xsd/gt-xsd-gml2.jar',
  'gt-xsd-gml3.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-geotools-xsd/gt-xsd-gml3.jar',
  'guava.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/com-google-guava/guava.jar',
  'hsqldb.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-hsqldb/hsqldb.jar',
  'httpclient.jar': '/usr/local/snap/s3tbx/modules/ext/org.esa.s3tbx.s3tbx-c2rcc/org-apache-httpcomponents/httpclient.jar',
  'httpcore.jar': '/usr/local/snap/s3tbx/modules/ext/org.esa.s3tbx.s3tbx-c2rcc/org-apache-httpcomponents/httpcore.jar',
  'imageio-ext-tiff.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-bigtiff/it-geosolutions-imageio-ext/imageio-ext-tiff.jar',
  'imageio-ext-utilities.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-bigtiff/it-geosolutions-imageio-ext/imageio-ext-utilities.jar',
  'j2objc-annotations.jar': '/usr/local/snap/s1tbx/modules/ext/org.esa.s1tbx.s1tbx-io/com-google-j2objc/j2objc-annotations.jar',
  'jai-codec.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-jai/javax-media-jai/jai-codec.jar',
  'jai-core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-jai/javax-media-jai/jai-core.jar',
  'jai-imageio.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-jai/com-sun-media/jai-imageio.jar',
  'jasypt.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-jasypt/jasypt.jar',
  'java-cup-11b-runtime.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/nz-ac-waikato-cms-weka-thirdparty/java-cup-11b-runtime.jar',
  'java-cup-11b.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/nz-ac-waikato-cms-weka-thirdparty/java-cup-11b.jar',
  'javaml.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/net-sf/javaml.jar',
  'jaxb2-basics-runtime.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-commons/org-jvnet-jaxb2_commons/jaxb2-basics-runtime.jar',
  'jaxen.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/jaxen/jaxen.jar',
  'jaxp-api.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-s2msi-reader/javax-xml-parsers/jaxp-api.jar',
  'jblas.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-nest/org-jblas/jblas.jar',
  'jcip-annotations.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/net-jcip/jcip-annotations.jar',
  'jcl-over-slf4j.jar': '/usr/local/snap/snap/modules/jcl-over-slf4j.jar',
  'jcommon.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/org-jfree/jcommon.jar',
  'jcoord.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-arcbingrid-reader/uk-me-jstott/jcoord.jar',
  'jdom.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-jdom/jdom.jar',
  'jdom2.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/org-jdom/jdom2.jar',
  'je.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/com-sleepycat/je.jar',
  'jfreechart.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/org-jfree/jfreechart.jar',
  'jgridshift.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/jgridshift/jgridshift.jar',
  'jhdf.jar': '/usr/local/snap/snap/modules/ext/ncsa.hdf.lib-hdf/ncsa-hdf/jhdf.jar',
  'jhdf4obj.jar': '/usr/local/snap/probavbox/modules/ext/org.vito.probavbox.probavbox-reader/ncsa-hdf/jhdf4obj.jar',
  'jhdf5.jar': '/usr/local/snap/snap/modules/ext/ncsa.hdf.lib-hdf/ncsa-hdf/jhdf5.jar',
  'jhdf5obj.jar': '/usr/local/snap/probavbox/modules/ext/org.vito.probavbox.probavbox-reader/ncsa-hdf/jhdf5obj.jar',
  'jhdfobj.jar': '/usr/local/snap/probavbox/modules/ext/org.vito.probavbox.probavbox-reader/ncsa-hdf/jhdfobj.jar',
  'jna-platform.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.lib-openjpeg/net-java-dev-jna/jna-platform.jar',
  'jna.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/com-sun-jna/jna.jar',
  'jnn.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/com-bc-jnn/jnn.jar',
  'joda-time.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/joda-time/joda-time.jar',
  'jpy.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-python/org-jpy/jpy.jar',
  'js.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-jai/rhino/js.jar',
  'json-simple.jar': '/usr/local/snap/s3tbx/modules/ext/org.esa.s3tbx.s3tbx-olci-radiometry/com-googlecode-json-simple/json-simple.jar',
  'jsoup.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-dem/org-jsoup/jsoup.jar',
  'jsr-275.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/net-java-dev-jsr-275/jsr-275.jar',
  'jsr305.jar': '/usr/local/snap/s1tbx/modules/ext/org.esa.s1tbx.s1tbx-io/com-google-code-findbugs/jsr305.jar',
  'jt-affine.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-affine/jt-affine.jar',
  'jt-algebra.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-algebra/jt-algebra.jar',
  'jt-bandcombine.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-bandcombine/jt-bandcombine.jar',
  'jt-bandmerge.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-bandmerge/jt-bandmerge.jar',
  'jt-bandselect.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-bandselect/jt-bandselect.jar',
  'jt-binarize.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-binarize/jt-binarize.jar',
  'jt-border.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-border/jt-border.jar',
  'jt-buffer.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-buffer/jt-buffer.jar',
  'jt-classifier.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-classifier/jt-classifier.jar',
  'jt-colorconvert.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-colorconvert/jt-colorconvert.jar',
  'jt-colorindexer.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-colorindexer/jt-colorindexer.jar',
  'jt-crop.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-crop/jt-crop.jar',
  'jt-errordiffusion.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-errordiffusion/jt-errordiffusion.jar',
  'jt-format.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-format/jt-format.jar',
  'jt-imagefunction.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-imagefunction/jt-imagefunction.jar',
  'jt-iterators.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-iterators/jt-iterators.jar',
  'jt-lookup.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-lookup/jt-lookup.jar',
  'jt-mosaic.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-mosaic/jt-mosaic.jar',
  'jt-nullop.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-nullop/jt-nullop.jar',
  'jt-orderdither.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-orderdither/jt-orderdither.jar',
  'jt-piecewise.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-piecewise/jt-piecewise.jar',
  'jt-rescale.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-rescale/jt-rescale.jar',
  'jt-rlookup.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-rlookup/jt-rlookup.jar',
  'jt-scale.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-scale/jt-scale.jar',
  'jt-stats.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-stats/jt-stats.jar',
  'jt-translate.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-translate/jt-translate.jar',
  'jt-utilities.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-utilities/jt-utilities.jar',
  'jt-utils.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-jaitools/jt-utils.jar',
  'jt-vectorbin.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-vectorbin/jt-vectorbin.jar',
  'jt-warp.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-warp/jt-warp.jar',
  'jt-zonal.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/it-geosolutions-jaiext-zonal/jt-zonal.jar',
  'jt-zonalstats.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-jaitools/jt-zonalstats.jar',
  'jtar.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-commons/org-xeustechnologies/jtar.jar',
  'jtransforms.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-raster/edu-emory-mathcs/jtransforms.jar',
  'jts.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/com-vividsolutions/jts.jar',
  'jxl.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-arcbingrid-reader/net-sourceforge-jexcelapi/jxl.jar',
  'jython-standalone.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-jython/org-python/jython-standalone.jar',
  'libsvm.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/tw-edu-ntu-csie/libsvm.jar',
  'lucene.jar': '/usr/local/snap/s1tbx/modules/ext/org.esa.s1tbx.s1tbx-op-sentinel1-ui/lucene/lucene.jar',
  'mlibwrapper-jai.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-jai/javax-media-jai/mlibwrapper-jai.jar',
  'mtj.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/com-googlecode-matrix-toolkits-java/mtj.jar',
  'native-libs.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/net-sf-sevenzipjbinding/native-libs.jar',
  'ncsa-hdf-lib-hdf.jar': '/usr/local/snap/snap/modules/ncsa-hdf-lib-hdf.jar',
  'net-java-html-boot-script.jar': '/usr/local/snap/snap/modules/net-java-html-boot-script.jar',
  'net-java-html-sound.jar': '/usr/local/snap/snap/modules/net-java-html-sound.jar',
  'netcdf.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/edu-ucar/netcdf.jar',
  'netlib-java.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/com-googlecode-netlib-java/netlib-java.jar',
  'nujan.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/edu-ucar/nujan.jar',
  'ogc-tools-gml-jts.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-commons/org-jvnet-ogc/ogc-tools-gml-jts.jar',
  'olingo-odata2-api.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-olingo/olingo-odata2-api.jar',
  'olingo-odata2-core.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-apache-olingo/olingo-odata2-core.jar',
  'org-csa-rstb-rstb-kit.jar': '/usr/local/snap/rstb/modules/org-csa-rstb-rstb-kit.jar',
  'org-csa-rstb-rstb-op-classification.jar': '/usr/local/snap/rstb/modules/org-csa-rstb-rstb-op-classification.jar',
  'org-csa-rstb-rstb-op-polarimetric-tools.jar': '/usr/local/snap/rstb/modules/org-csa-rstb-rstb-op-polarimetric-tools.jar',
  'org-esa-s1tbx-s1tbx-commons.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-commons.jar',
  'org-esa-s1tbx-s1tbx-io.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-io.jar',
  'org-esa-s1tbx-s1tbx-kit.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-kit.jar',
  'org-esa-s1tbx-s1tbx-op-calibration.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-op-calibration.jar',
  'org-esa-s1tbx-s1tbx-op-feature-extraction.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-op-feature-extraction.jar',
  'org-esa-s1tbx-s1tbx-op-insar.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-op-insar.jar',
  'org-esa-s1tbx-s1tbx-op-sar-processing.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-op-sar-processing.jar',
  'org-esa-s1tbx-s1tbx-op-sentinel1.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-op-sentinel1.jar',
  'org-esa-s1tbx-s1tbx-op-utilities.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-op-utilities.jar',
  'org-esa-s1tbx-s1tbx-rcp.jar': '/usr/local/snap/s1tbx/modules/org-esa-s1tbx-s1tbx-rcp.jar',
  'org-esa-s2tbx-lib-gdal.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-lib-gdal.jar',
  'org-esa-s2tbx-lib-openjpeg.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-lib-openjpeg.jar',
  'org-esa-s2tbx-s2tbx-biophysical.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-biophysical.jar',
  'org-esa-s2tbx-s2tbx-cache.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-cache.jar',
  'org-esa-s2tbx-s2tbx-commons.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-commons.jar',
  'org-esa-s2tbx-s2tbx-deimos-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-deimos-reader.jar',
  'org-esa-s2tbx-s2tbx-gdal-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-gdal-reader.jar',
  'org-esa-s2tbx-s2tbx-grm.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-grm.jar',
  'org-esa-s2tbx-s2tbx-jp2-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-jp2-reader.jar',
  'org-esa-s2tbx-s2tbx-jp2-writer.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-jp2-writer.jar',
  'org-esa-s2tbx-s2tbx-kit.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-kit.jar',
  'org-esa-s2tbx-s2tbx-land-cover.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-land-cover.jar',
  'org-esa-s2tbx-s2tbx-radiometric-indices.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-radiometric-indices.jar',
  'org-esa-s2tbx-s2tbx-rapideye-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-rapideye-reader.jar',
  'org-esa-s2tbx-s2tbx-reflectance-to-radiance.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-reflectance-to-radiance.jar',
  'org-esa-s2tbx-s2tbx-s2msi-aerosol-retrieval.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-s2msi-aerosol-retrieval.jar',
  'org-esa-s2tbx-s2tbx-s2msi-idepix.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-s2msi-idepix.jar',
  'org-esa-s2tbx-s2tbx-s2msi-mci.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-s2msi-mci.jar',
  'org-esa-s2tbx-s2tbx-s2msi-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-s2msi-reader.jar',
  'org-esa-s2tbx-s2tbx-s2msi-resampler.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-s2msi-resampler.jar',
  'org-esa-s2tbx-s2tbx-spot-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-spot-reader.jar',
  'org-esa-s2tbx-s2tbx-spot6-reader.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-spot6-reader.jar',
  'org-esa-s2tbx-s2tbx-sta-adapters-help.jar': '/usr/local/snap/s2tbx/modules/org-esa-s2tbx-s2tbx-sta-adapters-help.jar',
  'org-esa-s3tbx-s3tbx-aatsr-sst.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-aatsr-sst.jar',
  'org-esa-s3tbx-s3tbx-aerosol-retrieval.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-aerosol-retrieval.jar',
  'org-esa-s3tbx-s3tbx-alos-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-alos-reader.jar',
  'org-esa-s3tbx-s3tbx-arc.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-arc.jar',
  'org-esa-s3tbx-s3tbx-atsr-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-atsr-reader.jar',
  'org-esa-s3tbx-s3tbx-avhrr-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-avhrr-reader.jar',
  'org-esa-s3tbx-s3tbx-c2rcc.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-c2rcc.jar',
  'org-esa-s3tbx-s3tbx-chris-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-chris-reader.jar',
  'org-esa-s3tbx-s3tbx-flhmci.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-flhmci.jar',
  'org-esa-s3tbx-s3tbx-fu-operator.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-fu-operator.jar',
  'org-esa-s3tbx-s3tbx-fub-wew.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-fub-wew.jar',
  'org-esa-s3tbx-s3tbx-idepix.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-idepix.jar',
  'org-esa-s3tbx-s3tbx-kit.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-kit.jar',
  'org-esa-s3tbx-s3tbx-landsat-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-landsat-reader.jar',
  'org-esa-s3tbx-s3tbx-meris-brr.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-brr.jar',
  'org-esa-s3tbx-s3tbx-meris-cloud.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-cloud.jar',
  'org-esa-s3tbx-s3tbx-meris-l2auxdata.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-l2auxdata.jar',
  'org-esa-s3tbx-s3tbx-meris-ops.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-ops.jar',
  'org-esa-s3tbx-s3tbx-meris-radiometry.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-radiometry.jar',
  'org-esa-s3tbx-s3tbx-meris-sdr.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-sdr.jar',
  'org-esa-s3tbx-s3tbx-meris-smac.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-meris-smac.jar',
  'org-esa-s3tbx-s3tbx-merisl3-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-merisl3-reader.jar',
  'org-esa-s3tbx-s3tbx-modis-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-modis-reader.jar',
  'org-esa-s3tbx-s3tbx-mphchl.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-mphchl.jar',
  'org-esa-s3tbx-s3tbx-olci-radiometry.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-olci-radiometry.jar',
  'org-esa-s3tbx-s3tbx-owt-classification.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-owt-classification.jar',
  'org-esa-s3tbx-s3tbx-rad2refl.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-rad2refl.jar',
  'org-esa-s3tbx-s3tbx-sentinel3-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-sentinel3-reader.jar',
  'org-esa-s3tbx-s3tbx-slstr-pdu-stitching.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-slstr-pdu-stitching.jar',
  'org-esa-s3tbx-s3tbx-slstr-regrid.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-slstr-regrid.jar',
  'org-esa-s3tbx-s3tbx-spot-vgt-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-s3tbx-s3tbx-spot-vgt-reader.jar',
  'org-esa-snap-blue-marble-worldmap.jar': '/usr/local/snap/snap/modules/org-esa-snap-blue-marble-worldmap.jar',
  'org-esa-snap-ceres-binding.jar': '/usr/local/snap/snap/modules/org-esa-snap-ceres-binding.jar',
  'org-esa-snap-ceres-binio.jar': '/usr/local/snap/snap/modules/org-esa-snap-ceres-binio.jar',
  'org-esa-snap-ceres-core.jar': '/usr/local/snap/snap/modules/org-esa-snap-ceres-core.jar',
  'org-esa-snap-ceres-glayer.jar': '/usr/local/snap/snap/modules/org-esa-snap-ceres-glayer.jar',
  'org-esa-snap-ceres-jai.jar': '/usr/local/snap/snap/modules/org-esa-snap-ceres-jai.jar',
  'org-esa-snap-ceres-metadata.jar': '/usr/local/snap/snap/modules/org-esa-snap-ceres-metadata.jar',
  'org-esa-snap-globcover-worldmap.jar': '/usr/local/snap/snap/modules/org-esa-snap-globcover-worldmap.jar',
  'org-esa-snap-seadas-seadas-reader.jar': '/usr/local/snap/s3tbx/modules/org-esa-snap-seadas-seadas-reader.jar',
  'org-esa-snap-snap-arcbingrid-reader.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-arcbingrid-reader.jar',
  'org-esa-snap-snap-bigtiff.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-bigtiff.jar',
  'org-esa-snap-snap-binning.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-binning.jar',
  'org-esa-snap-snap-classification.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-classification.jar',
  'org-esa-snap-snap-cluster-analysis.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-cluster-analysis.jar',
  'org-esa-snap-snap-collocation.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-collocation.jar',
  'org-esa-snap-snap-core.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-core.jar',
  'org-esa-snap-snap-csv-dataio.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-csv-dataio.jar',
  'org-esa-snap-snap-dem.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-dem.jar',
  'org-esa-snap-snap-engine-kit.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-engine-kit.jar',
  'org-esa-snap-snap-engine-utilities.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-engine-utilities.jar',
  'org-esa-snap-snap-envi-reader.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-envi-reader.jar',
  'org-esa-snap-snap-envisat-reader.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-envisat-reader.jar',
  'org-esa-snap-snap-geotiff.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-geotiff.jar',
  'org-esa-snap-snap-getasse30-dem.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-getasse30-dem.jar',
  'org-esa-snap-snap-gpf.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-gpf.jar',
  'org-esa-snap-snap-hdf5-writer.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-hdf5-writer.jar',
  'org-esa-snap-snap-help.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-help.jar',
  'org-esa-snap-snap-jython.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-jython.jar',
  'org-esa-snap-snap-land-cover.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-land-cover.jar',
  'org-esa-snap-snap-ndvi.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-ndvi.jar',
  'org-esa-snap-snap-netcdf.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-netcdf.jar',
  'org-esa-snap-snap-pconvert.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-pconvert.jar',
  'org-esa-snap-snap-pgx-reader.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-pgx-reader.jar',
  'org-esa-snap-snap-pixel-extraction.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-pixel-extraction.jar',
  'org-esa-snap-snap-product-library.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-product-library.jar',
  'org-esa-snap-snap-python.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-python.jar',
  'org-esa-snap-snap-raster.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-raster.jar',
  'org-esa-snap-snap-smart-configurator.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-smart-configurator.jar',
  'org-esa-snap-snap-sta.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-sta.jar',
  'org-esa-snap-snap-statistics.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-statistics.jar',
  'org-esa-snap-snap-temporal-percentile.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-temporal-percentile.jar',
  'org-esa-snap-snap-unmix.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-unmix.jar',
  'org-esa-snap-snap-watermask.jar': '/usr/local/snap/snap/modules/org-esa-snap-snap-watermask.jar',
  'org-jlinda-jlinda-core.jar': '/usr/local/snap/s1tbx/modules/org-jlinda-jlinda-core.jar',
  'org-jlinda-jlinda-nest.jar': '/usr/local/snap/s1tbx/modules/org-jlinda-jlinda-nest.jar',
  'org-vito-probavbox-probavbox-kit.jar': '/usr/local/snap/probavbox/modules/org-vito-probavbox-probavbox-kit.jar',
  'org-vito-probavbox-probavbox-reader.jar': '/usr/local/snap/probavbox/modules/org-vito-probavbox-probavbox-reader.jar',
  'oro.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-sta/oro/oro.jar',
  'perf4j.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/org-perf4j/perf4j.jar',
  'picocontainer.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/picocontainer/picocontainer.jar',
  'prefuse-core.jar': '/usr/local/snap/s1tbx/modules/ext/org.esa.s1tbx.s1tbx-op-sentinel1-ui/de-sciss/prefuse-core.jar',
  'protobuf-java.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/com-google-protobuf/protobuf-java.jar',
  'quartz.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/org-quartz-scheduler/quartz.jar',
  'relaxngDatatype.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-s2msi-reader/relaxngDatatype/relaxngDatatype.jar',
  's2tbx-mosaic.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-kit/org-esa-s2tbx/s2tbx-mosaic.jar',
  'scpsolver.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/scpsolver/scpsolver.jar',
  'sevenzipjbinding.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/net-sf-sevenzipjbinding/sevenzipjbinding.jar',
  'slf4j-api.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/org-slf4j/slf4j-api.jar',
  'slf4j-simple.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/org-slf4j/slf4j-simple.jar',
  'snap-runtime.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-smart-configurator/org-esa-snap/snap-runtime.jar',
  'sqlite-jdbc.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-s2msi-reader/org-xerial/sqlite-jdbc.jar',
  'stax2-api.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-codehaus-woodstox/stax2-api.jar',
  'thumbnailator.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/net-coobird/thumbnailator.jar',
  'trove4j.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/net-sf-trove4j/trove4j.jar',
  'udunits.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-netcdf/edu-ucar/udunits.jar',
  'velocity.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/org-apache-velocity/velocity.jar',
  'weka-dev.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-classification/nz-ac-waikato-cms-weka/weka-dev.jar',
  'werken-xpath.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-sta/werken-xpath/werken-xpath.jar',
  'woodstox-core-asl.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-codehaus-woodstox/woodstox-core-asl.jar',
  'wvlpsolver.jar': '/usr/local/snap/s1tbx/modules/ext/org.jlinda.jlinda-core/com-winvector/wvlpsolver.jar',
  'xercesImpl.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/xerces/xercesImpl.jar',
  'xml-apis.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/xml-apis/xml-apis.jar',
  'xml-commons-resolver.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-apache-xml/xml-commons-resolver.jar',
  'xmlpull.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/xmlpull/xmlpull.jar',
  'xpp3_min.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/xpp3/xpp3_min.jar',
  'xsd.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-core/org-eclipse-xsd/xsd.jar',
  'xsom.jar': '/usr/local/snap/s2tbx/modules/ext/org.esa.s2tbx.s2tbx-s2msi-reader/com-sun-xsom/xsom.jar',
  'xstream.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.ceres-core/com-thoughtworks-xstream/xstream.jar',
  'xz.jar': '/usr/local/snap/snap/modules/ext/org.esa.snap.snap-engine-utilities/org-tukaani/xz.jar'},
 ['/usr/local/snap/snap/modules/lib/x86_64',
  '/usr/local/snap/snap/modules/lib'])
annotate_RasterDataNode_methods: Method "readValidMask": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
annotate_RasterDataNode_methods: Method "readPixels": modified parameter 4: mutable = True, return = True
/home/driesj/.local/share/snap
/home/driesj/.local/share/snap/etc/snap.properties

Load auxiliary data for Biophysical algorithm

The algorithm that we will use should normally write some data to the user dir. If this does not happen automatically, we can trigger it manually as shown below.

In [3]:
activator = snappy.jpy.get_type('org.esa.s2tbx.biophysical.BiophysicalActivator')
activator().start()

3. Find input data

On the exploitation platform, a catalog client is available to find input data, we use this to find the filename of a radiometry product. More information on the catalog client API can be found here: http://mep-catalogclient.readthedocs.io/en/latest/.

In [4]:
from catalogclient import catalog
cat=catalog.Catalog()
In [5]:
import datetime
date = datetime.date(2017, 7, 18)
products = cat.get_products('CGS_S2_RADIOMETRY', 
                            fileformat='GEOTIFF', 
                            startdate=date, 
                            enddate=date)
In [6]:
p = products[0]
f = p.file('B02')
print(f)
path = f[5:]
file:/data/MTDA/CGS_S2/CGS_S2_RADIOMETRY/2017/07/18/S2B_20170718T101029Z_32TQQ_CGS_V102_000/S2B_20170718T101029Z_32TQQ_TOC_V102/S2B_20170718T101029Z_32TQQ_TOC-B02_10M_V102.tif

4. Combine separate bands into a Sentinel 2 product

The algorithm that we want to use expects a product with specific metadata and bands. The products available on the platform are provided as individual tiff images. As a workaround, we load all images individually and combine them into a single product. I ensure that the layout of the product conforms to what the algorithm expects. Doing this required some trial and error, and inspection of the source code of the algorithm: https://github.com/senbox-org/s2tbx/blob/6.x/s2tbx-biophysical/src/main/java/org/esa/s2tbx/biophysical/BiophysicalOp.java

In [7]:
S2BandConstant = snappy.jpy.get_type('org.esa.s2tbx.biophysical.BiophysicalOp$S2BandConstant')
def getProduct(filename, bandconstant):
    inputProduct = snappy.ProductIO.readProduct(filename.replace("B02", bandconstant.getFilenameBandId()))
    inputProduct.getBandAt(0).setSpectralWavelength(bandconstant.getWavelengthCentral())
    inputProduct.getBandAt(0).setName(bandconstant.getPhysicalName())
    return inputProduct

file20M = path.replace("10M","20M")

b3Product = getProduct(path, S2BandConstant.B3)
ProductUtils.copyBand(S2BandConstant.B4.getPhysicalName(),getProduct(path,S2BandConstant.B4),b3Product,True)
ProductUtils.copyBand(S2BandConstant.B5.getPhysicalName(),getProduct(file20M,S2BandConstant.B5),b3Product,True)
ProductUtils.copyBand(S2BandConstant.B6.getPhysicalName(),getProduct(file20M,S2BandConstant.B6),b3Product,True)
ProductUtils.copyBand(S2BandConstant.B7.getPhysicalName(),getProduct(file20M,S2BandConstant.B7),b3Product,True)
ProductUtils.copyBand(S2BandConstant.B8A.getPhysicalName(),getProduct(file20M,S2BandConstant.B8A),b3Product,True)
ProductUtils.copyBand(S2BandConstant.B11.getPhysicalName(),getProduct(file20M,S2BandConstant.B11),b3Product,True)
ProductUtils.copyBand(S2BandConstant.B12.getPhysicalName(),getProduct(file20M,S2BandConstant.B12),b3Product,True)
for name in b3Product.getBandNames():
    print(name)
B3
B4
B5
B6
B7
B8A
B11
B12

5. Create empty bands for angles

The algorithm also expects angle information to be provided. At time of writing, there is no direct way to obtain this, so I add bands filled with zeroes. Do note that the Sentinel 2 toolbox does support reading this informationn, so it should not be impossible to retrieve these bands as well.

In [8]:
L2BInput = snappy.jpy.get_type('org.esa.s2tbx.biophysical.BiophysicalOp$L2BInput')
S2LikeProduct = b3Product
S2LikeProduct.addBand(L2BInput.VIEW_ZENITH.getBandName(),"0.0", ProductData.TYPE_FLOAT32)
S2LikeProduct.addBand(L2BInput.SUN_ZENITH.getBandName(),"0.0", ProductData.TYPE_FLOAT32)
S2LikeProduct.addBand(L2BInput.SUN_AZIMUTH.getBandName(),"0.0", ProductData.TYPE_FLOAT32)
S2LikeProduct.addBand(L2BInput.VIEW_AZIMUTH.getBandName(),"0.0", ProductData.TYPE_FLOAT32)
Out[8]:
org.esa.snap.core.datamodel.Band(objectRef=0x6ae0208)

6. Resample bands to common resolution

The product we created contains both 10M and 20M bands. This is not supported by most other operators, so the first operation we apply is a resample operation. Note that operations are evaluated lazily, so all operators in the next steps will not require a lot of time to create, and are only run when actual pixel values are retrieved. Before we apply the actual operator, we show how operator information can be retrieved from the API.

In [9]:
gpf = snappy.GPF.getDefaultInstance()
ops = gpf.getOperatorSpiRegistry()
ops.loadOperatorSpis()
In [10]:
def get_snap_info(operator):
    """
    Returns information about SNAP operators and their parameters
    """
    op_spi = snappy.GPF.getDefaultInstance().getOperatorSpiRegistry().getOperatorSpi(operator)
    print('Op name:', op_spi.getOperatorDescriptor().getName())
    print('Op alias:', op_spi.getOperatorDescriptor().getAlias()) 
    param_Desc = op_spi.getOperatorDescriptor().getParameterDescriptors()
    for param in param_Desc:
          print(param.getName(), "or", param.getAlias())

get_snap_info('BiophysicalOp')
get_snap_info('Subset')
('Op name:', 'org.esa.s2tbx.biophysical.BiophysicalOp')
('Op alias:', 'BiophysicalOp')
('computeLAI', 'or', None)
('computeFapar', 'or', None)
('computeFcover', 'or', None)
('computeCab', 'or', None)
('computeCw', 'or', None)
('Op name:', 'org.esa.snap.core.gpf.common.SubsetOp')
('Op alias:', 'Subset')
('bandNames', 'or', 'sourceBands')
('region', 'or', None)
('geoRegion', 'or', None)
('subSamplingX', 'or', None)
('subSamplingY', 'or', None)
('fullSwath', 'or', None)
('tiePointGridNames', 'or', None)
('copyMetadata', 'or', None)
In [11]:
get_snap_info('Resample')
('Op name:', 'org.esa.snap.core.gpf.common.resample.ResamplingOp')
('Op alias:', 'Resample')
('referenceBandName', 'or', 'referenceBand')
('targetWidth', 'or', 'targetWidth')
('targetHeight', 'or', 'targetHeight')
('targetResolution', 'or', 'targetResolution')
('upsamplingMethod', 'or', 'upsampling')
('downsamplingMethod', 'or', 'downsampling')
('flagDownsamplingMethod', 'or', 'flagDownsampling')
('resampleOnPyramidLevels', 'or', None)
In [12]:
parameters = snappy.HashMap()
parameters.put('referenceBandName', 'B3')
parameters.put('upsampling', 'Bilinear')
parameters.put('downsampling', 'Mean')
parameters.put('resampleOnPyramidLevels', False)
resampled = snappy.GPF.createProduct('Resample', parameters, S2LikeProduct)

7. Subset

Let's make the image a bit smaller for faster processing.

In [13]:
parameters = snappy.HashMap()
parameters.put('region', '500,500,2000,2000')
subset = snappy.GPF.createProduct('Subset', parameters, resampled)

8. Compute Biophysical parameters

The final operator to apply defines the actual parameters to compute. These parameters specify which output needs to be produced. All other inputs are contained in the S2 product.

In [14]:
parameters = snappy.HashMap()
parameters.put('computeCab', False)
parameters.put('computeCw', False)
parameters.put('computeFapar', True)
parameters.put('computeFcover', False)
parameters.put('computeLAI', False)
print(parameters)
biophysical_indexes = snappy.GPF.createProduct('BiophysicalOp', parameters, subset)
{computeCab=false, computeLAI=false, computeFcover=false, computeCw=false, computeFapar=true}

9. Save result

At this point we can save the result to file. Rembember that the Sentinel toolbox computes results lazily. So this step will also compute all previous operations that have been applied. Therefore, we time this step, to get an idea about the performance of our operator chain. (This includes reading the result, resampling, and saving back to disk. The subsetting operation that we applied will specify how many pixels we actually process.

In [15]:
snappy.EngineConfig.instance().preferences().put("snap.dataio.bigtiff.compression.type","LZW")
In [16]:
%time snappy.ProductIO.writeProduct(biophysical_indexes,  "FAPARsnappy","GeoTIFF-BigTIFF")
CPU times: user 2min 13s, sys: 4.43 s, total: 2min 18s
Wall time: 40.4 s

10. Export to numpy, plot & Histogram

In [17]:
import numpy
bioband = biophysical_indexes.getBandAt(0)
out = numpy.zeros(bioband.getRasterWidth()*bioband.getRasterHeight(), dtype=numpy.float32)
out = out.reshape((bioband.getRasterWidth(),bioband.getRasterHeight()))
out = bioband.readPixels(0,0,bioband.getRasterWidth(),bioband.getRasterHeight(),out)
print(out.shape)
(2000, 2000)
In [18]:
from rasterio import plot
import matplotlib
%matplotlib inline
from matplotlib import pyplot
fig, ax = pyplot.subplots(1, figsize=(12, 12))
plot.show(out,ax=ax)
Out[18]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f79ec0d4550>
In [19]:
from rasterio.plot import show_hist
show_hist(out, bins=100, lw=0.0, stacked=False, alpha=0.3,histtype='stepfilled', title="Histogram")