Cleaning up scansar modules

LT1AB
piyushrpt 2020-03-28 22:59:11 -07:00
parent f95a912462
commit ed30cbac42
17 changed files with 3 additions and 3293 deletions

View File

@ -78,9 +78,8 @@ listFiles = ['mdx.py',
'wbd.py',
'downsampleDEM.py',
'gdal2isce_xml.py',
'alos2App.py',
'alos2burstApp.py',
'scansarApp.py',
'alos2App.py',
'alos2burstApp.py',
'wbd_with_correction.py']
# 'isce2he5.py']

View File

@ -18,7 +18,7 @@ def cmdLineParse():
help = 'Input image for which the XML file needs to be fixed.')
fname = parser.add_mutually_exclusive_group(required=True)
fname.add_argument('-f', '--full', action='store_false',
fname.add_argument('-f', '--full', action='store_true',
help = 'Replace filename with full path including dir in which file is located')
fname.add_argument('-b', '--base', action='store_true',
help = 'Replace filename with basename to use in current directory')

View File

@ -1,881 +0,0 @@
#!/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
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 ScansarProc
logger = logging.getLogger('isce.insar')
SENSOR_NAME = Application.Parameter(
'sensorName',
public_name='sensor name',
default='ALOS2',
type=str,
mandatory=True,
doc="Sensor name"
)
FULL_APERTURE_PRODUCT = Application.Parameter(
'isFullApertureProduct',
public_name='is full aperture product',
default=False,
type=bool,
mandatory=True,
doc= "To indicate full aperture or burst-by-burst")
BURST_OVERLAP_THRESHOLD = Application.Parameter(
'burstOverlapThreshold',
public_name='burst overlap threshold',
default=85.0,
type=float,
mandatory=True,
doc='Minimum burst overlap needed to stop triggering common azimuth spectra filtering')
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'
)
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=''
)
FILTER_STRENGTH = Application.Parameter('filterStrength',
public_name='filter strength',
default=0.5,
type=float,
mandatory=False,
doc='')
OFFSET_SNR_THRESHOLD = Application.Parameter('offsetSNRThreshold',
public_name = 'offset SNR threshold',
default=8.0,
type=float,
mandatory = False,
doc = 'Offset SNR threshold')
####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')
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."
)
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')
#Facility declarations
MASTER = Application.Facility(
'master',
public_name='Master',
module='isceobj.Sensor.ScanSAR',
factory='createSensor',
args=(SENSOR_NAME, 'master'),
mandatory=True,
doc="Master raw data component"
)
SLAVE = Application.Facility(
'slave',
public_name='Slave',
module='isceobj.Sensor.ScanSAR',
factory='createSensor',
args=(SENSOR_NAME,'slave'),
mandatory=True,
doc="Slave raw data component"
)
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.ScansarProc',
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.ScansarProc',
factory='createUnwrap2Stage',
args=(SELF(), DO_UNWRAP_2STAGE, UNWRAPPER_NAME),
mandatory=False,
doc="Unwrapping module"
)
_INSAR = Application.Facility(
'_insar',
public_name='scansarproc',
module='isceobj.ScansarProc',
factory='createScansarProc',
args = ('scansarAppContext',isceobj.createCatalog('scansarProc')),
mandatory=False,
doc="ScansarProc object"
)
## Common interface for all insar applications.
class ScansarInSAR(Application):
family = 'scansarinsar'
## Define Class parameters in this list
parameter_list = (SENSOR_NAME,
UNWRAPPER_NAME,
DEM_FILENAME,
GEOCODE_DEM_FILENAME,
BURST_OVERLAP_THRESHOLD,
NUMBER_AZIMUTH_LOOKS,
NUMBER_RANGE_LOOKS,
FILTER_STRENGTH,
OFFSET_SNR_THRESHOLD,
DO_INSAR,
DO_UNWRAP,
USE_HIGH_RESOLUTION_DEM_ONLY,
GEOCODE_BOX,
PICKLE_DUMPER_DIR,
PICKLE_LOAD_DIR,
RENDERER,
DO_UNWRAP_2STAGE,
UNWRAPPER_2STAGE_NAME,
SOLVER_2STAGE,
GEOCODE_LIST,
USE_VIRTUAL_FILES,
SWATHS,
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,
FILTER_NULL,
FILTER_WIN_SIZE,
OFFSET_GEOCODE_LIST,
USE_GPU)
facility_list = (MASTER,
SLAVE,
DEM_STITCHER,
RUN_UNWRAPPER,
RUN_UNWRAP_2STAGE,
_INSAR)
_pickleObj = "_insar"
def __init__(self, family='', name='',cmdline=None):
import isceobj
from isceobj.ScansarProc import ScansarProc
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="scansarinsar.log")
self._add_methods()
self._insarProcFact = ScansarProc
return None
def Usage(self):
print("Usages: ")
print("scansarApp.py <input-file.xml>")
print("scansarApp.py --steps")
print("scansarApp.py --help")
print("scansarApp.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
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.warn((
"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.ScanSAR 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 = ScansarProc.createPreprocessor(self)
self.runCommonRangeSpectra = ScansarProc.createCommonRangeSpectra(self)
self.runEqualizeSlcs = ScansarProc.createEqualizeSlcs(self)
self.runEstimateBurstSync = ScansarProc.createEstimateBurstSync(self)
# self.runComputeBaseline = ScansarProc.createComputeBaseline(self)
# self.verifyDEM = ScansarProc.createVerifyDEM(self)
# self.verifyGeocodeDEM = ScansarProc.createVerifyGeocodeDEM(self)
# self.runTopo = ScansarProc.createTopo(self)
# self.runSubsetOverlaps = ScansarProc.createSubsetOverlaps(self)
# self.runCoarseOffsets = ScansarProc.createCoarseOffsets(self)
# self.runCoarseResamp = ScansarProc.createCoarseResamp(self)
# self.runOverlapIfg = ScansarProc.createOverlapIfg(self)
# self.runPrepESD = ScansarProc.createPrepESD(self)
# self.runESD = ScansarProc.createESD(self)
# self.runRangeCoreg = ScansarProc.createRangeCoreg(self)
# self.runFineOffsets = ScansarProc.createFineOffsets(self)
# self.runFineResamp = ScansarProc.createFineResamp(self)
# self.runBurstIfg = ScansarProc.createBurstIfg(self)
# self.runMergeBursts = ScansarProc.createMergeBursts(self)
# self.runFilter = ScansarProc.createFilter(self)
# self.runGeocode = ScansarProc.createGeocode(self)
# self.runDenseOffsets = ScansarProc.createDenseOffsets(self)
# self.runOffsetFilter = ScansarProc.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 master and slave sensor data to raw images"""
)
)
# Run common range spectra filtering
self.step('commonrangespectra',
func=self.runCommonRangeSpectra,
doc=("""Filter images to common range spectra"""))
#Run image equalization to make pixels same size
self.step('equalizeslcs',
func=self.runEqualizeSlcs,
doc=("""Make pixel sizes the same"""))
#Run estimation of burst sync
self.step('estimateburstsync',
func=self.runEstimateBurstSync,
doc=("""Estimate amount of burst sync"""))
# 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 slave bursts
#self.step('fineresamp', func=self.runFineResamp)
####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()
#Filter to common range spectra
self.runCommonRangeSpectra()
#Make pixels the same size
self.runEqualizeSlcs()
#Estimate amount of burst sync
self.runEstimateBurstSync()
#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 slave bursts
#self.runFineResamp()
###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 = ScansarInSAR(name="scansarApp")
insar.configure()
insar.run()

View File

@ -70,6 +70,5 @@ SConscript('Registry/SConscript')
SConscript('StripmapProc/SConscript')
SConscript('TopsProc/SConscript')
SConscript('RtcProc/SConscript')
SConscript('ScansarProc/SConscript')
SConscript('Alos2Proc/SConscript')
SConscript('Alos2burstProc/SConscript')

View File

@ -1,104 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2016
#
# Path to the _RunWrapper factories
_PATH = "isceobj.ScansarProc."
## A factory to make _RunWrapper factories
def _factory(name, other_name=None):
"""create_run_wrapper = _factory(name)
name is the module and class function name
"""
other_name = other_name or name
module = __import__(
_PATH+name, fromlist=[""]
)
cls = getattr(module, other_name)
def creater(other, *args, **kwargs):
"""_RunWrapper for object calling %s"""
return _RunWrapper(other, cls)
return creater
## Put in "_" to prevernt import on "from Factorties import *"
class _RunWrapper(object):
"""_RunWrapper(other, func)(*args, **kwargs)
executes:
func(other, *args, **kwargs)
(like a method)
"""
def __init__(self, other, func):
self.method = func
self.other = other
return None
def __call__(self, *args, **kwargs):
return self.method(self.other, *args, **kwargs)
pass
def createUnwrapper(other, do_unwrap = None, unwrapperName = None,
unwrap = None):
if not do_unwrap and not unwrap:
#if not defined create an empty method that does nothing
def runUnwrap(self):
return None
elif unwrapperName.lower() == 'snaphu':
from .runUnwrapSnaphu import runUnwrap
elif unwrapperName.lower() == 'snaphu_mcf':
from .runUnwrapSnaphu import runUnwrapMcf as runUnwrap
elif unwrapperName.lower() == 'icu':
from .runUnwrapIcu import runUnwrap
elif unwrapperName.lower() == 'grass':
from .runUnwrapGrass import runUnwrap
return _RunWrapper(other, runUnwrap)
def createUnwrap2Stage(other, do_unwrap_2stage = None, unwrapperName = None):
if (not do_unwrap_2stage) or (unwrapperName.lower() == 'icu') or (unwrapperName.lower() == 'grass'):
#if not defined create an empty method that does nothing
def runUnwrap2Stage(*arg, **kwargs):
return None
else:
try:
import pulp
from .runUnwrap2Stage import runUnwrap2Stage
except ImportError:
raise Exception('Please install PuLP Linear Programming API to run 2stage unwrap')
return _RunWrapper(other, runUnwrap2Stage)
createPreprocessor = _factory("runPreprocessor")
createCommonRangeSpectra = _factory("runCommonRangeSpectra")
createEqualizeSlcs = _factory("runEqualizeSlcs")
createEstimateBurstSync = _factory("runEstimateBurstSync")
#createComputeBaseline = _factory("runComputeBaseline")
#createVerifyDEM = _factory("runVerifyDEM")
#createVerifyGeocodeDEM = _factory("runVerifyGeocodeDEM")
#createTopo = _factory("runTopo")
#createSubsetOverlaps = _factory("runSubsetOverlaps")
#createCoarseOffsets = _factory("runCoarseOffsets")
#createCoarseResamp = _factory("runCoarseResamp")
#createOverlapIfg = _factory("runOverlapIfg")
#createPrepESD = _factory("runPrepESD")
#createESD = _factory("runESD")
#createRangeCoreg = _factory("runRangeCoreg")
#createFineOffsets = _factory("runFineOffsets")
#createFineResamp = _factory("runFineResamp")
#createBurstIfg = _factory("runBurstIfg")
#createMergeBursts = _factory("runMergeBursts")
#createFilter = _factory("runFilter")
#createGeocode = _factory("runGeocode")
#createMaskImages = _factory("runMaskImages")
#createCreateWbdMask = _factory("runCreateWbdMask")
###topsOffsetApp factories
#createMergeSLCs = _factory("runMergeSLCs")
#createDenseOffsets = _factory("runDenseOffsets")
#createOffsetFilter = _factory("runOffsetFilter")
#createOffsetGeocode = _factory("runOffsetGeocode")
#createCropOffsetGeo = _factory("runCropOffsetGeo")

View File

@ -1,48 +0,0 @@
#! /usr/bin/env python
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 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.
#
# Author: Eric Gurrola
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env python
import os
Import('envisceobj')
package = envisceobj['PACKAGE']
project = 'ScansarProc'
install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project)
listFiles = ['__init__.py', 'Factories.py', 'ScansarProc.py', 'runPreprocessor.py',
'runCommonRangeSpectra.py', 'runEqualizeSlcs.py',
'runEstimateBurstSync.py']
#, 'runComputeBaseline.py', 'runVerifyDEM.py', 'runTopo.py', 'runSubsetOverlaps.py', 'runCoarseOffsets.py', 'runCoarseResamp.py', 'runOverlapIfg.py', 'runPrepESD.py', 'runESD.py', 'runRangeCoreg.py', 'runFineOffsets.py', 'runFineResamp.py', 'runBurstIfg.py', 'runMergeBursts.py', 'runFilter.py', 'runUnwrapGrass.py', 'runUnwrapIcu.py', 'runUnwrapSnaphu.py', 'runGeocode.py', 'runMergeSLCs.py', 'runDenseOffsets.py', 'runOffsetFilter.py', 'runOffsetGeocode.py', 'runCropOffsetGeo.py', 'runUnwrap2Stage.py', 'VRTManager.py', 'runVerifyGeocodeDEM.py']
envisceobj.Install(install,listFiles)
envisceobj.Alias('install',install)

