From f98e99e16855c75aae8ea9ab457bf6dc5efc85e2 Mon Sep 17 00:00:00 2001 From: CunrenLiang <56097947+CunrenLiang@users.noreply.github.com> Date: Wed, 21 Oct 2020 13:32:36 -0700 Subject: [PATCH 1/3] support for alosStack in ISCE --- mintpy/load_data.py | 9 +- mintpy/objects/stackDict.py | 12 ++ mintpy/prep_isce.py | 94 ++++++++++----- mintpy/utils/isce_utils.py | 226 +++++++++++++++++++++++++++++++++--- mintpy/utils/readfile.py | 2 +- 5 files changed, 298 insertions(+), 45 deletions(-) diff --git a/mintpy/load_data.py b/mintpy/load_data.py index 1a72e2ff9..53592e4c4 100755 --- a/mintpy/load_data.py +++ b/mintpy/load_data.py @@ -583,9 +583,12 @@ def prepare_metadata(inpsDict): elif processor == 'isce': from mintpy import prep_isce + from mintpy.utils.isce_utils import get_processor + meta_files = sorted(glob.glob(inpsDict['mintpy.load.metaFile'])) if len(meta_files) < 1: warnings.warn('No input metadata file found: {}'.format(inpsDict['mintpy.load.metaFile'])) + try: # metadata and auxliary data meta_file = meta_files[0] @@ -597,7 +600,11 @@ def prepare_metadata(inpsDict): obs_keys = [i for i in obs_keys if i in inpsDict.keys()] obs_paths = [inpsDict[key] for key in obs_keys if inpsDict[key].lower() != 'auto'] if len(obs_paths) > 0: - obs_dir = os.path.dirname(os.path.dirname(obs_paths[0])) + processor = get_processor(meta_file) + if processor == 'alosStack': + obs_dir = os.path.dirname(obs_paths[0]) + else: + obs_dir = os.path.dirname(os.path.dirname(obs_paths[0])) obs_file = os.path.basename(obs_paths[0]) else: obs_dir = None diff --git a/mintpy/objects/stackDict.py b/mintpy/objects/stackDict.py index b7cf0442d..0ef80d0ff 100644 --- a/mintpy/objects/stackDict.py +++ b/mintpy/objects/stackDict.py @@ -287,6 +287,7 @@ class geometryDict: 'incidenceAngle':'$PROJECT_DIR/merged/geom_reference/los.rdr', 'heandingAngle' :'$PROJECT_DIR/merged/geom_reference/los.rdr', 'shadowMask' :'$PROJECT_DIR/merged/geom_reference/shadowMask.rdr', + 'waterMask' :'$PROJECT_DIR/merged/geom_reference/waterMask.rdr', 'bperp' :bperpDict ... } @@ -507,7 +508,18 @@ def write2hdf5(self, outputFile='geometryRadar.h5', access_mode='w', box=None, c t=str(dsDataType), s=dsShape, c=str(compression))) + + # read data = np.array(self.read(family=dsName, box=box)[0], dtype=dsDataType) + # water body: -1 for water and 0 for land + # water mask: 0 for water and 1 for land + fname = os.path.basename(self.datasetDict[dsName]) + if fname.startswith('waterBody') or fname.endswith('.wbd'): + data = data > -0.5 + print((' input file "{}" is water body (-1/0 for water/land), ' + 'convert to water mask (0/1 for water/land).'.format(fname))) + + # write ds = f.create_dataset(dsName, data=data, chunks=True, diff --git a/mintpy/prep_isce.py b/mintpy/prep_isce.py index 3ea90ec81..35e064d81 100755 --- a/mintpy/prep_isce.py +++ b/mintpy/prep_isce.py @@ -20,9 +20,12 @@ EXAMPLE = """example: # interferogram stack - prep_isce.py -d ./merged/interferograms -m ./reference/IW1.xml -b ./baselines -g ./merged/geom_reference #for topsStack - prep_isce.py -d ./Igrams -m ./referenceShelve/data.dat -b ./baselines -g ./geom_reference #for stripmapStack - prep_isce.py -m 20120507_slc_crop.xml -g ./geometry #for stripmapApp + prep_isce.py -d ./merged/interferograms -m ./reference/IW1.xml -b ./baselines -g ./merged/geom_reference #for topsStack + prep_isce.py -d ./Igrams -m ./referenceShelve/data.dat -b ./baselines -g ./geom_reference #for stripmapStack + prep_isce.py -m 20120507_slc_crop.xml -g ./geometry #for stripmapApp + + # here 150408 is the reference date of alosStack processing + prep_isce.py -d "pairs/*-*/insar" -m "pairs/*-*/150408.track.xml" -b baseline -g dates_resampled/150408/insar #for alosStack # offset stack from topsStack prep_isce.py -d ./merged/offsets -f filtAz*.off -m ./reference/IW1.xml -b ./baselines -g ./merged/offsets/geom_reference @@ -33,22 +36,22 @@ def create_parser(): parser = argparse.ArgumentParser(description='Prepare ISCE metadata files.', formatter_class=argparse.RawTextHelpFormatter, epilog=EXAMPLE) - parser.add_argument('-d', '--ds-dir', '--dset-dir', dest='dsetDir', type=str, default=None, + parser.add_argument('-d', '--ds-dir', '--dset-dir', dest='dsetDir', type=str, default=None, required=True, help='The directory which contains all pairs\n' 'e.g.: $PROJECT_DIR/merged/interferograms OR \n' + ' $PROJECT_DIR/pairs/*-*/insar OR \n' ' $PROJECT_DIR/merged/offsets') - parser.add_argument('-f', '--file-pattern', nargs = '+', dest='dsetFiles', type=str, - default=['filt_*.unw'], - help='A list of files that will be used in mintpy\n' - 'e.g.: filt_fine.unw filt_fine.cor OR\n' - ' filtAz*.off filtRa*.off') - parser.add_argument('-m', '--meta-file', dest='metaFile', type=str, default=None, + parser.add_argument('-f', '--file-pattern', nargs = '+', dest='dsetFiles', type=str, default=['filt_*.unw'], + help='List of observation files, e.g.: filt_fine.unw OR filtAz*.off') + parser.add_argument('-m', '--meta-file', dest='metaFile', type=str, default=None, required=True, help='Metadata file to extract common metada for the stack:\n' - 'e.g.: for ISCE/topsStack: reference/IW3.xml;\n' - ' for ISCE/stripmapStack: referenceShelve/data.dat') + 'e.g.: for ISCE/topsStack : reference/IW3.xml;\n' + ' for ISCE/stripmapStack: referenceShelve/data.dat;\n' + ' for ISCE/alosStack : pairs/150408-150701/150408.track.xml\n' + ' where 150408 is the reference date of stack processing') parser.add_argument('-b', '--baseline-dir', dest='baselineDir', type=str, default=None, help=' directory with baselines ') - parser.add_argument('-g', '--geometry-dir', dest='geometryDir', type=str, default=None, + parser.add_argument('-g', '--geometry-dir', dest='geometryDir', type=str, default=None, required=True, help=' directory with geometry files ') parser.add_argument('--force', dest='update_mode', action='store_false', help='Force to overwrite all .rsc metadata files.') @@ -58,9 +61,15 @@ def create_parser(): def cmd_line_parse(iargs = None): parser = create_parser() inps = parser.parse_args(args=iargs) - if all(not i for i in [inps.dsetDir, inps.geometryDir, inps.metaFile]): - parser.print_usage() - raise SystemExit('ERROR: at least one of the following arguments are required: -i, -g, -m') + + # translate wildcard in metaFile + if "*" in inps.metaFile: + fnames = glob.glob(inps.metaFile) + if len(fnames) > 0: + inps.metaFile = fnames[0] + else: + raise FileNotFoundError(inps.metaFile) + return inps @@ -89,17 +98,32 @@ def add_ifgram_metadata(metadata_in, dates=[], baseline_dict={}): return metadata -def prepare_geometry(geom_dir, metadata=dict(), update_mode=True): +def prepare_geometry(geom_dir, metadata=dict(), processor='tops', update_mode=True): """Prepare and extract metadata from geometry files""" + print('prepare .rsc file for geometry files') + geom_dir = os.path.abspath(geom_dir) + # grab all existed files - isce_files = [os.path.join(os.path.abspath(geom_dir), '{}.rdr'.format(i)) - for i in ['hgt','lat','lon','los','shadowMask','incLocal']] - isce_files = [i for i in isce_files if os.path.isfile(i)] - if len(isce_files) == 0: - isce_files = [os.path.join(os.path.abspath(geom_dir), '{}.rdr.full'.format(i)) - for i in ['hgt','lat','lon','los','shadowMask','incLocal']] + if processor in ['tops', 'stripmap']: + fbases = ['hgt', 'lat', 'lon', 'los', 'shadowMask', 'incLocal'] + isce_files = [os.path.join(geom_dir, '{}.rdr'.format(i)) for i in fbases] isce_files = [i for i in isce_files if os.path.isfile(i)] + if len(isce_files) == 0: + isce_files = [os.path.join(geom_dir, '{}.rdr.full'.format(i)) for i in fbases] + isce_files = [i for i in isce_files if os.path.isfile(i)] + + elif processor in ['alosStack']: + alooks = metadata['ALOOKS'] + rlooks = metadata['RLOOKS'] + isce_files = glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.hgt'.format(rlooks, alooks)))+\ + glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.lat'.format(rlooks, alooks)))+\ + glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.lon'.format(rlooks, alooks)))+\ + glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.los'.format(rlooks, alooks)))+\ + glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.wbd'.format(rlooks, alooks))) + + else: + raise Exception('unknown processor: {}'.format(processor)) # write rsc file for each file for isce_file in isce_files: @@ -118,9 +142,15 @@ def prepare_geometry(geom_dir, metadata=dict(), update_mode=True): return metadata -def prepare_stack(inputDir, filePattern, metadata=dict(), baseline_dict=dict(), update_mode=True): +def prepare_stack(inputDir, filePattern, metadata=dict(), baseline_dict=dict(), processor='tops', update_mode=True): print('prepare .rsc file for ', filePattern) - isce_files = sorted(glob.glob(os.path.join(os.path.abspath(inputDir), '*', filePattern))) + if processor in ['tops', 'stripmap']: + isce_files = sorted(glob.glob(os.path.join(os.path.abspath(inputDir), '*', filePattern))) + elif processor == 'alosStack': + isce_files = sorted(glob.glob(os.path.join(os.path.abspath(inputDir), filePattern))) + else: + raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) + if len(isce_files) == 0: raise FileNotFoundError('no file found in pattern: {}'.format(filePattern)) @@ -130,7 +160,15 @@ def prepare_stack(inputDir, filePattern, metadata=dict(), baseline_dict=dict(), for i in range(num_file): # prepare metadata for current file isce_file = isce_files[i] - dates = os.path.basename(os.path.dirname(isce_file)).split('_') # to modify to YYYYMMDDTHHMMSS + if processor in ['tops', 'stripmap']: + dates = os.path.basename(os.path.dirname(isce_file)).split('_') # to modify to YYYYMMDDTHHMMSS + elif processor == 'alosStack': + dates = os.path.basename(os.path.dirname(os.path.dirname(isce_file))).split('-') # to modify to YYYYMMDDTHHMMSS + #to fit into the format of other processors, all alos satellites are after 2000 + dates = ['20'+x for x in dates] + else: + raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) + ifg_metadata = readfile.read_attribute(isce_file, metafile_ext='.xml') ifg_metadata.update(metadata) ifg_metadata = add_ifgram_metadata(ifg_metadata, dates, baseline_dict) @@ -161,13 +199,16 @@ def main(iargs=None): # prepare metadata for geometry file if inps.geometryDir: + #metadata not changed here metadata = prepare_geometry(inps.geometryDir, metadata=metadata, + processor=inps.processor, update_mode=inps.update_mode) # read baseline info baseline_dict = {} if inps.baselineDir: + #for alosStack, if ref_date is provided, it should also be YYYYMMDD, rather than YYMMDD. baseline_dict = isce_utils.read_baseline_timeseries(inps.baselineDir, processor=inps.processor) @@ -177,6 +218,7 @@ def main(iargs=None): prepare_stack(inps.dsetDir, namePattern, metadata=metadata, baseline_dict=baseline_dict, + processor=inps.processor, update_mode=inps.update_mode) print('Done.') return diff --git a/mintpy/utils/isce_utils.py b/mintpy/utils/isce_utils.py index bd7326f0c..8d80e1495 100644 --- a/mintpy/utils/isce_utils.py +++ b/mintpy/utils/isce_utils.py @@ -3,6 +3,8 @@ # Copyright (c) 2013, Zhang Yunjun, Heresh Fattahi # # Author: Zhang Yunjun, Heresh Fattahi, Apr 2020 # ############################################################ +# 2020-07: Talib Oliver-Cabrera, add UAVSAR support w/in stripmapStack +# 2020-10: Cunren Liang, add alosStack support # Recommend import: # from mintpy.utils import isce_utils @@ -10,6 +12,7 @@ import os import glob import shelve +import datetime import numpy as np from mintpy.objects import sensor from mintpy.utils import readfile, writefile, utils1 as ut @@ -32,6 +35,7 @@ def get_processor(meta_file): meta_dir = os.path.dirname(meta_file) tops_meta_file = os.path.join(meta_dir, 'IW*.xml') stripmap_meta_files = [os.path.join(meta_dir, i) for i in ['data.dat', 'data']] + alos_stack_meta_frame_files = glob.glob(os.path.join(meta_dir, 'f1_*', '*.frame.xml')) processor = None if len(glob.glob(tops_meta_file)) > 0: @@ -42,6 +46,10 @@ def get_processor(meta_file): # stripmapStack processor = 'stripmap' + elif alos_stack_meta_frame_files != []: + # alosStack + processor = 'alosStack' + elif meta_file.endswith('.xml'): # stripmapApp processor = 'stripmap' @@ -169,13 +177,18 @@ def extract_isce_metadata(meta_file, geom_dir=None, rsc_file=None, update_mode=T print('extract metadata from ISCE/topsStack xml file:', meta_file) meta, frame = extract_tops_metadata(meta_file) + elif processor == 'alosStack': + print('extract metadata from ISCE/alosStack xml file:', meta_file) + meta, frame = extract_alosStack_metadata(meta_file, geom_dir) + else: print('extract metadata from ISCE/stripmapStack shelve file:', meta_file) meta, frame = extract_stripmap_metadata(meta_file) # 2. extract metadata from geometry file if geom_dir: - meta = extract_geometry_metadata(geom_dir, meta) + if processor != 'alosStack': + meta = extract_geometry_metadata(geom_dir, meta) # 3. common metadata meta['PROCESSOR'] = 'isce' @@ -333,6 +346,159 @@ def extract_stripmap_metadata(meta_file): return meta, frame +def extract_alosStack_metadata(meta_file, geom_dir): + + import isce + import isceobj + from isceobj.Planet.Planet import Planet + + track = load_track(os.path.dirname(meta_file), os.path.basename(meta_file).strip('.track.xml')) + rlooks, alooks, width, length = extract_image_size_alosStack(geom_dir) + spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes = alos2_acquisition_modes() + + meta = {} + meta['prf'] = track.prf + meta['startUTC'] = track.sensingStart + datetime.timedelta(seconds=(alooks-1.0)/2.0*track.azimuthLineInterval) + meta['stopUTC'] = meta['startUTC'] + datetime.timedelta(seconds=(length-1)*alooks*track.azimuthLineInterval) + meta['radarWavelength'] = track.radarWavelength + meta['startingRange'] = track.startingRange + (rlooks-1.0)/2.0*track.rangePixelSize + meta['passDirection'] = track.passDirection.upper() + meta['polarization'] = track.frames[0].swaths[0].polarization + #meta['trackNumber'] = track.trackNumber + #meta['orbitNumber'] = track.orbitNumber + + meta['PLATFORM'] = sensor.standardize_sensor_name('alos2') + + sensingMid = meta['startUTC'] + datetime.timedelta(seconds=(meta['stopUTC']-meta['startUTC']).total_seconds()/2.0) + time_seconds = (sensingMid.hour * 3600.0 + + sensingMid.minute * 60.0 + + sensingMid.second) + meta['CENTER_LINE_UTC'] = time_seconds + + peg = track.orbit.interpolateOrbit(sensingMid, method='hermite') + Vs = np.linalg.norm(peg.getVelocity()) + meta['azimuthPixelSize'] = Vs * track.azimuthLineInterval + meta['rangePixelSize'] = track.rangePixelSize + + azb = track.prf * 0.8 + if track.operationMode in scansarNominalModes: + azb /= 5.0 + if track.operationMode in scansarWideModes: + azb /= 7.0 + + #use a mean burst synchronizatino here + if track.operationMode in scansarModes: + azb *= 0.85 + + meta['azimuthResolution'] = Vs * (1.0/azb) + meta['rangeResolution'] = 0.5 * SPEED_OF_LIGHT * (1.0/track.frames[0].swaths[0].rangeBandwidth) + + elp = Planet(pname='Earth').ellipsoid + llh = elp.xyz_to_llh(peg.getPosition()) + elp.setSCH(llh[0], llh[1], track.orbit.getENUHeading(sensingMid)) + meta['HEADING'] = track.orbit.getENUHeading(sensingMid) + meta['earthRadius'] = elp.pegRadCur + meta['altitude'] = llh[2] + + meta['beam_mode'] = track.operationMode + meta['swathNumber'] = ''.join(str(swath.swathNumber) for swath in track.frames[0].swaths) + + meta['firstFrameNumber'] = track.frames[0].frameNumber + meta['lastFrameNumber'] = track.frames[-1].frameNumber + + meta['ALOOKS'] = alooks + meta['RLOOKS'] = rlooks + + # NCORRLOOKS for coherence calibration + rgfact = float(meta['rangeResolution']) / float(meta['rangePixelSize']) + azfact = float(meta['azimuthResolution']) / float(meta['azimuthPixelSize']) + meta['NCORRLOOKS'] = meta['RLOOKS'] * meta['ALOOKS'] / (rgfact * azfact) + + # update pixel_size for multilooked data + meta['rangePixelSize'] *= meta['RLOOKS'] + meta['azimuthPixelSize'] *= meta['ALOOKS'] + + edge = 3 + lat_file = glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.lat'.format(rlooks, alooks)))[0] + img = isceobj.createImage() + img.load(lat_file+'.xml') + width = img.width + length = img.length + data = np.memmap(lat_file, 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, '*_{}rlks_{}alks.lon'.format(rlooks, alooks)))[0] + data = np.memmap(lon_file, 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]) + + los_file = glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.los'.format(rlooks, alooks)))[0] + data = np.memmap(los_file, dtype='float32', mode='r', shape=(length*2, width))[0:length*2:2, :] + inc_angle = data[int(length/2), int(width/2)] + meta['CENTER_INCIDENCE_ANGLE'] = str(inc_angle) + + pointingDirection = {'right': -1, 'left' :1} + meta['ANTENNA_SIDE'] = str(pointingDirection[track.pointingDirection]) + + return meta, track + + +def alos2_acquisition_modes(): + ''' + return ALOS-2 acquisition mode + ''' + + spotlightModes = ['SBS'] + stripmapModes = ['UBS', 'UBD', 'HBS', 'HBD', 'HBQ', 'FBS', 'FBD', 'FBQ'] + scansarNominalModes = ['WBS', 'WBD', 'WWS', 'WWD'] + scansarWideModes = ['VBS', 'VBD'] + scansarModes = ['WBS', 'WBD', 'WWS', 'WWD', 'VBS', 'VBD'] + + return (spotlightModes, stripmapModes, scansarNominalModes, scansarWideModes, scansarModes) + + +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]) + + # grab the number of rows / coluns + lat = glob.glob(os.path.join(geom_dir, '*_{}rlks_{}alks.lat'.format(rlooks, alooks)))[0] + img = isceobj.createImage() + img.load(lat+'.xml') + width = img.width + length = img.length + + return (rlooks, alooks, width, length) + + +def load_track(trackDir, date): + ''' + Load the track using Product Manager. + trackDir: where *.track.xml is located + date: YYMMDD + ''' + + track = load_product(os.path.join(trackDir, '{}.track.xml'.format(date))) + + track.frames = [] + fnames = sorted(glob.glob(os.path.join(trackDir, 'f*_*/{}.frame.xml'.format(date)))) + for fname in fnames: + track.frames.append(load_product(fname)) + + return track + + + ##################################### geometry ####################################### def extract_multilook_number(geom_dir, meta=dict(), fext_list=['.rdr','.geo','.rdr.full','.geo.full']): for fbase in ['hgt','lat','lon','los']: @@ -477,6 +643,23 @@ def read_stripmap_baseline(baseline_file): return [bperp_top, bperp_bottom] +def read_alosStack_baseline(baseline_file): + '''read baseline file generated by alosStack + ''' + bDict = {} + with open(baseline_file, 'r') as f: + lines = [line for line in f if line.strip() != ''] + for x in lines[2:]: + blist = x.split() + #to fit into the format of other processors, all alos satellites are after 2000 + blist[0] = '20' + blist[0] + blist[1] = '20' + blist[1] + bDict[blist[1]] = [float(blist[3]), float(blist[3])] + bDict[blist[0]] = [0, 0] + + return bDict, blist[0] + + def read_baseline_timeseries(baseline_dir, processor='tops', ref_date=None): """Read bperp time-series from files in baselines directory Parameters: baseline_dir : str, path to the baselines directory @@ -495,30 +678,39 @@ def read_baseline_timeseries(baseline_dir, processor='tops', ref_date=None): bFiles = sorted(glob.glob(os.path.join(baseline_dir, '*/*.txt'))) elif processor == 'stripmap': bFiles = sorted(glob.glob(os.path.join(baseline_dir, '*.txt'))) + elif processor == 'alosStack': + # all baselines are in baseline_center.txt + bFiles = glob.glob(os.path.join(baseline_dir, 'baseline_center.txt')) else: raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) if len(bFiles) == 0: print('WARNING: no baseline text file found in dir {}'.format(os.path.abspath(baseline_dir))) return None - # ignore files with different date1 - # when re-run with different reference date - date1s = [os.path.basename(i).split('_')[0] for i in bFiles] - date1 = ut.most_common(date1s) - bFiles = [i for i in bFiles if os.path.basename(i).split('_')[0] == date1] - - # read files into dict - bDict = {} - for bFile in bFiles: - dates = os.path.basename(bFile).split('.txt')[0].split('_') - if processor == 'tops': - bDict[dates[1]] = read_tops_baseline(bFile) - else: - bDict[dates[1]] = read_stripmap_baseline(bFile) - bDict[dates[0]] = [0, 0] + if processor in ['tops', 'stripmap']: + # ignore files with different date1 + # when re-run with different reference date + date1s = [os.path.basename(i).split('_')[0] for i in bFiles] + date1 = ut.most_common(date1s) + bFiles = [i for i in bFiles if os.path.basename(i).split('_')[0] == date1] + + # read files into dict + bDict = {} + for bFile in bFiles: + dates = os.path.basename(bFile).split('.txt')[0].split('_') + if processor == 'tops': + bDict[dates[1]] = read_tops_baseline(bFile) + else: + bDict[dates[1]] = read_stripmap_baseline(bFile) + bDict[dates[0]] = [0, 0] + ref_date0 = dates[0] + elif processor == 'alosStack': + bDict, ref_date0 = read_alosStack_baseline(bFiles[0]) + else: + raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) # change reference date - if ref_date is not None and ref_date != dates[0]: + if ref_date is not None and ref_date != ref_date0: print('change reference date to {}'.format(ref_date)) ref_bperp = bDict[ref_date] diff --git a/mintpy/utils/readfile.py b/mintpy/utils/readfile.py index b6169148a..43567526e 100644 --- a/mintpy/utils/readfile.py +++ b/mintpy/utils/readfile.py @@ -362,7 +362,7 @@ def read_binary_file(fname, datasetName=None, box=None, xstep=1, ystep=1): data_type = dataTypeDict[data_type] k = atr['FILE_TYPE'].lower().replace('.', '') - if k in ['unw']: + if k in ['unw', 'cor']: band = min(2, num_band) if datasetName and datasetName in ['band1','intensity','magnitude']: band = 1 From 4c6eeef2f90a9a4d9ade10fdb7628259e042b4ed Mon Sep 17 00:00:00 2001 From: CunrenLiang <56097947+CunrenLiang@users.noreply.github.com> Date: Wed, 21 Oct 2020 13:51:40 -0700 Subject: [PATCH 2/3] example input file example input file for ingesting data processed by alosStack in ISCE --- docs/examples/input_files/NCalAlos2Scan.txt | 26 +++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 docs/examples/input_files/NCalAlos2Scan.txt diff --git a/docs/examples/input_files/NCalAlos2Scan.txt b/docs/examples/input_files/NCalAlos2Scan.txt new file mode 100644 index 000000000..e2e914630 --- /dev/null +++ b/docs/examples/input_files/NCalAlos2Scan.txt @@ -0,0 +1,26 @@ +# vim: set filetype=cfg: +##-------------------------------- MintPy -----------------------------## +########## 1. Load Data (--load to exit after this step) +## load_data.py -H to check more details and example inputs. +mintpy.load.processor = isce +##NOTE: 150408 is the reference date of alosStack processing. +## (parameter "reference date of the stack" of alosStack input xml file) +##---------for ISCE only: +mintpy.load.metaFile = ../pairs/*-*/150408.track.xml +mintpy.load.baselineDir = ../baseline +##---------interferogram datasets: +mintpy.load.unwFile = ../pairs/*-*/insar/filt_*-*_5rlks_28alks.unw +mintpy.load.corFile = ../pairs/*-*/insar/*-*_5rlks_28alks.cor +mintpy.load.connCompFile = ../pairs/*-*/insar/filt_*-*_5rlks_28alks.unw.conncomp +##---------geometry datasets: +mintpy.load.demFile = ../dates_resampled/150408/insar/*_5rlks_28alks.hgt +mintpy.load.lookupYFile = ../dates_resampled/150408/insar/*_5rlks_28alks.lat +mintpy.load.lookupXFile = ../dates_resampled/150408/insar/*_5rlks_28alks.lon +mintpy.load.incAngleFile = ../dates_resampled/150408/insar/*_5rlks_28alks.los +mintpy.load.azAngleFile = ../dates_resampled/150408/insar/*_5rlks_28alks.los +mintpy.load.waterMaskFile = ../dates_resampled/150408/insar/*_5rlks_28alks.wbd + +mintpy.reference.yx = 1500, 200 +mintpy.networkInversion.weightFunc = no +mintpy.topographicResidual.pixelwiseGeometry = no + From e3a8b121433d353d74119341b971b88ceddc352d Mon Sep 17 00:00:00 2001 From: Zhang Yunjun Date: Wed, 21 Oct 2020 22:08:37 -0700 Subject: [PATCH 3/3] update module_hierarchy --- docs/api/module_hierarchy.md | 2 +- mintpy/prep_isce.py | 28 +++++++++++++--------------- mintpy/utils/isce_utils.py | 22 +++++++++++++--------- 3 files changed, 27 insertions(+), 25 deletions(-) mode change 100644 => 100755 mintpy/utils/isce_utils.py diff --git a/docs/api/module_hierarchy.md b/docs/api/module_hierarchy.md index 63cb4a009..ad70c5f57 100644 --- a/docs/api/module_hierarchy.md +++ b/docs/api/module_hierarchy.md @@ -51,7 +51,7 @@ Hierarchy of sub-modules within MintPy. Level N modules depends on level N-1, N- /utils plot (objects/{stack, coord, colors}, utils/{ptime, utils0, utils1, readfile, network}) utils (objects/{stack, coord}, utils/{ptime, utils0, utils1, readfile}) - isce_utils (utils/{readfile, writefile, utils1}) + isce_utils (utils/{ptime, readfile, writefile, utils1}) ------------------ level 6 -------------------- /objects insar_vs_gps (objects/{stack, giant}, utils/{readfile, gps, plot, utils}) diff --git a/mintpy/prep_isce.py b/mintpy/prep_isce.py index 35e064d81..64e47e702 100755 --- a/mintpy/prep_isce.py +++ b/mintpy/prep_isce.py @@ -20,12 +20,12 @@ EXAMPLE = """example: # interferogram stack - prep_isce.py -d ./merged/interferograms -m ./reference/IW1.xml -b ./baselines -g ./merged/geom_reference #for topsStack - prep_isce.py -d ./Igrams -m ./referenceShelve/data.dat -b ./baselines -g ./geom_reference #for stripmapStack - prep_isce.py -m 20120507_slc_crop.xml -g ./geometry #for stripmapApp + prep_isce.py -d ./merged/interferograms -m ./reference/IW1.xml -b ./baselines -g ./merged/geom_reference #for topsStack + prep_isce.py -d ./Igrams -m ./referenceShelve/data.dat -b ./baselines -g ./geom_reference #for stripmapStack + prep_isce.py -m 20120507_slc_crop.xml -g ./geometry #for stripmapApp - # here 150408 is the reference date of alosStack processing - prep_isce.py -d "pairs/*-*/insar" -m "pairs/*-*/150408.track.xml" -b baseline -g dates_resampled/150408/insar #for alosStack + # 150408 is the reference date of alosStack processing + prep_isce.py -d "pairs/*-*/insar" -m "pairs/*-*/150408.track.xml" -b baseline -g dates_resampled/150408/insar #for alosStack # offset stack from topsStack prep_isce.py -d ./merged/offsets -f filtAz*.off -m ./reference/IW1.xml -b ./baselines -g ./merged/offsets/geom_reference @@ -139,7 +139,7 @@ def prepare_geometry(geom_dir, metadata=dict(), processor='tops', update_mode=Tr writefile.write_roipac_rsc(geom_metadata, rsc_file, update_mode=update_mode, print_msg=True) - return metadata + return def prepare_stack(inputDir, filePattern, metadata=dict(), baseline_dict=dict(), processor='tops', update_mode=True): @@ -164,8 +164,7 @@ def prepare_stack(inputDir, filePattern, metadata=dict(), baseline_dict=dict(), dates = os.path.basename(os.path.dirname(isce_file)).split('_') # to modify to YYYYMMDDTHHMMSS elif processor == 'alosStack': dates = os.path.basename(os.path.dirname(os.path.dirname(isce_file))).split('-') # to modify to YYYYMMDDTHHMMSS - #to fit into the format of other processors, all alos satellites are after 2000 - dates = ['20'+x for x in dates] + dates = ptime.yyyymmdd(dates) else: raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) @@ -199,23 +198,22 @@ def main(iargs=None): # prepare metadata for geometry file if inps.geometryDir: - #metadata not changed here - metadata = prepare_geometry(inps.geometryDir, - metadata=metadata, - processor=inps.processor, - update_mode=inps.update_mode) + prepare_geometry(inps.geometryDir, + metadata=metadata, + processor=inps.processor, + update_mode=inps.update_mode) # read baseline info baseline_dict = {} if inps.baselineDir: - #for alosStack, if ref_date is provided, it should also be YYYYMMDD, rather than YYMMDD. baseline_dict = isce_utils.read_baseline_timeseries(inps.baselineDir, processor=inps.processor) # prepare metadata for ifgram file if inps.dsetDir and inps.dsetFiles: for namePattern in inps.dsetFiles: - prepare_stack(inps.dsetDir, namePattern, + prepare_stack(inps.dsetDir, + namePattern, metadata=metadata, baseline_dict=baseline_dict, processor=inps.processor, diff --git a/mintpy/utils/isce_utils.py b/mintpy/utils/isce_utils.py old mode 100644 new mode 100755 index 8d80e1495..df1d3d950 --- a/mintpy/utils/isce_utils.py +++ b/mintpy/utils/isce_utils.py @@ -15,7 +15,7 @@ import datetime import numpy as np from mintpy.objects import sensor -from mintpy.utils import readfile, writefile, utils1 as ut +from mintpy.utils import ptime, readfile, writefile, utils1 as ut # suppress matplotlib DEBUG message import logging @@ -35,7 +35,7 @@ def get_processor(meta_file): meta_dir = os.path.dirname(meta_file) tops_meta_file = os.path.join(meta_dir, 'IW*.xml') stripmap_meta_files = [os.path.join(meta_dir, i) for i in ['data.dat', 'data']] - alos_stack_meta_frame_files = glob.glob(os.path.join(meta_dir, 'f1_*', '*.frame.xml')) + alosStack_meta_frame_files = glob.glob(os.path.join(meta_dir, 'f1_*', '*.frame.xml')) processor = None if len(glob.glob(tops_meta_file)) > 0: @@ -46,7 +46,7 @@ def get_processor(meta_file): # stripmapStack processor = 'stripmap' - elif alos_stack_meta_frame_files != []: + elif alosStack_meta_frame_files != []: # alosStack processor = 'alosStack' @@ -380,17 +380,16 @@ def extract_alosStack_metadata(meta_file, geom_dir): meta['azimuthPixelSize'] = Vs * track.azimuthLineInterval meta['rangePixelSize'] = track.rangePixelSize - azb = track.prf * 0.8 + azBandwidth = track.prf * 0.8 if track.operationMode in scansarNominalModes: - azb /= 5.0 + azBandwidth /= 5.0 if track.operationMode in scansarWideModes: - azb /= 7.0 - + azBandwidth /= 7.0 #use a mean burst synchronizatino here if track.operationMode in scansarModes: - azb *= 0.85 + azBandwidth *= 0.85 - meta['azimuthResolution'] = Vs * (1.0/azb) + meta['azimuthResolution'] = Vs * (1.0/azBandwidth) meta['rangeResolution'] = 0.5 * SPEED_OF_LIGHT * (1.0/track.frames[0].swaths[0].rangeBandwidth) elp = Planet(pname='Earth').ellipsoid @@ -665,6 +664,7 @@ def read_baseline_timeseries(baseline_dir, processor='tops', ref_date=None): Parameters: baseline_dir : str, path to the baselines directory processor : str, tops for Sentinel-1/TOPS stripmap for StripMap data + ref_date : str, reference date in (YY)YYMMDD Returns: bDict : dict, in the following format: {'20141213': [0.0, 0.0], '20141225': [104.6, 110.1], @@ -683,6 +683,7 @@ def read_baseline_timeseries(baseline_dir, processor='tops', ref_date=None): bFiles = glob.glob(os.path.join(baseline_dir, 'baseline_center.txt')) else: raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) + if len(bFiles) == 0: print('WARNING: no baseline text file found in dir {}'.format(os.path.abspath(baseline_dir))) return None @@ -704,13 +705,16 @@ def read_baseline_timeseries(baseline_dir, processor='tops', ref_date=None): bDict[dates[1]] = read_stripmap_baseline(bFile) bDict[dates[0]] = [0, 0] ref_date0 = dates[0] + elif processor == 'alosStack': bDict, ref_date0 = read_alosStack_baseline(bFiles[0]) + else: raise ValueError('Un-recognized ISCE stack processor: {}'.format(processor)) # change reference date if ref_date is not None and ref_date != ref_date0: + ref_date = ptime.yyyymmdd(ref_date) print('change reference date to {}'.format(ref_date)) ref_bperp = bDict[ref_date]