Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions tools/ARIAtools/product.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Author: Simran Sangha & David Bekaert
# Author: Simran Sangha, David Bekaert
# Copyright (c) 2023, by the California Institute of Technology. ALL RIGHTS
# RESERVED. United States Government Sponsorship acknowledged.
#
Expand All @@ -25,6 +25,7 @@
import ARIAtools.util.url
import ARIAtools.util.shp
import ARIAtools.util.meta_cache
import ARIAtools.util.misc
import ARIAtools.util.s3

osgeo.gdal.UseExceptions()
Expand Down Expand Up @@ -323,8 +324,9 @@ class Product:

def __init__(self, filearg, bbox=None, workdir='./', num_threads=1,
url_version='None', nc_version='None', projection='4326',
verbose=False, tropo_models=None, layers=None, croptounion=False,
runlog=None, demfile=None, mask=None):
verbose=False, tropo_models=None, layers=None,
croptounion=False, runlog=None, demfile=None, mask=None,
bandwidth=None):
"""
Parse products and input bounding box (if specified)
"""
Expand Down Expand Up @@ -412,6 +414,12 @@ def __init__(self, filearg, bbox=None, workdir='./', num_threads=1,
# Convert relative paths to absolute paths
self.files = [os.path.abspath(i) for i in self.files]

# Filter and check NISAR bandwidths
self.files = ARIAtools.util.misc.filter_and_check_nisar_bandwidths(
self.files,
requested_bw=bandwidth
)

# capture and remove duplicate files (if applicable)
self.files = ARIAtools.util.url.url_versions(
self.files, url_version, os.path.dirname(self.files[0]))
Expand Down
104 changes: 103 additions & 1 deletion tools/ARIAtools/util/misc.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Author: Emre Havazli
# Author: Emre Havazli, Simran Sangha
# Copyright (c) 2023, by the California Institute of Technology. ALL RIGHTS
# RESERVED. United States Government Sponsorship acknowledged.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import logging
import os
import sys
import time
from collections import Counter

import numpy as np


LOGGER = logging.getLogger(__name__)


class ProgressBar:
"""Creates a text-based progress bar. Call the object with
the simple print command to see the progress bar, which looks
Expand Down Expand Up @@ -124,3 +131,98 @@ def close(self):
of future statements."""
if self.print_msg:
print(' ')

def filter_and_check_nisar_bandwidths(filenames, requested_bw=None):
"""
Checks NISAR filenames for heterogeneous bandwidths and filters.

Parameters
----------
filenames : list
List of strings (paths or URLs)
requested_bw : str, optional
Bandwidth mode (e.g., '7700', '2005') to filter by.

Returns
-------
list
Filtered filenames
"""
bandwidths = []
parsed_files = []

# Standard NISAR polarizations used in file naming
valid_pols = [
'SH', 'SV', 'DH', 'DV', 'QP', 'HHNA', 'VVNA', 'CL', 'CR'
]

for f in filenames:
basename = os.path.basename(f)
# Skip non-NISAR files
if not basename.startswith('NISAR_'):
parsed_files.append((f, None))
continue

parts = basename.split('_')
bw = None

# Locate bandwidth: usually the segment just before polarization
for i, part in enumerate(parts):
if part in valid_pols and i > 0:
bw = parts[i-1]
break

# Fallback index if polarization segment wasn't matched
if bw is None and len(parts) > 8:
bw = parts[8]

bandwidths.append(bw)
parsed_files.append((f, bw))

# If no NISAR files were found, just return original list
if not bandwidths:
return filenames

# Filter if requested
if requested_bw is not None:
filtered = [
f for f, bw in parsed_files
if bw == requested_bw or bw is None
]

if len(filtered) < len(filenames):
LOGGER.info(
f"Filtered out {len(filenames) - len(filtered)} "
f"products not matching bandwidth '{requested_bw}'."
)

parsed_files = [
(f, bw) for f, bw in parsed_files
if bw == requested_bw or bw is None
]
bandwidths = [bw for _, bw in parsed_files if bw is not None]
filenames = [f for f, bw in parsed_files]

# Check heterogeneity
bw_counts = Counter(bandwidths)
if len(bw_counts) > 1:
LOGGER.warning("*" * 70)
LOGGER.warning(
"WARNING: Heterogeneous NISAR bandwidth modes detected!"
)
LOGGER.warning(
"Mixing bandwidths can introduce severe resolution "
"and phase discontinuities."
)
LOGGER.warning("Breakdown of bandwidths found:")

total = len(bandwidths)
for bw, count in bw_counts.items():
pct = (count / total) * 100
LOGGER.warning(
f" - Mode {bw}: {count} file(s) ({pct:.1f}%)"
)
LOGGER.warning("*" * 70)

return filenames

23 changes: 22 additions & 1 deletion tools/bin/ariaDownload.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Author: Brett A. Buzzanga, David Bekaert
# Author: Brett A. Buzzanga, David Bekaert, Simran Sangha
# Copyright (c) 2023, by the California Institute of Technology. ALL RIGHTS
# RESERVED. United States Government Sponsorship acknowledged.
#
Expand All @@ -26,6 +26,7 @@
import ARIAtools.util.log
from ARIAtools.util.shp import open_shp
from ARIAtools.util.url import url_versions
import ARIAtools.util.misc
import ARIAtools.util.s3

LOGGER = logging.getLogger('ariaDownload.py')
Expand Down Expand Up @@ -135,6 +136,13 @@ def createParser():
default='info',
help='Logger log level. Default: info.'
)
parser.add_argument(
'--bandwidth', dest='bandwidth', default=None, type=str,
choices=('4000', '2000', '7700', '0500', '0000'),
help='Specify NISAR bandwidth mode to filter products. '
'Warns if multiple bandwidths are mixed. Default captures '
'all.'
)
return parser