View File

@ -1,567 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2018
#
import os
import logging
import logging.config
from iscesys.Component.Component import Component
from iscesys.DateTimeUtil.DateTimeUtil import DateTimeUtil as DTU
from iscesys.Compatibility import Compatibility
MASTER_SLC_PRODUCT = Component.Parameter('masterSlcProduct',
public_name='master slc product',
default='master',
type=str,
mandatory=False,
doc='Directory name of the master SLC product')
SLAVE_SLC_PRODUCT = Component.Parameter('slaveSlcProduct',
public_name='slave slc product',
default='slave',
type=str,
mandatory=False,
doc='Directory name of the slave SLC product')
NUMBER_COMMON_BURSTS = Component.Parameter('numberOfCommonBursts',
public_name = 'number of common bursts',
default = None,
type = int,
container=list,
mandatory = False,
doc = 'Number of common bursts between slave and master')
DEM_FILENAME = Component.Parameter('demFilename',
public_name='dem image name',
default = None,
type = str,
mandatory = False,
doc = 'Name of the dem file')
GEOMETRY_DIRNAME = Component.Parameter('geometryDirname',
public_name='geometry directory name',
default='geom_master',
type=str,
mandatory=False,
doc = 'Geometry directory')
COMMON_RANGE_SPECTRA_SLC_DIRECTORY = Component.Parameter('commonRangeSpectraSlcDirectory',
public_name='equalized slc directory name',
default='commonrangespectra_slc',
type=str,
mandatory=False,
doc='directory with common range spectral slcs')
RANGE_SPECTRA_OVERLAP_THRESHOLD = Component.Parameter('rangeSpectraOverlapThreshold',
public_name='range spectra overlap threshold',
default=3.0e6,
type=float,
mandatory=False,
doc='Minimum range spectra overlap needed')
EQUALIZED_SLC_DIRECTORY = Component.Parameter('equalizedSlcDirectory',
public_name='equalized slc directory',
default='equalized_slc',
type=str,
mandatory=False,
doc='Directory with equalized slcs')
BURST_SYNC_DIRECTORY = Component.Parameter('burstSyncDirectory',
public_name='bursy sync directory',
default='burst_sync',
type=str,
mandatory=False,
doc='Directory with burst sync information')
COARSE_OFFSETS_DIRECTORY = Component.Parameter('coarseOffsetsDirname',
public_name = 'coarse offsets directory name',
default = 'coarse_offsets',
type = str,
mandatory = False,
doc = 'coarse offsets directory name')
COARSE_COREG_DIRECTORY = Component.Parameter('coarseCoregDirname',
public_name = 'coarse coreg directory name',
default = 'coarse_coreg',
type = str,
mandatory = False,
doc = 'coarse coregistered slc directory name')
COARSE_IFG_DIRECTORY = Component.Parameter('coarseIfgDirname',
public_name = 'coarse interferogram directory name',
default = 'coarse_interferogram',
type = str,
mandatory = False,
doc = 'Coarse interferogram directory')
FINE_OFFSETS_DIRECTORY = Component.Parameter('fineOffsetsDirname',
public_name = 'fine offsets directory name',
default = 'fine_offsets',
type = str,
mandatory = False,
doc = 'fine offsets directory name')
FINE_COREG_DIRECTORY = Component.Parameter('fineCoregDirname',
public_name = 'fine coreg directory name',
default = 'fine_coreg',
type = str,
mandatory = False,
doc = 'fine coregistered slc directory name')
FINE_IFG_DIRECTORY = Component.Parameter('fineIfgDirname',
public_name = 'fine interferogram directory name',
default = 'fine_interferogram',
type = str,
mandatory = False,
doc = 'Fine interferogram directory')
MERGED_DIRECTORY = Component.Parameter('mergedDirname',
public_name = 'merged products directory name',
default = 'merged',
type = str,
mandatory = False,
doc = 'Merged product directory')
OVERLAPS_SUBDIRECTORY = Component.Parameter('overlapsSubDirname',
public_name = 'overlaps subdirectory name',
default = 'overlaps',
type = str,
mandatory = False,
doc = 'Overlap region processing directory')
NUMBER_OF_SWATHS = Component.Parameter('numberOfSwaths',
public_name = 'number of swaths',
default=0,
type=int,
mandatory = False,
doc = 'Number of swaths')
MERGED_IFG_NAME = Component.Parameter(
'mergedIfgname',
public_name='merged interferogram name',
default='topophase.flat',
type=str,
mandatory=False,
doc='Filename of the merged interferogram.'
)
MERGED_LOS_NAME = Component.Parameter(
'mergedLosName',
public_name = 'merged los name',
default = 'los.rdr',
type = str,
mandatory = False,
doc = 'Merged los file name')
COHERENCE_FILENAME = Component.Parameter('coherenceFilename',
public_name='coherence name',
default='phsig.cor',
type=str,
mandatory=False,
doc='Coherence file name')
CORRELATION_FILENAME = Component.Parameter('correlationFilename',
public_name='correlation name',
default='topophase.cor',
type=str,
mandatory=False,
doc='Correlation file name')
FILTERED_INT_FILENAME = Component.Parameter('filtFilename',
public_name = 'filtered interferogram name',
default = 'filt_topophase.flat',
type = str,
mandatory = False,
doc = 'Filtered interferogram filename')
UNWRAPPED_INT_FILENAME = Component.Parameter('unwrappedIntFilename',
public_name='unwrapped interferogram filename',
default='filt_topophase.unw',
type=str,
mandatory=False,
doc='')
UNWRAPPED_2STAGE_FILENAME = Component.Parameter('unwrapped2StageFilename',
public_name='unwrapped 2Stage filename',
default='filt_topophase_2stage.unw',
type=str,
mandatory=False,
doc='Output File name of 2Stage unwrapper')
CONNECTED_COMPONENTS_FILENAME = Component.Parameter(
'connectedComponentsFilename',
public_name='connected component filename',
default=None,
type=str,
mandatory=False,
doc=''
)
DEM_CROP_FILENAME = Component.Parameter('demCropFilename',
public_name='dem crop file name',
default='dem.crop',
type=str,
mandatory=False,
doc='')
GEOCODE_LIST = Component.Parameter('geocode_list',
public_name='geocode list',
default=[COHERENCE_FILENAME,
CORRELATION_FILENAME,
UNWRAPPED_INT_FILENAME,
MERGED_LOS_NAME,
MERGED_IFG_NAME,
FILTERED_INT_FILENAME,
UNWRAPPED_2STAGE_FILENAME,
],
container=list,
type=str,
mandatory=False,
doc='List of files to geocode'
)
UNMASKED_PREFIX = Component.Parameter('unmaskedPrefix',
public_name='unmasked filename prefix',
default='unmasked',
type=str,
mandatory=False,
doc='Prefix prepended to the image filenames that have not been water masked')
####Adding things from topsOffsetApp for integration
OFFSET_TOP = Component.Parameter(
'offset_top',
public_name='Top offset location',
default=None,
type=int,
mandatory=False,
doc='Ampcor-calculated top offset location. Overridden by workflow.'
)
OFFSET_LEFT = Component.Parameter(
'offset_left',
public_name='Left offset location',
default=None,
type=int,
mandatory=False,
doc='Ampcor-calculated left offset location. Overridden by workflow.'
)
OFFSET_WIDTH = Component.Parameter(
'offset_width',
public_name='Offset image nCols',
default=None,
type=int,
mandatory=False,
doc='Number of columns in the final offset field (calculated in DenseAmpcor).'
)
OFFSET_LENGTH = Component.Parameter(
'offset_length',
public_name='Offset image nRows',
default=None,
type=int,
mandatory=False,
doc='Number of rows in the final offset field (calculated in DenseAmpcor).'
)
OFFSET_OUTPUT_FILE = Component.Parameter(
'offsetfile',
public_name='Offset filename',
default='dense_offsets.bil',
type=str,
mandatory=False,
doc='Filename for gross dense offsets BIL. Used in runDenseOffsets.'
)
OFFSET_SNR_FILE = Component.Parameter(
'snrfile',
public_name='Offset SNR filename',
default='dense_offsets_snr.bil',
type=str,
mandatory=False,
doc='Filename for gross dense offsets SNR. Used in runDenseOffsets.')
FILT_OFFSET_OUTPUT_FILE = Component.Parameter(
'filt_offsetfile',
public_name='Filtered offset filename',
default='filt_dense_offsets.bil',
type=str,
mandatory=False,
doc='Filename for filtered dense offsets BIL.'
)
OFFSET_GEOCODE_LIST = Component.Parameter('off_geocode_list',
public_name='offset geocode list',
default = [OFFSET_OUTPUT_FILE,
OFFSET_SNR_FILE,
FILT_OFFSET_OUTPUT_FILE],
container = list,
type=str,
mandatory=False,
doc = 'List of files on offset grid to geocode')
class ScansarProc(Component):
"""
This class holds the properties, along with methods (setters and getters)
to modify and return their values.
"""
parameter_list = (MASTER_SLC_PRODUCT,
SLAVE_SLC_PRODUCT,
DEM_FILENAME,
GEOMETRY_DIRNAME,
COMMON_RANGE_SPECTRA_SLC_DIRECTORY,
RANGE_SPECTRA_OVERLAP_THRESHOLD,
EQUALIZED_SLC_DIRECTORY,
BURST_SYNC_DIRECTORY,
COARSE_OFFSETS_DIRECTORY,
COARSE_COREG_DIRECTORY,
COARSE_IFG_DIRECTORY,
FINE_OFFSETS_DIRECTORY,
FINE_COREG_DIRECTORY,
FINE_IFG_DIRECTORY,
OVERLAPS_SUBDIRECTORY,
MERGED_DIRECTORY,
MERGED_IFG_NAME,
MERGED_LOS_NAME,
COHERENCE_FILENAME,
FILTERED_INT_FILENAME,
UNWRAPPED_INT_FILENAME,
UNWRAPPED_2STAGE_FILENAME,
CONNECTED_COMPONENTS_FILENAME,
DEM_CROP_FILENAME,
GEOCODE_LIST,
UNMASKED_PREFIX,
CORRELATION_FILENAME,
OFFSET_TOP,
OFFSET_LEFT,
OFFSET_LENGTH,
OFFSET_WIDTH,
OFFSET_OUTPUT_FILE,
OFFSET_SNR_FILE,
FILT_OFFSET_OUTPUT_FILE,
OFFSET_GEOCODE_LIST)
facility_list = ()
family='scansarcontext'
def __init__(self, name='', procDoc=None):
#self.updatePrivate()
super().__init__(family=self.__class__.family, name=name)
self.procDoc = procDoc
return None
def _init(self):
"""
Method called after Parameters are configured.
Determine whether some Parameters still have unresolved
Parameters as their default values and resolve them.
"""
#Determine whether the geocode_list still contains Parameters
#and give those elements the proper value. This will happen
#whenever the user doesn't provide as input a geocode_list for
#this component.
mergedir = self.mergedDirname
for i, x in enumerate(self.geocode_list):
if isinstance(x, Component.Parameter):
y = getattr(self, getattr(x, 'attrname'))
self.geocode_list[i] = os.path.join(mergedir, y)
for i,x in enumerate(self.off_geocode_list):
if isinstance(x, Component.Parameter):
y = getattr(self, getattr(x, 'attrname'))
self.off_geocode_list[i] = os.path.join(mergedir, y)
return
def loadProduct(self, xmlname):
'''
Load the product using Product Manager.
'''
from iscesys.Component.ProductManager import ProductManager as PM
pm = PM()
pm.configure()
obj = pm.loadProduct(xmlname)
return obj
def saveProduct(self, obj, xmlname):
'''
Save the product to an XML file using Product Manager.
'''
from iscesys.Component.ProductManager import ProductManager as PM
pm = PM()
pm.configure()
pm.dumpProduct(obj, xmlname)
return None
def getMergedOrbit(self, products):
from isceobj.Orbit.Orbit import Orbit
###Create merged orbit
orb = Orbit()
orb.configure()
burst = product[0]
#Add first burst orbit to begin with
for sv in burst.orbit:
orb.addStateVector(sv)
for pp in product:
##Add all state vectors
for sv in pp.orbit:
if (sv.time< orb.minTime) or (sv.time > orb.maxTime):
orb.addStateVector(sv)
pp.orbit = orb
return orb
def getInputSwathList(self, inlist):
'''
To be used to get list of swaths that user wants us to process.
'''
if len(inlist) == 0:
return [x+1 for x in range(self.numberOfSwaths)]
else:
return inlist
def getValidSwathList(self, inlist):
'''
Used to get list of swaths left after applying all filters - e.g, region of interest.
'''
import glob
inswaths = glob.glob( os.path.join(self.masterSlcProduct, 's*.xml'))
swaths = []
for x in inswaths:
swaths.append( int(os.path.splitext(os.path.basename(x))[0][-1]))
return sorted(swaths)
def hasGPU(self):
'''
Determine if GPU modules are available.
'''
flag = False
try:
from zerodop.GPUtopozero.GPUtopozero import PyTopozero
from zerodop.GPUgeo2rdr.GPUgeo2rdr import PyGeo2rdr
flag = True
except:
pass
return flag
def getOverlapFrequency(self, centerfreq1, bandwidth1,
centerfreq2, bandwidth2):
startfreq1 = centerfreq1 - bandwidth1 / 2.0
endingfreq1 = centerfreq1 + bandwidth1 / 2.0
startfreq2 = centerfreq2 - bandwidth2 / 2.0
endingfreq2 = centerfreq2 + bandwidth2 / 2.0
overlapfreq = []
if startfreq2 <= startfreq1 <= endingfreq2:
overlapfreq.append(startfreq1)
if startfreq2 <= endingfreq1 <= endingfreq2:
overlapfreq.append(endingfreq1)
if startfreq1 < startfreq2 < endingfreq1:
overlapfreq.append(startfreq2)
if startfreq1 < endingfreq2 < endingfreq1:
overlapfreq.append(endingfreq2)
if len(overlapfreq) != 2:
#no overlap bandwidth
return None
else:
startfreq = min(overlapfreq)
endingfreq = max(overlapfreq)
return [startfreq, endingfreq]
@property
def commonRangeSpectraMasterSlcProduct(self):
infile = self.masterSlcProduct
if infile[-1] == os.path.sep:
infile = infile[:-1]
base = os.path.sep.join( infile.split(os.path.sep)[-2:])
return os.path.join( self.commonRangeSpectraSlcDirectory, base)
@property
def commonRangeSpectraSlaveSlcProduct(self):
infile = self.slaveSlcProduct
if infile[-1] == os.path.sep:
infile = infile[:-1]
base = os.path.sep.join( infile.split(os.path.sep)[-2:])
return os.path.join( self.commonRangeSpectraSlcDirectory, base)
@property
def equalizedMasterSlcProduct(self):
infile = self.masterSlcProduct
if infile[-1] == os.path.sep:
infile = infile[:-1]
base = os.path.sep.join(infile.split(os.path.sep)[-2:])
return os.path.join( self.equalizedSlcDirectory, base)
@property
def equalizedSlaveSlcProduct(self):
infile = self.slaveSlcProduct
if infile[-1] == os.path.sep:
infile = infile[:-1]
base = os.path.sep.join(infile.split(os.path.sep)[-2:])
return os.path.join( self.equalizedSlcDirectory, base)
def writeBurstSyncFile(self, outfile, rgoff, azoff,
nb, nc,
unsynLines, synLines):
with open(outfile, 'w') as fid:
fid.write('image pair range offset: {0}\n'.format(rgoff))
fid.write('image pair azimuth offset: {0}\n'.format(azoff))
fid.write('number of lines in a burst: {0}\n'.format(nb))
fid.write('number of lines in a burst cycle: {0}\n'.format(nc))
fid.write('number of unsynchronized lines in a burst: {0}\n'.format(unsynLines))
fid.write('burst synchronization: {0}%'.format((synLines/nb)*100.0))

