WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit d5b572b

Browse files
authored
Merge pull request #81 from GeoscienceAustralia/upgrade/GA_docker_image
Upgrade/ga docker image
2 parents 7fae2fb + f51f479 commit d5b572b

File tree

7 files changed

+143
-39
lines changed

7 files changed

+143
-39
lines changed

Docker/Dockerfile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ rm $HOME/miniconda.sh
2929
ENV PATH=${CONDA_PREFIX}/bin:${PATH}
3030
RUN ${CONDA_PREFIX}/bin/conda init bash
3131

32-
# Download the opera-adt/RTC code - UPDATE VERSION AND TAG HERE IF NEEDED
33-
ARG RTC_VERSION=RTC-1.0.4
34-
ARG RTC_VERSION_TAG=v1.0.4
35-
RUN curl -sSL https://github.com/opera-adt/RTC/archive/refs/tags/$RTC_VERSION_TAG.tar.gz -o $RTC_VERSION.tar.gz &&\
32+
# Download and install the Geoscience Australia fork of the opera/RTC project
33+
# UPDATE VERSION AND TAG HERE IF NEEDED
34+
ARG RTC_VERSION=RTC-1.0.4-GA-prod
35+
ARG RTC_VERSION_TAG=v1.0.4-GA-prod
36+
RUN curl -sSL https://github.com/GeoscienceAustralia/RTC/archive/refs/tags/$RTC_VERSION_TAG.tar.gz -o $RTC_VERSION.tar.gz &&\
3637
tar -xvf $RTC_VERSION.tar.gz -C OPERA &&\
3738
rm $RTC_VERSION.tar.gz
3839

docs/workflows/aws.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ The AWS pipeline runs using a docker container. At runtime, the script [run_aws_
6868
--skip_upload_to_s3=false
6969
--scene_data_source="CDSE"
7070
--orbit_data_source="CDSE"
71-
--validate_stac=false
71+
--skip_validate_stac=false
7272
# Required inputs for linking RTC_S1_STATIC to RTC_S1
7373
# Assumes that a RTC_S1_STATIC products exist for all RTC_S1 bursts being processed
7474
--link_static_layers=false
@@ -90,7 +90,7 @@ The AWS pipeline runs using a docker container. At runtime, the script [run_aws_
9090
- `skip_upload_to_s3` -> Make the products, but skip uploading them to S3.
9191
- `scene_data_source` -> Where to download the scene slc file. Either `ASF` or `CDSE`. The default is `CDSE`.
9292
- `orbit_data_source` -> Where to download the orbit files. Either `ASF` or `CDSE`. The default is `CDSE`.
93-
- `validate_stac` -> Whether to validate the created STAC doc within the code. If the stac is invalid, products will not be uploaded.
93+
- `skip_validate_stac` -> To skip validation of the created STAC doc within the code. If the stac is invalid, products will not be uploaded.
9494
- `link_static_layers` -> Flag to link RTC_S1_STATIC to RTC_S1
9595
- `linked_static_layers_s3_bucket` -> bucket where RTC_S1_STATIC stored
9696
- `linked_static_layers_s3_project_folder` -> folder within bucket where RTC_S1_STATIC stored
@@ -99,9 +99,9 @@ The AWS pipeline runs using a docker container. At runtime, the script [run_aws_
9999

100100
**Final paths of products**:
101101

102-
- **RTC_S1** -> final path will be `s3_bucket/s3_project_folder/collection/burst_id/burst_year/burst_month/burst_day/*files*`
103-
- **RTC_S1_STATIC** -> final path will be `s3_bucket/s3_project_folder/collection/burst_id/*files*`
104-
102+
Final product output paths follow the following structure. odc-product is determined by factors such as the input scene polarisations.
103+
- **RTC_S1** -> s3_bucket/s3_project_folder/c{collection_number}/collection/odc_product_name/burst_id/year/month/day/*files
104+
- **RTC_S1_STATIC** -> s3_bucket/s3_project_folder/c{collection_number}/collection/odc_product_name/burst_id/*files
105105

106106
## Environment Variables
107107

sar_pipeline/aws/cli.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
)
2929
from sar_pipeline.utils.s3upload import push_files_in_folder_to_s3
3030
from sar_pipeline.utils.general import log_timing
31+
from sar_pipeline.utils.spatial import write_burst_geometries_to_geojson
3132

3233
from dem_handler.dem.cop_glo30 import get_cop30_dem_for_bounds
3334
from dem_handler.dem.rema import get_rema_dem_for_bounds
@@ -171,6 +172,13 @@
171172
help="Where to download the scene from.",
172173
)
173174
@click.option("--make-folders", required=False, default=True, help="Create folders")
175+
@click.option(
176+
"--save-burst-geometries",
177+
required=False,
178+
default=False,
179+
is_flag=True,
180+
help="Save the burst geometries to a geojson",
181+
)
174182
@log_timing
175183
def get_data_for_scene_and_make_run_config(
176184
scene,
@@ -194,6 +202,7 @@ def get_data_for_scene_and_make_run_config(
194202
scene_data_source,
195203
orbit_data_source,
196204
make_folders,
205+
save_burst_geometries,
197206
):
198207
"""Download the required data for the RTC/opera and create a configuration
199208
file for the run that points to appropriate files and has the required settings
@@ -329,6 +338,13 @@ def get_data_for_scene_and_make_run_config(
329338
burst_geoms_to_process = [
330339
all_scene_burst_info[id_]["geometry"] for id_ in burst_id_list_to_process
331340
]
341+
# write the geometries to a geojson. Useful for debugging if needed
342+
if save_burst_geometries:
343+
write_burst_geometries_to_geojson(
344+
burst_id_list_to_process,
345+
burst_geoms_to_process,
346+
out_folder / f"{scene}_burst_geoms.json",
347+
)
332348
combined_burst_geom = shapely.ops.unary_union(burst_geoms_to_process)
333349
logger.info(f"The scene shape is : {scene_polygon}")
334350
logger.info(f"The scene bounds are : {scene_polygon.bounds}")
@@ -595,6 +611,7 @@ def make_rtc_opera_stac_and_upload_bursts(
595611
if link_static_layers and product == "RTC_S1":
596612
# link to static layer metadata is in the .h5 file
597613
# use this to map assets to the file
614+
logger.info("Linking static layers to product")
598615
burst_stac_manager.add_linked_static_layer_assets_and_link()
599616
stac_filename = "metadata.json"
600617
burst_stac_manager.add_self_link(filename=stac_filename)
@@ -608,7 +625,9 @@ def make_rtc_opera_stac_and_upload_bursts(
608625
burst_stac_manager.item.validate()
609626
logger.info("STAC is valid.")
610627
except Exception as e:
611-
logger.error(f"STAC validation failed: {e}")
628+
logger.error(
629+
f"STAC validation failed, correct error or run without --validate-stac flag.\n{e}"
630+
)
612631
raise
613632
else:
614633
logger.warning(

sar_pipeline/aws/metadata/stac.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,11 @@ def add_properties_from_h5(self):
363363
)
364364
self.item.properties["sarard:ionospheric_correction_applied"] = False
365365

366-
# TODO fill with study result values
367-
self.item.properties["sarard:geometric_accuracy_ALE"] = "TODO"
368-
self.item.properties["sarard:geometric_accuracy_rmse"] = "TODO"
369-
self.item.properties["sarard:geometric_accuracy_range"] = "TODO"
370-
self.item.properties["sarard:geometric_accuracy_azimuth"] = "TODO"
366+
# TODO when official doccument, link the study supporting these values
367+
self.item.properties["sarard:geometric_accuracy_ALE"] = 2.94
368+
self.item.properties["sarard:geometric_accuracy_rmse"] = 3.08
369+
self.item.properties["sarard:geometric_accuracy_range"] = 1.63
370+
self.item.properties["sarard:geometric_accuracy_azimuth"] = 1.92
371371

372372
# add the storage stac extension properties
373373
self.item.properties["storage:schemes"] = {
@@ -647,6 +647,7 @@ def add_linked_static_layer_assets_and_link(self):
647647
burst_static_layer_stac_url = os.path.join(
648648
static_layer_url, self.burst_id, "metadata.json"
649649
)
650+
logger.info(f"Static layer url: {burst_static_layer_stac_url}")
650651

651652
try:
652653
# Send HTTP GET request

sar_pipeline/utils/spatial.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
from shapely import wkt
44
from shapely.geometry import mapping, box, Polygon
55
from shapely import segmentize
6+
import json
7+
from pathlib import Path
68
import logging
79

10+
811
logging.basicConfig(level=logging.INFO)
912
logger = logging.getLogger(__name__)
1013

@@ -136,3 +139,44 @@ def reproject_bbox_to_geometry(
136139
segmentized_geometry = segmentize(bbox_geometry, max_segment_length=segment_length)
137140
transformed_geometry = transform_polygon(segmentized_geometry, src_crs, trg_crs)
138141
return transformed_geometry
142+
143+
144+
def write_burst_geometries_to_geojson(burst_id_list, burst_geometry_list, save_path):
145+
"""
146+
Write burst geometries and their IDs to a GeoJSON file.
147+
148+
Parameters
149+
----------
150+
burst_id_list : list of str
151+
List of burst identifiers (e.g., "t007_014545_iw2").
152+
burst_geometry_list : list of shapely.geometry.BaseGeometry
153+
List of corresponding geometries for each burst ID. Must be in the same order as `burst_id_list`.
154+
save_path : str or Path
155+
Path to save the resulting GeoJSON file. Will be overwritten if it exists.
156+
157+
Raises
158+
------
159+
ValueError
160+
If `burst_id_list` and `burst_geometry_list` have different lengths.
161+
162+
"""
163+
if len(burst_id_list) != len(burst_geometry_list):
164+
raise ValueError(
165+
"burst_id_list and burst_geometry_list must have the same length."
166+
)
167+
168+
features = []
169+
for burst_id, geom in zip(burst_id_list, burst_geometry_list):
170+
features.append(
171+
{
172+
"type": "Feature",
173+
"geometry": mapping(geom),
174+
"properties": {"burst_id": burst_id},
175+
}
176+
)
177+
178+
geojson_obj = {"type": "FeatureCollection", "features": features}
179+
180+
Path(save_path).parent.mkdir(parents=True, exist_ok=True)
181+
with open(save_path, "w", encoding="utf-8") as f:
182+
json.dump(geojson_obj, f, indent=2)

scripts/run_aws_pipeline.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ make_existing_products=false
1515
skip_upload_to_s3=false
1616
scene_data_source="ASF"
1717
orbit_data_source="ASF"
18-
validate_stac=false
18+
skip_validate_stac=false
1919
## -- WORKFLOW INPUTS TO LINK RTC_S1_STATIC in RTC_S1 metadata--
20-
# Assumes that a RTC_S1_STATIC products exist for all RTC_S1 bursts being processed
20+
# if link_static_layers, RTC_S1_STATIC products must exist for all RTC_S1 bursts being processed
2121
link_static_layers=false
2222
linked_static_layers_s3_bucket="deant-data-public-dev"
2323
linked_static_layers_s3_project_folder="ga_s1"
@@ -47,7 +47,7 @@ while [[ "$#" -gt 0 ]]; do
4747
--linked_static_layers_s3_project_folder) linked_static_layers_s3_project_folder="$2"; shift 2 ;;
4848
--scene_data_source) scene_data_source="$2"; shift 2 ;;
4949
--orbit_data_source) orbit_data_source="$2"; shift 2 ;;
50-
--validate_stac) validate_stac=true; shift ;;
50+
--skip_validate_stac) skip_validate_stac=true; shift ;;
5151
--burst_id_list)
5252
shift
5353
if [[ $# -eq 1 && -f "$1" ]]; then
@@ -112,7 +112,7 @@ echo make_existing_products : "$make_existing_products"
112112
echo skip_upload_to_s3 : "$skip_upload_to_s3"
113113
echo scene_data_source : "$scene_data_source"
114114
echo orbit_data_source : "$orbit_data_source"
115-
echo validate_stac : "$validate_stac"
115+
echo skip_validate_stac : "$skip_validate_stac"
116116

117117
# warn the user about linking static layers
118118
if [[ "$link_static_layers" = true && "$product" = "RTC_S1" ]]; then
@@ -244,7 +244,7 @@ if [ "$link_static_layers" = true ] ; then
244244
# The url link to static layers is read in from results .h5 file
245245
cmd+=( --link-static-layers)
246246
fi
247-
if [ "$validate_stac" = true ] ; then
247+
if [ "$skip_validate_stac" != true ] ; then
248248
# validate the stac doc within the code
249249
cmd+=( --validate-stac)
250250
fi

tests/sar_pipeline/test_full_aws_docker_run.py

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@
6868
except:
6969
raise FileExistsError(
7070
"Could not find env.secret file at project root containing required environment variables for run. "
71-
"Create this file with required variables or ensure environment is configured correctly "
72-
"(for example when running automated tests on GitHub)"
71+
"Create this file with required variables OR ensure environment is configured correctly "
72+
"(e.g. when running automated tests on GitHub)"
7373
)
7474

7575

@@ -86,7 +86,7 @@ def build_image():
8686
"-t",
8787
f"sar-pipeline:{docker_tag}",
8888
"-f",
89-
"Docker/Dockerfile",
89+
"Docker/isce3-v0.24.4.Dockerfile",
9090
".",
9191
],
9292
stdout=sys.stdout,
@@ -100,29 +100,68 @@ def build_image():
100100

101101
def test_docker_with_args():
102102
logging.info(f"Running full process, this may take a while...")
103+
logging.info(f"Static layers will be produced and linked to backscatter data.")
103104
run_dt = str(datetime.now()).replace(" ", "_")
104105
test_name = Path(__file__).stem
105106
test_s3_bucket = "deant-data-public-dev"
106107
test_s3_project_folder = f"TMP/sar-pipeline/{run_dt}/{test_name}"
107108
logging.info(f"Uploading outputs to : {test_s3_bucket}/{test_s3_project_folder}")
108109
docker_tag = re.sub(r"[^a-zA-Z0-9_.-]", "-", sar_pipeline.__version__)
110+
111+
logging.info(f"RUN 1: Producing Static Layers")
112+
cmd = [
113+
"docker",
114+
"run",
115+
"--rm",
116+
*ENV_VARS,
117+
f"sar-pipeline:{docker_tag}",
118+
"--scene",
119+
"S1A_IW_SLC__1SSH_20220101T124744_20220101T124814_041267_04E7A2_1DAD",
120+
"--burst_id_list",
121+
"t070_149815_iw3",
122+
"--product",
123+
"RTC_S1_STATIC",
124+
"--collection",
125+
"s1_rtc_static_c1",
126+
"--s3_bucket",
127+
test_s3_bucket,
128+
"--s3_project_folder",
129+
test_s3_project_folder,
130+
]
109131
result = subprocess.run(
110-
[
111-
"docker",
112-
"run",
113-
"--rm",
114-
*ENV_VARS,
115-
f"sar-pipeline:{docker_tag}",
116-
"--scene",
117-
"S1A_IW_SLC__1SSH_20220101T124744_20220101T124814_041267_04E7A2_1DAD",
118-
"--burst_id_list",
119-
"t070_149815_iw3",
120-
"--s3_bucket",
121-
test_s3_bucket,
122-
"--s3_project_folder",
123-
test_s3_project_folder,
124-
"--validate_stac",
125-
],
132+
cmd,
133+
stdout=sys.stdout,
134+
stderr=sys.stderr,
135+
text=True,
136+
)
137+
assert (
138+
result.returncode == 0
139+
), f"Non-zero exit code: {result.returncode}\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
140+
141+
logging.info(f"RUN 2: Producing Backscatter and Linking to Static Layers")
142+
cmd = [
143+
"docker",
144+
"run",
145+
"--rm",
146+
*ENV_VARS,
147+
f"sar-pipeline:{docker_tag}",
148+
"--scene",
149+
"S1A_IW_SLC__1SSH_20220101T124744_20220101T124814_041267_04E7A2_1DAD",
150+
"--burst_id_list",
151+
"t070_149815_iw3",
152+
"--s3_bucket",
153+
test_s3_bucket,
154+
"--s3_project_folder",
155+
test_s3_project_folder,
156+
"--link_static_layers",
157+
"--linked_static_layers_s3_project_folder",
158+
test_s3_project_folder,
159+
"--linked_static_layers_collection",
160+
"s1_rtc_static_c1",
161+
]
162+
163+
result = subprocess.run(
164+
cmd,
126165
stdout=sys.stdout,
127166
stderr=sys.stderr,
128167
text=True,

0 commit comments

Comments
 (0)