Skip to content

Commit 3b0005e

Browse files
authored
prep_gmtsar: grab A/RLOOKS from GMTSAR config file if available (#1389)
+ utils.readfile.read_gmtsar_prm(): support reading GMTSAR config file, which may have empty key values or may not have some keys as in the PRM file + prep_gmtsar.extract_gmtsar_metadata(): support grabing A/RLOOKS from the config file if available, which is usually named as config.{SAT}.txt, where SAT can be ERS, ENVI, ALOS, ALOS_SLC, ALOS2, ALOS2_SCAN, S1_STRIP, S1_TOPS, CSK_RAW, CSK_SLC, CSG, TSX, RS2, GF3, LT1 + docs/dir_structure.md: add config.tops.txt file to the example directory + docs/demo_dataset.md: update the zenodo link for the new example dataset (with the config.tops.txt file added)
1 parent ee92927 commit 3b0005e

File tree

5 files changed

+62
-17
lines changed

5 files changed

+62
-17
lines changed

docs/demo_dataset.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ smallbaselineApp.py ${MINTPY_HOME}/docs/templates/RidgecrestSenDT71.txt
5858
### Sentinel-1 on San Francisco Bay with GMTSAR ###
5959

6060
+ Area: San Francisco Bay, California, USA
61-
+ Data: Sentinel-1 A/B descending track 42 during December 2014 - June 2024 (333 acquisitoins; [Zenodo](https://zenodo.org/records/12773014))
61+
+ Data: Sentinel-1 A/B descending track 42 during December 2014 - June 2024 (333 acquisitions; [Zenodo](https://zenodo.org/records/15814132))
6262
+ Size: ~2.3 GB
6363

6464
```bash
65-
wget https://zenodo.org/records/12773014/files/SanFranBaySenD42.tar.xz
65+
wget https://zenodo.org/records/15814132/files/SanFranBaySenD42.tar.xz
6666
tar -xvJf SanFranBaySenD42.tar.xz
6767
cd SanFranBaySenD42
6868
smallbaselineApp.py ${MINTPY_HOME}/docs/templates/SanFranBaySenD42.txt

docs/dir_structure.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ Below is a recipe to prepare a stack of interferograms from Sentinel-1:
487487
```
488488
$DATA_DIR/SanFranBaySenD42
489489
├── baseline_table.dat
490+
├── config.tops.txt # configuration file for p2p_processing.csh
490491
├── supermaster.PRM
491492
├── geometry
492493
| ├── dem.grd

src/mintpy/asc_desc2horz_vert.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,10 @@ def run_asc_desc2horz_vert(inps):
201201
print(f'read 2D LOS incidence / azimuth angles from file: {inps.geom_file[i]}')
202202
else:
203203
los_inc_angle[i] = ut.incidence_angle(atr, dimension=0, print_msg=False)
204-
los_az_angle[i] = ut.heading2azimuth_angle(float(atr['HEADING']))
204+
los_az_angle[i] = ut.heading2azimuth_angle(float(atr['HEADING']), look_direction='right')
205205
print('calculate the constant LOS incidence / azimuth angles from metadata as:')
206206
print(f'LOS incidence angle: {los_inc_angle[i]:.1f} deg')
207-
print(f'LOS azimuth angle: {los_az_angle[i]:.1f} deg')
207+
print(f'LOS azimuth angle: {los_az_angle[i]:.1f} deg, assuming right-looking radar.')
208208

209209

210210
## 3. decompose LOS displacements into horizontal / Vertical displacements

src/mintpy/prep_gmtsar.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def get_lalo_ref(ifg_dir, prm_dict, fbases=['corr', 'phase', 'phasefilt', 'unwra
9090
return prm_dict
9191

9292
# read corners lat/lon info
93+
print(f'grab LAT/LON_REF1/2/3/4 from file: {geo_file}')
9394
ds = gdal.Open(geo_file, gdal.GA_ReadOnly)
9495
transform = ds.GetGeoTransform()
9596
x_step = abs(transform[1])
@@ -138,6 +139,7 @@ def get_slant_range_distance(ifg_dir, prm_dict, fbases=['corr', 'phase', 'phasef
138139
raise ValueError(f'No radar-coord files found in {ifg_dir} with suffix: {fbases}')
139140

140141
# read width from rdr_file
142+
print(f'grab SLANT_RANGE_DISTANCE, INCIDENCE_ANGLE from file: {geo_file}')
141143
ds = gdal.Open(geo_file, gdal.GA_ReadOnly)
142144
width = ds.RasterXSize
143145

@@ -189,20 +191,53 @@ def extract_gmtsar_metadata(meta_file, unw_file, template_file, rsc_file=None, u
189191
ifg_dir = os.path.dirname(unw_file)
190192

191193
# 1. read *.PRM file
192-
#prm_file = get_prm_files(ifg_dir)[0]
194+
# prm_file = get_prm_files(ifg_dir)[0]
195+
meta_file = os.path.abspath(meta_file)
196+
print(f'extract metadata from metadata file: {meta_file}')
193197
meta = readfile.read_gmtsar_prm(meta_file)
194198
meta['PROCESSOR'] = 'gmtsar'
195199

196-
# 2. read template file: HEADING, ORBIT_DIRECTION
200+
# 2. grab A/RLOOKS from config or template file
201+
# config file name convention: config.{SAT}.txt, where SAT can be ERS, ENVI, ALOS, ALOS_SLC,
202+
# ALOS2, ALOS2_SCAN, S1_STRIP, S1_TOPS, CSK_RAW, CSK_SLC, CSG, TSX, RS2, GF3, LT1
197203
template = readfile.read_template(template_file)
198-
for key in ['HEADING', 'ALOOKS', 'RLOOKS']:
204+
config_file = os.path.join(os.path.dirname(meta_file), 'config.*.txt')
205+
config_files = glob.glob(config_file)
206+
207+
if len(config_files) >= 1:
208+
# read config file
209+
config = readfile.read_gmtsar_prm(config_files[0])
210+
filter_wvl = float(config.get('filter_wavelength', 200))
211+
# calc a/rlooks
212+
# Note from Xiaohua Xu: GMTSAR is applying Gaussian filtering, instead of multilooing,
213+
# thus, the equivalent value is ~0.3 times the mainlobe response of the boxcar filtering.
214+
print(f'grab A/RLOOKS from config file: {config_file}')
215+
meta['ALOOKS'] = np.rint(0.3 * filter_wvl / meta['AZIMUTH_PIXEL_SIZE']).astype(int)
216+
meta['RLOOKS'] = np.rint(0.3 * filter_wvl / meta['RANGE_PIXEL_SIZE']).astype(int)
217+
218+
else:
219+
print(f'WARNING: No config file found for {config_file}!')
220+
# read from template file
221+
for key in ['ALOOKS', 'RLOOKS']:
222+
if key in template.keys():
223+
print(f'grab {key} from template file: {template_file}')
224+
meta[key] = int(template[key])
225+
else:
226+
msg = f'Attribute {key} is missing! '
227+
msg += f'Please manually specify it in the template file: {template_file}'
228+
raise ValueError(msg)
229+
230+
# 2. grab HEADING from template file
231+
for key in ['HEADING']:
199232
if key in template.keys():
233+
print(f'grab {key} from template file: {template_file}')
200234
meta[key] = template[key].lower()
201235
else:
202-
raise ValueError(f'Attribute {key} is missing! Please manually specify it in the template file.')
236+
msg = f'Attribute {key} is missing! '
237+
msg += f'Please manually specify it in the template file: {template_file}'
238+
raise ValueError(msg)
203239

204-
# 3. grab A/RLOOKS from radar-coord data file
205-
#meta['ALOOKS'], meta['RLOOKS'] = get_multilook_number(ifg_dir)
240+
# 3. update AZIMUTH/RANGE_PIXEL_SIZE
206241
meta['AZIMUTH_PIXEL_SIZE'] *= int(meta['ALOOKS'])
207242
meta['RANGE_PIXEL_SIZE'] *= int(meta['RLOOKS'])
208243

@@ -215,6 +250,7 @@ def extract_gmtsar_metadata(meta_file, unw_file, template_file, rsc_file=None, u
215250
x_step = abs(transform[1])
216251
y_step = abs(transform[5]) * -1.
217252
if 1e-7 < x_step < 1.:
253+
print(f'grab Y/X_FIRST/STEP from {unw_file}')
218254
meta['X_STEP'] = x_step
219255
meta['Y_STEP'] = y_step
220256
meta['X_FIRST'] = transform[0] - x_step / 2.

src/mintpy/utils/readfile.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,9 +1788,11 @@ def read_gmtsar_prm(fname, delimiter='='):
17881788
prmDict = {}
17891789
for line in lines:
17901790
c = [i.strip() for i in line.strip().replace('\t',' ').split(delimiter, 1)]
1791-
key = c[0]
1792-
value = c[1].replace('\n', '').strip()
1793-
prmDict[key] = value
1791+
# ignore lines with empty key values
1792+
if len(c) >= 2:
1793+
key = c[0]
1794+
value = c[1].replace('\n', '').strip()
1795+
prmDict[key] = value
17941796

17951797
prmDict = _attribute_gmtsar2roipac(prmDict)
17961798
prmDict = standardize_metadata(prmDict)
@@ -1838,12 +1840,18 @@ def _attribute_gmtsar2roipac(prm_dict_in):
18381840
prm_dict['RANGE_PIXEL_SIZE'] = SPEED_OF_LIGHT / value / 2.0
18391841

18401842
# SC_clock_start/stop -> CENTER_LINE_TUC
1841-
dt_center = (float(prm_dict['SC_clock_start']) + float(prm_dict['SC_clock_stop'])) / 2.0
1842-
t_center = dt_center - int(dt_center)
1843-
prm_dict['CENTER_LINE_UTC'] = str(t_center * 24. * 60. * 60.)
1843+
key = 'SC_clock_start'
1844+
if key in prm_dict_in.keys():
1845+
dt_start = float(prm_dict['SC_clock_start'])
1846+
dt_stop = float(prm_dict['SC_clock_stop'])
1847+
dt_center = (dt_start + dt_stop) / 2.0
1848+
t_center = dt_center - int(dt_center)
1849+
prm_dict['CENTER_LINE_UTC'] = str(t_center * 24. * 60. * 60.)
18441850

18451851
# SC_identity -> PLATFORM
1846-
prm_dict['PLATFORM'] = GMTSAR_SENSOR_ID2NAME[int(prm_dict['SC_identity'])]
1852+
key = 'SC_identity'
1853+
if key in prm_dict_in.keys():
1854+
prm_dict['PLATFORM'] = GMTSAR_SENSOR_ID2NAME[int(prm_dict[key])]
18471855

18481856
return prm_dict
18491857

0 commit comments

Comments
 (0)