View File

@ -1,22 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2016
#
from .ScansarProc import *
from .Factories import *
def getFactoriesInfo():
return {'ScansarProc':
{'args':
{
'procDoc':{'value':None,'type':'Catalog','optional':True}
},
'factory':'createScansarProc'
}
}
def createScansarProc(name=None, procDoc= None):
from .ScansarProc import ScansarProc
return ScansarProc(name = name,procDoc = procDoc)

View File

@ -1,120 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2016
#
import logging
import isceobj
import os
from isceobj.Constants import SPEED_OF_LIGHT
import numpy as np
logger = logging.getLogger('isce.scansarinsar.runCommonRangeSpectra')
def createVirtualCopy(infile, outfile):
'''
Create a virtual copy as is.
'''
from osgeo import gdal
import shutil
ds = gdal.Open(infile + '.vrt', gdal.GA_ReadOnly)
width = ds.RasterXSize
lgth = ds.RasterYSize
ds = None
img = isceobj.createSlcImage()
img.setWidth(width)
img.setLength(lgth)
img.setAccessMode('READ')
img.setFilename(outfile)
img.renderHdr()
##Copy VRT as is
shutil.copyfile( infile + '.vrt', outfile + '.vrt')
def runCommonRangeSpectra(self):
'''Align central frequencies and pixel sizes.
'''
swathList = self._insar.getValidSwathList(self.swaths)
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
print('Common swaths: ', swathList)
for ind, swath in enumerate(swathList):
##Load master swath
master = self._insar.loadProduct( os.path.join(self._insar.masterSlcProduct,
's{0}.xml'.format(swath)))
##Load slave swath
slave = self._insar.loadProduct( os.path.join(self._insar.slaveSlcProduct,
's{0}.xml'.format(swath)))
##Check for overlap frequency
centerfreq1 = SPEED_OF_LIGHT / master.radarWavelegth
bandwidth1 = np.abs( master.instrument.pulseLength * master.instrument.chirpSlope)
centerfreq2 = SPEED_OF_LIGHT / slave.radarWavelegth
bandwidth2 = np.abs( slave.instrument.pulseLength * slave.instrument.chirpSlope)
overlapfreq = self._insar.getOverlapFrequency(centerfreq1, bandwidth1,
centerfreq2, bandwidth2)
if (overlapfreq is None):
print('No range bandwidth overlap found for swath {0}'.format(swath))
raise Exception('No range spectra overlap')
overlapbw = overlapfreq[1] - overlapfreq[0]
print('Range spectra overlap for swath {0} : {1}'.format(swath, overlapbw))
if overlapbw < self._insar.rangeSpectraOverlapThreshold:
raise Exception('Not enough range spectra overlap for swath {0}'.format(swath))
centerfreq = 0.5 * (centerfreq1 + centerfreq2)
###Check if master needs range filtering
if (np.abs(centerfreq1 - centerfreq) < 1.0) and ((bandwidth1 - 1.0) < overlapbw):
print('No need to range filter master slc for swath {0}'.format(swath))
infile = master.image.filename
outfile = os.path.join(self._insar.commonRangeSpectraSlcDirectory,
os.path.sep.join(infile.split(os.path.sep)[-4:]))
os.makedirs( os.path.dirname(outfile))
createVirtualCopy(infile, outfile)
##Generate product
master.image.filename = outfile
self._insar.saveProduct(master, os.path.dirname(outfile) + '.xml')
else:
raise NotImplementedError('This feature will be available after porting rg_filter')
###Check if slave needs range filtering
if (np.abs(centerfreq2 - centerfreq) < 1.0) and ((bandwidth2 - 1.0) < overlapbw):
print('No need to range filter slave slc for swath {0}'.format(swath))
infile = slave.image.filename
outfile = os.path.join(self._insar.commonRangeSpectraSlcDirectory,
os.path.sep.join(infile.split(os.path.sep)[-4:]))
os.makedirs( os.path.dirname(outfile))
createVirtualCopy(infile, outfile)
##Generate product
slave.image.filename = outfile
self._insar.saveProduct(slave, os.path.dirname(outfile) + '.xml')
else:
raise NotImplementedError('This feature will be available after porting rg_filter')
catalog.printToLog(logger, "runCommonRangeSpectra")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -1,91 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2016
#
import logging
import isceobj
import os
import numpy as np
logger = logging.getLogger('isce.scansarinsar.runCommonRangeSpectra')
def createVirtualCopy(infile, outfile):
'''
Create a virtual copy as is.
'''
from osgeo import gdal
import shutil
ds = gdal.Open(infile + '.vrt', gdal.GA_ReadOnly)
width = ds.RasterXSize
lgth = ds.RasterYSize
ds = None
img = isceobj.createSlcImage()
img.setWidth(width)
img.setLength(lgth)
img.setAccessMode('READ')
img.setFilename(outfile)
img.renderHdr()
##Copy VRT as is
shutil.copyfile( infile + '.vrt', outfile + '.vrt')
def runEqualizeSlcs(self):
'''Align central frequencies and pixel sizes.
'''
swathList = self._insar.getValidSwathList(self.swaths)
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
print('Common swaths: ', swathList)
for ind, swath in enumerate(swathList):
##Load master swath
master = self._insar.loadProduct( os.path.join(self._insar.commonRangeSpectraMasterSlcProduct,
's{0}.xml'.format(swath)))
##Load slave swath
slave = self._insar.loadProduct( os.path.join(self._insar.commonRangeSpectraSlaveSlcProduct,
's{0}.xml'.format(swath)))
###Check if master needs range filtering
if (np.abs(master.instrument.rangeSamplingRate - slave.instrument.rangeSamplingRate) < 1.0) and ((master.PRF - slave.PRF) < 1.0):
print('No need to equalize pixesl for swath {0}'.format(swath))
####Copy master as is
infile = master.image.filename
outfile = os.path.join(self._insar.equalizedMasterSlcProduct,
's{0}/swath.slc'.format(swath))
os.makedirs( os.path.dirname(outfile))
createVirtualCopy(infile, outfile)
##Generate product
master.image.filename = outfile
self._insar.saveProduct(master, os.path.dirname(outfile) + '.xml')
###Copy slave as is
infile = slave.image.filename
outfile = os.path.join(self._insar.equalizedSlaveSlcProduct,
's{0}/swath.slc'.format(swath))
os.makedirs( os.path.dirname(outfile))
createVirtualCopy(infile, outfile)
##Generate product
slave.image.filename = outfile
self._insar.saveProduct(slave, os.path.dirname(outfile) + '.xml')
else:
raise NotImplementedError("We haven't implemented this yet. Maybe we can get around this. To be explored ...")
catalog.printToLog(logger, "runEqualizeSlcs")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -1,123 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2016
#
import logging
import isceobj
import os
import numpy as np
import datetime
logger = logging.getLogger('isce.scansarinsar.runEstimateBurstSync')
def runEstimateBurstSync(self):
'''Estimate burst sync between acquisitions.
'''
swathList = self._insar.getValidSwathList(self.swaths)
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
print('Common swaths: ', swathList)
if not os.path.isdir(self._insar.burstSyncDirectory):
os.makedirs(self._insar.burstSyncDirectory)
for ind, swath in enumerate(swathList):
##Load master swath
master = self._insar.loadProduct( os.path.join(self._insar.equalizedMasterSlcProduct,
's{0}.xml'.format(swath)))
##Load slave swath
slave = self._insar.loadProduct( os.path.join(self._insar.equalizedSlaveSlcProduct,
's{0}.xml'.format(swath)))
##Replacing Cunren's original high fidelity implementation with simpler more efficient one
##To estimate burst sync, we dont really need the DEM. Hardly changes with topography
##Topo impacts range offset but hardly affects azimuth offsets. Hence using a single estimate
##At mid range and start of middle burst of the master.
##In the original implementation - topo and geo2rdr were performed to the mid 100 lines of
##master image. Eventually, offset estimates were averaged to a single number.
##Our single estimate gets us to that number in a simpler manner.
###Get mid range for middle burst of master
midRange = master.startingRange + 0.5 * master.numberOfSamples * master.instrument.rangePixelSize
midLine = master.burstStartLines[len(master.burstStartLines)//2]
tmaster = master.sensingStart + datetime.timedelta(seconds = midLine / master.PRF)
llh = master.orbit.rdr2geo(tmaster, midRange)
slvaz, slvrng = slave.orbit.geo2rdr(llh)
###Translate to offsets
rgoff = ((slvrng - slave.startingRange) / slave.instrument.rangePixelSize) - 0.5 * master.numberOfSamples
azoff = ((slvaz - slave.sensingStart).total_seconds() * slave.PRF) - midLine
##Jumping back to Cunren's original code
scburstStartLine = master.burstStartLines[0] + azoff
nb = slave.nbraw
nc = slave.ncraw
#Slave burst start times corresponding to master burst start times implies 100% synchronization
scburstStartLines = scburstStartLine + np.arange(-100000, 100000)*nc
dscburstStartLines = -(slave.burstStartLines[0] - scburstStartLines)
unsynLines = dscburstStartLines[ np.argmin( np.abs(dscburstStartLines))]
if np.abs(unsynLines) >= nb:
synLines = 0
if unsynLines > 0:
unsynLines = nb
else:
unsynLines = -nb
else:
synLines = nb - np.abs(unsynLines)
##Copy of illustration from Cunren's code
############################################################# ###############################
#illustration of the sign of the number of unsynchronized lin es (unsynLines)
#The convention is the same as ampcor offset, that is,
# slaveLineNumber = masterLineNumber + unsynLine s
#
# |-----------------------| ------------
# | | ^
# | | |
# | | | unsynLines < 0
# | | |
# | | \ /
# | | |-----------------------|
# | | | |
# | | | |
# |-----------------------| | |
# Master Burst | |
# | |
# | |
# | |
# | |
# |-----------------------|
# Slave Burst
#
#
############################################################# ###############################
##For now keeping Cunren's text file format.
##Could be streamlined
outfile = os.path.join(self._insar.burstSyncDirectory, 's{0}.txt'.format(swath))
self._insar.writeBurstSyncFile(outfile, rgoff, azoff,
nb, nc,
unsynLines, synLines)
synPerc = (synLines/nb)*100.0
if synPerc < self.burstOverlapThreshold:
print('Sync overlap {0} < {1}. Will trigger common azimuth spectra filter for swath {2}'.format(synPerc, self.burstOverlapThreshold, swath))
else:
print('Sync overlap {0} >= {1}. No common azimuth spectra filter applied for swath {2}'.format(synPerc, self.burstOverlapThreshold, swath))
catalog.printToLog(logger, "runEstimateBurstSync")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -1,80 +0,0 @@
#
# Author: Piyush Agram
# Copyright 2016
#
import logging
import isceobj
import mroipac
from mroipac.baseline.Baseline import Baseline
import copy
import os
logger = logging.getLogger('isce.scansarinsar.runPreprocessor')
def runPreprocessor(self):
'''Extract images.
'''
virtual = self.useVirtualFiles
catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
###First set maximum number of swaths possible for a sensor.
self._insar.numberOfSwaths = self.master.maxSwaths
swathList = self._insar.getInputSwathList(self.swaths)
catalog.addItem('Input list of swaths to process: ', swathList, 'common')
self.master.configure()
##Processing master first.
self.master.configure()
self.master.swaths = swathList
self.master.virtualFiles = self.useVirtualFiles
##Assume a single folder is provided for now.
##Leaving room for future extensions.
self.master.inputDirList = self.master.inputDirList[0]
swaths = self.master.extractImage()
self.insar.masterSlcProduct = os.path.dirname(os.path.dirname(swaths[0].image.filename))
print('Master product: ', self.insar.masterSlcProduct)
for ind, swath in enumerate(swaths):
catalog.addInputsFrom(swath, 'master.sensor_{0}'.format(swathList[ind]))
catalog.addItem('swathWidth_{0}'.format(swathList[ind]), swath.numberOfSamples, 'master')
catalog.addItem('swathLength_{0}'.format(swathList[ind]), swath.numberOfLines, 'master')
#catalog.addItem('numberOfBursts_{0}'.format(swathList[ind]), len(swath.burstStartLines), 'master')
self._insar.saveProduct(swath, os.path.dirname(swath.image.filename) + '.xml')
##Processing slave next.
self.slave.configure()
self.slave.swaths = swathList
self.slave.virtualFiles = self.useVirtualFiles
##Assume a single folder is provided for now.
##Leaving room for future extensions.
self.slave.inputDirList = self.slave.inputDirList[0]
swaths = self.slave.extractImage()
self.insar.slaveSlcProduct = os.path.dirname( os.path.dirname(swaths[0].image.filename))
print('Slave Product: ', self.insar.slaveSlcProduct)
for ind, swath in enumerate(swaths):
catalog.addInputsFrom(swath, 'slave.sensor_{0}'.format(swathList[ind]))
catalog.addItem('swathWidth_{0}'.format(swathList[ind]), swath.numberOfSamples, 'slave')
catalog.addItem('swathLength_{0}'.format(swathList[ind]), swath.numberOfLines, 'slave')
#catalog.addItem('numberOfBursts_{0}'.format(swathList[ind]), len(swath.burstStartLines), 'master')
self._insar.saveProduct(swath, os.path.dirname(swath.image.filename) + '.xml')
catalog.printToLog(logger, "runPreprocessor")
self._insar.procDoc.addAllFromCatalog(catalog)

View File

@ -56,5 +56,4 @@ SConscript(os.path.join('src', 'SConscript'),
variant_dir = os.path.join(install, 'src'))
SConscript(os.path.join('TOPS','SConscript'))
SConscript(os.path.join('GRD', 'SConscript'))
SConscript(os.path.join('ScanSAR', 'SConscript'))
SConscript(os.path.join('MultiMode', 'SConscript'))

File diff suppressed because it is too large Load Diff

View File

@ -1,119 +0,0 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2010 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.
#
# Author: Walter Szeliga
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import datetime
from iscesys.Component.Component import Component
from isceobj.Scene.Frame import Frame
FMRATE_VS_PIXEL = Component.Parameter('_fmrateVsPixel',
public_name = 'FMRATE_VS_PIXEL',
default = [],
type = float,
mandatory = True,
container = list,
doc = 'Doppler polynomial coefficients vs pixel number')
BURST_LENGTH = Component.Parameter('_burstLength',
public_name = 'Burst Length',
default = None,
type = int,
mandatory = True,
doc = 'Number of pulses in a burst')
BURST_CYCLE_LENGTH = Component.Parameter('_burstCycleLength',
public_name = 'Burst cycle length',
default = None,
type = float,
mandatory = True,
doc = 'Number of pulses in a full cycle')
BURST_START_LINES = Component.Parameter('burstStartLines',
public_name = 'Burst start lines',
default = [],
type = float,
container=list,
mandatory = True,
doc = 'Start lines of bursts in SLC')
class FullApertureSwathSLCProduct(Frame):
"""A class to represent a frame along a radar track"""
family = 'frame'
logging_name = 'isce.isceobj.scansar.fullapertureswathslcproduct'
parameter_list = Frame.parameter_list + (BURST_LENGTH,
BURST_CYCLE_LENGTH,
BURST_START_LINES,
FMRATE_VS_PIXEL)
def __init__(self, name=''):
super(FullApertureSwathSLCProduct, self).__init__(name=name)
return None
@property
def nbraw(self):
return self._burstLength
@nbraw.setter
def nbraw(self, x):
self._burstLength = x
@property
def ncraw(self):
return self._burstCycleLength
@ncraw.setter
def ncraw(self, x):
self._burstCycleLength = x
@property
def burstLength(self):
return self._burstLength
@burstLength.setter
def burstLength(self, x):
self._burstLength = x
@property
def burstCycleLength(self):
return self._burstCycleLength
@burstCycleLength.setter
def burstCycleLength(self, x):
self._burstCycleLength = x
@property
def fmrateVsPixel(self):
return self._fmrateVsPixel
@fmrateVsPixel.setter
def fmrateVsPixel(self,x):
self._fmrateVsPixel = x

View File

@ -1,31 +0,0 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Walter Szeliga
# NASA Jet Propulsion Laboratory
# California Institute of Technology
# (c) 2010 All Rights Reserved
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env python
import os
Import('envSensor')
envTOPS = envSensor.Clone()
project = 'ScanSAR'
package = envTOPS['PACKAGE']
envTOPS['PROJECT'] = project
envTOPS['SENSOR_SCONS_INSTALL'] = os.path.join(
envTOPS['PRJ_SCONS_INSTALL'], package, 'Sensor',project)
install = envTOPS['SENSOR_SCONS_INSTALL']
listFiles = ['__init__.py','FullApertureSwathSLCProduct.py','ALOS2.py']
helpList,installHelp = envTOPS['HELP_BUILDER'](envTOPS,'__init__.py',install)
envTOPS.Install(installHelp,helpList)
envTOPS.Alias('install',installHelp)
envTOPS.Install(install,listFiles)
envTOPS.Alias('install',install)

View File

@ -1,74 +0,0 @@
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2015 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.
#
# Author: Piyush Agram
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def createFullApertureSwathSLCProduct():
from .FullApertureSwathSLCProduct import FullApertureSwathSLCProduct
return FullApertureSwathSLCProduct()
def createALOS2(name=None):
from .ALOS2 import ALOS2Scanner
return ALOS2Scanner()
SENSORS = {
'ALOS2' : createALOS2,
}
def getFactoriesInfo():
"""
Returns a dictionary with information on how to create an object Sensor from its factory
"""
return {'ScanSARSensor':
{'args':
{
'sensor':{'value':list(SENSORS.keys()),'type':'str','optional':False}
},
'factory':'createSensor'
}
}
def createSensor(sensor='', name=None):
try:
cls = SENSORS[str(sensor).upper()]
try:
instance = cls(name)
except AttributeError:
raise TypeError("'sensor name'=%s cannot be interpreted" %
str(sensor))
pass
except:
print("Sensor type not recognized. Valid Sensor types:\n",
SENSORS.keys())
instance = None
pass
return instance