Skip to content

Commit 829dc14

Browse files
gshiromabhawkins
authored andcommitted
Populate missing metadata in writers/SLC.py (#745)
* populate missing metadata in writers/SLC.py * populate metadata/processingInformation/inputs * Update python/packages/pybind_nisar/products/writers/SLC.py Co-Authored-By: Brian P Hawkins <[email protected]> Co-authored-by: Brian P Hawkins <[email protected]>
1 parent e1cd209 commit 829dc14

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

python/packages/pybind_nisar/products/writers/SLC.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,53 @@ def set_parameters(self, dop: LUT2d, epoch: DateTime, frequency='A'):
5555
g.require_dataset("effectiveVelocity", v.shape, v.dtype, data=v)
5656
fg.require_dataset("azimuthFMRate", v.shape, v.dtype, data=v)
5757
# TODO weighting, ref height
58+
if "rangeChirpWeighting" not in g:
59+
g.require_dataset("rangeChirpWeighting", v.shape, np.float32,
60+
data=v)
61+
if "referenceTerrainHeight" not in g:
62+
ref_terrain_height = np.zeros((v.shape[0]))
63+
g.require_dataset("referenceTerrainHeight", (v.shape[0]),
64+
np.float32, data=ref_terrain_height)
65+
66+
# TODO populate processingInformation/algorithms
67+
algorithms_ds = self.root.require_group("metadata/processingInformation/algorithms")
68+
algorithms_dataset_list = ["ISCEVersion",
69+
"SWSTCorrection",
70+
"azimuthCompression",
71+
"azimuthPresumming",
72+
"dopplerCentroidEstimation",
73+
"driftCompensator",
74+
"elevationAntennaPatternCorrection",
75+
"internalCalibration",
76+
"patchProcessing",
77+
"postProcessing",
78+
"rangeCellMigration",
79+
"rangeCompression",
80+
"rangeDependentGainCorrection",
81+
"rangeReferenceFunctionGenerator",
82+
"rangeSpreadingLossCorrection",
83+
"secondaryRangeCompression"]
84+
85+
for algorithm in algorithms_dataset_list:
86+
if algorithm in g:
87+
continue
88+
algorithms_ds.require_dataset(algorithm, (), 'S27',
89+
data=np.string_(""))
90+
91+
# TODO populate processingInformation/inputs
92+
inputs_ds = self.root.require_group("metadata/processingInformation/inputs")
93+
inputs_dataset_list = ["l0bGranules",
94+
"orbitFiles",
95+
"attitudeFiles",
96+
"auxcalFiles",
97+
"configFiles",
98+
"demFiles"]
99+
100+
for inp in inputs_dataset_list:
101+
if inp in g:
102+
continue
103+
inputs_ds.require_dataset(inp, (), 'S1', data=np.string_(""))
104+
58105

59106
def swath(self, frequency="A") -> h5py.Group:
60107
return self.root.require_group(f"swaths/frequency{frequency}")
@@ -265,3 +312,68 @@ def set_geolocation_grid(self, orbit: Orbit, grid: RadarGridParameters,
265312
)
266313
add_geolocation_grid_cubes_to_hdf5(self, group_name, grid, heights,
267314
orbit, doppler, rslc_doppler, epsg, **tol)
315+
316+
317+
def add_calibration_section(self, frequency, pol,
318+
az_time_orig_vect: np.array,
319+
epoch: DateTime,
320+
slant_range_orig_vect: np.array):
321+
assert len(pol) == 2 and pol[0] in "HVLR" and pol[1] in "HV"
322+
323+
calibration_section_sampling = 50
324+
g = self.root.require_group("metadata/calibrationInformation")
325+
326+
if "zeroDopplerTime" in g:
327+
t = g['zeroDopplerTime']
328+
else:
329+
t = az_time_orig_vect[0:-1:calibration_section_sampling]
330+
d = g.require_dataset("zeroDopplerTime", t.shape, t.dtype, data=t)
331+
d.attrs["units"] = np.string_(time_units(epoch))
332+
d.attrs["description"] = np.string_(
333+
"CF compliant dimension associated with azimuth time")
334+
335+
if "slantRange" in g:
336+
r = g['slantRange']
337+
else:
338+
r = slant_range_orig_vect[0:-1:calibration_section_sampling]
339+
d = g.require_dataset("slantRange", r.shape, r.dtype, data=r)
340+
d.attrs["units"] = np.string_("meters")
341+
d.attrs["description"] = np.string_("CF compliant dimension associated"
342+
" with slant range")
343+
344+
dummy_array = np.ones((t.size, r.size), dtype=np.float32)
345+
346+
if "geometry/beta0" not in g:
347+
d = g.require_dataset(f"geometry/beta0", dummy_array.shape,
348+
np.float32, data=dummy_array)
349+
d.attrs["description"] = np.string_(
350+
"2D LUT to convert DN to beta 0 assuming as a function"
351+
" of zero doppler time and slant range")
352+
353+
if "geometry/sigma0" not in g:
354+
d = g.require_dataset(f"geometry/sigma0", dummy_array.shape,
355+
np.float32, data=dummy_array)
356+
d.attrs["description"] = np.string_(
357+
"2D LUT to convert DN to sigma 0 assuming as a function"
358+
" of zero doppler time and slant range")
359+
360+
361+
if "geometry/gamma0" not in g:
362+
d = g.require_dataset(f"geometry/gamma0", dummy_array.shape,
363+
np.float32, data=dummy_array)
364+
d.attrs["description"] = np.string_(
365+
"2D LUT to convert DN to gamma 0 as a function of zero"
366+
" doppler time and slant range")
367+
368+
d = g.require_dataset(
369+
f"frequency{frequency}/{pol}/elevationAntennaPattern",
370+
dummy_array.shape, np.float32, data=dummy_array)
371+
d.attrs["description"] = np.string_(
372+
"Complex two-way elevation antenna pattern")
373+
374+
dummy_array = np.zeros((t.size, r.size))
375+
d = g.require_dataset(
376+
f"frequency{frequency}/{pol}/nes0",
377+
dummy_array.shape, np.float32, data=dummy_array)
378+
d.attrs["description"] = np.string_(
379+
"Thermal noise equivalent sigma0")

python/packages/pybind_nisar/workflows/focus.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,11 @@ def focus(runconfig):
551551
r = og.starting_range + np.arange(og.width) * og.range_pixel_spacing
552552
slc.update_swath(t, og.ref_epoch, r, fc, frequency)
553553

554+
# add calibration section
555+
for pol in raw.polarizations[frequency]:
556+
slc.add_calibration_section(frequency, pol, t,
557+
orbit.reference_epoch, r)
558+
554559
freq = raw.frequencies[0]
555560
slc.set_geolocation_grid(orbit, ogrid[freq], dop[freq],
556561
epsg=4326, dem=dem,

0 commit comments

Comments
 (0)