Skip to content

Commit de15823

Browse files
authored
Merge pull request #149 from betonr/master
fix generate cube sentinel with 0.8.0 version - get nodata values by params
2 parents e32eb62 + 76c16c9 commit de15823

File tree

3 files changed

+102
-87
lines changed

3 files changed

+102
-87
lines changed

cube_builder_aws/cube_builder_aws/controller.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,8 @@ def get_cube_status(self, cube_name):
468468

469469

470470
def start_harmonization_process(self, params):
471-
_ = prepare_harm(self, params['scenes'], params['bucket_dst'], params['bucket_angles'])
471+
_ = prepare_harm(self, params['scenes'], params['bucket_dst'],
472+
params['bucket_angles'], params['satellite'])
472473

473474
return dict(
474475
message='Harmonization processing started with succesfully'
@@ -534,10 +535,17 @@ def start_process(self, params):
534535

535536
bands_list = []
536537
bands_ids_list = {}
538+
quality_nodata = 0
539+
nodata = 0
537540
for band in bands:
538541
if band.name.upper() not in [i['common_name'].upper() for i in indexes]:
539542
bands_list.append(band.name)
540543
bands_ids_list[band.id] = band.name
544+
if band.name == quality_band:
545+
quality_nodata = band.nodata
546+
else:
547+
nodata = band.nodata
548+
541549
elif band._metadata and band._metadata.get('expression') and band._metadata['expression'].get('value'):
542550
meta = deepcopy(band._metadata)
543551
meta['data_type'] = band.data_type
@@ -564,7 +572,7 @@ def start_process(self, params):
564572
formatted_version = format_version(cube_infos.version)
565573
not_started = prepare_merge(self, cube_infos.name, cube_infos_irregular.name, collections, satellite,
566574
bands_list, bands_ids_list, bands_ql_list, float(bands[0].resolution_x),
567-
float(bands[0].resolution_y), int(bands[0].nodata), crs, quality_band, functions, formatted_version,
575+
float(bands[0].resolution_y), crs, nodata, quality_nodata, quality_band, functions, formatted_version,
568576
params.get('force', False), mask, bands_expressions=bands_expressions,
569577
indexes_only_regular_cube=params.get('indexes_only_regular_cube'),
570578
landsat_harmonization=landsat_harmonization)

cube_builder_aws/cube_builder_aws/maestro.py

Lines changed: 84 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -275,14 +275,15 @@ def harmonization(self, activity):
275275
# MERGE
276276
###############################
277277
def prepare_merge(self, datacube, irregular_datacube, datasets, satellite, bands, bands_ids,
278-
quicklook, resx, resy, nodata, crs, quality_band, functions, version,
278+
quicklook, resx, resy, crs, nodata, quality_nodata, quality_band, functions, version,
279279
force=False, mask=None, bands_expressions=dict(), indexes_only_regular_cube=False,
280280
landsat_harmonization=None):
281281
services = self.services
282282

283283
# Build the basics of the merge activity
284284
activity = {}
285285
activity['action'] = 'merge'
286+
activity['bucket_name'] = services.bucket_name
286287
activity['datacube'] = datacube
287288
activity['irregular_datacube'] = irregular_datacube
288289
activity['version'] = version
@@ -294,9 +295,9 @@ def prepare_merge(self, datacube, irregular_datacube, datasets, satellite, bands
294295
activity['quicklook'] = quicklook
295296
activity['resx'] = resx
296297
activity['resy'] = resy
297-
activity['nodata'] = nodata
298298
activity['srs'] = crs
299-
activity['bucket_name'] = services.bucket_name
299+
activity['nodata'] = int(nodata)
300+
activity['quality_nodata'] = int(quality_nodata)
300301
activity['quality_band'] = quality_band
301302
activity['functions'] = functions
302303
activity['force'] = force
@@ -549,7 +550,7 @@ def merge_warped(self, activity):
549550
ymax = float(activity['ymax'])
550551
dist_x = float(activity['dist_x'])
551552
dist_y = float(activity['dist_y'])
552-
nodata = int(activity['nodata'])
553+
nodata = int(activity['quality_nodata']) if is_quality_band else int(activity['nodata'])
553554

554555
shape = activity.get('shape', None)
555556
if shape:
@@ -570,14 +571,13 @@ def merge_warped(self, activity):
570571

571572
is_sentinel_landsat_quality_fmask = ('LANDSAT' in satellite or satellite == 'SENTINEL-2') and \
572573
(is_quality_band and activity_mask['nodata'] != 0)
573-
source_nodata = 0
574+
source_nodata = activity.get('source_nodata', 0)
574575

575576
# Quality band is resampled by nearest, other are bilinear
576577
if is_quality_band:
577578
resampling = Resampling.nearest
578579

579-
nodata = activity_mask['nodata']
580-
source_nodata = nodata
580+
source_nodata = source_nodata if activity.get('source_nodata') else activity_mask['nodata']
581581

582582
raster = numpy.zeros((numlin, numcol,), dtype=numpy.uint16)
583583
raster_merge = numpy.full((numlin, numcol,), dtype=numpy.uint16, fill_value=source_nodata)
@@ -616,96 +616,98 @@ def merge_warped(self, activity):
616616
new_url = url
617617
if landsat_harmonization:
618618
if not is_quality_band:
619-
bucket_src = HARMONIZATION['landsat']['bucket_src']
620-
new_url = new_url.replace(bucket_src, landsat_harmonization['bucket_dst'])
619+
key_path = new_url.replace(HARMONIZATION['landsat']['bucket_src'], '')
620+
if services.s3_file_exists(bucket_name=landsat_harmonization['bucket_dst'], key=key_path, request_payer=True):
621+
bucket_src = HARMONIZATION['landsat']['bucket_src'].replace('s3://', '')
622+
new_url = new_url.replace(bucket_src, landsat_harmonization['bucket_dst'])
621623

622-
from rasterio.session import AWSSession
624+
from rasterio.session import AWSSession
623625

624-
aws_session = AWSSession(services.session, requester_pays=True)
625-
with rasterio.Env(aws_session, AWS_SESSION_TOKEN=""):
626+
aws_session = AWSSession(services.session, requester_pays=True)
627+
with rasterio.Env(aws_session, AWS_SESSION_TOKEN=""):
626628

627-
with rasterio.open(new_url) as src:
629+
with rasterio.open(new_url) as src:
628630

629-
kwargs = src.meta.copy()
631+
kwargs = src.meta.copy()
632+
kwargs.update({
633+
'width': numcol,
634+
'height': numlin
635+
})
636+
if not shape:
630637
kwargs.update({
631-
'width': numcol,
632-
'height': numlin
638+
'crs': activity['srs'],
639+
'transform': transform
633640
})
634-
if not shape:
635-
kwargs.update({
636-
'crs': activity['srs'],
637-
'transform': transform
638-
})
639-
640-
if src.profile['nodata'] is not None:
641-
source_nodata = src.profile['nodata']
642-
643-
elif 'source_nodata' in activity:
644-
source_nodata = activity['source_nodata']
645641

646-
elif 'LANDSAT' in satellite and not is_quality_band:
647-
source_nodata = nodata if src.profile['dtype'] == 'int16' else 0
642+
if src.profile['nodata'] is not None:
643+
source_nodata = src.profile['nodata']
644+
645+
elif 'source_nodata' in activity:
646+
source_nodata = activity['source_nodata']
647+
648+
elif 'LANDSAT' in satellite and not is_quality_band:
649+
source_nodata = nodata if src.profile['dtype'] == 'int16' else 0
650+
651+
elif 'CBERS' in satellite and not is_quality_band:
652+
source_nodata = nodata
648653

649-
elif 'CBERS' in satellite and not is_quality_band:
650-
source_nodata = nodata
654+
kwargs.update({
655+
'nodata': source_nodata
656+
})
651657

658+
if is_quality_band and activity_mask.get('bits'):
652659
kwargs.update({
653-
'nodata': source_nodata
660+
'blockxsize': 2048,
661+
'blockysize': 2048,
662+
'tiled': True
654663
})
655664

656-
if is_quality_band and activity_mask.get('bits'):
657-
kwargs.update({
658-
'blockxsize': 2048,
659-
'blockysize': 2048,
660-
'tiled': True
661-
})
662-
663-
with MemoryFile() as memfile:
664-
with memfile.open(**kwargs) as dst:
665-
if shape:
666-
raster = src.read(1)
667-
else:
668-
reproject(
669-
source=rasterio.band(src, 1),
670-
destination=raster,
671-
src_transform=src.transform,
672-
src_crs=src.crs,
673-
dst_transform=transform,
674-
dst_crs=activity['srs'],
675-
src_nodata=source_nodata,
676-
dst_nodata=nodata,
677-
resampling=resampling)
678-
679-
if not is_quality_band or is_sentinel_landsat_quality_fmask:
680-
valid_data_scene = raster[raster != nodata]
681-
raster_merge[raster != nodata] = valid_data_scene.reshape(numpy.size(valid_data_scene))
682-
683-
valid_data_scene = None
684-
else:
685-
factor = raster * raster_mask
686-
raster_merge = raster_merge + factor
665+
with MemoryFile() as memfile:
666+
with memfile.open(**kwargs) as dst:
667+
if shape:
668+
raster = src.read(1)
669+
else:
670+
reproject(
671+
source=rasterio.band(src, 1),
672+
destination=raster,
673+
src_transform=src.transform,
674+
src_crs=src.crs,
675+
dst_transform=transform,
676+
dst_crs=activity['srs'],
677+
src_nodata=source_nodata,
678+
dst_nodata=nodata,
679+
resampling=resampling)
680+
681+
if not is_quality_band or is_sentinel_landsat_quality_fmask:
682+
valid_data_scene = raster[raster != nodata]
683+
raster_merge[raster != nodata] = valid_data_scene.reshape(numpy.size(valid_data_scene))
684+
685+
valid_data_scene = None
686+
else:
687+
factor = raster * raster_mask
688+
raster_merge = raster_merge + factor
687689

688-
raster_mask[raster != nodata] = 0
690+
raster_mask[raster != nodata] = 0
689691

690-
if build_provenance:
691-
raster_masked = numpy.ma.masked_where(raster == nodata, raster)
692+
if build_provenance:
693+
raster_masked = numpy.ma.masked_where(raster == nodata, raster)
692694

693-
where_valid = numpy.invert(raster_masked.mask)
694-
raster_provenance[where_valid] = datasets.index(platforms[url])
695+
where_valid = numpy.invert(raster_masked.mask)
696+
raster_provenance[where_valid] = datasets.index(platforms[url])
695697

696-
where_valid = None
697-
raster_masked = None
698+
where_valid = None
699+
raster_masked = None
698700

699-
if template is None:
700-
template = dst.profile
701+
if template is None:
702+
template = dst.profile
701703

702-
template['driver'] = 'GTiff'
704+
template['driver'] = 'GTiff'
703705

704-
raster_blocks = list(dst.block_windows())
706+
raster_blocks = list(dst.block_windows())
705707

706-
if not is_quality_band:
707-
template.update({'dtype': 'int16'})
708-
template['nodata'] = nodata
708+
if not is_quality_band:
709+
template.update({'dtype': 'int16'})
710+
template['nodata'] = nodata
709711

710712

711713
raster = None
@@ -734,7 +736,7 @@ def merge_warped(self, activity):
734736
else:
735737
raster_merge = raster_merge.astype(numpy.uint8)
736738

737-
nodata = activity_mask['nodata']
739+
nodata = activity['quality_nodata']
738740

739741
# Save merged image on S3
740742
create_cog_in_s3(services, template, key, raster_merge, bucket_name, nodata=nodata)
@@ -779,7 +781,7 @@ def next_blend(services, mergeactivity):
779781
blendactivity = {}
780782
blendactivity['action'] = 'blend'
781783
for key in ['datasets', 'satellite', 'bands', 'quicklook', 'srs', 'functions', 'bands_ids',
782-
'tileid', 'start', 'end', 'dirname', 'nodata', 'bucket_name', 'quality_band',
784+
'tileid', 'start', 'end', 'dirname', 'nodata', 'bucket_name', 'quality_band', 'quality_nodata',
783785
'internal_bands', 'force', 'version', 'datacube', 'irregular_datacube', 'mask',
784786
'bands_expressions', 'indexes_only_regular_cube', 'empty_file', 'landsat_harmonization']:
785787
blendactivity[key] = mergeactivity.get(key, '')
@@ -950,9 +952,7 @@ def blend(self, activity):
950952
band = activity['band']
951953
numscenes = len(activity['scenes'])
952954

953-
nodata = int(activity.get('nodata', -9999))
954-
if band == activity['quality_band']:
955-
nodata = activity_mask['nodata']
955+
nodata = int(activity.get('nodata', -9999)) if band != activity['quality_band'] else activity['quality_nodata']
956956

957957
# Check if band ARDfiles are in activity
958958
for date_ref in activity['scenes']:
@@ -1010,6 +1010,8 @@ def blend(self, activity):
10101010
resolution = 10
10111011
mask_tuples.append((100. * efficacy / resolution, key))
10121012

1013+
mask_tuples = sorted(mask_tuples, reverse=True)
1014+
10131015
provenance_merge_map = dict()
10141016
build_provenance = activity.get('internal_band') == PROVENANCE_NAME
10151017
build_clear_observation = activity.get('internal_band') == CLEAR_OBSERVATION_NAME

cube_builder_aws/cube_builder_aws/services.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,9 @@ def search_STAC(self, activity):
516516
_ = stac['instance'].catalog
517517

518518
filter_opts['collections'] = [stac['collection']]
519-
filter_opts['query'] = dict(collections=[stac['collection']])
519+
# TODO: STAC https://landsatlook.usgs.gov/ does not conform to specification
520+
if '.usgs.gov' in stac['url']:
521+
filter_opts['query'] = dict(collections=[stac['collection']])
520522
items = stac['instance'].search(filter=filter_opts)
521523

522524
res = self._parse_stac_result(items, stac['collection'], bands, harm_bands_map)
@@ -561,11 +563,14 @@ def create_bucket(self, name, requester_pay=True):
561563
return False
562564
return True
563565

564-
def s3_file_exists(self, bucket_name=None, key=''):
566+
def s3_file_exists(self, bucket_name=None, key='', request_payer=False):
565567
try:
566568
if not bucket_name:
567569
bucket_name = self.bucket_name
568-
return self.S3client.head_object(Bucket=bucket_name, Key=key)
570+
if request_payer:
571+
return self.S3client.head_object(Bucket=bucket_name, Key=key, RequestPayer='requester')
572+
else:
573+
return self.S3client.head_object(Bucket=bucket_name, Key=key)
569574
except ClientError:
570575
return False
571576

0 commit comments

Comments
 (0)