sarpyx 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. docs/examples/advanced/batch_processing.py +1 -1
  2. docs/examples/advanced/custom_processing_chains.py +1 -1
  3. docs/examples/advanced/performance_optimization.py +1 -1
  4. docs/examples/basic/snap_integration.py +1 -1
  5. docs/examples/intermediate/quality_assessment.py +1 -1
  6. outputs/baseline/20260205-234828/__init__.py +33 -0
  7. outputs/baseline/20260205-234828/main.py +493 -0
  8. outputs/final/20260205-234851/__init__.py +33 -0
  9. outputs/final/20260205-234851/main.py +493 -0
  10. sarpyx/__init__.py +2 -2
  11. sarpyx/algorithms/__init__.py +2 -2
  12. sarpyx/cli/__init__.py +1 -1
  13. sarpyx/cli/focus.py +3 -5
  14. sarpyx/cli/main.py +106 -7
  15. sarpyx/cli/shipdet.py +1 -1
  16. sarpyx/cli/worldsar.py +549 -0
  17. sarpyx/processor/__init__.py +1 -1
  18. sarpyx/processor/core/decode.py +43 -8
  19. sarpyx/processor/core/focus.py +104 -57
  20. sarpyx/science/__init__.py +1 -1
  21. sarpyx/sla/__init__.py +8 -0
  22. sarpyx/sla/metrics.py +101 -0
  23. sarpyx/{snap → snapflow}/__init__.py +1 -1
  24. sarpyx/snapflow/engine.py +6165 -0
  25. sarpyx/{snap → snapflow}/op.py +0 -1
  26. sarpyx/utils/__init__.py +1 -1
  27. sarpyx/utils/geos.py +652 -0
  28. sarpyx/utils/grid.py +285 -0
  29. sarpyx/utils/io.py +77 -9
  30. sarpyx/utils/meta.py +55 -0
  31. sarpyx/utils/nisar_utils.py +652 -0
  32. sarpyx/utils/rfigen.py +108 -0
  33. sarpyx/utils/wkt_utils.py +109 -0
  34. sarpyx/utils/zarr_utils.py +55 -37
  35. {sarpyx-0.1.5.dist-info → sarpyx-0.1.6.dist-info}/METADATA +9 -5
  36. {sarpyx-0.1.5.dist-info → sarpyx-0.1.6.dist-info}/RECORD +41 -32
  37. {sarpyx-0.1.5.dist-info → sarpyx-0.1.6.dist-info}/WHEEL +1 -1
  38. sarpyx-0.1.6.dist-info/licenses/LICENSE +201 -0
  39. sarpyx-0.1.6.dist-info/top_level.txt +4 -0
  40. tests/test_zarr_compat.py +35 -0
  41. sarpyx/processor/core/decode_v0.py +0 -0
  42. sarpyx/processor/core/decode_v1.py +0 -849
  43. sarpyx/processor/core/focus_old.py +0 -1550
  44. sarpyx/processor/core/focus_v1.py +0 -1566
  45. sarpyx/processor/core/focus_v2.py +0 -1625
  46. sarpyx/snap/engine.py +0 -633
  47. sarpyx-0.1.5.dist-info/top_level.txt +0 -2
  48. {sarpyx-0.1.5.dist-info → sarpyx-0.1.6.dist-info}/entry_points.txt +0 -0
@@ -51,7 +51,7 @@ from sarpyx.sla import SLAProcessor
51
51
  from sarpyx.utils import io as sarpyx_io
52
52
  from sarpyx.utils import viz as sarpyx_viz
53
53
  from sarpyx.science import indices
54
- from sarpyx.snap import engine as snap_engine
54
+ from sarpyx.snapflow import engine as snap_engine
55
55
 
56
56
  # Configure logging
57
57
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@@ -42,7 +42,7 @@ from sarpyx.sla import SLAProcessor
42
42
  from sarpyx.utils import io as sarpyx_io
43
43
  from sarpyx.utils import viz as sarpyx_viz
44
44
  from sarpyx.science import indices
45
- from sarpyx.snap import engine as snap_engine
45
+ from sarpyx.snapflow import engine as snap_engine
46
46
 
