Skip to content
This repository was archived by the owner on Feb 23, 2026. It is now read-only.

Commit d7ac24a

Browse files
authored
Merge pull request #242 from brazil-data-cube/master
Merge 0.8.3 with 1.0
2 parents a883831 + e3d2d65 commit d7ac24a

15 files changed

Lines changed: 480 additions & 330 deletions

CHANGES.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ Changes
2121
=======
2222

2323

24+
Version 0.8.3 (2022-10-03)
25+
--------------------------
26+
27+
- Add support to customize data cube path and data cube item (`#236 <https://github.com/brazil-data-cube/cube-builder/issues/236>`_)
28+
- Review docs related with new path format cubes
29+
30+
2431
Version 1.0.0a1 (2022-09-27)
2532
----------------------------
2633

INSTALL.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Install in development mode:
7979

8080
.. code-block:: shell
8181
82+
$ pip3 install -U pip setuptools wheel
8283
$ pip3 install -e .[all]
8384
8485

USING.rst

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,21 @@ The response will have status code ``201`` and the body::
126126
Creating data cube Landsat-8
127127
----------------------------
128128

129-
In order to create data cube ``Landsat-8`` monthly using the composite function ``Least Cloud Cover First`` (`LC8_30_1M_LCF`), use the following command to create data cube metadata::
129+
In order to create data cube ``Landsat-8`` monthly using the composite function ``Least Cloud Cover First`` (`LC8-1M`), use the following command to create data cube metadata::
130130

