Skip to content

Commit

Permalink
untested refactor to isolate noise loading from annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
LiangJYu committed Sep 21, 2022
1 parent 2913b29 commit f019bae
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 267 deletions.
237 changes: 0 additions & 237 deletions src/s1reader/s1_annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,114 +201,6 @@ def from_et(cls, et_in: ET, path_annotation: str):
return cls


@dataclass
class NoiseAnnotation(AnnotationBase):
'''
Reader for Noise Annotation Data Set (NADS) for IW SLC
Based on ESA documentation: "Thermal Denoising of Products Generated by the S-1 IPF"
'''

basename_annotation: str
rg_list_azimuth_time: np.ndarray
rg_list_line: list
rg_list_pixel: list
rg_list_noise_range_lut: list
az_first_azimuth_line: int
az_first_range_sample: int
az_last_azimuth_line: int
az_last_range_sample: int
az_line: np.ndarray
az_noise_azimuth_lut: np.ndarray

@classmethod
def from_et(cls,et_in: ET, ipf_version: version.Version, path_annotation: str):
'''
Extracts list of noise information from etree
Parameter
----------
et_in : xml.etree.ElementTree
Parsed NADS annotation .xml
Return
-------
cls: NoiseAnnotation
Parsed NADS from et_in
'''

cls.xml_et = et_in
cls.basename_annotation = os.path.basename(path_annotation)

if ipf_version < min_ipf_version_az_noise_vector: # legacy SAFE data
cls.rg_list_azimuth_time = \
cls._parse_vectorlist('noiseVectorList',
'azimuthTime',
'datetime')
cls.rg_list_line = \
cls._parse_vectorlist('noiseVectorList',
'line',
'scalar_int')
cls.rg_list_pixel = \
cls._parse_vectorlist('noiseVectorList',
'pixel',
'vector_int')
cls.rg_list_noise_range_lut = \
cls._parse_vectorlist('noiseVectorList',
'noiseLut',
'vector_float')

cls.az_first_azimuth_line = None
cls.az_first_range_sample = None
cls.az_last_azimuth_line = None
cls.az_last_range_sample = None
cls.az_line = None
cls.az_noise_azimuth_lut = None

else:
cls.rg_list_azimuth_time = \
cls._parse_vectorlist('noiseRangeVectorList',
'azimuthTime',
'datetime')
cls.rg_list_line = \
cls._parse_vectorlist('noiseRangeVectorList',
'line',
'scalar_int')
cls.rg_list_pixel = \
cls._parse_vectorlist('noiseRangeVectorList',
'pixel',
'vector_int')
cls.rg_list_noise_range_lut = \
cls._parse_vectorlist('noiseRangeVectorList',
'noiseRangeLut',
'vector_float')
cls.az_first_azimuth_line = \
cls._parse_vectorlist('noiseAzimuthVectorList',
'firstAzimuthLine',
'scalar_int')[0]
cls.az_first_range_sample = \
cls._parse_vectorlist('noiseAzimuthVectorList',
'firstRangeSample',
'scalar_int')[0]
cls.az_last_azimuth_line = \
cls._parse_vectorlist('noiseAzimuthVectorList',
'lastAzimuthLine',
'scalar_int')[0]
cls.az_last_range_sample = \
cls._parse_vectorlist('noiseAzimuthVectorList',
'lastRangeSample',
'scalar_int')[0]
cls.az_line = \
cls._parse_vectorlist('noiseAzimuthVectorList',
'line',
'vector_int')[0]
cls.az_noise_azimuth_lut = \
cls._parse_vectorlist('noiseAzimuthVectorList',
'noiseAzimuthLut',
'vector_float')[0]

return cls