47
47
  # Configure logging
48
48
  logging.basicConfig(level=logging.INFO)
@@ -50,7 +50,7 @@ from sarpyx.sla import SLAProcessor
50
50
  from sarpyx.utils import io as sarpyx_io
51
51
  from sarpyx.utils import viz as sarpyx_viz
52
52
  from sarpyx.science import indices
53
- from sarpyx.snap import engine as snap_engine
53
+ from sarpyx.snapflow import engine as snap_engine
54
54
 
55
55
  # Optional GPU acceleration imports
56
56
  try:
@@ -16,7 +16,7 @@ import matplotlib.pyplot as plt
16
16
  from pathlib import Path
17
17
 
18
18
  try:
19
- from sarpyx.snap import GPT, SNAPProcessor
19
+ from sarpyx.snapflow import GPT, SNAPProcessor
20
20
  from sarpyx.utils import visualization
21
21
  except ImportError as e:
22
22
  print(f"Error importing SARPYX: {e}")
@@ -34,7 +34,7 @@ from sarpyx.sla import SLAProcessor
34
34
  from sarpyx.utils import io as sarpyx_io
35
35
  from sarpyx.utils import viz as sarpyx_viz
36
36
  from sarpyx.science import indices
37
- from sarpyx.snap import engine as snap_engine
37
+ from sarpyx.snapflow import engine as snap_engine
38
38
 
39
39
  # Configure logging
40
40
  logging.basicConfig(level=logging.INFO)
