sicor.sensors.S2MSI.S2Image package

Submodules

sicor.sensors.S2MSI.S2Image.S2Image module

Read Sentinel-2 Level-1C and Level-2A data into RSImage object.

class sicor.sensors.S2MSI.S2Image.S2Image.S2Image(granule_path, import_bands='all', namespace_candidate=None, aux_fields=None, default_u=1.0, target_resolution=None, dtype_float=<class 'numpy.float16'>, dtype_int=<class 'numpy.int16'>, unit='reflectance', interpolation_order=1, data_mode='dense', driver='OpenJpeg2000', call_cmd=None, logger=None, slice_x=slice(None, None, None), slice_y=slice(None, None, None), default_solar_irradiance={'B01': 1913.57, 'B02': 1941.63, 'B03': 1822.61, 'B04': 1512.79, 'B05': 1425.56, 'B06': 1288.32, 'B07': 1163.19, 'B08': 1036.39, 'B09': 813.04, 'B10': 367.15, 'B11': 245.59, 'B12': 85.25, 'B8A': 955.19}, **kwarg)[source]

Bases: RSImage

Load Sentinel-2 Level-1C or Level-2A product.

Reads Sentinel-2 MSI data into numpy array. Images for different channels are resampled to a common sampling :param granule_path: path to granule folder, folder should contain IMG_DATA folder and S2A_[..].xml file :param import_bands: list of bands to import, default: [‘B01’, ‘B02’, ‘B03’, ‘B04’, ‘B05’, ‘B06’, ‘B07’, ‘B08’,

‘B8A’, ‘B09’, ‘B10’, ‘B11’, ‘B12’,]

Parameters:
  • namespace_candidate – for XML file, or None, then several default namespaces are tested

  • target_resolution – spatial resolution in meter, or None for data not interpolated

  • interpolation_order – integer for interpolation 1,2,3

  • data_mode – either “dense” or “sparse”

  • aux_fields – either None or dict of to be loaded aux fields, e.g. {“cwv”:[ss],”spr”:[ss],”ozo”:[ss]} with ss being “mean” or iterable of spatial samplings, e.g. [20.0] or [20.0,60.0]

  • driver – should be “OpenJpeg2000” -> glymur, “kdu_expand”->shell command, “gdal_[driver] e.g. gdal_JP2ECW gdal_JPEG2000, gdal_JP2OpenJPEG,gdal_JP2KAK

..todo:: Real nodata mask

__rd()
__read_img(fn)
__read_jp2_kdu_app(call_cmd=None)
static _band_name_l1c(fn)[source]

S2 helper function, parse band name from jp2 file name :param fn: filename :return: string with band name

static _band_name_l2a(fn)[source]
static _spatial_sampling_msk(fn)[source]
bad_data_mask(image_data)[source]

Return mask of bad data :param image_data: numpy array :return: 2D boolean array

static find_in_xml(xml, *branch)[source]

S2 xml helper function :param xml: xml object :param branch: iterate to branches using find :return: xml object, None if nothing was found

static find_in_xml_root(namespace, xml_root, branch, *branches, findall=None)[source]

S2 xml helper function, search from root :param namespace: :param xml_root: :param branch: first branch, is combined with namespace :param branches: repeated find’s along these parameters :param findall: if given, at final a findall :return: found xml object, None if nothing was found

static gdal_read(fnjp, driver_name)[source]

Read image file using gdal.

static geotransform2mapinfo(gt, prj)[source]

Builds an ENVI map info from given GDAL GeoTransform and Projection :param gt: GDAL GeoTransform, e.g. (249885.0, 30.0, 0.0, 4578615.0, 0.0, -30.0) :param prj: GDAL Projection - WKT Format :returns: ENVI map info, e.g. [ UTM , 1 , 1 , 256785.0 , 4572015.0 , 30.0 , 30.0 , 43 , North , WGS-84 ] :rtype: list

get_granule_metadata_xml()[source]

Try to find metadata xml file for the granule.

static get_projection(file_name)[source]

:param file_name string, points to filename :return: return {“gt”:geotransform,”prj”:coordinate projections string} for filename :rtype dict

static get_values_from_xml(leaf, dtype=<class 'float'>)[source]

S2 xml helper function :param leaf: xml object which is searched for VALUES tag which are then composed into a numpy array :param dtype: dtype of returned numpy array :return: numpy array

static parse_s2_granule_xml(fn, namespace)[source]

parse XML file in granule folder and return metadata :param fn: full filename tile xml file :param namespace: xml namespace :return: dictionary with metadata

static parse_s2_product_xml(fn)[source]

S2 XML helper function to parse product xml file :param fn: file name of xml file :return: metadata dictionary

static read_aux_data(fn)[source]

