|
| 1 | +from nisar.products.readers import SLC |
1 | 2 | from nisar.workflows.geo2rdr_runconfig import Geo2rdrRunConfig
|
| 3 | +import nisar.workflows.helpers as helpers |
2 | 4 | import journal
|
3 | 5 | import os
|
| 6 | +import h5py |
| 7 | +import numpy as np |
4 | 8 | import warnings
|
5 | 9 |
|
6 | 10 | class InsarRunConfig(Geo2rdrRunConfig):
|
@@ -150,6 +154,185 @@ def yaml_check(self):
|
150 | 154 | if algorithm not in self.cfg['processing']['phase_unwrap']:
|
151 | 155 | self.cfg['processing']['phase_unwrap'][algorithm]={}
|
152 | 156 |
|
| 157 | + iono_cfg = self.cfg['processing']['ionosphere_phase_correction'] |
| 158 | + |
| 159 | + # If ionosphere phase correction is enabled, check defaults |
| 160 | + if iono_cfg['enabled']: |
| 161 | + # Extract split-spectrum dictionary |
| 162 | + split_cfg = iono_cfg['split_range_spectrum'] |
| 163 | + iono_freq_pol = iono_cfg['list_of_frequencies'] |
| 164 | + iono_method = iono_cfg['spectral_diversity'] |
| 165 | + |
| 166 | + # Extract main range bandwidth from reference SLC |
| 167 | + ref_slc_path = self.cfg['input_file_group']['input_file_path'] |
| 168 | + sec_slc_path = self.cfg['input_file_group']['secondary_file_path'] |
| 169 | + |
| 170 | + ref_slc = SLC(hdf5file=ref_slc_path) |
| 171 | + sec_slc = SLC(hdf5file=sec_slc_path) |
| 172 | + |
| 173 | + # extract the polarizations from reference and secondary hdf5 |
| 174 | + with h5py.File(ref_slc_path, 'r', libver='latest', |
| 175 | + swmr=True) as ref_h5, \ |
| 176 | + h5py.File(sec_slc_path, 'r', libver='latest', |
| 177 | + swmr=True) as sec_h5: |
| 178 | + |
| 179 | + ref_pol_path = os.path.join( |
| 180 | + ref_slc.SwathPath, 'frequencyA', 'listOfPolarizations') |
| 181 | + ref_pols_freqA = list( |
| 182 | + np.array(ref_h5[ref_pol_path][()], dtype=str)) |
| 183 | + |
| 184 | + sec_pol_path = os.path.join( |
| 185 | + sec_slc.SwathPath, 'frequencyA', 'listOfPolarizations') |
| 186 | + sec_pols_freqA = list( |
| 187 | + np.array(sec_h5[sec_pol_path][()], dtype=str)) |
| 188 | + |
| 189 | + rg_main_bandwidth = ref_slc.getSwathMetadata( |
| 190 | + 'A').processed_range_bandwidth |
| 191 | + |
| 192 | + # get common polarzations of freqA from reference and secondary |
| 193 | + common_pol_refsec_freqA = set.intersection( |
| 194 | + set(ref_pols_freqA), set(sec_pols_freqA)) |
| 195 | + |
| 196 | + # If no common polarizations found between reference and secondary, |
| 197 | + # then throw errors. |
| 198 | + if not common_pol_refsec_freqA: |
| 199 | + err_str = "No common polarization between frequency A rasters" |
| 200 | + error_channel.log(err_str) |
| 201 | + raise FileNotFoundError(err_str) |
| 202 | + |
| 203 | + # If polarizations are given, then check if HDF5 has them. |
| 204 | + # If not, then throw error. |
| 205 | + if iono_freq_pol['A']: |
| 206 | + for iono_pol in iono_freq_pol['A']: |
| 207 | + if (iono_pol not in ref_pols_freqA) or \ |
| 208 | + (iono_pol not in sec_pols_freqA): |
| 209 | + err_str = f"polarzations {iono_pol} for ionosphere estimation are requested, but not found" |
| 210 | + error_channel.log(err_str) |
| 211 | + raise FileNotFoundError(err_str) |
| 212 | + |
| 213 | + # If common polarization found, but input polarizations are not given, |
| 214 | + # then assign the common polarization for split_main_band |
| 215 | + if (common_pol_refsec_freqA) and (not iono_freq_pol['A']): |
| 216 | + # Co-polarizations are found, split_main_band will be used for co-pols |
| 217 | + common_copol_ref_sec = [pol for pol in common_pol_refsec_freqA |
| 218 | + if pol in ['VV', 'HH']] |
| 219 | + iono_freq_pol['A'] = common_copol_ref_sec |
| 220 | + |
| 221 | + # If common co-pols not found, cross-pol will be alternatively used. |
| 222 | + if not common_copol_ref_sec: |
| 223 | + iono_freq_pol['A'] = common_pol_refsec_freqA |
| 224 | + |
| 225 | + warning_str = f"{iono_freq_pol} will be used for {iono_method}" |
| 226 | + warning_channel.log(warning_str) |
| 227 | + self.cfg['processing'][ |
| 228 | + 'ionosphere_phase_correction'][ |
| 229 | + 'list_of_frequencies'] = iono_freq_pol |
| 230 | + |
| 231 | + # Depending on how the user has selected "spectral_diversity" check if |
| 232 | + # "low_bandwidth" and "high_bandwidth" are assigned. Otherwise, use default |
| 233 | + if iono_method == 'split_main_band': |
| 234 | + # If "low_bandwidth" or 'high_bandwidth" is not allocated, split the main range bandwidth |
| 235 | + # into two 1/3 sub-bands. |
| 236 | + if split_cfg['low_band_bandwidth'] is None: |
| 237 | + split_cfg['low_band_bandwidth'] = rg_main_bandwidth / 3.0 |
| 238 | + info_str = "low band width for low sub-bands are not given;"\ |
| 239 | + "It is automatically set by 1/3 of range bandwidth of frequencyA" |
| 240 | + warning_channel.log(info_str) |
| 241 | + |
| 242 | + if split_cfg['high_band_bandwidth'] is None: |
| 243 | + split_cfg['high_band_bandwidth'] = rg_main_bandwidth / 3.0 |
| 244 | + info_str = "high band width for high sub-band are not given;"\ |
| 245 | + "It is automatically set by 1/3 of range bandwidth of frequencyA" |
| 246 | + warning_channel.log(info_str) |
| 247 | + |
| 248 | + # If polarzations for frequency B are requested |
| 249 | + # for split_main_band method, then throw error |
| 250 | + if iono_freq_pol['B']: |
| 251 | + err_str = f"Incorrect polarzations {iono_freq_pol['B']} for frequency B are requested. "\ |
| 252 | + f"{iono_method} should not have polarizations in frequency B." |
| 253 | + error_channel.log(err_str) |
| 254 | + raise FileNotFoundError(err_str) |
| 255 | + |
| 256 | + # methods that use side band |
| 257 | + if iono_method in ['main_side_band', 'main_diff_main_side_band']: |
| 258 | + # extract the polarizations from reference and secondary hdf5 |
| 259 | + with h5py.File(ref_slc_path, 'r', libver='latest', |
| 260 | + swmr=True) as ref_h5, \ |
| 261 | + h5py.File(sec_slc_path, 'r', libver='latest', |
| 262 | + swmr=True) as sec_h5: |
| 263 | + |
| 264 | + ref_pol_path = os.path.join( |
| 265 | + ref_slc.SwathPath, 'frequencyB', 'listOfPolarizations') |
| 266 | + ref_pols_freqB = list( |
| 267 | + np.array(ref_h5[ref_pol_path][()], dtype=str)) |
| 268 | + |
| 269 | + sec_pol_path = os.path.join( |
| 270 | + sec_slc.SwathPath, 'frequencyB', 'listOfPolarizations') |
| 271 | + sec_pols_freqB = list( |
| 272 | + np.array(sec_h5[sec_pol_path][()], dtype=str)) |
| 273 | + |
| 274 | + # find common polarizations for freq B between ref and sec HDF5 |
| 275 | + common_pol_refsec_freqB = set.intersection( |
| 276 | + set(ref_pols_freqB), set(sec_pols_freqB)) |
| 277 | + |
| 278 | + # when common polarzations are not found, throw error. |
| 279 | + if not common_pol_refsec_freqB: |
| 280 | + err_str = "No common polarization between frequencyB rasters" |
| 281 | + error_channel.log(err_str) |
| 282 | + raise FileNotFoundError(err_str) |
| 283 | + |
| 284 | + common_pol_ref_freq_a_b = set.intersection( |
| 285 | + set(ref_pols_freqA), set(ref_pols_freqB)) |
| 286 | + if not common_pol_ref_freq_a_b: |
| 287 | + err_str = "No common polarization between frequency A and B rasters" |
| 288 | + error_channel.log(err_str) |
| 289 | + raise FileNotFoundError(err_str) |
| 290 | + |
| 291 | + # If polarizations are given, then check if HDF5 has them. |
| 292 | + # If not, then throw error. |
| 293 | + if iono_freq_pol['B']: |
| 294 | + for iono_pol in iono_freq_pol['B']: |
| 295 | + if (iono_pol not in ref_pols_freqB) or \ |
| 296 | + (iono_pol not in sec_pols_freqB): |
| 297 | + err_str = f"polarzations {iono_pol} for ionosphere"\ |
| 298 | + "estimation are requested, but not found" |
| 299 | + error_channel.log(err_str) |
| 300 | + raise FileNotFoundError(err_str) |
| 301 | + |
| 302 | + # Co-polarizations are found and input pol for freq B is not given |
| 303 | + else: |
| 304 | + common_pol_refsec_freq_ab = set.intersection( |
| 305 | + set(common_pol_refsec_freqB), set(common_pol_ref_freq_a_b)) |
| 306 | + |
| 307 | + # if pol of freq A is given, this pol is used for freq B. |
| 308 | + if iono_freq_pol['A']: |
| 309 | + common_pol_refsec_freq_ab = set.intersection( |
| 310 | + set(iono_freq_pol['A']), set(common_pol_refsec_freq_ab)) |
| 311 | + |
| 312 | + common_copol_ref_sec = [pol for pol in common_pol_refsec_freq_ab |
| 313 | + if pol in ['VV', 'HH']] |
| 314 | + |
| 315 | + if common_copol_ref_sec: |
| 316 | + info_str = f"{common_copol_ref_sec} will be "\ |
| 317 | + f"used for {iono_method}" |
| 318 | + warning_channel.log(info_str) |
| 319 | + self.cfg['processing'][ |
| 320 | + 'ionosphere_phase_correction'][ |
| 321 | + 'list_of_frequencies']['A'] = common_copol_ref_sec |
| 322 | + self.cfg['processing'][ |
| 323 | + 'ionosphere_phase_correction'][ |
| 324 | + 'list_of_frequencies']['A'] = common_copol_ref_sec |
| 325 | + |
| 326 | + # If common co-pols not found, cross-pol will be alternatively used. |
| 327 | + else: |
| 328 | + info_str = f"{common_pol_refsec_freq_ab} will be used for split_main_band" |
| 329 | + warning_channel.log(info_str) |
| 330 | + self.cfg['processing'][ |
| 331 | + 'ionosphere_phase_correction'][ |
| 332 | + 'list_of_frequencies']['A'] = common_pol_refsec_freq_ab |
| 333 | + self.cfg['processing'][ |
| 334 | + 'ionosphere_phase_correction'][ |
| 335 | + 'list_of_frequencies']['B'] = common_pol_refsec_freq_ab |
153 | 336 |
|
154 | 337 | if 'interp_method' not in self.cfg['processing']['geocode']:
|
155 | 338 | self.cfg['processing']['geocode']['interp_method'] = 'BILINEAR'
|
|
0 commit comments