Skip to content

Commit 22f5529

Browse files
authored
Merge pull request #84 from GeoscienceAustralia/upgrade/dem-logic
DEM Logic and Backscatter Convention Specification
2 parents d785872 + 9f8dc6d commit 22f5529

13 files changed

Lines changed: 225 additions & 143 deletions

File tree

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.pixi

Docker/Dockerfile

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,15 @@ chown -R rtc_user:rtc_user /home/rtc_user/OPERA
1818

1919
USER rtc_user
2020

21-
ENV CONDA_PREFIX=/home/rtc_user/miniconda3
22-
23-
# Install Miniconda
21+
# Install Miniforge
2422
WORKDIR /home/rtc_user
25-
RUN curl -sSL https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -o miniconda.sh &&\
26-
bash miniconda.sh -b -p ${CONDA_PREFIX} &&\
27-
rm $HOME/miniconda.sh
23+
ENV CONDA_PREFIX=/home/rtc_user/miniforge3
24+
ENV PATH=$CONDA_PREFIX/bin:$PATH
2825

29-
ENV PATH=${CONDA_PREFIX}/bin:${PATH}
30-
RUN ${CONDA_PREFIX}/bin/conda init bash
26+
RUN curl -sSL https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -o miniforge.sh &&\
27+
bash miniforge.sh -b -p $CONDA_PREFIX &&\
28+
rm miniforge.sh &&\
29+
$CONDA_PREFIX/bin/conda init bash
3130

3231
# Download and install the Geoscience Australia fork of the opera/RTC project
3332
# UPDATE VERSION AND TAG HERE IF NEEDED

