Skip to content

Commit

Permalink
read/load support for isce2/alos2App dense offset (#1143)
Browse files Browse the repository at this point in the history
+ utils.readfile.auto_no_data_value(): support alos2App dense offset

+ utils.readfile.get_slice_list(): alos2App uses rg/az order, instead of az/rg order in other isce2 applications.

+ utils.isce_utils.extract_alosStack_metadata/extract_image_size_alosStack(): support geometry files from alos2App/dense_offset, which have different naming conventions than those from InSAR.

+ load_data: use absolute path for better robustness
  • Loading branch information
yunjunz authored Jan 29, 2024
1 parent ab9334e commit a2ffa04
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/mintpy/load_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ def prepare_metadata(iDict):
# --baseline-dir / --geometry-dir
baseline_dir = iDict['mintpy.load.baselineDir']
geom_dir = os.path.dirname(iDict['mintpy.load.demFile'])
geom_dir = os.path.abspath(geom_dir)

# --dset-dir / --file-pattern
obs_keys = [
Expand Down
57 changes: 39 additions & 18 deletions src/mintpy/utils/isce_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def get_processor(meta_file):
"""
Get the name of ISCE processor (imaging mode)
"""
meta_dir = os.path.dirname(meta_file)
meta_dir = os.path.dirname(os.path.abspath(meta_file))
tops_meta_file = os.path.join(meta_dir, 'IW*.xml')
alos_meta_file = os.path.join(meta_dir, '*.track.xml')
stripmap_meta_files = [os.path.join(meta_dir, i) for i in ['data.db', 'data.dat', 'data']]
Expand Down Expand Up @@ -366,29 +366,40 @@ def extract_alosStack_metadata(meta_file, geom_dir):
meta['azimuthPixelSize'] *= meta['ALOOKS']

# LAT/LON_REF1/2/3/4
lat_files = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lat'))
if len(lat_files) > 0:
# geometry files from alosStack
lat_files = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lat'))
lon_files = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lon'))
los_files = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.los'))
else:
# geometry files from alos2App / dense offset, which are then multilooked by mintpy
lat_files = [os.path.join(geom_dir, 'lat.rdr.mli')]
lon_files = [os.path.join(geom_dir, 'lon.rdr.mli')]
los_files = [os.path.join(geom_dir, 'los.rdr.mli')]

edge = 3
lat_file = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lat'))[0]
img = isceobj.createImage()
img.load(lat_file+'.xml')
img.load(lat_files[0] + '.xml')
width = img.width
length = img.length
data = np.memmap(lat_file, dtype='float64', mode='r', shape=(length, width))

data = np.memmap(lat_files[0], dtype='float64', mode='r', shape=(length, width))
meta['LAT_REF1'] = str(data[ 0+edge, 0+edge])
meta['LAT_REF2'] = str(data[ 0+edge, -1-edge])
meta['LAT_REF3'] = str(data[-1-edge, 0+edge])
meta['LAT_REF4'] = str(data[-1-edge, -1-edge])

lon_file = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lon'))[0]
data = np.memmap(lon_file, dtype='float64', mode='r', shape=(length, width))
data = np.memmap(lon_files[0], dtype='float64', mode='r', shape=(length, width))
meta['LON_REF1'] = str(data[ 0+edge, 0+edge])
meta['LON_REF2'] = str(data[ 0+edge, -1-edge])
meta['LON_REF3'] = str(data[-1-edge, 0+edge])
meta['LON_REF4'] = str(data[-1-edge, -1-edge])

# CENTER_INCIDENCE_ANGLE is optional
los_files = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.los'))
if len(los_files) > 0:
data = np.memmap(los_files[0], dtype='float32', mode='r', shape=(length*2, width))[0:length*2:2, :]
# use readfile.read() instead of np.memmap() to better handle different interleaves
data = readfile.read(los_files[0], datasetName='incidenceAngle')[0]
inc_angle = data[int(length/2), int(width/2)]
meta['CENTER_INCIDENCE_ANGLE'] = str(inc_angle)

Expand All @@ -414,20 +425,30 @@ def alos2_acquisition_modes():


def extract_image_size_alosStack(geom_dir):
import isce
import isceobj

# grab the number of looks in azimuth / range direction
lats = glob.glob(os.path.join(geom_dir, '*_*rlks_*alks.lat'))
rlooks = max(int(os.path.splitext(os.path.basename(x))[0].split('_')[1].strip('rlks')) for x in lats)
alooks = max(int(os.path.splitext(os.path.basename(x))[0].split('_')[2].strip('alks')) for x in lats)
lat_files = glob.glob(os.path.join(geom_dir, '*_*rlks_*alks.lat'))
lat_xml_files = [os.path.join(geom_dir, f'lat.rdr{x}.xml') for x in ['', '.mli']]
lat_xml_files = [x for x in lat_xml_files if os.path.exists(x)]
if len(lat_files) > 0:
# alosStack for InSAR
rlooks = max(int(os.path.splitext(os.path.basename(x))[0].split('_')[1].strip('rlks')) for x in lat_files)
alooks = max(int(os.path.splitext(os.path.basename(x))[0].split('_')[2].strip('alks')) for x in lat_files)
lat_xml_file = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lat.xml'))[0]
elif len(lat_xml_files) == 2:
# alos2App for dense offset, which are multilooked by mintpy
meta_ori = readfile.read_isce_xml(lat_xml_files[0])
meta_mli = readfile.read_isce_xml(lat_xml_files[1])
rlooks = int(np.floor( int(meta_ori['WIDTH']) / int(meta_mli['WIDTH']) ))
alooks = int(np.floor( int(meta_ori['LENGTH']) / int(meta_mli['LENGTH']) ))
lat_xml_file = lat_xml_files[1]
else:
raise ValueError(f'Un-recognized lookup table files in directory: {geom_dir}!')

# grab the number of rows / coluns
lat = glob.glob(os.path.join(geom_dir, f'*_{rlooks}rlks_{alooks}alks.lat'))[0]
img = isceobj.createImage()
img.load(lat+'.xml')
width = img.width
length = img.length
meta_mli = readfile.read_isce_xml(lat_xml_file)
width = int(meta_mli['WIDTH'])
length = int(meta_mli['LENGTH'])

return (rlooks, alooks, width, length)

Expand Down
21 changes: 18 additions & 3 deletions src/mintpy/utils/readfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,10 +838,17 @@ def get_hdf5_2d_dataset(name, obj):
elif 'offset' in fbase and num_band == 2:
# ampcor offset file, e.g. offset.bip, dense_offsets.bil
slice_list = ['azimuthOffset', 'rangeOffset']
if fname.endswith('_denseoffset.off'):
# for alos2App dense offset, the file has the opposite band order
# e.g. 231206-240103_denseoffset.off
slice_list = ['rangeOffset', 'azimuthOffset']

elif 'offset' in fbase and '_cov' in fbase and num_band == 3:
elif 'offset' in fbase and 'cov' in fname and num_band == 3:
# ampcor offset covariance file, e.g. offset_cov.bip, dense_offsets_cov.bil
slice_list = ['azimuthOffsetVar', 'rangeOffsetVar', 'offsetCovar']
if fname.endswith('_denseoffset.cov'):
# for alos2App dense offset, e.g. 231206-240103_denseoffset.cov
slice_list = ['rangeOffsetVar', 'azimuthOffsetVar', 'offsetCovar']

elif fext in ['.lkv']:
slice_list = ['east', 'north', 'up']
Expand Down Expand Up @@ -1364,8 +1371,16 @@ def auto_no_data_value(meta):

# known file types
# isce2: dense offsets from topsApp.py
if processor == 'isce' and fname.endswith('dense_offsets.bil') and num_band == 2:
no_data_value = -10000.
if processor == 'isce' and num_band == 2:
# isce2 dense offset
if fname.endswith('dense_offsets.bil'):
# from topsApp.py
no_data_value = -10000.
elif fname.endswith('_denseoffset.off'):
# from alos2App.py
no_data_value = 0.
else:
no_data_value = None

else:
# default value for unknown file types
Expand Down

0 comments on commit a2ffa04

Please sign in to comment.