auscophub.sen2meta

Classes for handling the various metadata files which come with Sentinel-2

exception auscophub.sen2meta.Sen2MetaError
class auscophub.sen2meta.Sen2TileMeta(filename=None, fileobj=None, zipfilename=None)

Metadata for a single granule (i.e. 100km tile) within the SAFE file.

satId

Short string for which Sentinel-2 satellite

tileId

ID string of 100km tile (i.e. MGRS ID with “T” prefix)

cloudPcnt

ESA’s estimate of percentage cloud cover

datetime

datetime object of image acquisition

procLevel

Processing level string (e.g. “L1C”)

processingSoftwareVersion

ESA’s processing baseline version number string

dimsByRes

Image dimensions (numRows, numCols) as dictionary, keyed by image resolution

epsg

EPSG number of image projection

angleGridXres

X resolution of angles grids (usually 5000m)

angleGridYres

Y resolution of angles grids

anglesGridShape

dimensions of angles grids

anglesULXY

(X, Y) coordinates of top-left corner of angles grids (not necessarily aligned with imagery)

meanSunAzimuth

Whole-image mean of sun azimuth angle (degrees)

meanSunZenith

Whole-image mean of sun zenith angle (degrees)

sunAzimuthGrid

Coarse grid of sun azimuth angles

sunZenithGrid

Coarse grid of sun zenith angles

meanViewAzimuth

Whole-image/all-band mean of satellite azimuth angle

meanViewAzimuthByBand

Whole-image/per-band means of satellite azimuth angles

meanViewZenith

Whole-image/all-band mean of satellite azimuth angle

meanViewZenithByBand

Whole-image/per-band means of satellite zenith angles

viewAzimuthDict

Per-band coarse grids of satellite azimuth angles (keyed by band id number string)

viewZenithDict

Per-band coarse grids of satellite zenith angles (keyed by band id number string)

ulxyByRes

(X, Y) coordinates of top-left corner of angles grids, keyed by pixel size

buildViewAngleArr(viewingAngleNodeList, angleName)

Build up the named viewing angle array from the various detector strips given as separate arrays. I don’t really understand this, and may need to re-write it once I have worked it out……

The angleName is one of ‘Zenith’ or ‘Azimuth’. Returns a dictionary of 2-d arrays, keyed by the bandId string.

calcMGRSname()

Calculate the US-MGRS 100km grid square identifier. This should not be necessary, as ESA have supplied the tile name in the granule names, but they appear to have got it wrong sometimes. So, in order to make sure we have it right, I calculate it myself. How very tiresome.

getCtrLongLat()

Return the (longitude, latitude) of the scene centre

getCtrXY()

Return the (X, Y) coordinates of the scene centre (in image projection, generally UTM)

getUTMzone()

Return the UTM zone of the tile, as an integer

makeQVFname()

Make a QVF name for the current tile. Stage is aa0 and suffix is .meta, but these are just notional placeholders.

static makeValueArray(valuesListNode)

Take a <Values_List> node from the XML, and return an array of the values contained within it. This will be a 2-d numpy array of float32 values (should I pass the dtype in??)

class auscophub.sen2meta.Sen2ZipfileMeta(xmlStr=None, xmlfilename=None, zipfilename=None)

The metadata associated with the SAFE format file, which is a collection of multiple tiles. At the top of the SAFE hierarchy is a single XML file with metadata which applies to the whole collection, and this class carries information from that XML file.

There are three field names which are aliases for other fields. These are provided for compatibility with JRSRP/RSC code, which used an earlier version of this class. They are datetime, relOrbit, absOrbit. These names should not be used in new code.

spacecraftName

Long string for which Sentinel-2 satellite

satId

Short string for which Sentinel-2 satellite

startTime

datetime object for start of image acquisition

stopTime

datetime object for end of image acquisition (usually equal to startTime, I have no idea why)

relativeOrbitNumber

Permanent number for this swathe (like Landsat path)

absoluteOrbitNumber

Unique number for this specific orbit

nullVal

Pixel value for ‘No Data’, same for all bands

saturatedVal

Pixel value indicating radiometric saturation

scaleValue

Factor to convert pixel values to reflectance units (N.B. see offsetValDict)

offsetValDict

Dictionary of pixel value offsets (per band). Only relevant after ESA version 04.00, None if not. See ESA doc for usage.

processingLevel

e.g. “Level-1C”

processingSoftwareVersion

ESA’s “Processing Baseline” version number

generationTime

A datetime object for when the image was processed by ESA

cloudPcnt

ESA’s estimate of percentage cloud cover

EsunDict

Dictionary of solar irradiance values, keyed by band name.

zipfileMetaXML

String of input XML

centroidXY

[x, y] location of image centre

extPosWKT

WKT of polygon outline of non-null image

previewImgBin

Binary data of preview image (or None if not available)

aotScaleValue

Scale factor for aerosol raster (L2A only)

wvpScaleValue

Scale factor for water vapour raster (L2A only)

class auscophub.sen2meta.Sen2ZipfileSubstrings(zipfilename)

Decompose a Sentinel-2 zipfile into a set of substrings for the different fields in the file name. Copes with both the old and new naming formats, populating the same fields, wherever possible.

Note that the resulting substrings are only strings, mostly the substrings as separated by the ‘_’.

auscophub.sen2meta.calcMGRSnameFromCoords(epsg, easting, northing)

Calculate the US-MGRS 100km grid square identifier, which is then used for the the ESA tile ID string. This should not be necessary, as ESA have supplied the tile name in the granule names, but they appear to have got it wrong sometimes. So, in order to make sure we have it right, I calculate it myself. How very tiresome.

The inputs are the easting and northing in UTM coords, along with the EPSG number of the relevant UTM projection. It is assumed that the EPSG is for the WGS84 spheroid/datum, and hence is either 326nn or 327nn (north or south hemisphere).

My reference on how to do this is mostly

https://en.wikipedia.org/wiki/Military_grid_reference_system

but also with help from

http://earth-info.nga.mil/GandG/publications/tm8358.1/tr83581f.html

and some source code at

http://earth-info.nga.mil/GandG/geotrans/index.html

From the source code page, download mgrs.tgz, and look in MGRS.cpp. The routines MGRS::getGridValues() and MGRS::fromUTM() are particularly instructive.

I have not coded the variations for the polar regions, nor for Svalbard and south-west Norway. However, it appears that ESA have not used the special polar cases anyway. For latitude < -80 or > +84, MGRS is supposed to use Universal Polar Stereographic projection (UPS) instead of UTM, but it seems that the ESA processing software leaves everything in UTM, and assigns a tile name according to the UTM algorithm anyway. From my testing, it seems this routine gets the same tile name as ESA, so I am leaving it that way.

I have no idea what ESA do in Svarlbard or south-west Norway.

auscophub.sen2meta.findElementByXPath(node, xpath)

Find a sub-node under the given XML minidom node, by traversing the given XPATH notation. Searches all possible values, and returns a list of whatever it finds which matches.

It would be better if minidom understood XPATH, but it does not seem to. I could use some of the other libraries, but ElementTree seems to have obscure bugs, and I did not want to introduce any other dependencies. Sigh…..