Skip to content

Commit bb17d79

Browse files
authored
Merge pull request #580 from ngageoint/integration/1.3.60
Merge integration/1.3.60 into master
2 parents dad0ba7 + a8424ca commit bb17d79

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+535
-168
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ SarPy follows a continuous release process, so there are fairly frequent release
44
Since essentially every (squash merge) commit corresponds to a release, specific
55
release points are not being annotated in GitHub.
66

7+
## [1.3.60] - 2025-01-24
8+
### Added
9+
- Support for file objects in `sarpy.io.phase_history.converter.open_phase_history`
10+
### Fixed
11+
- Typo in SIDD 2.0+ DigitalElevationData/Geoposition/CoordinateSystemType enum (GGS -> GCS)
12+
- Account for timezones in generated datetimes
13+
- SIDD ProductProcessing handling
14+
- NITF attachment level interpretation
15+
- Enable TREElement.to_dict() to handle floating-point values
16+
- Consider implicit edges in certain `sarpy/processing/ortho_rectify` bounds calculations
17+
- Restored missing antenna beam footprints in some KMZs
18+
- Handle reading Sentinel-1 SLC files without noiseAzimuthVectors
19+
### Removed
20+
- Dropped support for Python 3.6 and 3.7
21+
722
## [1.3.59] - 2024-10-03
823
### Added
924
- `noxfile.py`

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ package update mechanism, while `python setup.py install` **does not**.
148148
Issues and Bugs
149149
---------------
150150
Support for Python 2 has been dropped. The core sarpy functionality has been
151-
tested for Python 3.6, 3.7, 3.8, 3.9, 3.10, and 3.11.
151+
tested for Python 3.8, 3.9, 3.10, 3.11, 3.12.
152152

153153
Changes to sarpy for the sole purpose of supporting a Python version beyond
154154
end-of-life are unlikely to be considered.

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import nox
1010

11-
_PYTHON_VERSIONS = ['3.6', '3.11']
11+
_PYTHON_VERSIONS = ['3.8', '3.12']
1212
_LOCATIONS = ["tests"]
1313

1414

sarpy/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
'__license__', '__copyright__']
2828

2929
from sarpy.__details__ import __classification__, _post_identifier
30-
_version_number = '1.3.59'
30+
_version_number = '1.3.60'
3131

3232
__version__ = _version_number + _post_identifier
3333

sarpy/_extensions.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
__classification__ = "UNCLASSIFIED"
2+
3+
import importlib.metadata
4+
5+
6+
def entry_points(*, group):
7+
"""
8+
Simple wrapper around importlib.metadata.entry_points
9+
10+
Parameters
11+
----------
12+
group : str
13+
entry point group name
14+
15+
Returns
16+
-------
17+
list of entry points belonging to group
18+
19+
Notes
20+
-----
21+
This function is only needed to support Python < 3.10.
22+
importlib.metadata was introduced in Python 3.8 as a provisional module.
23+
The stable interface was introduced in Python 3.10 and the original interface was removed in 3.12.
24+
"""
25+
26+
eps = importlib.metadata.entry_points()
27+
if hasattr(eps, 'select'):
28+
# Python >= 3.10
29+
return eps.select(group=group)
30+
else:
31+
return eps.get(group, [])

sarpy/io/complex/csk.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from numpy.polynomial import polynomial
1717
from scipy.constants import speed_of_light
1818

19+
import sarpy._extensions
1920
from sarpy.compliance import bytes_to_string
2021
from sarpy.io.complex.base import SICDTypeReader
2122
from sarpy.io.complex.sicd_elements.blocks import Poly1DType, Poly2DType, RowColType
@@ -40,11 +41,6 @@
4041
from sarpy.io.general.utils import get_seconds, parse_timestring, is_file_like, is_hdf5, h5py
4142
from sarpy.io.complex.utils import fit_time_coa_polynomial, fit_position_xvalidation
4243

43-
try:
44-
from sarpy.io.complex import csk_addin
45-
except ImportError:
46-
csk_addin = None
47-
4844
logger = logging.getLogger(__name__)
4945

5046
_unhandled_id_text = 'Unhandled mission id `{}`'
@@ -62,6 +58,22 @@ def _extract_attrs(h5_element, out=None):
6258
return out
6359

6460

61+
def load_addin():
62+
"""Check for a CSK addin module"""
63+
try:
64+
from sarpy.io.complex import csk_addin
65+
return csk_addin
66+
except ImportError:
67+
pass
68+
69+
eps = sarpy._extensions.entry_points(group='sarpy.io.complex.csk')
70+
if not eps:
71+
return None
72+
if len(eps) > 1:
73+
raise RuntimeError("More than one CSK addin found")
74+
return list(eps)[0].load()
75+
76+
6577
###########
6678
# parser and interpreter for hdf5 attributes
6779

@@ -562,6 +574,7 @@ def update_rma_and_grid(sicd: SICDType, band_name: str) -> None:
562574
sicd.Grid.TimeCOAPoly = fit_time_coa_polynomial(
563575
sicd.RMA.INCA, sicd.ImageData, sicd.Grid, dop_rate_poly_rg_shifted, poly_order=2)
564576

577+
csk_addin = load_addin()
565578
if csk_addin is not None:
566579
csk_addin.check_sicd(sicd, self.mission_id, h5_dict)
567580

sarpy/io/complex/naming/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
from importlib import import_module
1111
from datetime import datetime
1212

13+
import sarpy._extensions
14+
15+
1316
logger = logging.getLogger(__name__)
1417

1518
###########
@@ -58,6 +61,9 @@ def parse_name_functions():
5861
if hasattr(sub_module, 'get_commercial_id'):
5962
register_name_function(sub_module.get_commercial_id)
6063

64+
for entry in sarpy._extensions.entry_points(group='sarpy.io.complex.naming.get_commercial_id'):
65+
register_name_function(entry.load())
66+
6167

6268
def get_sicd_name(the_sicd, product_number=1):
6369
"""

sarpy/io/complex/radarsat.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from sarpy.geometry.geocoords import geodetic_to_ecf
2222

23+
import sarpy._extensions
2324
from sarpy.io.complex.base import SICDTypeReader
2425
from sarpy.io.complex.other_nitf import ComplexNITFReader
2526
from sarpy.io.complex.sicd_elements.blocks import Poly1DType, Poly2DType
@@ -70,6 +71,22 @@ def _format_class_str(class_str: str) -> str:
7071
return class_str
7172

7273

74+
def load_addin():
75+
"""Check for a Radarsat addin module"""
76+
try:
77+
from sarpy.io.complex import radarsat_addin
78+
return radarsat_addin
79+
except ImportError:
80+
pass
81+
82+
eps = sarpy._extensions.entry_points(group='sarpy.io.complex.radarsat')
83+
if not eps:
84+
return None
85+
if len(eps) > 1:
86+
raise RuntimeError("More than one Radarsat addin found")
87+
return list(eps)[0].load()
88+
89+
7390
def _validate_segment_and_sicd(
7491
the_sicd: SICDType,
7592
data_segment: DataSegment,
@@ -535,10 +552,7 @@ def _get_sicd_collection_info(self, start_time: numpy.datetime64) -> Tuple[dict,
535552
collection_info : CollectionInfoType
536553
"""
537554

538-
try:
539-
import sarpy.io.complex.radarsat_addin as radarsat_addin
540-
except ImportError:
541-
radarsat_addin = None
555+
radarsat_addin = load_addin()
542556

543557
collector_name = self.satellite
544558
start_time_dt = start_time.astype(datetime)

sarpy/io/complex/sentinel.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -979,15 +979,18 @@ def populate_noise(sicd, index): # type: (SICDType, int) -> None
979979
if root_node.find('./noiseVectorList') is not None:
980980
# probably prior to March 2018
981981
range_line, range_pixel, range_noise = extract_vector('noise')
982-
azimuth_line, azimuth_pixel, azimuth_noise = None, None, None
983982
else:
984983
# noiseRange and noiseAzimuth fields began in March 2018
985984
range_line, range_pixel, range_noise = extract_vector('noiseRange')
985+
# NB: range_line is actually a list of 1 element arrays - probably should have been parsed better
986+
range_line = numpy.concatenate(range_line, axis=0)
987+
988+
if root_node.find('./noiseAzimuthVectorList/noiseAzimuthVector') is not None:
986989
azimuth_line, azimuth_pixel, azimuth_noise = extract_vector('noiseAzimuth')
987990
azimuth_line = numpy.concatenate(azimuth_line, axis=0)
991+
else:
992+
azimuth_line, azimuth_pixel, azimuth_noise = None, None, None
988993

989-
# NB: range_line is actually a list of 1 element arrays - probably should have been parsed better
990-
range_line = numpy.concatenate(range_line, axis=0)
991994
for ind, sic in enumerate(sicds):
992995
populate_noise(sic, ind)
993996

sarpy/io/complex/sicd.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import re
1010
import logging
11-
from datetime import datetime
11+
import datetime
1212
from typing import BinaryIO, Union, Optional, Dict, Tuple, Sequence
1313

1414
import numpy
@@ -475,15 +475,17 @@ def validate_sicd_for_writing(sicd_meta: SICDType) -> SICDType:
475475
sicd_meta = sicd_meta.copy()
476476

477477
profile = '{} {}'.format(__title__, __version__)
478+
# use naive datetime because numpy warns about parsing timezone aware
479+
now = numpy.datetime64(datetime.datetime.now(tz=datetime.timezone.utc).replace(tzinfo=None))
478480
if sicd_meta.ImageCreation is None:
479481
sicd_meta.ImageCreation = ImageCreationType(
480482
Application=profile,
481-
DateTime=numpy.datetime64(datetime.now()),
483+
DateTime=now,
482484
Profile=profile)
483485
else:
484486
sicd_meta.ImageCreation.Profile = profile
485487
if sicd_meta.ImageCreation.DateTime is None:
486-
sicd_meta.ImageCreation.DateTime = numpy.datetime64(datetime.now())
488+
sicd_meta.ImageCreation.DateTime = now
487489
return sicd_meta
488490

489491

0 commit comments

Comments
 (0)