ISCE_INSAR/applications/topsApp.py

1078 lines
34 KiB
Python
Raw Normal View History

2019-01-16 19:40:08 +00:00
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Authors: Giangi Sacco, Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import time
import sys
from isce import logging
2019-01-16 19:40:08 +00:00
import isce
import isceobj
import iscesys
from iscesys.Component.Application import Application
from iscesys.Compatibility import Compatibility
from iscesys.Component.Configurable import SELF
from isceobj import TopsProc
logger = logging.getLogger('isce.insar')
SENSOR_NAME = Application.Parameter(
'sensorName',
public_name='sensor name',
default='SENTINEL1',
type=str,
mandatory=True,
doc="Sensor name"
)
DO_ESD = Application.Parameter('doESD',
public_name = 'do ESD',
default = True,
type = bool,
mandatory = False,
doc = 'Perform ESD estimation')
DO_DENSE_OFFSETS = Application.Parameter('doDenseOffsets',
public_name='do dense offsets',
default = False,
type = bool,
mandatory = False,
doc = 'Perform dense offset estimation')
UNWRAPPER_NAME = Application.Parameter(
'unwrapper_name',
public_name='unwrapper name',
default='icu',
type=str,
mandatory=False,
doc="Unwrapping method to use. To be used in combination with UNWRAP."
)
# not fully supported yet; use UNWRAP instead
DO_UNWRAP = Application.Parameter(
'do_unwrap',
public_name='do unwrap',
default=False,
type=bool,
mandatory=False,
doc="True if unwrapping is desired. To be unsed in combination with UNWRAPPER_NAME."
)
DO_UNWRAP_2STAGE = Application.Parameter(
'do_unwrap_2stage',
public_name='do unwrap 2 stage',
default=False,
type=bool,
mandatory=False,
doc="True if unwrapping is desired. To be unsed in combination with UNWRAPPER_NAME."
)
UNWRAPPER_2STAGE_NAME = Application.Parameter(
'unwrapper_2stage_name',
public_name='unwrapper 2stage name',
default='REDARC0',
type=str,
mandatory=False,
doc="2 Stage Unwrapping method to use. Available: MCF, REDARC0, REDARC1, REDARC2"
)
SOLVER_2STAGE = Application.Parameter(
'solver_2stage',
public_name='SOLVER_2STAGE',
default='pulp',
type=str,
mandatory=False,
doc='Linear Programming Solver for 2Stage; Options: pulp, gurobi, glpk; Used only for Redundant Arcs'
)
USE_HIGH_RESOLUTION_DEM_ONLY = Application.Parameter(
'useHighResolutionDemOnly',
public_name='useHighResolutionDemOnly',
default=False,
type=int,
mandatory=False,
doc=(
"""If True and a dem is not specified in input, it will only
download the SRTM highest resolution dem if it is available
and fill the missing portion with null values (typically -32767)."""
)
)
DEM_FILENAME = Application.Parameter(
'demFilename',
public_name='demFilename',
default='',
type=str,
mandatory=False,
doc="Filename of the Digital Elevation Model (DEM)"
)
GEOCODE_DEM_FILENAME = Application.Parameter(
'geocodeDemFilename',
public_name='geocode demfilename',
default='',
type=str,
mandatory=False,
doc='Filename of the DEM for geocoding')
GEOCODE_BOX = Application.Parameter(
'geocode_bbox',
public_name='geocode bounding box',
default = None,
container=list,
type=float,
doc='Bounding box for geocoding - South, North, West, East in degrees'
)
REGION_OF_INTEREST = Application.Parameter(
'roi',
public_name = 'region of interest',
default = None,
container = list,
type = float,
doc = 'Bounding box for unpacking data - South, North, West, East in degrees')
PICKLE_DUMPER_DIR = Application.Parameter(
'pickleDumpDir',
public_name='pickle dump directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory in which to store pickle objects."
)
)
PICKLE_LOAD_DIR = Application.Parameter(
'pickleLoadDir',
public_name='pickle load directory',
default='PICKLE',
type=str,
mandatory=False,
doc=(
"If steps is used, the directory from which to retrieve pickle objects."
)
)
RENDERER = Application.Parameter(
'renderer',
public_name='renderer',
default='xml',
type=str,
mandatory=True,
doc=(
"Format in which the data is serialized when using steps. Options are xml (default) or pickle."
))
NUMBER_AZIMUTH_LOOKS = Application.Parameter('numberAzimuthLooks',
public_name='azimuth looks',
default=7,
type=int,
mandatory=False,
doc='')
NUMBER_RANGE_LOOKS = Application.Parameter('numberRangeLooks',
public_name='range looks',
default=19,
type=int,
mandatory=False,
doc=''
)
ESD_AZIMUTH_LOOKS = Application.Parameter('esdAzimuthLooks',
public_name = 'ESD azimuth looks',
default = 5,
type = int,
mandatory = False,
doc = 'Number of azimuth looks for overlap IFGs')
ESD_RANGE_LOOKS = Application.Parameter('esdRangeLooks',
public_name = 'ESD range looks',
default = 15,
type = int,
mandatory = False,
doc = 'Number of range looks for overlap IFGs')
FILTER_STRENGTH = Application.Parameter('filterStrength',
public_name='filter strength',
default=0.5,
type=float,
mandatory=False,
doc='')
ESD_COHERENCE_THRESHOLD = Application.Parameter('esdCoherenceThreshold',
public_name ='ESD coherence threshold',
default = 0.85,
type = float,
mandatory = False,
doc = 'ESD coherence threshold')
OFFSET_SNR_THRESHOLD = Application.Parameter('offsetSNRThreshold',
public_name = 'offset SNR threshold',
default=8.0,
type=float,
mandatory = False,
doc = 'Offset SNR threshold')
EXTRA_ESD_CYCLES = Application.Parameter('extraESDCycles',
public_name = 'extra ESD cycles',
default = 0.,
type = float,
mandatory = False,
doc = 'Extra ESD cycles to interpret overlap phase')
####New parameters for multi-swath
USE_VIRTUAL_FILES = Application.Parameter('useVirtualFiles',
public_name = 'use virtual files',
default=True,
type=bool,
mandatory=False,
doc = 'Use virtual files when possible to save space')
SWATHS = Application.Parameter('swaths',
public_name = 'swaths',
default = [],
type=int,
container=list,
mandatory=False,
doc = 'Swaths to process')
ROI = Application.Parameter('regionOfInterest',
public_name = 'region of interest',
default = [],
container = list,
type = float,
doc = 'User defined area to crop in SNWE')
DO_INSAR = Application.Parameter('doInSAR',
public_name = 'do interferogram',
default = True,
type = bool,
doc = 'Perform interferometry. Set to false to skip insar steps.')
GEOCODE_LIST = Application.Parameter(
'geocode_list',
public_name='geocode list',
default = None,
container=list,
type=str,
doc = "List of products to geocode."
)
######Adding stuff from topsOffsetApp for integration
WINDOW_SIZE_WIDTH = Application.Parameter(
'winwidth',
public_name='Ampcor window width',
default=64,
type=int,
mandatory=False,
doc='Ampcor main window size width. Used in runDenseOffsets.'
)
WINDOW_SIZE_HEIGHT = Application.Parameter(
'winhgt',
public_name='Ampcor window height',
default=64,
type=int,
mandatory=False,
doc='Ampcor main window size height. Used in runDenseOffsets.')
SEARCH_WINDOW_WIDTH = Application.Parameter(
'srcwidth',
public_name='Ampcor search window width',
default=20,
type=int,
mandatory=False,
doc='Ampcor search window size width. Used in runDenseOffsets.'
)
SEARCH_WINDOW_HEIGHT = Application.Parameter(
'srchgt',
public_name='Ampcor search window height',
default=20,
type=int,
mandatory=False,
doc='Ampcor search window size height. Used in runDenseOffsets.'
)
SKIP_SAMPLE_ACROSS = Application.Parameter(
'skipwidth',
public_name='Ampcor skip width',
default=32,
type=int,
mandatory=False,
doc='Ampcor skip across width. Used in runDenseOffsets.'
)
SKIP_SAMPLE_DOWN = Application.Parameter(
'skiphgt',
public_name='Ampcor skip height',
default=32,
type=int,
mandatory=False,
doc='Ampcor skip down height. Used in runDenseOffsets.'
)
OFFSET_MARGIN = Application.Parameter(
'margin',
public_name='Ampcor margin',
default=50,
type=int,
mandatory=False,
doc='Ampcor margin offset. Used in runDenseOffsets.'
)
OVERSAMPLING_FACTOR = Application.Parameter(
'oversample',
public_name='Ampcor oversampling factor',
default=32,
type=int,
mandatory=False,
doc='Ampcor oversampling factor. Used in runDenseOffsets.'
)
ACROSS_GROSS_OFFSET = Application.Parameter(
'rgshift',
public_name='Range shift',
default=0,
type=int,
mandatory=False,
doc='Ampcor gross offset across. Used in runDenseOffsets.'
)
DOWN_GROSS_OFFSET = Application.Parameter(
'azshift',
public_name='Azimuth shift',
default=0,
type=int,
mandatory=False,
doc='Ampcor gross offset down. Used in runDenseOffsets.'
)
DENSE_OFFSET_SNR_THRESHOLD = Application.Parameter(
'dense_offset_snr_thresh',
public_name='SNR Threshold factor',
default=None,
type=float,
mandatory=False,
doc='SNR Threshold factor used in filtering offset field objects.')
FILTER_NULL = Application.Parameter(
'filt_null',
public_name='Filter NULL factor',
default=-10000.,
type=float,
mandatory=False,
doc='NULL factor to use in filtering offset fields to avoid numpy type issues.'
)
FILTER_WIN_SIZE = Application.Parameter(
'filt_size',
public_name='Filter window size',
default=5,
type=int,
mandatory=False,
doc='Window size for median_filter.'
)
OFFSET_GEOCODE_LIST = Application.Parameter(
'off_geocode_list',
public_name='offset geocode list',
default=None,
container=list,
type=str,
mandatory=False,
doc='List of offset-specific files to geocode.'
)
USE_GPU = Application.Parameter(
'useGPU',
public_name='use GPU',
default=False,
type=bool,
mandatory=False,
doc='Allow App to use GPU when available')
#####################################################################
#ionospheric correction
ION_DO_ION = Application.Parameter('ION_doIon',
public_name = 'do ionosphere correction',
default = False,
type = bool,
mandatory = False,
doc = '')
ION_APPLY_ION = Application.Parameter('ION_applyIon',
public_name = 'apply ionosphere correction',
default = False,
type = bool,
mandatory = False,
doc = '')
ION_CONSIDER_BURST_PROPERTIES = Application.Parameter('ION_considerBurstProperties',
public_name = 'consider burst properties in ionosphere computation',
default = False,
type = bool,
mandatory = False,
doc = '')
2019-01-16 19:40:08 +00:00
ION_START_STEP = Application.Parameter(
'ION_startStep',
public_name='start ionosphere step',
default='subband',
type=str,
mandatory=False,
doc=""
)
ION_END_STEP = Application.Parameter(
'ION_endStep',
public_name='end ionosphere step',
default='esd',
type=str,
mandatory=False,
doc=""
)
ION_ION_HEIGHT = Application.Parameter('ION_ionHeight',
public_name='height of ionosphere layer in km',
default=200.0,
type=float,
mandatory=False,
doc='')
ION_ION_FIT = Application.Parameter('ION_ionFit',
public_name = 'apply polynomial fit before filtering ionosphere phase',
default = True,
type = bool,
mandatory = False,
doc = '')
ION_ION_FILTERING_WINSIZE_MAX = Application.Parameter('ION_ionFilteringWinsizeMax',
public_name='maximum window size for filtering ionosphere phase',
default=200,
type=int,
mandatory=False,
doc='')
ION_ION_FILTERING_WINSIZE_MIN = Application.Parameter('ION_ionFilteringWinsizeMin',
public_name='minimum window size for filtering ionosphere phase',
default=100,
type=int,
mandatory=False,
doc='')
ION_IONSHIFT_FILTERING_WINSIZE_MAX = Application.Parameter('ION_ionshiftFilteringWinsizeMax',
public_name='maximum window size for filtering ionosphere azimuth shift',
default=150,
type=int,
mandatory=False,
doc='')
ION_IONSHIFT_FILTERING_WINSIZE_MIN = Application.Parameter('ION_ionshiftFilteringWinsizeMin',
public_name='minimum window size for filtering ionosphere azimuth shift',
default=75,
type=int,
mandatory=False,
doc='')
ION_AZSHIFT_FLAG = Application.Parameter('ION_azshiftFlag',
public_name='correct phase error caused by ionosphere azimuth shift',
default=1,
type=int,
mandatory=False,
doc='')
#seperated islands or areas usually affect ionosphere estimation and it's better to mask them
#out. check ion/ion_cal/raw_no_projection.ion for areas to be masked out.
#The parameter is a 2-D list. Each element in the 2-D list is a four-element list: [firstLine,
#lastLine, firstColumn, lastColumn], with line/column numbers starting with 1. If one of the
#four elements is specified as -1, the program will use firstLine/lastLine/firstColumn/
#lastColumn instead. For exmple, if you want to mask the following two areas out, you can
#specify a 2-D list like:
#[[100, 200, 100, 200],[1000, 1200, 500, 600]]
ION_MASKED_AREAS = Application.Parameter('ION_maskedAreas',
public_name = 'areas masked out in ionospheric phase estimation',
default = None,
type = int,
mandatory = False,
container = list,
doc = 'areas masked out in ionospheric phase estimation')
2019-01-16 19:40:08 +00:00
ION_NUMBER_AZIMUTH_LOOKS = Application.Parameter('ION_numberAzimuthLooks',
public_name='total number of azimuth looks in the ionosphere processing',
default=50,
type=int,
mandatory=False,
doc='')
ION_NUMBER_RANGE_LOOKS = Application.Parameter('ION_numberRangeLooks',
public_name='total number of range looks in the ionosphere processing',
default=200,
type=int,
mandatory=False,
doc='')
ION_NUMBER_AZIMUTH_LOOKS0 = Application.Parameter('ION_numberAzimuthLooks0',
public_name='number of azimuth looks at first stage for ionosphere phase unwrapping',
default=10,
type=int,
mandatory=False,
doc='')
ION_NUMBER_RANGE_LOOKS0 = Application.Parameter('ION_numberRangeLooks0',
public_name='number of range looks at first stage for ionosphere phase unwrapping',
default=40,
type=int,
mandatory=False,
doc='')
#####################################################################
#Facility declarations
REFERENCE = Application.Facility(
'reference',
public_name='Reference',
2019-01-16 19:40:08 +00:00
module='isceobj.Sensor.TOPS',
factory='createSensor',
args=(SENSOR_NAME, 'reference'),
2019-01-16 19:40:08 +00:00
mandatory=True,
doc="Reference raw data component"
2019-01-16 19:40:08 +00:00
)
SECONDARY = Application.Facility(
'secondary',
public_name='Secondary',
2019-01-16 19:40:08 +00:00
module='isceobj.Sensor.TOPS',
factory='createSensor',
args=(SENSOR_NAME,'secondary'),
2019-01-16 19:40:08 +00:00
mandatory=True,
doc="Secondary raw data component"
2019-01-16 19:40:08 +00:00
)
DEM_STITCHER = Application.Facility(
'demStitcher',
public_name='demStitcher',
module='iscesys.DataManager',
factory='createManager',
args=('dem1','iscestitcher',),
mandatory=False,
doc="Object that based on the frame bounding boxes creates a DEM"
)
RUN_UNWRAPPER = Application.Facility(
'runUnwrapper',
public_name='Run unwrapper',
module='isceobj.TopsProc',
factory='createUnwrapper',
args=(SELF(), DO_UNWRAP, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
RUN_UNWRAP_2STAGE = Application.Facility(
'runUnwrap2Stage',
public_name='Run unwrapper 2 Stage',
module='isceobj.TopsProc',
factory='createUnwrap2Stage',
args=(SELF(), DO_UNWRAP_2STAGE, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
_INSAR = Application.Facility(
'_insar',
public_name='topsproc',
module='isceobj.TopsProc',
factory='createTopsProc',
args = ('topsAppContext',isceobj.createCatalog('topsProc')),
mandatory=False,
doc="TopsProc object"
)
## Common interface for all insar applications.
class TopsInSAR(Application):
family = 'topsinsar'
## Define Class parameters in this list
parameter_list = (SENSOR_NAME,
UNWRAPPER_NAME,
DEM_FILENAME,
GEOCODE_DEM_FILENAME,
NUMBER_AZIMUTH_LOOKS,
NUMBER_RANGE_LOOKS,
ESD_AZIMUTH_LOOKS,
ESD_RANGE_LOOKS,
FILTER_STRENGTH,
ESD_COHERENCE_THRESHOLD,
OFFSET_SNR_THRESHOLD,
DO_ESD,
DO_DENSE_OFFSETS,
DO_INSAR,
DO_UNWRAP,
USE_HIGH_RESOLUTION_DEM_ONLY,
GEOCODE_BOX,
PICKLE_DUMPER_DIR,
PICKLE_LOAD_DIR,
REGION_OF_INTEREST,
RENDERER,
DO_UNWRAP_2STAGE,
UNWRAPPER_2STAGE_NAME,
SOLVER_2STAGE,
GEOCODE_LIST,
USE_VIRTUAL_FILES,
SWATHS,
ROI,
WINDOW_SIZE_HEIGHT,
WINDOW_SIZE_WIDTH,
SEARCH_WINDOW_HEIGHT,
SEARCH_WINDOW_WIDTH,
SKIP_SAMPLE_ACROSS,
SKIP_SAMPLE_DOWN,
OFFSET_MARGIN,
OVERSAMPLING_FACTOR,
ACROSS_GROSS_OFFSET,
DOWN_GROSS_OFFSET,
DENSE_OFFSET_SNR_THRESHOLD,
EXTRA_ESD_CYCLES,
FILTER_NULL,
FILTER_WIN_SIZE,
OFFSET_GEOCODE_LIST,
USE_GPU,
########################################################
#for ionospheric correction
ION_DO_ION,
ION_APPLY_ION,
ION_CONSIDER_BURST_PROPERTIES,
2019-01-16 19:40:08 +00:00
ION_START_STEP,
ION_END_STEP,
ION_ION_HEIGHT,
ION_ION_FIT,
ION_ION_FILTERING_WINSIZE_MAX,
ION_ION_FILTERING_WINSIZE_MIN,
ION_IONSHIFT_FILTERING_WINSIZE_MAX,
ION_IONSHIFT_FILTERING_WINSIZE_MIN,
ION_AZSHIFT_FLAG,
ION_MASKED_AREAS,
2019-01-16 19:40:08 +00:00
ION_NUMBER_AZIMUTH_LOOKS,
ION_NUMBER_RANGE_LOOKS,
ION_NUMBER_AZIMUTH_LOOKS0,
ION_NUMBER_RANGE_LOOKS0
########################################################
)
facility_list = (REFERENCE,
SECONDARY,
2019-01-16 19:40:08 +00:00
DEM_STITCHER,
RUN_UNWRAPPER,
RUN_UNWRAP_2STAGE,
_INSAR)
_pickleObj = "_insar"
def __init__(self, family='', name='',cmdline=None):
import isceobj
from isceobj.TopsProc import TopsProc
from iscesys.StdOEL.StdOELPy import create_writer
super().__init__(
family=family if family else self.__class__.family, name=name,
cmdline=cmdline)
self._stdWriter = create_writer("log", "", True, filename="topsinsar.log")
self._add_methods()
self._insarProcFact = TopsProc
return None
def Usage(self):
print("Usages: ")
print("topsApp.py <input-file.xml>")
print("topsApp.py --steps")
print("topsApp.py --help")
print("topsApp.py --help --steps")
def _init(self):
message = (
("ISCE VERSION = %s, RELEASE_SVN_REVISION = %s,"+
"RELEASE_DATE = %s, CURRENT_SVN_REVISION = %s") %
(isce.__version__,
isce.release_svn_revision,
isce.release_date,
isce.svn_revision)
)
logger.info(message)
print(message)
return None
def _configure(self):
self.insar.procDoc._addItem("ISCE_VERSION",
"Release: %s, svn-%s, %s. Current svn-%s" %
(isce.release_version, isce.release_svn_revision,
isce.release_date, isce.svn_revision
),
["insarProc"]
)
#Ensure consistency in geocode_list maintained by insarApp and
#InsarProc. If it is configured in both places, the one in insarApp
#will be used. It is complicated to try to merge the two lists
#because InsarProc permits the user to change the name of the files
#and the linkage between filename and filetype is lost by the time
#geocode_list is fully configured. In order to safely change file
#names and also specify the geocode_list, then insarApp should not
#be given a geocode_list from the user.
if(self.geocode_list is None):
#if not provided by the user use the list from InsarProc
self.geocode_list = self.insar.geocode_list
#for ionosphere
if 'topophase.ion' not in self.geocode_list:
self.geocode_list.append('topophase.ion')
2019-01-16 19:40:08 +00:00
else:
#if geocode_list defined here, then give it to InsarProc
#for consistency between insarApp and InsarProc and warn the user
#check if the two geocode_lists differ in content
g_count = 0
for g in self.geocode_list:
if g not in self.insar.geocode_list:
g_count += 1
#warn if there are any differences in content
if g_count > 0:
print()
logger.warning((
2019-01-16 19:40:08 +00:00
"Some filenames in insarApp.geocode_list configuration "+
"are different from those in InsarProc. Using names given"+
" to insarApp."))
print("insarApp.geocode_list = {}".format(self.geocode_list))
print(("InsarProc.geocode_list = {}".format(
self.insar.geocode_list)))
self.insar.geocode_list = self.geocode_list
if (self.off_geocode_list is None):
self.off_geocode_list = self.insar.off_geocode_list
else:
g_count = 0
for g in self.off_geocode_list:
if g not in self.insar.off_geocode_list:
g_count += 1
if g_count > 0:
self.insar.off_geocode_list = self.geocode_list
return None
@property
def insar(self):
return self._insar
@insar.setter
def insar(self, value):
self._insar = value
return None
@property
def procDoc(self):
return self.insar.procDoc
@procDoc.setter
def procDoc(self):
raise AttributeError(
"Can not assign to .insar.procDoc-- but you hit all its other stuff"
)
def _finalize(self):
pass
def help(self):
from isceobj.Sensor.TOPS import SENSORS
print(self.__doc__)
lsensors = list(SENSORS.keys())
lsensors.sort()
print("The currently supported sensors are: ", lsensors)
return None
def help_steps(self):
print(self.__doc__)
print("A description of the individual steps can be found in the README file")
print("and also in the ISCE.pdf document")
return
def renderProcDoc(self):
self.procDoc.renderXml()
def startup(self):
self.help()
self._insar.timeStart = time.time()
def endup(self):
self.renderProcDoc()
self._insar.timeEnd = time.time()
logger.info("Total Time: %i seconds" %
(self._insar.timeEnd-self._insar.timeStart))
return None
## Add instance attribute RunWrapper functions, which emulate methods.
def _add_methods(self):
self.runPreprocessor = TopsProc.createPreprocessor(self)
self.runComputeBaseline = TopsProc.createComputeBaseline(self)
self.verifyDEM = TopsProc.createVerifyDEM(self)
self.verifyGeocodeDEM = TopsProc.createVerifyGeocodeDEM(self)
self.runTopo = TopsProc.createTopo(self)
self.runSubsetOverlaps = TopsProc.createSubsetOverlaps(self)
self.runCoarseOffsets = TopsProc.createCoarseOffsets(self)
self.runCoarseResamp = TopsProc.createCoarseResamp(self)
self.runOverlapIfg = TopsProc.createOverlapIfg(self)
self.runPrepESD = TopsProc.createPrepESD(self)
self.runESD = TopsProc.createESD(self)
self.runRangeCoreg = TopsProc.createRangeCoreg(self)
self.runFineOffsets = TopsProc.createFineOffsets(self)
self.runFineResamp = TopsProc.createFineResamp(self)
self.runIon = TopsProc.createIon(self)
self.runBurstIfg = TopsProc.createBurstIfg(self)
self.runMergeBursts = TopsProc.createMergeBursts(self)
self.runFilter = TopsProc.createFilter(self)
self.runGeocode = TopsProc.createGeocode(self)
self.runDenseOffsets = TopsProc.createDenseOffsets(self)
self.runOffsetFilter = TopsProc.createOffsetFilter(self)
return None
def _steps(self):
self.step('startup', func=self.startup,
doc=("Print a helpful message and "+
"set the startTime of processing")
)
# Run a preprocessor for the two sets of frames
self.step('preprocess',
func=self.runPreprocessor,
doc=(
"""Preprocess the reference and secondary sensor data to raw images"""
2019-01-16 19:40:08 +00:00
)
)
# Compute baselines and estimate common bursts
self.step('computeBaselines',
func=self.runComputeBaseline,
doc=(
"""Compute baseline and number of common bursts"""
)
)
# Verify whether the DEM was initialized properly. If not, download
# a DEM
self.step('verifyDEM', func=self.verifyDEM)
##Run topo for each bursts
self.step('topo', func=self.runTopo)
##Run subset overlaps
self.step('subsetoverlaps', func=self.runSubsetOverlaps)
##Run coarse offsets
self.step('coarseoffsets', func=self.runCoarseOffsets)
####Run coarse resamp
self.step('coarseresamp', func=self.runCoarseResamp)
####Run overlap ifgs
self.step('overlapifg', func=self.runOverlapIfg)
###Run prepare ESD inputs
self.step('prepesd', func=self.runPrepESD)
###Run ESD
self.step('esd', func=self.runESD)
###Run range coregistration
self.step('rangecoreg', func=self.runRangeCoreg)
###Estimate fine offsets
self.step('fineoffsets', func=self.runFineOffsets)
###Resample secondary bursts
2019-01-16 19:40:08 +00:00
self.step('fineresamp', func=self.runFineResamp)
###calculate ionospheric phase
self.step('ion', func=self.runIon)
####Create burst interferograms
self.step('burstifg', func=self.runBurstIfg)
###Merge burst products into a single file
self.step('mergebursts', func=self.runMergeBursts)
###Filter the interferogram
self.step('filter', func=self.runFilter)
# Unwrap ?
self.step('unwrap', func=self.runUnwrapper)
# Conditional 2 stage unwrapping
self.step('unwrap2stage', func=self.runUnwrap2Stage,
args=(self.unwrapper_2stage_name, self.solver_2stage))
# Geocode
self.step('geocode', func=self.runGeocode,
args=(self.geocode_list, self.do_unwrap, self.geocode_bbox))
# Dense offsets
self.step('denseoffsets', func=self.runDenseOffsets)
#Filter offsets
self.step('filteroffsets', func=self.runOffsetFilter)
#Geocode offsets
self.step('geocodeoffsets', func=self.runGeocode,
args=(self.off_geocode_list, False, self.geocode_bbox, True))
# self.step('endup', func=self.endup)
return None
## Main has the common start to both insarApp and dpmApp.
def main(self):
self.help()
timeStart= time.time()
# Run a preprocessor for the two sets of frames
self.runPreprocessor()
#Compute baselines and common bursts
self.runComputeBaseline()
#Verify whether user defined a dem component. If not, then download
# SRTM DEM.
self.verifyDEM()
##Run topo for each burst
self.runTopo()
##Run subset overlaps
self.runSubsetOverlaps()
##Run coarse offsets
self.runCoarseOffsets()
##Run coarse resamp
self.runCoarseResamp()
##Run ifg
self.runOverlapIfg()
##Prepare for ESD
self.runPrepESD()
#Run ESD
self.runESD()
###Estimate range misregistration
self.runRangeCoreg()
###Estimate fine offsets
self.runFineOffsets()
###Resample secondary bursts
2019-01-16 19:40:08 +00:00
self.runFineResamp()
###calculate ionospheric phase
self.runIon()
###Create burst interferograms
self.runBurstIfg()
####Merge bursts into single files
self.runMergeBursts()
###Filter the interferogram
self.runFilter()
#add water mask to coherence and interferogram
#self.runMaskImages()
# Unwrap ?
self.runUnwrapper()
# 2Stage Unwrapping
self.runUnwrap2Stage(self.unwrapper_2stage_name, self.solver_2stage)
# Geocode
self.runGeocode(self.geocode_list, self.do_unwrap, self.geocode_bbox)
#Dense offsets
self.runDenseOffsets()
#Filter offsets
self.runOffsetFilter()
#Geocode offsets
self.runGeocode(self.off_geocode_list, False, self.geocode_bbox, True)
timeEnd = time.time()
logger.info("Total Time: %i seconds" %(timeEnd - timeStart))
self.renderProcDoc()
return None
if __name__ == "__main__":
import sys
insar = TopsInSAR(name="topsApp")
insar.configure()
insar.run()