Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
3# gms_preprocessing, spatial and spectral homogenization of satellite remote sensing data
4#
5# Copyright (C) 2020 Daniel Scheffler (GFZ Potsdam, daniel.scheffler@gfz-potsdam.de)
6#
7# This software was developed within the context of the GeoMultiSens project funded
8# by the German Federal Ministry of Education and Research
9# (project grant code: 01 IS 14 010 A-C).
10#
11# This program is free software: you can redistribute it and/or modify it under
12# the terms of the GNU General Public License as published by the Free Software
13# Foundation, either version 3 of the License, or (at your option) any later version.
14# Please note the following exception: `gms_preprocessing` depends on tqdm, which
15# is distributed under the Mozilla Public Licence (MPL) v2.0 except for the files
16# "tqdm/_tqdm.py", "setup.py", "README.rst", "MANIFEST.in" and ".gitignore".
17# Details can be found here: https://github.com/tqdm/tqdm/blob/master/LICENCE.
18#
19# This program is distributed in the hope that it will be useful, but WITHOUT
20# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
22# details.
23#
24# You should have received a copy of the GNU Lesser General Public License along
25# with this program. If not, see <http://www.gnu.org/licenses/>.
27"""Level 2C Processor: Quality layers"""
29import numpy as np
30from collections import OrderedDict
32from geoarray import GeoArray
34from ..misc.definition_dicts import bandslist_all_errors, get_outFillZeroSaturated
35from .L2B_P import L2B_object
36from ..options.config import GMS_config as CFG
38__author__ = 'Daniel Scheffler'
41class L2C_object(L2B_object):
42 def __init__(self, L2B_obj=None):
43 super(L2C_object, self).__init__()
45 if L2B_obj:
46 # populate attributes
47 [setattr(self, key, value) for key, value in L2B_obj.__dict__.items()]
49 self.proc_level = 'L2C'
50 self.proc_status = 'initialized'
53class AccuracyCube(GeoArray):
54 def __init__(self, GMS_obj):
55 self._GMS_obj = GMS_obj
57 # privates
58 self._layers = None
60 if self.layers:
61 GMS_obj.logger.info('Generating combined accuracy layers array..')
62 super(AccuracyCube, self).__init__(self.generate_array(),
63 geotransform=list(self.layers.values())[0].gt,
64 projection=list(self.layers.values())[0].prj,
65 bandnames=self.get_bandnames(),
66 nodata=get_outFillZeroSaturated('int16')[0])
68 else:
69 raise ValueError('The given GMS_object contains no accuracy layers for combination.')
71 @property
72 def layers(self):
73 # type: () -> OrderedDict
74 if not self._layers:
75 errs = OrderedDict((band, getattr(self._GMS_obj, band)) for band in bandslist_all_errors)
76 self._layers = \
77 OrderedDict((band, err) for band, err in errs.items() if isinstance(err, (np.ndarray, GeoArray)))
79 return self._layers
81 def get_bandnames(self):
82 bandnames = []
83 for errArrName, errArr in self.layers.items():
84 if errArrName == 'ac_errors':
85 if CFG.ac_bandwise_accuracy:
86 bandnames.extend(['AC errors %s' % bN for bN in errArr.bandnames])
87 else:
88 bandnames.append('median of AC errors')
90 elif errArrName == 'mask_clouds_confidence':
91 bandnames.append('confidence of cloud mask')
93 elif errArrName == 'spat_homo_errors':
94 bandnames.append('shift reliability percentage')
96 elif errArrName == 'spec_homo_errors':
97 if CFG.spechomo_bandwise_accuracy:
98 bandnames.extend(['error of spectral homogenization %s' % bN for bN in errArr.bandnames])
99 else:
100 bandnames.append('median error of spectral homogenization')
102 else:
103 raise RuntimeError('Error setting bandnames for %s.' % errArrName)
105 return bandnames
107 def generate_array(self):
108 err_layers = self.layers.copy() # copy OrdDict, otherwise attributes of GMS_object are overwritten
110 # validate dimensionality of ac_errors array
111 if 'ac_errors' in err_layers and not CFG.ac_bandwise_accuracy:
112 assert err_layers['ac_errors'].ndim == 2, "Received a 3D 'ac_errors' array although CFG.ac_bandwise " \
113 "accuracy is False."
115 # # validate dimensionality of spec_homo_errors array
116 if 'spec_homo_errors' in err_layers and not CFG.spechomo_bandwise_accuracy:
117 assert err_layers['spec_homo_errors'].ndim == 2, "Received a 3D 'spec_homo_errors' array although " \
118 "CFG.spechomo_bandwise_accuracy is False."
120 # stack all accuracy layers together
121 accArr = np.dstack(list(err_layers.values())).astype('int16')
123 # apply int16 nodata value
124 accArr[self._GMS_obj.arr.mask_nodata.astype(np.int8) == 0] = get_outFillZeroSaturated('int16')[0]
126 return accArr