docs/workflows/aws.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ The AWS pipeline runs using a docker container. At runtime, the script [run_aws_
6161
--output_crs=""
6262
--dem_type="cop_glo30"
6363
--product="RTC_S1"
64+
--backscatter_convention="gamma0"
6465
--s3_bucket="deant-data-public-dev"
6566
--s3_project_folder="experimental"
6667
--collection="s1_rtc_c1"
@@ -82,9 +83,10 @@ The AWS pipeline runs using a docker container. At runtime, the script [run_aws_
8283
- `output_crs` -> The target crs of the products. If not specified, the UTM of the scene center will be used. Expects integer values (e.g. 3031)
8384
- `dem_type` -> The type of digital elevation model (DEM) to download and use for processing. Supported values: `cop_glo30`, `REMA_32`, `REMA_10`, `REMA_2`.
8485
- `product` -> The product being created with the workflow. Must be `RTC_S1` or `RTC_S1_STATIC`.
86+
- `backscatter_convention` -> the output backscatter convention from the workflow. Note sigma0 data is referenced to the DEM. To create sigma0 ellipsoid referenced data, the beta0 layer and static incidence_angle layer is required; sigma0_ellipsoid = beta0*sin(incidence_angle).
8587
- `s3_bucket` -> the bucket to upload the products
8688
- `s3_project_folder` -> The project folder to upload to.
87-
- `collection` -> The collection which the set of products belongs. Must end with 'cX' where X is a valid integer reffering to the collection number of the product. e.g. rtc_s1_c1.
89+
- `collection` -> The collection which the set of products belongs. Must end with 'cX' where X is a valid integer referring to the collection number of the product. e.g. rtc_s1_c1.
8890
- `make_existing_products` -> Whether to generate products even if they already exist in AWS S3 under the specified product folder path `s3_bucket/s3_project_folder/collection/...`.
8991
- **WARNING** - Passing this flag will create duplicate files and overwrite existing metadata, which may affect downstream workflows.
9092
- `skip_upload_to_s3` -> Make the products, but skip uploading them to S3.

environment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,6 @@ dependencies:
3232
- ruamel-yaml>=0.18.10
3333
- s1-orbits>=0.1.3
3434
- cdsetool>=0.2.13
35-
- dem-handler @ git+https://github.com/GeoscienceAustralia/dem-handler.git@v0.2.2
35+
- dem-handler @ git+https://github.com/GeoscienceAustralia/dem-handler.git@v0.2.3
3636
- python-dotenv>=1.1.1, <2
3737
- pystac[validation]==1.13.0

pixi.lock

Lines changed: 11 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ dependencies = [
2424
"ruamel-yaml>=0.18.10",
2525
"s1-orbits>=0.1.3",
2626
"cdsetool>=0.2.13",
27-
"dem-handler @ git+https://github.com/GeoscienceAustralia/dem-handler.git@v0.2.2",
27+
"dem-handler @ git+https://github.com/GeoscienceAustralia/dem-handler.git@v0.2.3",
2828
"python-dotenv>=1.1.1,<2",
2929
"pystac[validation]==1.13.0",
3030
]

sar_pipeline/aws/cli.py

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
)
2121

2222
from sar_pipeline.aws.preparation.config import RTCConfigManager
23-
from sar_pipeline.aws.metadata.h5 import update_h5_file_metadata
2423
from sar_pipeline.aws.metadata.stac import BurstH5toStacManager
2524
from sar_pipeline.aws.metadata.odc import (
2625
make_static_layer_base_url,
@@ -35,11 +34,14 @@
3534
from dem_handler.utils.spatial import (
3635
check_s1_bounds_cross_antimeridian,
3736
get_correct_bounds_from_shape_at_antimeridian,
37+
check_dem_type_in_bounds,
3838
)
3939

4040
logging.basicConfig(level=logging.INFO)
4141
logger = logging.getLogger(__name__)
4242

43+
VALID_DEMS = ["cop_glo30", "REMA_32", "REMA_10", "REMA_2"]
44+
4345

4446
@click.command()
4547
@click.option(
@@ -69,15 +71,27 @@
6971
@click.option(
7072
"--dem-type",
7173
required=True,
72-
type=click.Choice(["cop_glo30", "REMA_32", "REMA_10", "REMA_2"]),
73-
help="The type of DEM that should be downloaded for processing the scene.",
74+
type=str,
75+
help="The type of DEM that should be downloaded for processing the scene. "
76+
"Can be passed as a string or list of preferences separated by a space. "
77+
"If DEM data does not exist in the area of the first preference, the next will be used. "
78+
"E.g. `--dem-type REMA_32 cop_glo30` will first look for the Antarctic specific REMA DEM @32m before settling on the cop_glo30. "
79+
f"Values must be one of {VALID_DEMS}",
7480
)
7581
@click.option(
7682
"--product",
7783
required=True,
7884
type=click.Choice(["RTC_S1", "RTC_S1_STATIC"]),
7985
help="The product to be made",
8086
)
87+
@click.option(
88+
"--backscatter-convention",
89+
required=False,
90+
default="gamma0",
91+
type=click.Choice(["gamma0", "sigma0", "beta0"]),
92+
help="Backscatter convention of the product to be made (gamma0, sigma0 or beta0). "
93+
"Note, sigma0 data is referenced to the DEM. See docs for information on creating ellipsoid referenced sigma0 data.",
94+
)
8195
@click.option(
8296
"--s3-bucket",
8397
required=True,
@@ -187,6 +201,7 @@ def get_data_for_scene_and_make_run_config(
187201
output_crs,
188202
dem_type,
189203
product,
204+
backscatter_convention,
190205
s3_bucket,
191206
s3_project_folder,
192207
collection,
@@ -212,6 +227,10 @@ def get_data_for_scene_and_make_run_config(
212227
logger.info(f"Data source for scene download : {scene_data_source}")
213228
logger.info(f"Data source for orbit download : {orbit_data_source}")
214229

230+
# get the preference list of dem types
231+
dem_types = dem_type.split(" ")
232+
logger.info(f"The order of DEM preference is : {dem_types}")
233+
215234
# make the base .yaml for RTC processing
216235
if product == "RTC_S1":
217236
RTC_RUN_CONFIG = RTCConfigManager(base_config="S1_RTC.yaml")
@@ -220,21 +239,22 @@ def get_data_for_scene_and_make_run_config(
220239
else:
221240
raise ValueError("product must be S1_RTC or S1_RTC_STATIC")
222241

242+
if backscatter_convention not in ["gamma0", "sigma0", "beta0"]:
243+
raise ValueError("backscatter_convention must be one of gamma0, sigma0, beta0")
244+
223245
# ensure the collection ends with cX, where X is a positive integer.
224246
# Raise error for invalid naming
225247
_ = get_collection_number(collection)
226248

227249
# sub-folders for downloads
228250
orbit_folder = download_folder / "orbits"
229251
scene_folder = download_folder / "scenes"
230-
dem_folder = download_folder / "dem" / dem_type
231252

232253
if make_folders:
233254
logger.info(f"Making output folders if not existing")
234255
download_folder.mkdir(parents=True, exist_ok=True)
235256
orbit_folder.mkdir(parents=True, exist_ok=True)
236257
scene_folder.mkdir(parents=True, exist_ok=True)
237-
dem_folder.mkdir(parents=True, exist_ok=True)
238258
out_folder.mkdir(parents=True, exist_ok=True)
239259
scratch_folder.mkdir(parents=True, exist_ok=True)
240260
run_config_save_path.parent.mkdir(parents=True, exist_ok=True)
@@ -331,9 +351,6 @@ def get_data_for_scene_and_make_run_config(
331351
)
332352
logger.info(f"File downloaded to : {ORBIT_PATHS[0]}")
333353

334-
# download the dem
335-
DEM_PATH = dem_folder / f"{scene}_dem.tif"
336-
337354
# get the shape of the area covering the bursts to be processed
338355
burst_geoms_to_process = [
339356
all_scene_burst_info[id_]["geometry"] for id_ in burst_id_list_to_process
@@ -363,13 +380,36 @@ def get_data_for_scene_and_make_run_config(
363380
bounds = get_correct_bounds_from_shape_at_antimeridian(scene_bounds)
364381
logger.info(f"The corrected scene bounds are : {bounds}")
365382
# increase the buffer to ensure DEM sufficiently covers area
366-
# shape is a little odd due to merging either side of AM
383+
# cop30 shape is a little odd due to merging either side of AM
367384
cop30_buffer_degrees = 0.8
368385
else:
369386
logger.info(f"Downloading DEM data for the combined burst bounds")
370387
bounds = combined_burst_bounds
371388
cop30_buffer_degrees = 0.3
372389

390+
logger.info(f"Finding the best DEM in order of preference: {dem_types}")
391+
392+
for dem_type in dem_types:
393+
if dem_type == "cop_glo30":
394+
dem_resolution = 30
395+
elif dem_type in ["REMA_32", "REMA_10", "REMA_2"]:
396+
dem_resolution = int(dem_type.split("_")[1])
397+
dem_in_bounds = check_dem_type_in_bounds(dem_type, dem_resolution, bounds)
398+
if dem_in_bounds:
399+
# dem has data in the bounds we want, exit with dem_type set
400+
break
401+
elif dem_type == dem_types[-1] and not dem_in_bounds:
402+
logger.warning(
403+
"No DEM data could not be found in the requested bounds. "
404+
"The bursts will be processed with ellipsoidal heights. "
405+
"Change `dem_type` if this is not desired."
406+
)
407+
408+
dem_folder = download_folder / "dem" / dem_type
409+
DEM_PATH = dem_folder / f"{scene}_dem.tif"
410+
if make_folders:
411+
dem_folder.mkdir(parents=True, exist_ok=True)
412+
373413
logger.info(f"Downloading DEM type `{dem_type}` to path : {DEM_PATH}")
374414
if dem_type == "cop_glo30":
375415
get_cop30_dem_for_bounds(
@@ -385,7 +425,6 @@ def get_data_for_scene_and_make_run_config(
385425
download_geoid=True,
386426
)
387427
elif dem_type in ["REMA_32", "REMA_10", "REMA_2"]:
388-
dem_resolution = int(dem_type.split("_")[1])
389428
get_rema_dem_for_bounds(
390429
bounds=bounds,
391430
bounds_src_crs=4326,
@@ -413,6 +452,14 @@ def get_data_for_scene_and_make_run_config(
413452
RTC_RUN_CONFIG.set(f"{gk}.input_file_group.orbit_file_path", [str(ORBIT_PATHS[0])])
414453
RTC_RUN_CONFIG.set(f"{gk}.dynamic_ancillary_file_group.dem_file", str(DEM_PATH))
415454

455+
# set the backscatter convention and if rtc_apply is true
456+
if backscatter_convention == "beta0":
457+
RTC_RUN_CONFIG.set(f"{gk}.processing.apply_rtc", False)
458+
# note output_type is still set to gamma0, but it is ignored as apply_rtc=False
459+
else:
460+
RTC_RUN_CONFIG.set(f"{gk}.processing.apply_rtc", True)
461+
RTC_RUN_CONFIG.set(f"{gk}.processing.rtc.output_type", backscatter_convention)
462+
416463
# set the dem input source
417464
if dem_type == "cop_glo30":
418465
demSource = "https://registry.opendata.aws/copernicus-dem/"
@@ -495,6 +542,13 @@ def get_data_for_scene_and_make_run_config(
495542
type=click.Choice(["RTC_S1", "RTC_S1_STATIC"]),
496543
help="The product being made. Determines bucket structure",
497544
)
545+
@click.option(
546+
"--backscatter-convention",
547+
required=False,
548+
default="gamma0",
549+
type=click.Choice(["gamma0", "sigma0", "beta0"]),
550+
help="Backscatter convention of the product to be made (gamma0, sigma0 or beta0)",
551+
)
498552
@click.option(
499553
"--collection",
500554
required=True,
@@ -550,6 +604,7 @@ def make_rtc_opera_stac_and_upload_bursts(
550604
results_folder,
551605
run_config_path,
552606
product,
607+
backscatter_convention,
553608
collection,
554609
s3_bucket,
555610
s3_project_folder,
@@ -579,17 +634,13 @@ def make_rtc_opera_stac_and_upload_bursts(
579634
f"This error might be caused by repeat runs. Delete duplicate files or change run settings."
580635
)
581636
burst_h5_filepath = burst_folder / burst_h5_files[0]
582-
burst_tif_files = list(burst_folder.glob("*.tif"))
583-
# update GeoTIFFs and h5 metadata to reflect GA processing
584-
logging.info(f"Updating .h5 file with GA parameters")
585-
update_h5_file_metadata(burst_h5_filepath)
586-
# TODO Update .tif files with GA parameters
587637
# make the stac metadata from the .h5 metadata
588638
logging.info(f"Making stac metadata from .h5 file")
589639
# initialise the class to convert data from the .h5 to a stac doc
590640
burst_stac_manager = BurstH5toStacManager(
591641
h5_filepath=burst_h5_filepath,
592642
product=product,
643+
backscatter_convention=backscatter_convention,
593644
collection=collection,
594645
s3_bucket=s3_bucket,
595646
s3_project_folder=s3_project_folder,

0 commit comments

Comments
 (0)