Expand Down Expand Up @@ -267,6 +275,19 @@ def __call__(self):
scenes = self.query_asf()
urls, ifgs, is_nisar_file = get_url_ifg(scenes)

if is_nisar_file:
filtered_urls = (
ARIAtools.util.misc.filter_and_check_nisar_bandwidths(
urls,
requested_bw=self.args.bandwidth
)
)

# Realign scenes and ifgs based on the filtered urls
scenes = [s for s, u in zip(scenes, urls) if u in filtered_urls]
ifgs = [i for i, u in zip(ifgs, urls) if u in filtered_urls]
urls = filtered_urls

# Subset everything by version
if is_nisar_file and self.args.version is not None:
raise Exception(
Expand Down
10 changes: 9 additions & 1 deletion tools/bin/ariaExtract.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ def createParser():
default='info',
help='Logger log level. Default: info.'
)
parser.add_argument(
'--bandwidth', dest='bandwidth', default=None, type=str,
choices=('4000', '2000', '7700', '0500', '0000'),
help='Specify NISAR bandwidth mode to filter products. '
'Warns if multiple bandwidths are mixed. Default captures '
'all.'
)
return parser


Expand Down Expand Up @@ -211,7 +218,8 @@ def main():
url_version=args.version, nc_version=args.nc_version,
verbose=args.verbose, tropo_models=args.tropo_models,
layers=args.layers, croptounion=args.croptounion, runlog=runlog,
demfile=args.demfile, mask=args.mask)
demfile=args.demfile, mask=args.mask,
bandwidth=args.bandwidth)

# Perform initial layer, product, and correction sanity checks
args.layers, args.tropo_total, \
Expand Down
12 changes: 10 additions & 2 deletions tools/bin/ariaPlot.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#! /usr/bin/env python3
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Author: Simran Sangha & David Bekaert
# Author: Simran Sangha, David Bekaert
# Copyright (c) 2023, by the California Institute of Technology. ALL RIGHTS
# RESERVED. United States Government Sponsorship acknowledged.
#
Expand Down Expand Up @@ -136,6 +136,13 @@ def createParser():
default='info',
help='Logger log level. Default: info.'
)
parser.add_argument(
'--bandwidth', dest='bandwidth', default=None, type=str,
choices=('4000', '2000', '7700', '0500', '0000'),
help='Specify NISAR bandwidth mode to filter products. '
'Warns if multiple bandwidths are mixed. Default captures '
'all.'
)
return parser


Expand All @@ -161,7 +168,8 @@ def main(inps=None):
standardproduct_info = ARIAtools.product.Product(
args.imgfile, bbox=args.bbox, workdir=args.workdir,
num_threads=args.num_threads, url_version=args.version,
nc_version=args.nc_version, verbose=args.verbose)
nc_version=args.nc_version, verbose=args.verbose,
bandwidth=args.bandwidth)

# If user requests to generate all plots.
if args.plotall:
Expand Down
10 changes: 9 additions & 1 deletion tools/bin/ariaTSsetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ def create_parser():
default='info',
help='Logger log level. Default: info.'
)
parser.add_argument(
'--bandwidth', dest='bandwidth', default=None, type=str,
choices=('4000', '2000', '7700', '0500', '0000'),
help='Specify NISAR bandwidth mode to filter products. '
'Warns if multiple bandwidths are mixed. Default captures '
'all.'
)
return parser


Expand Down Expand Up @@ -524,7 +531,8 @@ def main():
url_version=args.version, nc_version=args.nc_version,
verbose=args.verbose, tropo_models=args.tropo_models,
layers=args.layers, croptounion=args.croptounion, runlog=runlog,
demfile=args.demfile, mask=args.mask)
demfile=args.demfile, mask=args.mask,
bandwidth=args.bandwidth)

# extract/merge productBoundingBox layers for each pair and update dict,
# report common track bbox (default is to take common intersection,
Expand Down