Commit 2bdabd85 authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Bugfix for spectral homogenization.

parent 0265d0b5
Pipeline #1880 failed with stage
in 9 minutes and 41 seconds
......@@ -63,9 +63,10 @@ class L2B_object(L2A_object):
# FIXME exclude or include thermal bands; respect sorted CWLs in context of LayerBandsAssignment
tgt_cwls = CFG.target_CWL
tgt_sat, tgt_sen = datasetid_to_sat_sen(CFG.datasetid_spectral_ref)
# NOTE: get target LBA at L2A, because spectral characteristics of target sensor do not change after AC
tgt_LBA = get_LayerBandsAssignment(
dict(Satellite=tgt_sat, Sensor=tgt_sen, Subsystem=None,
image_type='RSD', proc_level='L2B', dataset_ID=src_dsID, logger=None))
image_type='RSD', proc_level='L2A', dataset_ID=src_dsID, logger=None))
####################################################
# special cases where homogenization is not needed #
......@@ -107,18 +108,17 @@ class L2B_object(L2A_object):
kwargs=dict(kind='linear')
))
self.arr = outArr
###################
# update metadata #
###################
# TODO better band names for homogenized product -> include in get_LayerBandsAssignment
self.LayerBandsAssignment = []
self.LayerBandsAssignment = tgt_LBA
self.meta_odict['wavelength'] = list(tgt_cwls)
self.meta_odict['bands'] = len(tgt_cwls)
if 'band names' in self.meta_odict: # FIXME bug workaround
del self.meta_odict['band names'] # TODO
self.arr = outArr
class SpectralHomogenizer(object):
"""Class for applying spectral homogenization by applying an interpolation or machine learning approach."""
......
......@@ -31,6 +31,14 @@ class FmaskError(RuntimeError):
"""An error within the Fmask wrapper of gms_preprocessing."""
#######
# AC #
#######
class ACNotSupportedError(RuntimeError):
"""An error raised if there is currently no AC supported for the current sensor."""
####################################
# SPECTRAL HOMOGENIZATION EXCEPTIONS
####################################
......@@ -49,5 +57,5 @@ class ClassifierNotAvailableError(RuntimeError):
def __str__(self):
return 'No %s classifier available for predicting %s %s %s from %s %s %s'\
% (self.spechomo_method, self.src_sat, self.src_sen, self.src_LBA,
self.tgt_sat, self.tgt_sen, self.tgt_LBA)
% (self.spechomo_method, self.tgt_sat, self.tgt_sen, self.tgt_LBA,
self.src_sat, self.src_sen, self.src_LBA,)
......@@ -29,7 +29,10 @@ from gms_preprocessing.algorithms import geoprocessing as GEOP
from gms_preprocessing.misc import helper_functions as HLP_F
from gms_preprocessing.misc import database_tools as DB_T
from gms_preprocessing.misc.path_generator import path_generator, get_path_ac_options
from gms_preprocessing.misc.definition_dicts import get_GMS_sensorcode, is_dataset_provided_as_fullScene
from gms_preprocessing.misc.definition_dicts import get_GMS_sensorcode, is_dataset_provided_as_fullScene, \
datasetid_to_sat_sen
from gms_preprocessing.misc.exceptions import ACNotSupportedError
from sicor.options import get_options as get_ac_options
......@@ -1859,14 +1862,11 @@ def get_LayerBandsAssignment(GMS_identifier, nBands=None, sort_by_cwl=None, no_t
if GMS_identifier['proc_level'] not in [None, 'L1A', 'L1B']: # TODO replace with enum procL
if CFG.target_radunit_optical == 'BOA_Ref':
path_ac_options = get_path_ac_options(GMS_identifier)
if path_ac_options and os.path.exists(path_ac_options):
# FIXME this does not work for L7
# NOTE: don't validate because options contain pathes that do not exist on another server
ac_bandNs = get_ac_options(path_ac_options, validation=False)['AC']['bands']
ac_out_LBA = [bN.split('B0')[1] if bN.startswith('B0') else bN.split('B')[1] for bN in ac_bandNs]
# return LBA after AC
try:
ac_out_LBA = get_LBA_after_AC(GMS_identifier)
LayerBandsAssignment = [i for i in LayerBandsAssignment if i in ac_out_LBA]
else:
except ACNotSupportedError:
# atmospheric correction is not yet supported -> LBA will be the same after L1C
pass
......@@ -1875,14 +1875,48 @@ def get_LayerBandsAssignment(GMS_identifier, nBands=None, sort_by_cwl=None, no_t
if GMS_identifier['dataset_ID'] == CFG.datasetid_spectral_ref:
pass # return normal LBA from above
elif CFG.datasetid_spectral_ref is not None:
# the target sensor is NOT a custom sensor but has the spectral characteristics of a known sensor
# => use the LBA of the target sensor after AC as the new LBA for the requested sensor
# find out how the spectral characteristics of this known target sensor look like after AC
tgt_sat, tgt_sen = datasetid_to_sat_sen(CFG.datasetid_spectral_ref)
tgt_GMSid = dict(image_type='RSD', Satellite=tgt_sat, Sensor=tgt_sen, Subsystem='', proc_level='L2A',
dataset_ID='', logger=None)
try:
tgt_sen_LBA = get_LBA_after_AC(tgt_GMSid)
except ACNotSupportedError:
# use the target sensor LBA before AC (because target sensor could not be atmospherically corrected)
tgt_GMSid.update(dict(proc_level='L1B'))
tgt_sen_LBA = get_LayerBandsAssignment(tgt_GMSid)
LayerBandsAssignment = tgt_sen_LBA
else:
# TODO check if dataset belongs to a known datasetid and use LBA of this dataset
# return a LBA matching the number of bands after spectral homogenization
# fallback: return a LBA matching the number of bands after spectral homogenization
LayerBandsAssignment = [str(i + 1) for i in range(len(CFG.target_CWL))]
return LayerBandsAssignment
def get_LBA_after_AC(GMS_identifier):
path_ac_options = get_path_ac_options(GMS_identifier)
if not path_ac_options or not os.path.exists(path_ac_options):
raise ACNotSupportedError('Atmospheric correction is not yet supported for %s %s.'
% (GMS_identifier['Satellite'], GMS_identifier['Sensor']))
# FIXME this does not work for L7
# NOTE: don't validate because options contain pathes that do not exist on another server
ac_bandNs = get_ac_options(path_ac_options, validation=False)['AC']['bands']
ac_out_LBA = [bN.split('B0')[1] if bN.startswith('B0') else bN.split('B')[1] for bN in ac_bandNs]
return ac_out_LBA
def get_dict_LayerOptTherm(GMS_identifier, LayerBandsAssignment):
dict_out = collections.OrderedDict()
[dict_out.update({lr: 'thermal' if isTHERMAL(GMS_identifier, lr) else 'optical'}) for lr in LayerBandsAssignment]
......
......@@ -387,7 +387,7 @@ class JobConfig(object):
self.virtual_sensor_name = VSSpecs['name']
# spectral specifications
self.datasetid_spectral_ref = VSSpecs['spectral_characteristics_datasetid']
self.datasetid_spectral_ref = VSSpecs['spectral_characteristics_datasetid'] # None in case of custom sensor
# FIXME column is empty a known datasetid as spectral characteristics virtual sensor is chosen:
self.target_CWL = VSSpecs['wavelengths_pos']
# FIXME column is empty a known datasetid as spectral characteristics virtual sensor is chosen:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment