Skip to content

Commit 8962607

Browse files
bhawkinsGitHub Enterprise
authored andcommitted
Baseband RSLC (#749)
* Remove range carrier from RSLC * Add kludgy function for reading complex float16. * Check that RSLC is actually baseband.
1 parent 83de041 commit 8962607

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,28 @@
1+
import h5py
12
import numpy as np
23

34
complex32 = np.dtype([('r', np.float16), ('i', np.float16)])
45

6+
57
def to_complex32(z: np.array):
68
zf = np.zeros(z.shape, dtype=complex32)
79
zf['r'] = z.real
810
zf['i'] = z.imag
911
return zf
12+
13+
14+
def read_c4_dataset_as_c8(ds: h5py.Dataset, key=np.s_[...]):
15+
"""
16+
Read a complex float16 HDF5 dataset as a numpy.complex64 array.
17+
18+
Avoids h5py/numpy dtype bugs and uses numpy float16 -> float32 conversions
19+
which are about 10x faster than HDF5 ones.
20+
"""
21+
# This context manager avoids h5py exception:
22+
# TypeError: data type '<c4' not understood
23+
with ds.astype(complex32):
24+
z = ds[key]
25+
# Define a similar datatype for complex64 to be sure we cast safely.
26+
complex64 = np.dtype([("r", np.float32), ("i", np.float32)])
27+
# Cast safely and then view as native complex64 numpy dtype.
28+
return z.astype(complex64).view(np.complex64)

python/packages/pybind_nisar/workflows/focus.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,14 @@ def delete_safely(filename):
468468
pass
469469

470470

471+
def get_range_deramp(grid: isce.product.RadarGridParameters) -> np.ndarray:
472+
"""Compute the phase ramp required to shift a backprojected grid to
473+
baseband in range.
474+
"""
475+
r = grid.starting_range + grid.range_pixel_spacing * np.arange(grid.width)
476+
return np.exp(-1j * 4 * np.pi / grid.wavelength * r)
477+
478+
471479
def focus(runconfig):
472480
# Strip off two leading namespaces.
473481
cfg = runconfig.runconfig.groups
@@ -643,6 +651,8 @@ def temp(suffix):
643651
if not cfg.processing.is_enabled.azcomp:
644652
continue
645653

654+
deramp = get_range_deramp(ogrid[frequency])
655+
646656
for i in range(0, ogrid[frequency].length, na):
647657
# h5py doesn't follow usual slice rules, raises exception
648658
# if dest_sel slices extend past dataset shape.
@@ -658,6 +668,7 @@ def temp(suffix):
658668
kernel, atmos, vars(cfg.processing.azcomp.rdr2geo),
659669
vars(cfg.processing.azcomp.geo2rdr))
660670
log.debug(f"max(abs(z)) = {np.max(np.abs(z))}")
671+
z *= deramp[None, j:jmax]
661672
zf = to_complex32(scale * z)
662673
acdata.write_direct(zf, dest_sel=block)
663674

tests/python/packages/pybind_nisar/workflows/focus.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import iscetest
22
from pybind_nisar.workflows import focus
3+
import pybind_nisar as nisar
34
import os
5+
import numpy as np
46
import numpy.testing as npt
57

8+
69
def get_test_cfg():
710
# Don't just call main() because need to update raw data file name.
811
rawname = os.path.join(iscetest.data, "REE_L0B_out17.h5")
@@ -11,6 +14,17 @@ def get_test_cfg():
1114
cfg.runconfig.groups.InputFileGroup.InputFilePath = [rawname]
1215
return cfg
1316

17+
18+
def slc_is_baseband(filename: str, tol=2*np.pi/100, frequency="A", polarization="HH") -> bool:
19+
rslc = nisar.products.readers.SLC(hdf5file=filename)
20+
ds = rslc.getSlcDataset(frequency, polarization)
21+
# work around h5py/numpy awkwardness with Complex{Float16}
22+
z = nisar.types.read_c4_dataset_as_c8(ds)
23+
dz = z[:, 1:] * z[:, :-1].conj()
24+
return abs(np.angle(dz.sum())) < tol
25+
26+
1427
def test_focus():
1528
cfg = get_test_cfg()
1629
focus.focus(cfg)
30+
assert slc_is_baseband(cfg.runconfig.groups.ProductPathGroup.SASOutputFile)

0 commit comments

Comments
 (0)