@dataclass
class ProductAnnotation(AnnotationBase):
'''
Expand Down Expand Up @@ -557,135 +449,6 @@ def closest_block_to_azimuth_time(vector_azimuth_time: np.ndarray,
return np.argmin(np.abs(vector_azimuth_time-azimuth_time_burst))


@dataclass
class BurstNoise:
'''Noise correction information for Sentinel-1 burst'''
basename_nads: str
range_azimith_time: datetime.datetime
range_line: float
range_pixel: np.ndarray
range_lut: np.ndarray

azimuth_first_azimuth_line: int
azimuth_first_range_sample: int
azimuth_last_azimuth_line: int
azimuth_last_range_sample: int
azimuth_line: np.ndarray
azimuth_lut: np.ndarray

line_from: int
line_to: int

@classmethod
def from_noise_annotation(cls, noise_annotation: NoiseAnnotation,
azimuth_time: datetime.datetime,
line_from: int,
line_to: int,
ipf_version: version.Version):
'''
Extracts the noise correction information for individual burst from NoiseAnnotation
Parameters
----------
noise_annotation: NoiseAnnotation
Subswath-wide noise annotation information
azimuth_time : datetime.datetime
Azimuth time of the burst
line_from: int
First line of the burst in the subswath
line_to: int
Last line of the burst in the subswath
ipf_version: float
IPF version of the SAFE data
Returns
-------
cls: BurstNoise
Instance of BurstNoise initialized by the input parameters
'''

basename_nads = noise_annotation.basename_annotation
id_closest = closest_block_to_azimuth_time(noise_annotation.rg_list_azimuth_time,
azimuth_time)

range_azimith_time = noise_annotation.rg_list_azimuth_time[id_closest]
range_line = noise_annotation.rg_list_line[id_closest]
range_pixel = noise_annotation.rg_list_pixel[id_closest]
range_lut = noise_annotation.rg_list_noise_range_lut[id_closest]

azimuth_first_azimuth_line = noise_annotation.az_first_azimuth_line
azimuth_first_range_sample = noise_annotation.az_first_range_sample
azimuth_last_azimuth_line = noise_annotation.az_last_azimuth_line
azimuth_last_range_sample = noise_annotation.az_last_range_sample

if ipf_version >= min_ipf_version_az_noise_vector:
# Azimuth noise LUT exists - crop to the extent of the burst
id_top = np.argmin(np.abs(noise_annotation.az_line-line_from))
id_bottom = np.argmin(np.abs(noise_annotation.az_line-line_to))

# put some margin when possible
if id_top > 0:
id_top -= 1
if id_bottom < len(noise_annotation.az_line)-1:
id_bottom += 1
azimuth_line = noise_annotation.az_line[id_top:id_bottom + 1]
azimuth_lut = noise_annotation.az_noise_azimuth_lut[id_top:id_bottom + 1]

else:
azimuth_line = None
azimuth_lut = None

return cls(basename_nads, range_azimith_time, range_line, range_pixel, range_lut,
azimuth_first_azimuth_line, azimuth_first_range_sample,
azimuth_last_azimuth_line, azimuth_last_range_sample,
azimuth_line, azimuth_lut,
line_from, line_to)


def compute_thermal_noise_lut(self, shape_lut):
'''
Calculate thermal noise LUT whose shape is `shape_lut`
Parameter:
----------
shape_lut: tuple or list
Shape of the output LUT
Returns
-------
arr_lut_total: np.ndarray
2d array containing thermal noise correction look up table values
'''

nrows, ncols = shape_lut

# Interpolate the range noise vector
rg_lut_interp_obj = InterpolatedUnivariateSpline(self.range_pixel,
self.range_lut,
k=1)
if self.azimuth_last_range_sample is not None:
vec_rg = np.arange(self.azimuth_last_range_sample + 1)
else:
vec_rg = np.arange(ncols)
rg_lut_interpolated = rg_lut_interp_obj(vec_rg)

# Interpolate the azimuth noise vector
if (self.azimuth_line is None) or (self.azimuth_lut is None):
az_lut_interpolated = np.ones(nrows)
else: # IPF >= 2.90
az_lut_interp_obj = InterpolatedUnivariateSpline(self.azimuth_line,
self.azimuth_lut,
k=1)
vec_az = np.arange(self.line_from, self.line_to + 1)
az_lut_interpolated = az_lut_interp_obj(vec_az)

arr_lut_total = np.matmul(az_lut_interpolated[..., np.newaxis],
rg_lut_interpolated[np.newaxis, ...])

return arr_lut_total


@dataclass
class BurstCalibration:
'''Calibration information for Sentinel-1 IW SLC burst
Expand Down
Loading

0 comments on commit f019bae

Please sign in to comment.