Commit c24ca205 authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Merge branch 'enhancement/provide_more_options'

parents 3615716f 7051ba14
...@@ -40,9 +40,23 @@ __author__ = 'Daniel Scheffler' ...@@ -40,9 +40,23 @@ __author__ = 'Daniel Scheffler'
class Scene_finder(object): class Scene_finder(object):
"""Scene_finder class to query the postgreSQL database to find a suitable reference scene for co-registration."""
def __init__(self, src_boundsLonLat, src_AcqDate, src_prj, src_footprint_poly, sceneID_excluded=None, def __init__(self, src_boundsLonLat, src_AcqDate, src_prj, src_footprint_poly, sceneID_excluded=None,
min_overlap=20, min_cloudcov=0, max_cloudcov=20, plusminus_days=30, plusminus_years=10): min_overlap=20, min_cloudcov=0, max_cloudcov=20, plusminus_days=30, plusminus_years=10):
"""Initialize Scene_finder.
:param src_boundsLonLat:
:param src_AcqDate:
:param src_prj:
:param src_footprint_poly:
:param sceneID_excluded:
:param min_overlap: minimum overlap of reference scene in percent
:param min_cloudcov: minimum cloud cover of reference scene in percent
:param max_cloudcov: maximum cloud cover of reference scene in percent
:param plusminus_days: maximum time interval between target and reference scene in days
:param plusminus_years: maximum time interval between target and reference scene in years
"""
self.boundsLonLat = src_boundsLonLat self.boundsLonLat = src_boundsLonLat
self.src_AcqDate = src_AcqDate self.src_AcqDate = src_AcqDate
self.src_prj = src_prj self.src_prj = src_prj
...@@ -245,7 +259,12 @@ class L1B_object(L1A_object): ...@@ -245,7 +259,12 @@ class L1B_object(L1A_object):
boundsLonLat = corner_coord_to_minmax(self.trueDataCornerLonLat) boundsLonLat = corner_coord_to_minmax(self.trueDataCornerLonLat)
footprint_poly = HLP_F.CornerLonLat_to_shapelyPoly(self.trueDataCornerLonLat) footprint_poly = HLP_F.CornerLonLat_to_shapelyPoly(self.trueDataCornerLonLat)
RSF = Scene_finder(boundsLonLat, self.acq_datetime, self.meta_odict['coordinate system string'], RSF = Scene_finder(boundsLonLat, self.acq_datetime, self.meta_odict['coordinate system string'],
footprint_poly, self.scene_ID, 20, 0, 20, 30, 10) footprint_poly, self.scene_ID,
min_overlap=CFG.spatial_ref_min_overlap,
min_cloudcov=CFG.spatial_ref_min_cloudcov,
max_cloudcov=CFG.spatial_ref_max_cloudcov,
plusminus_days=CFG.spatial_ref_plusminus_days,
plusminus_years=CFG.spatial_ref_plusminus_years)
# run spatial query # run spatial query
self.logger.info('Querying database in order to find a suitable reference scene for co-registration.') self.logger.info('Querying database in order to find a suitable reference scene for co-registration.')
...@@ -510,7 +529,8 @@ class L1B_object(L1A_object): ...@@ -510,7 +529,8 @@ class L1B_object(L1A_object):
elif self.coreg_needed and self.spatRef_available: elif self.coreg_needed and self.spatRef_available:
geoArr_ref = GeoArray(self.spatRef_scene.filePath) geoArr_ref = GeoArray(self.spatRef_scene.filePath)
geoArr_shift = GeoArray(self.arr) geoArr_shift = GeoArray(self.arr)
r_b4match, s_b4match = self.get_opt_bands4matching(target_cwlPos_nm=550, v=False) r_b4match, s_b4match = self.get_opt_bands4matching(target_cwlPos_nm=CFG.band_wavelength_for_matching,
v=False)
coreg_kwargs = dict( coreg_kwargs = dict(
r_b4match=r_b4match, r_b4match=r_b4match,
s_b4match=s_b4match, s_b4match=s_b4match,
...@@ -619,7 +639,7 @@ class L1B_object(L1A_object): ...@@ -619,7 +639,7 @@ class L1B_object(L1A_object):
cliptoextent=cliptoextent, cliptoextent=cliptoextent,
clipextent=mapBounds, clipextent=mapBounds,
align_grids=True, align_grids=True,
resamp_alg='nearest' if attrname == 'masks' else 'cubic', resamp_alg='nearest' if attrname == 'masks' else CFG.spatial_resamp_alg,
CPUs=None if CFG.allow_subMultiprocessing else 1, CPUs=None if CFG.allow_subMultiprocessing else 1,
progress=True if v else False, progress=True if v else False,
q=True, q=True,
......
...@@ -251,7 +251,10 @@ class JobConfig(object): ...@@ -251,7 +251,10 @@ class JobConfig(object):
gp('scale_factor_TOARef', json_processors['general_opts']['scale_factor_TOARef']) gp('scale_factor_TOARef', json_processors['general_opts']['scale_factor_TOARef'])
self.scale_factor_BOARef = \ self.scale_factor_BOARef = \
gp('scale_factor_BOARef', json_processors['general_opts']['scale_factor_BOARef']) gp('scale_factor_BOARef', json_processors['general_opts']['scale_factor_BOARef'])
self.mgrs_pixel_buffer = \
gp('mgrs_pixel_buffer', json_processors['general_opts']['mgrs_pixel_buffer'])
self.output_data_compression = \
gp('output_data_compression', json_processors['general_opts']['output_data_compression'])
# processor specific opts # processor specific opts
# L1A # L1A
...@@ -270,6 +273,18 @@ class JobConfig(object): ...@@ -270,6 +273,18 @@ class JobConfig(object):
json_processors['L1B']['write_output'], json_processors['L1B']['write_output'],
json_processors['L1B']['delete_output']]) json_processors['L1B']['delete_output']])
self.skip_coreg = gp('skip_coreg', json_processors['L1B']['skip_coreg']) self.skip_coreg = gp('skip_coreg', json_processors['L1B']['skip_coreg'])
self.spatial_ref_min_overlap = \
gp('spatial_ref_min_overlap', json_processors['L1B']['spatial_ref_min_overlap'])
self.spatial_ref_min_cloudcov = \
gp('spatial_ref_min_cloudcov', json_processors['L1B']['spatial_ref_min_cloudcov'])
self.spatial_ref_max_cloudcov = \
gp('spatial_ref_max_cloudcov', json_processors['L1B']['spatial_ref_max_cloudcov'])
self.spatial_ref_plusminus_days = \
gp('spatial_ref_plusminus_days', json_processors['L1B']['spatial_ref_plusminus_days'])
self.spatial_ref_plusminus_years = \
gp('spatial_ref_plusminus_years', json_processors['L1B']['spatial_ref_plusminus_years'])
self.band_wavelength_for_matching = \
gp('band_wavelength_for_matching', json_processors['L1B']['band_wavelength_for_matching'])
# L1C # L1C
self.exec_L1CP = gp('exec_L1CP', [ self.exec_L1CP = gp('exec_L1CP', [
...@@ -292,6 +307,8 @@ class JobConfig(object): ...@@ -292,6 +307,8 @@ class JobConfig(object):
json_processors['L2A']['delete_output']]) json_processors['L2A']['delete_output']])
self.align_coord_grids = gp('align_coord_grids', json_processors['L2A']['align_coord_grids']) self.align_coord_grids = gp('align_coord_grids', json_processors['L2A']['align_coord_grids'])
self.match_gsd = gp('match_gsd', json_processors['L2A']['match_gsd']) self.match_gsd = gp('match_gsd', json_processors['L2A']['match_gsd'])
self.spatial_resamp_alg = gp('spatial_resamp_alg', json_processors['L2A']['spatial_resamp_alg'])
self.clip_to_extent = gp('clip_to_extent', json_processors['L2A']['clip_to_extent'])
# L2B # L2B
self.exec_L2BP = gp('exec_L2BP', [ self.exec_L2BP = gp('exec_L2BP', [
......
...@@ -45,7 +45,9 @@ ...@@ -45,7 +45,9 @@
"target_radunit_optical": "BOA_Ref", /*'Rad' / 'TOA_Ref' / 'BOA_Ref'*/ "target_radunit_optical": "BOA_Ref", /*'Rad' / 'TOA_Ref' / 'BOA_Ref'*/
"target_radunit_thermal": "Rad", /*'Rad' / 'Temp'*/ "target_radunit_thermal": "Rad", /*'Rad' / 'Temp'*/
"scale_factor_TOARef": 10000, "scale_factor_TOARef": 10000,
"scale_factor_BOARef": 10000 "scale_factor_BOARef": 10000,
"mgrs_pixel_buffer": 10, /*pixel buffer to apply to each mgrs tile polygon when clipping output data*/
"output_data_compression": false /*compress output data*/
}, },
"L1A": { /*Level 1A processing: Data import and metadata homogenization*/ "L1A": { /*Level 1A processing: Data import and metadata homogenization*/
...@@ -61,7 +63,13 @@ ...@@ -61,7 +63,13 @@
"run_processor": true, "run_processor": true,
"write_output": true, "write_output": true,
"delete_output": true, "delete_output": true,
"skip_coreg": false "skip_coreg": false,
"spatial_ref_min_overlap": 20, /*minimum overlap of reference scene in percent*/
"spatial_ref_min_cloudcov": 0, /*minimum cloud cover of reference scene in percent*/
"spatial_ref_max_cloudcov": 20, /*maximum cloud cover of reference scene in percent*/
"spatial_ref_plusminus_days": 30, /*maximum time interval between target and reference scene in days*/
"spatial_ref_plusminus_years": 10, /*maximum time interval between target and reference scene in years*/
"band_wavelength_for_matching": 550 /*optimal wavelength [nm] of the spectral bands used for matching*/
}, },
"L1C": { /*Level 1C processing: atmospheric correction*/ "L1C": { /*Level 1C processing: atmospheric correction*/
...@@ -86,7 +94,11 @@ ...@@ -86,7 +94,11 @@
"write_output": true, "write_output": true,
"delete_output": true, "delete_output": true,
"align_coord_grids": true, /*allows to force deactivation of image resampling*/ "align_coord_grids": true, /*allows to force deactivation of image resampling*/
"match_gsd": true "match_gsd": true,
"spatial_resamp_alg": "cubic", /*the resampling algorithm to be used if neccessary
(valid algorithms: nearest, bilinear, cubic, cubic_spline, lanczos,
average, mode, max, min, med, q1, q3)*/
"clip_to_extent": true /*whether to clip the output to its actual corner coordinates*/
}, },
"L2B": { /*Level 2B processing: spectral homogenization*/ "L2B": { /*Level 2B processing: spectral homogenization*/
......
...@@ -48,6 +48,8 @@ gms_schema_input = dict( ...@@ -48,6 +48,8 @@ gms_schema_input = dict(
target_radunit_thermal=dict(type='string', required=False, allowed=['Rad', 'Temp']), target_radunit_thermal=dict(type='string', required=False, allowed=['Rad', 'Temp']),
scale_factor_TOARef=dict(type='integer', required=False), scale_factor_TOARef=dict(type='integer', required=False),
scale_factor_BOARef=dict(type='integer', required=False), scale_factor_BOARef=dict(type='integer', required=False),
mgrs_pixel_buffer=dict(type='integer', required=False),
output_data_compression=dict(type='boolean', required=False),
)), )),
L1A=dict(type='dict', required=False, schema=dict( L1A=dict(type='dict', required=False, schema=dict(
run_processor=dict(type='boolean', required=False), run_processor=dict(type='boolean', required=False),
...@@ -61,6 +63,12 @@ gms_schema_input = dict( ...@@ -61,6 +63,12 @@ gms_schema_input = dict(
write_output=dict(type='boolean', required=False), write_output=dict(type='boolean', required=False),
delete_output=dict(type='boolean', required=False), delete_output=dict(type='boolean', required=False),
skip_coreg=dict(type='boolean', required=False), skip_coreg=dict(type='boolean', required=False),
spatial_ref_min_overlap=dict(type='float', required=False, min=0, max=100),
spatial_ref_min_cloudcov=dict(type='float', required=False, min=0, max=100),
spatial_ref_max_cloudcov=dict(type='float', required=False, min=0, max=100),
spatial_ref_plusminus_days=dict(type='integer', required=False),
spatial_ref_plusminus_years=dict(type='integer', required=False),
band_wavelength_for_matching=dict(type='integer', required=False, min=350, max=2500),
)), )),
L1C=dict(type='dict', required=False, schema=dict( L1C=dict(type='dict', required=False, schema=dict(
run_processor=dict(type='boolean', required=False), run_processor=dict(type='boolean', required=False),
...@@ -86,6 +94,10 @@ gms_schema_input = dict( ...@@ -86,6 +94,10 @@ gms_schema_input = dict(
delete_output=dict(type='boolean', required=False), delete_output=dict(type='boolean', required=False),
align_coord_grids=dict(type='boolean', required=False), align_coord_grids=dict(type='boolean', required=False),
match_gsd=dict(type='boolean', required=False), match_gsd=dict(type='boolean', required=False),
spatial_resamp_alg=dict(type='string', required=False,
allowed=['nearest', 'bilinear', 'cubic', 'cubic_spline', 'lanczos', 'average',
'mode', 'max', 'min', 'med', 'q1', 'q3']),
clip_to_extent=dict(type='boolean', required=False),
)), )),
L2B=dict(type='dict', required=False, schema=dict( L2B=dict(type='dict', required=False, schema=dict(
run_processor=dict(type='boolean', required=False), run_processor=dict(type='boolean', required=False),
......
...@@ -151,7 +151,8 @@ def L2A_map(L1C_objs, block_size=None): ...@@ -151,7 +151,8 @@ def L2A_map(L1C_objs, block_size=None):
# correct geometric displacements and resample to target grid # correct geometric displacements and resample to target grid
common_extent = get_common_extent([obj.trueDataCornerLonLat for obj in L2A_objs]) if len(L2A_objs) > 1 else None common_extent = get_common_extent([obj.trueDataCornerLonLat for obj in L2A_objs]) if len(L2A_objs) > 1 else None
[L2A_obj.correct_spatial_shifts(clipextent=common_extent, clipextent_prj=4326) for L2A_obj in L2A_objs] for L2A_obj in L2A_objs:
L2A_obj.correct_spatial_shifts(cliptoextent=CFG.clip_to_extent, clipextent=common_extent, clipextent_prj=4326)
# merge multiple subsystems belonging to the same scene ID to a single GMS object # merge multiple subsystems belonging to the same scene ID to a single GMS object
L2A_obj = L2A_P.L2A_object().from_sensor_subsystems(L2A_objs) if len(L2A_objs) > 1 else L2A_objs[0] L2A_obj = L2A_P.L2A_object().from_sensor_subsystems(L2A_objs) if len(L2A_objs) > 1 else L2A_objs[0]
...@@ -189,7 +190,7 @@ def L2C_map(L2B_obj): ...@@ -189,7 +190,7 @@ def L2C_map(L2B_obj):
# type: (L2B_P.L2B_object) -> L2C_P.L2C_object # type: (L2B_P.L2B_object) -> L2C_P.L2C_object
L2C_obj = L2C_P.L2C_object(L2B_obj) L2C_obj = L2C_P.L2C_object(L2B_obj)
if CFG.exec_L2CP[1]: if CFG.exec_L2CP[1]:
L2C_MRGS_tiles = L2C_obj.to_MGRS_tiles(pixbuffer=10) L2C_MRGS_tiles = L2C_obj.to_MGRS_tiles(pixbuffer=CFG.mgrs_pixel_buffer)
[MGRS_tile.to_ENVI(compression=False) for MGRS_tile in L2C_MRGS_tiles] [MGRS_tile.to_ENVI(compression=CFG.output_data_compression) for MGRS_tile in L2C_MRGS_tiles]
L2C_obj.delete_tempFiles() L2C_obj.delete_tempFiles()
return L2C_obj # contains no array data in Python mode return L2C_obj # contains no array data in Python mode
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