11#!/usr/bin/env python3
2- """Generate GeoZarr conversion parameters from collection registry .
2+ """GeoZarr conversion parameters for satellite collections .
33
4- This script exports conversion parameters (groups, flags, chunks) for
5- different satellite collections, enabling the workflow template to use
6- data-driven configuration instead of hard-coded bash conditionals.
7-
8- Environment Variable Overrides (for testing/debugging):
9- OVERRIDE_GROUPS: Override groups parameter
10- OVERRIDE_EXTRA_FLAGS: Override extra_flags parameter
11- OVERRIDE_SPATIAL_CHUNK: Override spatial_chunk parameter
12- OVERRIDE_TILE_WIDTH: Override tile_width parameter
4+ Provides conversion parameters (groups, flags, chunks) for different
5+ satellite collections. Supports Sentinel-1 and Sentinel-2 with simple
6+ prefix matching.
137
148Usage:
159 python3 get_conversion_params.py --collection sentinel-1-l1-grd
1610 python3 get_conversion_params.py --collection sentinel-2-l2a --format json
1711 python3 get_conversion_params.py --collection sentinel-2-l2a --param groups
18- OVERRIDE_GROUPS="/custom/path" python3 get_conversion_params.py --collection sentinel-2-l2a
1912"""
2013
2114from __future__ import annotations
2215
2316import argparse
2417import json
25- import os
2618import sys
27- from typing import Any , cast
28-
29- # Import collection configs from augment_stac_item
30- # In production, this would be a shared module
31- _COLLECTION_CONFIGS : dict [str , dict [str , Any ]] = {
32- "sentinel-1-l1-grd" : {
33- "pattern" : "sentinel-1-l1-grd*" ,
34- "conversion" : {
35- "groups" : "/measurements" ,
36- "extra_flags" : "--gcp-group /conditions/gcp" ,
37- "spatial_chunk" : 4096 , # Increased from 2048 for faster I/O
38- "tile_width" : 512 ,
39- },
19+ from typing import Any
20+
21+ # Conversion parameters by mission
22+ CONFIGS : dict [str , dict [str , Any ]] = {
23+ "sentinel-1" : {
24+ "groups" : "/measurements" ,
25+ "extra_flags" : "--gcp-group /conditions/gcp" ,
26+ "spatial_chunk" : 4096 ,
27+ "tile_width" : 512 ,
4028 },
41- "sentinel-2-l2a" : {
42- "pattern" : "sentinel-2-l2a*" ,
43- "conversion" : {
44- "groups" : "/quality/l2a_quicklook/r10m" ,
45- "extra_flags" : "--crs-groups /quality/l2a_quicklook/r10m" ,
46- "spatial_chunk" : 4096 ,
47- "tile_width" : 512 ,
48- },
29+ "sentinel-2" : {
30+ "groups" : "/quality/l2a_quicklook/r10m" ,
31+ "extra_flags" : "--crs-groups /quality/l2a_quicklook/r10m" ,
32+ "spatial_chunk" : 4096 ,
33+ "tile_width" : 512 ,
4934 },
5035}
5136
52- _DEFAULT_COLLECTION = "sentinel-2-l2a"
53-
54-
55- def _match_collection_config (collection_id : str ) -> dict [str , Any ] | None :
56- """Match collection ID to configuration using pattern matching."""
57- for _key , config in _COLLECTION_CONFIGS .items ():
58- # mypy needs help understanding .items() returns dict values
59- cfg = cast (dict [str , Any ], config ) # type: ignore[redundant-cast]
60- pattern = str (cfg .get ("pattern" , "" ))
61- if collection_id .startswith (pattern .rstrip ("*" )):
62- return cfg
63- return None
64-
6537
6638def get_conversion_params (collection_id : str ) -> dict [str , Any ]:
6739 """Get conversion parameters for collection.
6840
69- Environment variables can override configuration values:
70- - OVERRIDE_GROUPS: Override groups parameter
71- - OVERRIDE_EXTRA_FLAGS: Override extra_flags parameter
72- - OVERRIDE_SPATIAL_CHUNK: Override spatial_chunk parameter (integer)
73- - OVERRIDE_TILE_WIDTH: Override tile_width parameter (integer)
74-
7541 Args:
76- collection_id: Collection identifier (e.g., sentinel-1-l1-grd-dp-test)
42+ collection_id: Collection identifier (e.g., sentinel-1-l1-grd, sentinel-2-l2a -dp-test)
7743
7844 Returns:
7945 Dict of conversion parameters (groups, extra_flags, spatial_chunk, tile_width)
80-
81- Raises:
82- ValueError: If collection not found in registry
8346 """
84- config = _match_collection_config (collection_id )
85- if not config :
86- # Fallback to default - mypy needs help with dict.get() return type
87- default_config = cast (dict [str , Any ] | None , _COLLECTION_CONFIGS .get (_DEFAULT_COLLECTION )) # type: ignore[redundant-cast]
88- if not default_config :
89- raise ValueError (f"No config for collection { collection_id } " )
90- config = default_config
91-
92- conversion_params = cast (dict [str , Any ], config .get ("conversion" , {}))
93-
94- # Apply environment variable overrides (useful for testing/debugging)
95- return {
96- "groups" : os .getenv ("OVERRIDE_GROUPS" , conversion_params .get ("groups" , "" )),
97- "extra_flags" : os .getenv ("OVERRIDE_EXTRA_FLAGS" , conversion_params .get ("extra_flags" , "" )),
98- "spatial_chunk" : int (
99- os .getenv ("OVERRIDE_SPATIAL_CHUNK" , str (conversion_params .get ("spatial_chunk" , 4096 )))
100- ),
101- "tile_width" : int (
102- os .getenv ("OVERRIDE_TILE_WIDTH" , str (conversion_params .get ("tile_width" , 512 )))
103- ),
104- }
47+ # Extract mission prefix (sentinel-1 or sentinel-2)
48+ parts = collection_id .lower ().split ("-" )
49+ if len (parts ) >= 2 :
50+ prefix = f"{ parts [0 ]} -{ parts [1 ]} " # "sentinel-1" or "sentinel-2"
51+ if prefix in CONFIGS :
52+ return CONFIGS [prefix ]
53+
54+ # Default to Sentinel-2 if no match
55+ return CONFIGS ["sentinel-2" ]
10556
10657
10758def main (argv : list [str ] | None = None ) -> int :
10859 """Main entry point."""
10960 parser = argparse .ArgumentParser (
110- description = "Get GeoZarr conversion parameters from collection registry "
61+ description = "Get GeoZarr conversion parameters for satellite collections "
11162 )
11263 parser .add_argument (
11364 "--collection" ,
11465 required = True ,
115- help = "Collection ID (e.g., sentinel-1-l1-grd, sentinel-2-l2a-dp-test )" ,
66+ help = "Collection ID (e.g., sentinel-1-l1-grd, sentinel-2-l2a)" ,
11667 )
11768 parser .add_argument (
11869 "--format" ,
@@ -127,27 +78,20 @@ def main(argv: list[str] | None = None) -> int:
12778 )
12879
12980 args = parser .parse_args (argv )
130-
131- try :
132- params = get_conversion_params (args .collection )
133- except ValueError as exc :
134- # Use print for CLI output, not logging
135- print (f"Error: { exc } " , file = sys .stderr )
136- sys .exit (1 )
81+ params = get_conversion_params (args .collection )
13782
13883 if args .param :
13984 # Output single parameter (for shell variable assignment)
140- value = params .get (args .param , "" )
141- print (value )
85+ print (params .get (args .param , "" ))
14286 elif args .format == "json" :
14387 # Output JSON (for parsing with jq)
14488 print (json .dumps (params , indent = 2 ))
14589 else :
14690 # Output shell variables (for eval/source)
147- print (f"ZARR_GROUPS='{ params . get ( 'groups' , '' ) } '" )
148- print (f"EXTRA_FLAGS='{ params . get ( 'extra_flags' , '' ) } '" )
149- print (f"CHUNK={ params . get ( 'spatial_chunk' , 4096 ) } " )
150- print (f"TILE_WIDTH={ params . get ( 'tile_width' , 512 ) } " )
91+ print (f"ZARR_GROUPS='{ params [ 'groups' ] } '" )
92+ print (f"EXTRA_FLAGS='{ params [ 'extra_flags' ] } '" )
93+ print (f"CHUNK={ params [ 'spatial_chunk' ] } " )
94+ print (f"TILE_WIDTH={ params [ 'tile_width' ] } " )
15195
15296 return 0
15397
0 commit comments