131131
curl --location \
132132
--request POST '127.0.0.1:5000/cubes' \
133133
--header 'Content-Type: application/json' \
134134
--data-raw '
135135
{
136-
"datacube": "LC8",
136+
"datacube": "LC8-1M",
137+
"datacube_identity": "LC8",
137138
"grs": "BRAZIL_MD",
138139
"title": "Landsat-8 (OLI) Cube Monthly - v001",
139140
"resolution": 30,
140141
"version": 1,
141142
"metadata": {
142-
"license": "MIT",
143+
"license": "proprietary",
143144
"platform": {
144145
"code": "Landsat-8",
145146
"instruments": "OLI"
@@ -230,7 +231,7 @@ Brazil Data Cube environment. If you don't have any account, please, refer to `B
230231
Once the data cube definition is created, you can trigger a data cube using the following command::
231232

232233
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
233-
cube-builder build LC8_30_1M_LCF \
234+
cube-builder build LC8-1M \
234235
--stac-url https://brazildatacube.dpi.inpe.br/stac/ \
235236
--collections=LC8_SR-1 \
236237
--tiles=011009 \
@@ -244,12 +245,12 @@ Once the data cube definition is created, you can trigger a data cube using the
244245

245246
# Using curl (Make sure to execute cube-builder run)
246247
curl --location \
247-
--request POST '127.0.0.1:5000/start-cube' \
248+
--request POST '127.0.0.1:5000/start' \
248249
--header 'Content-Type: application/json' \
249250
--data-raw '{
250251
"stac_url": "https://brazildatacube.dpi.inpe.br/stac/",
251252
"token": "<USER_BDC_TOKEN>",
252-
"datacube": "LC8_30_1M_LCF",
253+
"datacube": "LC8-1M",
253254
"collections": ["LC8_SR-1"],
254255
"tiles": ["011009"],
255256
"start_date": "2019-01-01",
@@ -278,13 +279,14 @@ In order to create data cube Sentinel 2, use the following command to create dat
278279
--header 'Content-Type: application/json' \
279280
--data-raw '
280281
{
281-
"datacube": "S2",
282+
"datacube": "S2-16D",
283+
"datacube_identity": "S2",
282284
"grs": "BRAZIL_SM",
283285
"title": "Sentinel-2 SR - Cube LCF 16 days -v001",
284286
"resolution": 10,
285287
"version": 1,
286288
"metadata": {
287-
"license": "MIT",
289+
"license": "proprietary",
288290
"platform": {
289291
"code": "Sentinel-2",
290292
"instruments": "MSI"
@@ -364,11 +366,11 @@ In order to create data cube Sentinel 2, use the following command to create dat
364366
}
365367
}'
366368
367-
In order to trigger a data cube, we are going to use a collection `S2_10_16D_LCF-1` made with Surface Reflectance using Sen2Cor::
369+
In order to trigger a data cube, we are going to use a collection `S2-16-1` made with Surface Reflectance using Sen2Cor::
368370

369371
# Using cube-builder command line
370372
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
371-
cube-builder build S2_10_16D_LCF \
373+
cube-builder build S2-16D \
372374
--stac-url https://brazildatacube.dpi.inpe.br/stac/ \
373375
--collections=S2_L2A-1 \
374376
--tiles=017019 \
@@ -389,12 +391,14 @@ In order to create data cube CBERS4 AWFI, use the following command to create da
389391
--header 'Content-Type: application/json' \
390392
--data-raw '
391393
{
392-
"datacube": "CB4",
394+
"datacube": "CB4-16D",
395+
"datacube_identity": "CB4",
393396
"grs": "BRAZIL_LG",
394397
"title": "CBERS-4 (AWFI) SR - Data Cube LCF 16 days - v001",
395398
"resolution": 64,
396399
"version": 1,
397400
"metadata": {
401+
"license": "cc-by-sa-3.0",
398402
"platform": {
399403
"code": "CBERS-4",
400404
"instruments": "AWFI"
@@ -473,7 +477,7 @@ Trigger data cube generation with following command:
473477
474478
# Using cube-builder command line
475479
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
476-
cube-builder build CB4_64_16D_LCF \
480+
cube-builder build CB4-16D \
477481
--stac-url https://brazildatacube.dpi.inpe.br/stac/ \
478482
--collections=CBERS4_AWFI_L4_SR \
479483
--tiles=005004 \
@@ -489,21 +493,21 @@ When the ``Cube-Builder`` could not generate data cube for any unknown issue, yo
489493
with the same command you have dispatched::
490494

491495
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
492-
cube-builder build CB4_64_16D_LCF \
496+
cube-builder build CB4-16D \
493497
--stac-url https://brazildatacube.dpi.inpe.br/stac/ \
494498
--collections=CBERS4_AWFI_L4_SR \
495-
--tiles=022024 \
499+
--tiles=005004 \
496500
--start=2019-01-01 \
497501
--end=2019-01-31 \
498502
--token <USER_BDC_TOKEN>
499503

500504
It will reuse most of files that were already processed, executing only the failed tasks. If you notice anything suspicious or want to re-create theses files again, use the option ``--force``::
501505

502506
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
503-
cube-builder build CB4_64_16D_LCF \
507+
cube-builder build CB4-16D \
504508
--stac-url https://brazildatacube.dpi.inpe.br/stac/ \
505509
--collections=CBERS4_AWFI_L4_SR \
506-
--tiles=022024 \
510+
--tiles=005004 \
507511
--start=2019-01-01 \
508512
--end=2019-01-31 \
509513
--token <USER_BDC_TOKEN> \
@@ -515,10 +519,10 @@ Data Cube Parameters
515519

516520
The ``Cube-Builder`` supports a few parameters to be set during the data cube execution.
517521

518-
In order to check the parameters associated with data cube ``CB4_64_16D_STK-1``, use the command::
522+
In order to check the parameters associated with data cube ``CB4-16D-1``, use the command::
519523

520524
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
521-
cube-builder show-parameters CB4_64_16D_LCF-1
525+
cube-builder show-parameters CB4-16D-1
522526

523527

524528
The following output represents all the parameters related with the given data cube::
@@ -532,7 +536,7 @@ The following output represents all the parameters related with the given data c
532536
You can change any parameter with the command ``cube-builder configure`` with ``DataCubeName-Version``::
533537

534538
SQLALCHEMY_DATABASE_URI="postgresql://postgres:postgres@localhost/bdc" \
535-
cube-builder configure CB4_64_16D_LCF-1 --stac-url=AnySTAC
539+
cube-builder configure CB4-16D-1 --stac-url=AnySTAC
536540

537541

538542
.. note::

cube_builder/celery/tasks.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@
3434
from ..models import Activity
3535
from ..utils import get_srid_column
3636
from ..utils.image import check_file_integrity, create_empty_raster, match_histogram_with_merges
37-
from ..utils.processing import DataCubeFragments
3837
from ..utils.processing import blend as blend_processing
39-
from ..utils.processing import build_cube_path, compute_data_set_stats, get_cube_id, get_item_id, get_or_create_model
38+
from ..utils.processing import build_cube_path, compute_data_set_stats, get_item_id, get_or_create_model
4039
from ..utils.processing import merge as merge_processing
4140
from ..utils.processing import post_processing_quality, publish_datacube, publish_merge
4241
from ..utils.timeline import temporal_priority_timeline
@@ -107,16 +106,16 @@ def warp_merge(activity, band_map, mask, force=False, data_dir=None, **kwargs):
107106
collection_id = f'{record.collection_id}-{version}'
108107

109108
if kwargs.get('reuse_data_cube'):
110-
ref_cube_idt = get_cube_id(kwargs['reuse_data_cube']['name'])
109+
ref_cube_idt = kwargs['reuse_data_cube']['name']
111110
# TODO: Should we search in Activity instead?
112111
merge_file_path = build_cube_path(ref_cube_idt, merge_date, tile_id,
113112
version=kwargs['reuse_data_cube']['version'], band=record.band,
114-
prefix=data_dir) # check published dir
113+
prefix=data_dir, composed=False, **kwargs) # check published dir
115114

116115
if merge_file_path is None:
117116
merge_file_path = build_cube_path(record.warped_collection_id, merge_date,
118117
tile_id, version=version, band=record.band,
119-
prefix=data_dir)
118+
prefix=data_dir, composed=False, **kwargs)
120119

121120
if activity['band'] == quality_band and len(activity['args']['datasets']):
122121
kwargs['build_provenance'] = True
@@ -267,9 +266,16 @@ def prepare_blend(merges, band_map: dict, reuse_data_cube=None, **kwargs):
267266

268267
version = merges[0]['args']['version']
269268
identity_cube = merges[0]['warped_collection_id']
269+
collection_ref: Collection = (
270+
Collection.query()
271+
.filter(Collection.name == merges[0]['collection_id'],
272+
Collection.version == version)
273+
.first()
274+
)
275+
composite_function = collection_ref.composite_function.alias
270276

271277
if reuse_data_cube:
272-
identity_cube = get_cube_id(reuse_data_cube['name'])
278+
identity_cube = reuse_data_cube['name']
273279
version = reuse_data_cube['version']
274280

275281
kwargs['mask'] = kwargs['mask'] or dict()
@@ -283,20 +289,20 @@ def prepare_blend(merges, band_map: dict, reuse_data_cube=None, **kwargs):
283289
if not was_reused:
284290
logging.info(f'Applying post-processing in {str(quality_file)}')
285291
post_processing_quality(quality_file, bands, identity_cube,
286-
period, merges[0]['tile_id'], quality_band, band_map,
292+
period, merges[0]['tile_id'],
293+
band_map=band_map,
287294
version=version, block_size=block_size,
288-
datasets=merges[0]['args']['datasets'])
295+
datasets=merges[0]['args']['datasets'],
296+
**kwargs)
289297
else:
290298
logging.info(f'Skipping post-processing {str(quality_file)}')
291299

292-
def _is_not_stk(_merge):
300+
def _is_not_stk(merge):
293301
"""Control flag to generate cloud mask.
294302
295303
This function is a utility to dispatch the cloud mask generation only for STK data cubes.
296304
"""
297-
collection_id = _merge['collection_id']
298-
fragments = DataCubeFragments(collection_id)
299-
return _merge['band'] == quality_band and fragments.composite_function not in ('STK', 'LCF')
305+
return merge['band'] == quality_band and composite_function not in ('STK', 'LCF')
300306

301307
for _merge in merges:
302308
# Skip quality generation for MEDIAN, AVG
@@ -306,6 +312,7 @@ def _is_not_stk(_merge):
306312

307313
activity = activities.get(_merge['band'], dict(scenes=dict()))
308314

315+
activity['composite_function'] = composite_function
309316
activity['datacube'] = _merge['collection_id']
310317
activity['warped_datacube'] = _merge['warped_collection_id']
311318
activity['band'] = _merge['band']
@@ -382,10 +389,8 @@ def _is_not_stk(_merge):
382389
# Prepare list of activities to dispatch
383390
activity_list = list(activities.values())
384391

385-
datacube = activity_list[0]['datacube']
386-
387392
# For IDENTITY data cube trigger, just publish
388-
if DataCubeFragments(datacube).composite_function == IDENTITY:
393+
if composite_function == 'IDT':
389394
task = publish.s(list(activities.values()), reuse_data_cube=reuse_data_cube, band_map=band_map, **kwargs)
390395
return task.apply_async()
391396

@@ -427,9 +432,9 @@ def blend(activity, band_map, build_clear_observation=False, reuse_data_cube=Non
427432

428433
logging.warning('Executing blend - {} - {}'.format(activity.get('datacube'), activity.get('band')))
429434

430-
return blend_processing(activity, band_map, kwargs['quality_band'], build_clear_observation,
431-
block_size=block_size, reuse_data_cube=reuse_data_cube,
432-
apply_valid_range=kwargs.get('apply_valid_range'))
435+
return blend_processing(activity, band_map,
436+
build_clear_observation=build_clear_observation,
437+
block_size=block_size, reuse_data_cube=reuse_data_cube, **kwargs)
433438

434439

435440
@celery_app.task(queue=Config.QUEUE_PUBLISH_CUBE)
@@ -468,7 +473,7 @@ def publish(blends, band_map, quality_band: str, reuse_data_cube=None, **kwargs)
468473
merges = dict()
469474
blend_files = dict()
470475

471-
composite_function = DataCubeFragments(cube.name).composite_function
476+
composite_function = cube.composite_function.alias
472477

473478
quality_blend = dict(efficacy=100, cloudratio=0)
474479

@@ -525,7 +530,8 @@ def publish(blends, band_map, quality_band: str, reuse_data_cube=None, **kwargs)
525530
continue
526531

527532
_merge_result[merge_date] = publish_merge(quick_look_bands, wcube, tile_id, merge_date, definition,
528-
reuse_data_cube=reuse_data_cube, srid=srid, data_dir=kwargs.get('data_dir'))
533+
reuse_data_cube=reuse_data_cube, srid=srid,
534+
**kwargs)
529535

530536
try:
531537
db.session.commit()

0 commit comments

Comments
 (0)