@@ -0,0 +1,33 @@
1
+ """
2
+ SAR Processing Module.
3
+
4
+ This module provides comprehensive SAR (Synthetic Aperture Radar) processing
5
+ capabilities including focusing algorithms, autofocus methods, data I/O,
6
+ and various processing utilities.
7
+
8
+ Submodules:
9
+ core: Core processing algorithms (focus, decode, transforms)
10
+ autofocus: Autofocus algorithms and quality metrics
11
+ algorithms: High-level processing algorithms (RDA, back-projection)
12
+ data: Data readers, writers, and format converters
13
+ utils: Processing utilities and helper functions
14
+
15
+ Legacy:
16
+ AutoFocusNet: Original AutoFocusNet implementation (maintained for compatibility)
17
+ """
18
+
19
+ # Import main submodules
20
+ from . import core
21
+ from . import algorithms
22
+ from . import data
23
+ from . import utils
24
+
25
+
26
+ __all__ = [
27
+ 'core',
28
+ 'algorithms',
29
+ 'data',
30
+ 'utils',
31
+ ]
32
+
33
+ __version__ = "0.1.5"
@@ -0,0 +1,493 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ SARPyX Command Line Interface.
4
+
5
+ Main entry point for all sarpyx CLI tools.
6
+ """
7
+
8
+ import argparse
9
+ import sys
10
+ from typing import List
11
+
12
+
13
+ def create_main_parser() -> argparse.ArgumentParser:
14
+ """
15
+ Create the main argument parser with subcommands.
16
+
17
+ Returns:
18
+ Configured ArgumentParser instance.
19
+ """
20
+ parser = argparse.ArgumentParser(
21
+ prog='sarpyx',
22
+ description='SARPyX: A comprehensive toolkit for SAR data processing',
23
+ formatter_class=argparse.RawDescriptionHelpFormatter,
24
+ epilog="""
25
+ Available commands:
26
+ decode Decode Sentinel-1 Level-0 products to zarr format
27
+ focus Focus SAR data using Range-Doppler Algorithm
28
+ shipdet Ship detection using SNAP GPT engine
29
+ unzip Extract SAR data from zip archives
30
+ upload Upload data to Hugging Face Hub
31
+ worldsar Process SAR products with SNAP GPT pipelines and tiling
32
+
33
+ Examples:
34
+ sarpyx decode --input /path/to/file.dat --output /path/to/output
35
+ sarpyx focus --input /path/to/data.zarr --output /path/to/output
36
+ sarpyx shipdet --product-path /path/to/S1A_*.SAFE --outdir /path/to/output
37
+ sarpyx unzip --input /path/to/file.zip --output /path/to/output
38
+ sarpyx upload --folder /path/to/folder --repo username/dataset-name
39
+ sarpyx worldsar --input /path/to/product --output /path/to/output \\
40
+ --cuts-outdir /path/to/tiles --product-wkt "POLYGON ((...))" \\
41
+ --prod-mode S1TOPS
42
+
43
+ For command-specific help:
44
+ sarpyx <command> --help
45
+ """
46
+ )
47
+
48
+ parser.add_argument(
49
+ '--version',
50
+ action='version',
51
+ version='sarpyx-cli 0.1.5'
52
+ )
53
+
54
+ # Create subparsers for different commands
55
+ subparsers = parser.add_subparsers(
56
+ dest='command',
57
+ help='Available commands',
58
+ metavar='<command>'
59
+ )
60
+
61
+ # Decode subcommand
62
+ decode_parser = subparsers.add_parser(
63
+ 'decode',
64
+ help='Decode Sentinel-1 Level-0 products to zarr format',
65
+ description='Decode S1 L0 products (.dat files or .SAFE folders) to zarr format'
66
+ )
67
+ _add_decode_arguments(decode_parser)
68
+
69
+ # Focus subcommand
70
+ focus_parser = subparsers.add_parser(
71
+ 'focus',
72
+ help='Focus SAR data using Range-Doppler Algorithm',
73
+ description='Focus SAR data from zarr files using CoarseRDA processor'
74
+ )
75
+ _add_focus_arguments(focus_parser)
76
+
77
+ # Ship detection subcommand
78
+ shipdet_parser = subparsers.add_parser(
79
+ 'shipdet',
80
+ help='Ship detection using SNAP GPT engine',
81
+ description='Detect ships in SAR data using adaptive thresholding and object discrimination'
82
+ )
83
+ _add_shipdet_arguments(shipdet_parser)
84
+
85
+ # Unzip subcommand
86
+ unzip_parser = subparsers.add_parser(
87
+ 'unzip',
88
+ help='Extract SAR data from zip archives',
89
+ description='Extract zip files containing SAR data'
90
+ )
91
+ _add_unzip_arguments(unzip_parser)
92
+
93
+ # Upload subcommand
94
+ upload_parser = subparsers.add_parser(
95
+ 'upload',
96
+ help='Upload data to Hugging Face Hub',
97
+ description='Upload processed SAR data to Hugging Face Hub'
98
+ )
99
+ _add_upload_arguments(upload_parser)
100
+
101
+ # WorldSAR subcommand
102
+ worldsar_parser = subparsers.add_parser(
103
+ 'worldsar',
104
+ help='Process SAR products with SNAP GPT pipelines and tiling',
105
+ description='Process SAR products from multiple missions and generate tiles'
106
+ )
107
+ _add_worldsar_arguments(worldsar_parser)
108
+
109
+ return parser
110
+
111
+
112
+ def _add_decode_arguments(parser: argparse.ArgumentParser) -> None:
113
+ """
114
+ Add arguments for the decode subcommand.
115
+
116
+ Args:
117
+ parser: The subparser for decode command.
118
+ """
119
+ parser.add_argument(
120
+ '--input',
121
+ type=str,
122
+ required=True,
123
+ help='Path to .dat file or .SAFE folder'
124
+ )
125
+ parser.add_argument(
126
+ '--output',
127
+ type=str,
128
+ default='./decoded_data',
129
+ help='Output directory for decoded files (default: ./decoded_data)'
130
+ )
131
+ parser.add_argument(
132
+ '--verbose',
133
+ '-v',
134
+ action='store_true',
135
+ help='Enable verbose logging'
136
+ )
137
+ parser.add_argument(
138
+ '--debug',
139
+ action='store_true',
140
+ help='Enable debug logging'
141
+ )
142
+
143
+
144
+ def _add_focus_arguments(parser: argparse.ArgumentParser) -> None:
145
+ """
146
+ Add arguments for the focus subcommand.
147
+
148
+ Args:
149
+ parser: The subparser for focus command.
150
+ """
151
+ parser.add_argument(
152
+ '--input',
153
+ type=str,
154
+ required=True,
155
+ help='Input zarr file path'
156
+ )
157
+ parser.add_argument(
158
+ '--output',
159
+ type=str,
160
+ default='./focused_data',
161
+ help='Output directory (default: ./focused_data)'
162
+ )
163
+ parser.add_argument(
164
+ '--slice-height',
165
+ type=int,
166
+ default=15000,
167
+ help='Slice height for processing (default: 15000)'
168
+ )
169
+ parser.add_argument(
170
+ '--verbose',
171
+ '-v',
172
+ action='store_true',
173
+ help='Enable verbose output'
174
+ )
175
+ parser.add_argument(
176
+ '--keep-tmp',
177
+ action='store_true',
178
+ help='Keep temporary files after processing'
179
+ )
180
+
181
+
182
+ def _add_shipdet_arguments(parser: argparse.ArgumentParser) -> None:
183
+ """
184
+ Add arguments for the shipdet subcommand.
185
+
186
+ Args:
187
+ parser: The subparser for shipdet command.
188
+ """
189
+ # Required arguments
190
+ parser.add_argument(
191
+ '--product-path',
192
+ type=str,
193
+ required=True,
194
+ help='Path to the SAR product (.SAFE directory or zip file)'
195
+ )
196
+ parser.add_argument(
197
+ '--outdir',
198
+ type=str,
199
+ required=True,
200
+ help='Output directory for processed data'
201
+ )
202
+
203
+ # Optional processing arguments
204
+ parser.add_argument(
205
+ '--format',
206
+ type=str,
207
+ default='BEAM-DIMAP',
208
+ choices=['BEAM-DIMAP', 'GeoTIFF', 'NetCDF4-CF', 'ENVI', 'HDF5'],
209
+ help='Output format (default: BEAM-DIMAP)'
210
+ )
211
+ parser.add_argument(
212
+ '--gpt-path',
213
+ type=str,
214
+ default=None,
215
+ help='Path to GPT executable (default: None - use system PATH)'
216
+ )
217
+
218
+ # Calibration arguments
219
+ parser.add_argument(
220
+ '--output-complex',
221
+ action='store_true',
222
+ help='Output complex values for calibration (default: False)'
223
+ )
224
+ parser.add_argument(
225
+ '--polarizations',
226
+ type=str,
227
+ nargs='+',
228
+ default=['VV'],
229
+ choices=['VV', 'VH', 'HH', 'HV'],
230
+ help='Polarizations to process (default: VV)'
231
+ )
232
+
233
+ # Adaptive thresholding arguments
234
+ parser.add_argument(
235
+ '--pfa',
236
+ type=float,
237
+ default=6.5,
238
+ help='Probability of false alarm for adaptive thresholding (default: 6.5)'
239
+ )
240
+ parser.add_argument(
241
+ '--background-window-m',
242
+ type=float,
243
+ default=800.0,
244
+ help='Background window size in meters (default: 800.0)'
245
+ )
246
+ parser.add_argument(
247
+ '--guard-window-m',
248
+ type=float,
249
+ default=500.0,
250
+ help='Guard window size in meters (default: 500.0)'
251
+ )
252
+ parser.add_argument(
253
+ '--target-window-m',
254
+ type=float,
255
+ default=50.0,
256
+ help='Target window size in meters (default: 50.0)'
257
+ )
258
+
259
+ # Object discrimination arguments
260
+ parser.add_argument(
261
+ '--min-target-m',
262
+ type=float,
263
+ default=50.0,
264
+ help='Minimum target size in meters (default: 50.0)'
265
+ )
266
+ parser.add_argument(
267
+ '--max-target-m',
268
+ type=float,
269
+ default=600.0,
270
+ help='Maximum target size in meters (default: 600.0)'
271
+ )
272
+
273
+ # Processing options
274
+ parser.add_argument(
275
+ '--skip-calibration',
276
+ action='store_true',
277
+ help='Skip calibration step (default: False)'
278
+ )
279
+ parser.add_argument(
280
+ '--skip-discrimination',
281
+ action='store_true',
282
+ help='Skip object discrimination step (default: False)'
283
+ )
284
+ parser.add_argument(
285
+ '--verbose',
286
+ '-v',
287
+ action='store_true',
288
+ help='Enable verbose output (default: False)'
289
+ )
290
+
291
+
292
+ def _add_unzip_arguments(parser: argparse.ArgumentParser) -> None:
293
+ """
294
+ Add arguments for the unzip subcommand.
295
+
296
+ Args:
297
+ parser: The subparser for unzip command.
298
+ """
299
+ parser.add_argument(
300
+ '--input',
301
+ type=str,
302
+ required=True,
303
+ help='Path to zip file or directory containing zip files'
304
+ )
305
+ parser.add_argument(
306
+ '--output',
307
+ type=str,
308
+ default='./extracted_data',
309
+ help='Output directory for extracted files (default: ./extracted_data)'
310
+ )
311
+ parser.add_argument(
312
+ '--recursive',
313
+ '-r',
314
+ action='store_true',
315
+ help='Recursively search for zip files in subdirectories'
316
+ )
317
+ parser.add_argument(
318
+ '--verbose',
319
+ '-v',
320
+ action='store_true',
321
+ help='Enable verbose logging'
322
+ )
323
+
324
+
325
+ def _add_upload_arguments(parser: argparse.ArgumentParser) -> None:
326
+ """
327
+ Add arguments for the upload subcommand.
328
+
329
+ Args:
330
+ parser: The subparser for upload command.
331
+ """
332
+ parser.add_argument(
333
+ '--folder',
334
+ type=str,
335
+ required=True,
336
+ help='Path to the folder to upload'
337
+ )
338
+ parser.add_argument(
339
+ '--repo',
340
+ type=str,
341
+ required=True,
342
+ help='Repository ID in format username/repo-name'
343
+ )
344
+ parser.add_argument(
345
+ '--repo-type',
346
+ type=str,
347
+ default='dataset',
348
+ choices=['dataset', 'model', 'space'],
349
+ help='Type of repository (default: dataset)'
350
+ )
351
+ parser.add_argument(
352
+ '--verbose',
353
+ '-v',
354
+ action='store_true',
355
+ help='Enable verbose logging'
356
+ )
357
+
358
+
359
+ def _add_worldsar_arguments(parser: argparse.ArgumentParser) -> None:
360
+ """
361
+ Add arguments for the worldsar subcommand.
362
+
363
+ Args:
364
+ parser: The subparser for worldsar command.
365
+ """
366
+ parser.add_argument(
367
+ '--input',
368
+ '-i',
369
+ dest='product_path',
370
+ type=str,
371
+ required=True,
372
+ help='Path to the input SAR product.'
373
+ )
374
+ parser.add_argument(
375
+ '--output',
376
+ '-o',
377
+ dest='output_dir',
378
+ type=str,
379
+ required=True,
380
+ help='Directory to save the processed output.'
381
+ )
382
+ parser.add_argument(
383
+ '--cuts-outdir',
384
+ '--cuts_outdir',
385
+ dest='cuts_outdir',
386
+ type=str,
387
+ required=True,
388
+ help='Where to store the tiles after extraction.'
389
+ )
390
+ parser.add_argument(
391
+ '--product-wkt',
392
+ '--product_wkt',
393
+ dest='product_wkt',
394
+ type=str,
395
+ required=True,
396
+ help='WKT string defining the product region of interest.'
397
+ )
398
+ parser.add_argument(
399
+ '--prod-mode',
400
+ '--prod_mode',
401
+ dest='prod_mode',
402
+ type=str,
403
+ required=True,
404
+ help='Product mode: ["S1TOPS", "S1STRIP", "BM", "NISAR", "TSX", "CSG", "ICE"].'
405
+ )
406
+ parser.add_argument(
407
+ '--gpt-path',
408
+ dest='gpt_path',
409
+ type=str,
410
+ default=None,
411
+ help='Override GPT executable path (default: gpt_path env var).'
412
+ )
413
+ parser.add_argument(
414
+ '--grid-path',
415
+ dest='grid_path',
416
+ type=str,
417
+ default=None,
418
+ help='Override grid GeoJSON path (default: grid_path env var).'
419
+ )
420
+ parser.add_argument(
421
+ '--db-dir',
422
+ dest='db_dir',
423
+ type=str,
424
+ default=None,
425
+ help='Override database output directory (default: db_dir env var).'
426
+ )
427
+ parser.add_argument(
428
+ '--gpt-memory',
429
+ dest='gpt_memory',
430
+ type=str,
431
+ default=None,
432
+ help='Override GPT Java heap (e.g., 24G).'
433
+ )
434
+ parser.add_argument(
435
+ '--gpt-parallelism',
436
+ dest='gpt_parallelism',
437
+ type=int,
438
+ default=None,
439
+ help='Override GPT parallelism (number of tiles).'
440
+ )
441
+
442
+
443
+ def main() -> None:
444
+ """
445
+ Main entry point for sarpyx CLI.
446
+ """
447
+ parser = create_main_parser()
448
+ args = parser.parse_args()
449
+
450
+ # Check if a command was provided
451
+ if args.command is None:
452
+ parser.print_help()
453
+ sys.exit(1)
454
+
455
+ # Route to appropriate command handler
456
+ original_argv = sys.argv.copy()
457
+
458
+ try:
459
+ if args.command == 'decode':
460
+ from .decode import main as decode_main
461
+ sys.argv = ['sarpyx-decode'] + [arg for arg in original_argv[2:]]
462
+ decode_main()
463
+ elif args.command == 'focus':
464
+ from .focus import main as focus_main
465
+ sys.argv = ['sarpyx-focus'] + [arg for arg in original_argv[2:]]
466
+ focus_main()
467
+ elif args.command == 'shipdet':
468
+ from .shipdet import main as shipdet_main
469
+ sys.argv = ['sarpyx-shipdet'] + [arg for arg in original_argv[2:]]
470
+ shipdet_main()
471
+ elif args.command == 'unzip':
472
+ from .unzip import main as unzip_main
473
+ sys.argv = ['sarpyx-unzip'] + [arg for arg in original_argv[2:]]
474
+ unzip_main()
475
+ elif args.command == 'upload':
476
+ from .upload import main as upload_main
477
+ sys.argv = ['sarpyx-upload'] + [arg for arg in original_argv[2:]]
478
+ upload_main()
479
+ elif args.command == 'worldsar':
480
+ from .worldsar import main as worldsar_main
481
+ sys.argv = ['sarpyx-worldsar'] + [arg for arg in original_argv[2:]]
482
+ worldsar_main()
483
+ else:
484
+ print(f'Unknown command: {args.command}', file=sys.stderr)
485
+ sys.exit(1)
486
+ except SystemExit as e:
487
+ sys.exit(e.code)
488
+ finally:
489
+ sys.argv = original_argv
490
+
491
+
492
+ if __name__ == '__main__':
493
+ main()
@@ -0,0 +1,33 @@
1
+ """
2
+ SAR Processing Module.
3
+
4
+ This module provides comprehensive SAR (Synthetic Aperture Radar) processing
5
+ capabilities including focusing algorithms, autofocus methods, data I/O,
6
+ and various processing utilities.
7
+
8
+ Submodules:
9
+ core: Core processing algorithms (focus, decode, transforms)
10
+ autofocus: Autofocus algorithms and quality metrics
11
+ algorithms: High-level processing algorithms (RDA, back-projection)
12
+ data: Data readers, writers, and format converters
13
+ utils: Processing utilities and helper functions
14
+
15
+ Legacy:
16
+ AutoFocusNet: Original AutoFocusNet implementation (maintained for compatibility)
17
+ """
18
+
19
+ # Import main submodules
20
+ from . import core
21
+ from . import algorithms
22
+ from . import data
23
+ from . import utils
24
+
25
+
26
+ __all__ = [
27
+ 'core',
28
+ 'algorithms',
29
+ 'data',
30
+ 'utils',
31
+ ]
32
+
33
+ __version__ = "0.1.6"