Read grib file with aux data, return dictionary :param fn: path to granule :return: dict with data

static save_rgb_image(rgb_img, fn, dpi=100.0)[source]

Save image as RGB to file system.

static transform_utm_to_wgs84(easting, northing, zone, south=False)[source]

returns lon, lat, altitude

sicor.sensors.S2MSI.S2Image.S2Image.get_tck(x, y, z, kk_default=3, logger=None)[source]

Estimate spline model parameters.

class sicor.sensors.S2MSI.S2Image.S2Image.s2_snr_model(s2_snr_csv_file, rfl_to_rad, logger=None)[source]

Bases: object

Sentinel-2 SNR model from CNES instrument characterization. :param: s2_snr_csv_file: path to valid s2_snr_csv_file, e.g. line: B1,129.0,588,”0,04840000”,”0,00003130”, “4,07374605”,”129,00”,”525,5132410906”,”0,1370807224”,”941,05”,”1614,99”,”983,3” :param: rfl_to_rad: dict with band names as keys and conversion factor from reflectance to radiance, e.g.:

rfl_to_rad={‘B8a’: 0.0, ‘B12’: 0.0, ‘B10’: 0.0, ‘B03’: 0.0, ‘B07’: 0.0, ‘B04’: 0.0, ‘B11’: 0.0, ‘B02’: 0.0, ‘B08’: 0.0, ‘B05’: 0.0, ‘B09’: 0.0, ‘B01’: 0.0, ‘B06’: 0.0}

noise(reflectance, band_name)[source]

Sentinel-2 radiance to noise model

Module contents

class sicor.sensors.S2MSI.S2Image.RSImage(unit='reflectance', target_resolution=None, bad_data_value=nan, dtype_float=<class 'numpy.float16'>, mask_clouds=None, **kwargs)[source]

Bases: object

Remote Sensing Image base class.

Parameters:
  • unit – string “reflectance”, in future other units might be supported

  • target_resolution – None: keep data as is (e.g. separate bands), or give spatial sampling for interpolation to larger cube

  • bad_data_value – vale to exclude data from processing

  • dtype_float – dtype for intermediate computations

  • *kwargs

    See below

Keyword Arguments:
  • data: {B10:ndarray(dtype=float16),[…],B09:ndarray(dtype=float16)}

  • tile_name: “32UMA”

  • nodata (and or yesdata with same interface){60.0:ndarray(dtype=bool),[…],20.0:ndarray(dtype=bool)}

  • band_spatial_sampling: {B10:60.0,[…],B02:10.0,[…],B11:20.0}

  • mask_clouds: should be instance of S2MSI.Mask or similar object, some attributes need to be

    present: [‘clf_to_col’, ‘export_confidence_to_jpeg2000’, ‘export_mask_blend’, ‘export_mask_rgb’, ‘export_to_jpeg200’, ‘geo_coding’, ‘mask_array’, ‘mask_confidence_array’, ‘mask_legend’, ‘mask_legend_inv’, ‘mask_rgb_array’, ‘metadata’, ‘mk_mask_at_spatial_scales’]

  • metadata:

{"U":1.0,# Eun - Earth distance
 "SENSING_TIME":2015-08-12 10:40:21.459000+00:00,
 "viewing_zenith":{B10:ndarray(dtype=float16),[...],B09:ndarray(dtype=float16)},
 "viewing_azimut":{B10:ndarray(dtype=float16),[...],B09:ndarray(dtype=float16)},
 "sun_mean_azimuth":161.57,
 "sun_mean_zenith":36.21,
 "solar_irradiance:{B10:367.15,[...],B09:813.04},
 "aux_data":{},
 "spatial_samplings":{
        60.0:{
        XDIM:60,
        NCOLS:1830,
        NROWS:1830,
        YDIM:-60,
        ULX:399960,
        ULY:5600040
        },
        10.0:{
        XDIM:10,
        NCOLS:10980,
        NROWS:10980,
        YDIM:-10,
        ULX:399960,
        ULY:5600040
        },
        20.0:{
        XDIM:20,
        NCOLS:5490,
        NROWS:5490,
        YDIM:-20,
        ULX:399960,
        ULY:5600040
        }}
_validate()[source]
ecmwf_xi()[source]
image_subsample(channels, target_resolution, order=3)[source]
Parameters:
  • channels – list of strings with channel names

  • target_resolution – float

  • order – interpolation order, integer

Returns:

data as desired

image_to_rgb(rgb_bands=('B11', 'B08', 'B03'), rgb_gamma=(1.0, 1.0, 1.0), hist_chop_off_fraction=0.01, output_size=None, max_hist_pixel=1000000, resample_order=3)[source]
class sicor.sensors.S2MSI.S2Image.S2Image(granule_path, import_bands='all', namespace_candidate=None, aux_fields=None, default_u=1.0, target_resolution=None, dtype_float=<class 'numpy.float16'>, dtype_int=<class 'numpy.int16'>, unit='reflectance', interpolation_order=1, data_mode='dense', driver='OpenJpeg2000', call_cmd=None, logger=None, slice_x=slice(None, None, None), slice_y=slice(None, None, None), default_solar_irradiance={'B01': 1913.57, 'B02': 1941.63, 'B03': 1822.61, 'B04': 1512.79, 'B05': 1425.56, 'B06': 1288.32, 'B07': 1163.19, 'B08': 1036.39, 'B09': 813.04, 'B10': 367.15, 'B11': 245.59, 'B12': 85.25, 'B8A': 955.19}, **kwarg)[source]

Bases: RSImage

Load Sentinel-2 Level-1C or Level-2A product.

Reads Sentinel-2 MSI data into numpy array. Images for different channels are resampled to a common sampling :param granule_path: path to granule folder, folder should contain IMG_DATA folder and S2A_[..].xml file :param import_bands: list of bands to import, default: [‘B01’, ‘B02’, ‘B03’, ‘B04’, ‘B05’, ‘B06’, ‘B07’, ‘B08’,

‘B8A’, ‘B09’, ‘B10’, ‘B11’, ‘B12’,]

Parameters:
  • namespace_candidate – for XML file, or None, then several default namespaces are tested

  • target_resolution – spatial resolution in meter, or None for data not interpolated

  • interpolation_order – integer for interpolation 1,2,3

  • data_mode – either “dense” or “sparse”

  • aux_fields – either None or dict of to be loaded aux fields, e.g. {“cwv”:[ss],”spr”:[ss],”ozo”:[ss]} with ss being “mean” or iterable of spatial samplings, e.g. [20.0] or [20.0,60.0]

  • driver – should be “OpenJpeg2000” -> glymur, “kdu_expand”->shell command, “gdal_[driver] e.g. gdal_JP2ECW gdal_JPEG2000, gdal_JP2OpenJPEG,gdal_JP2KAK

..todo:: Real nodata mask

__rd()
__read_img(fn)
__read_jp2_kdu_app(call_cmd=None)
static _band_name_l1c(fn)[source]

S2 helper function, parse band name from jp2 file name :param fn: filename :return: string with band name

static _band_name_l2a(fn)[source]
static _spatial_sampling_msk(fn)[source]
bad_data_mask(image_data)[source]

Return mask of bad data :param image_data: numpy array :return: 2D boolean array

static find_in_xml(xml, *branch)[source]

S2 xml helper function :param xml: xml object :param branch: iterate to branches using find :return: xml object, None if nothing was found

static find_in_xml_root(namespace, xml_root, branch, *branches, findall=None)[source]

S2 xml helper function, search from root :param namespace: :param xml_root: :param branch: first branch, is combined with namespace :param branches: repeated find’s along these parameters :param findall: if given, at final a findall :return: found xml object, None if nothing was found

static gdal_read(fnjp, driver_name)[source]

Read image file using gdal.

static geotransform2mapinfo(gt, prj)[source]

Builds an ENVI map info from given GDAL GeoTransform and Projection :param gt: GDAL GeoTransform, e.g. (249885.0, 30.0, 0.0, 4578615.0, 0.0, -30.0) :param prj: GDAL Projection - WKT Format :returns: ENVI map info, e.g. [ UTM , 1 , 1 , 256785.0 , 4572015.0 , 30.0 , 30.0 , 43 , North , WGS-84 ] :rtype: list

get_granule_metadata_xml()[source]

Try to find metadata xml file for the granule.

static get_projection(file_name)[source]

:param file_name string, points to filename :return: return {“gt”:geotransform,”prj”:coordinate projections string} for filename :rtype dict

static get_values_from_xml(leaf, dtype=<class 'float'>)[source]

S2 xml helper function :param leaf: xml object which is searched for VALUES tag which are then composed into a numpy array :param dtype: dtype of returned numpy array :return: numpy array

static parse_s2_granule_xml(fn, namespace)[source]

parse XML file in granule folder and return metadata :param fn: full filename tile xml file :param namespace: xml namespace :return: dictionary with metadata

static parse_s2_product_xml(fn)[source]

S2 XML helper function to parse product xml file :param fn: file name of xml file :return: metadata dictionary

static read_aux_data(fn)[source]

Read grib file with aux data, return dictionary :param fn: path to granule :return: dict with data

static save_rgb_image(rgb_img, fn, dpi=100.0)[source]

Save image as RGB to file system.

static transform_utm_to_wgs84(easting, northing, zone, south=False)[source]

returns lon, lat, altitude