diff --git a/applications/SConscript b/applications/SConscript index acd8d83..5f38f64 100644 --- a/applications/SConscript +++ b/applications/SConscript @@ -78,7 +78,10 @@ listFiles = ['mdx.py', 'wbd.py', 'downsampleDEM.py', 'gdal2isce_xml.py', - 'scansarApp.py'] + 'alos2App.py', + 'alos2burstApp.py', + 'scansarApp.py', + 'wbd_with_correction.py'] # 'isce2he5.py'] envapplications.Install(install, listFiles) diff --git a/applications/alos2App.py b/applications/alos2App.py new file mode 100755 index 0000000..e3cda6c --- /dev/null +++ b/applications/alos2App.py @@ -0,0 +1,1079 @@ +#!/usr/bin/env python3 + +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + + +import time +import os +import sys +import logging +import logging.config + +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 Alos2Proc + +logging.config.fileConfig( + os.path.join(os.environ['ISCE_HOME'], 'defaults', 'logging', + 'logging.conf') +) + +logger = logging.getLogger('isce.insar') + + +MASTER_DIR = Application.Parameter('masterDir', + public_name='master directory', + default=None, + type=str, + mandatory=False, + doc="master data directory") + +SLAVE_DIR = Application.Parameter('slaveDir', + public_name='slave directory', + default=None, + type=str, + mandatory=False, + doc="slave data directory") + +MASTER_FRAMES = Application.Parameter('masterFrames', + public_name = 'master frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'master frames to process') + +SLAVE_FRAMES = Application.Parameter('slaveFrames', + public_name = 'slave frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'slave frames to process') + +MASTER_POLARIZATION = Application.Parameter('masterPolarization', + public_name='master polarization', + default='HH', + type=str, + mandatory=False, + doc="master polarization to process") + +SLAVE_POLARIZATION = Application.Parameter('slavePolarization', + public_name='slave polarization', + default='HH', + type=str, + mandatory=False, + doc="slave polarization to process") + +#for ScanSAR-stripmap, always process all swaths, +#user's settings are overwritten +STARTING_SWATH = Application.Parameter('startingSwath', + public_name='starting swath', + default=None, + type=int, + mandatory=False, + doc="starting swath to process") + +ENDING_SWATH = Application.Parameter('endingSwath', + public_name='ending swath', + default=None, + type=int, + mandatory=False, + doc="ending swath to process") + +DEM = Application.Parameter('dem', + public_name='dem for coregistration', + default=None, + type=str, + mandatory=False, + doc='dem for coregistration file') + +DEM_GEO = Application.Parameter('demGeo', + public_name='dem for geocoding', + default=None, + type=str, + mandatory=False, + doc='dem for geocoding file') + +#this water body is used to create water body in radar coordinate used in processing +#radar-coordinate water body is created two times in runRdr2Geo.py and runLook.py, respectively +#radar-coordinate water body is used in: +#(1) determining the number of offsets in slc offset estimation, and radar/dem offset estimation +#(2) masking filtered interferogram or unwrapped interferogram +#(3) determining the number of offsets in slc residual offset estimation after geometric offset +# computation in coregistering slcs in dense offset. +#(4) masking dense offset field +WBD = Application.Parameter('wbd', + public_name='water body', + default=None, + type=str, + mandatory=False, + doc='water body file') + +USE_VIRTUAL_FILE = Application.Parameter('useVirtualFile', + public_name = 'use virtual file', + default=True, + type=bool, + mandatory=False, + doc = 'use virtual file when possible to save space') + +USE_GPU = Application.Parameter('useGPU', + public_name='use GPU', + default=False, + type=bool, + mandatory=False, + doc='Allow App to use GPU when available') + + +BURST_SYNCHRONIZATION_THRESHOLD = Application.Parameter('burstSynchronizationThreshold', + public_name = 'burst synchronization threshold', + default = 75.0, + type=float, + mandatory = True, + doc = 'burst synchronization threshold in percentage') + +CROP_SLC = Application.Parameter('cropSlc', + public_name = 'crop slc', + default=False, + type=bool, + mandatory=False, + doc = 'crop slcs to the overlap area (always crop for ScanSAR-stripmap)') + +#for areas where no water body data available, turn this off, otherwise the program will use geometrical offset, which is not accuate enough +#if it still does not work, set "number of range offsets for slc matching" and "number of azimuth offsets for slc matching" +USE_WBD_FOR_NUMBER_OFFSETS = Application.Parameter('useWbdForNumberOffsets', + public_name = 'use water body to dertermine number of matching offsets', + default = True, + type = bool, + mandatory = False, + doc = 'use water body to dertermine number of matching offsets') + +NUMBER_RANGE_OFFSETS = Application.Parameter('numberRangeOffsets', + public_name = 'number of range offsets for slc matching', + default = None, + type = int, + mandatory = False, + container = list, + doc = 'number of range offsets for slc matching') + +NUMBER_AZIMUTH_OFFSETS = Application.Parameter('numberAzimuthOffsets', + public_name = 'number of azimuth offsets for slc matching', + default = None, + type = int, + mandatory = False, + container = list, + doc = 'number of azimuth offsets for slc matching') + +NUMBER_RANGE_LOOKS1 = Application.Parameter('numberRangeLooks1', + public_name='number of range looks 1', + default=None, + type=int, + mandatory=False, + doc="number of range looks when forming interferogram") + +NUMBER_AZIMUTH_LOOKS1 = Application.Parameter('numberAzimuthLooks1', + public_name='number of azimuth looks 1', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when forming interferogram") + +NUMBER_RANGE_LOOKS2 = Application.Parameter('numberRangeLooks2', + public_name='number of range looks 2', + default=None, + type=int, + mandatory=False, + doc="number of range looks for further multiple looking") + +NUMBER_AZIMUTH_LOOKS2 = Application.Parameter('numberAzimuthLooks2', + public_name='number of azimuth looks 2', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for further multiple looking") + +NUMBER_RANGE_LOOKS_SIM = Application.Parameter('numberRangeLooksSim', + public_name='number of range looks sim', + default=None, + type=int, + mandatory=False, + doc="number of range looks when simulating radar image") + +NUMBER_AZIMUTH_LOOKS_SIM = Application.Parameter('numberAzimuthLooksSim', + public_name='number of azimuth looks sim', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when simulating radar image") + +SWATH_OFFSET_MATCHING = Application.Parameter('swathOffsetMatching', + public_name = 'do matching when computing adjacent swath offset', + default=True, + type=bool, + mandatory=False, + doc = 'do matching when computing adjacent swath offset') + +FRAME_OFFSET_MATCHING = Application.Parameter('frameOffsetMatching', + public_name = 'do matching when computing adjacent frame offset', + default=True, + type=bool, + mandatory=False, + doc = 'do matching when computing adjacent frame offset') + +FILTER_STRENGTH = Application.Parameter('filterStrength', + public_name = 'interferogram filter strength', + default = 0.3, + type=float, + mandatory = True, + doc = 'interferogram filter strength (power spectrum filter)') + +FILTER_WINSIZE = Application.Parameter('filterWinsize', + public_name = 'interferogram filter window size', + default = 32, + type=int, + mandatory = False, + doc = 'interferogram filter window size') + +FILTER_STEPSIZE = Application.Parameter('filterStepsize', + public_name = 'interferogram filter step size', + default = 4, + type=int, + mandatory = False, + doc = 'interferogram filter step size') + +REMOVE_MAGNITUDE_BEFORE_FILTERING = Application.Parameter('removeMagnitudeBeforeFiltering', + public_name = 'remove magnitude before filtering', + default=True, + type=bool, + mandatory=False, + doc = 'remove magnitude before filtering') + +WATERBODY_MASK_STARTING_STEP = Application.Parameter('waterBodyMaskStartingStep', + public_name='water body mask starting step', + default='unwrap', + type=str, + mandatory=False, + doc='water body mask starting step: None, filt, unwrap') + +GEOCODE_LIST = Application.Parameter('geocodeList', + public_name = 'geocode file list', + default=None, + type=str, + container=list, + mandatory=False, + doc = 'geocode file list') + +GEOCODE_BOUNDING_BOX = Application.Parameter('bbox', + public_name = 'geocode bounding box', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'geocode bounding box') + +GEOCODE_INTERP_METHOD = Application.Parameter('geocodeInterpMethod', + public_name='geocode interpolation method', + default=None, + type=str, + mandatory=False, + doc='geocode interpolation method: sinc, bilinear, bicubic, nearest') +##################################################################### + +#ionospheric correction parameters +DO_ION = Application.Parameter('doIon', + public_name = 'do ionospheric phase estimation', + default = True, + type = bool, + mandatory = False, + doc = 'do ionospheric phase estimation') + +APPLY_ION = Application.Parameter('applyIon', + public_name = 'apply ionospheric phase correction', + default = True, + type = bool, + mandatory = False, + doc = 'apply ionospheric phase correction') + +NUMBER_RANGE_LOOKS_ION = Application.Parameter('numberRangeLooksIon', + public_name='number of range looks ion', + default=None, + type=int, + mandatory=False, + doc="number of range looks for ionospheric correction") + +NUMBER_AZIMUTH_LOOKS_ION = Application.Parameter('numberAzimuthLooksIon', + public_name='number of azimuth looks ion', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for ionospheric correction") + +MASKED_AREAS_ION = Application.Parameter('maskedAreasIon', + 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') + +FIT_ION = Application.Parameter('fitIon', + public_name = 'apply polynomial fit before filtering ionosphere phase', + default = True, + type = bool, + mandatory = False, + doc = 'apply polynomial fit before filtering ionosphere phase') + +FILTERING_WINSIZE_MAX_ION = Application.Parameter('filteringWinsizeMaxIon', + public_name='maximum window size for filtering ionosphere phase', + default=151, + type=int, + mandatory=False, + doc='maximum window size for filtering ionosphere phase') + +FILTERING_WINSIZE_MIN_ION = Application.Parameter('filteringWinsizeMinIon', + public_name='minimum window size for filtering ionosphere phase', + default=41, + type=int, + mandatory=False, + doc='minimum window size for filtering ionosphere phase') + +FILTER_SUBBAND_INT = Application.Parameter('filterSubbandInt', + public_name = 'filter subband interferogram', + default = False, + type = bool, + mandatory = False, + doc = 'filter subband interferogram') + +FILTER_STRENGTH_SUBBAND_INT = Application.Parameter('filterStrengthSubbandInt', + public_name = 'subband interferogram filter strength', + default = 0.3, + type=float, + mandatory = True, + doc = 'subband interferogram filter strength (power spectrum filter)') + +FILTER_WINSIZE_SUBBAND_INT = Application.Parameter('filterWinsizeSubbandInt', + public_name = 'subband interferogram filter window size', + default = 32, + type=int, + mandatory = False, + doc = 'subband interferogram filter window size') + +FILTER_STEPSIZE_SUBBAND_INT = Application.Parameter('filterStepsizeSubbandInt', + public_name = 'subband interferogram filter step size', + default = 4, + type=int, + mandatory = False, + doc = 'subband interferogram filter step size') + +REMOVE_MAGNITUDE_BEFORE_FILTERING_SUBBAND_INT = Application.Parameter('removeMagnitudeBeforeFilteringSubbandInt', + public_name = 'remove magnitude before filtering subband interferogram', + default=True, + type=bool, + mandatory=False, + doc = 'remove magnitude before filtering subband interferogram') +##################################################################### + +#dense offset parameters +DO_DENSE_OFFSET = Application.Parameter('doDenseOffset', + public_name='do dense offset', + default = False, + type = bool, + mandatory = False, + doc = 'perform dense offset estimation') + +ESTIMATE_RESIDUAL_OFFSET = Application.Parameter('estimateResidualOffset', + public_name='estimate residual offset after geometrical coregistration', + default = True, + type = bool, + mandatory = False, + doc = 'estimate residual offset after geometrical coregistration') + +DELETE_GEOMETRY_FILES = Application.Parameter('deleteGeometryFiles', + public_name='delete geometry files used for dense offset estimation', + default = False, + type = bool, + mandatory = False, + doc = 'delete geometry files used for dense offset estimation') + + +#for the following set of matching parameters +#from: dense offset estimation window width +#to: dense offset covariance surface oversample window size +#normally we only have to set the following parameters. +#a good set of parameters other than default is: +# 128 +# 128 +# 64 +# 64 + +OFFSET_WINDOW_WIDTH = Application.Parameter('offsetWindowWidth', + public_name='dense offset estimation window width', + default=64, + type=int, + mandatory=False, + doc='dense offset estimation window width') + +OFFSET_WINDOW_HEIGHT = Application.Parameter('offsetWindowHeight', + public_name='dense offset estimation window hight', + default=64, + type=int, + mandatory=False, + doc='dense offset estimation window hight') + +#NOTE: actual number of resulting correlation pixels: offsetSearchWindowWidth*2+1 +OFFSET_SEARCH_WINDOW_WIDTH = Application.Parameter('offsetSearchWindowWidth', + public_name='dense offset search window width', + default=8, + type=int, + mandatory=False, + doc='dense offset search window width') + +#NOTE: actual number of resulting correlation pixels: offsetSearchWindowHeight*2+1 +OFFSET_SEARCH_WINDOW_HEIGHT = Application.Parameter('offsetSearchWindowHeight', + public_name='dense offset search window hight', + default=8, + type=int, + mandatory=False, + doc='dense offset search window hight') + +OFFSET_SKIP_WIDTH = Application.Parameter('offsetSkipWidth', + public_name='dense offset skip width', + default=32, + type=int, + mandatory=False, + doc='dense offset skip width') + +OFFSET_SKIP_HEIGHT = Application.Parameter('offsetSkipHeight', + public_name='dense offset skip hight', + default=32, + type=int, + mandatory=False, + doc='dense offset skip hight') + +OFFSET_COVARIANCE_OVERSAMPLING_FACTOR = Application.Parameter('offsetCovarianceOversamplingFactor', + public_name='dense offset covariance surface oversample factor', + default=64, + type=int, + mandatory=False, + doc='dense offset covariance surface oversample factor') + +OFFSET_COVARIANCE_OVERSAMPLING_WINDOWSIZE = Application.Parameter('offsetCovarianceOversamplingWindowsize', + public_name='dense offset covariance surface oversample window size', + default=16, + type=int, + mandatory=False, + doc='dense offset covariance surface oversample window size') + +MASK_OFFSET_WITH_WBD = Application.Parameter('maskOffsetWithWbd', + public_name='mask dense offset with water body', + default = True, + type = bool, + mandatory = False, + doc = 'mask dense offset with water body') + +DO_OFFSET_FILTERING = Application.Parameter('doOffsetFiltering', + public_name='do offset filtering', + default = False, + type = bool, + mandatory = False, + doc = 'perform dense offset filtering') + +OFFSET_FILTER_WINDOWSIZE = Application.Parameter('offsetFilterWindowsize', + public_name='offset filter window size', + default=3, + type=int, + mandatory=False, + doc='offset filter window size') + +OFFSET_FILTER_SNR_THRESHOLD = Application.Parameter('offsetFilterSnrThreshold', + public_name = 'offset filter snr threshold', + default = 0.0, + type=float, + mandatory = False, + doc = 'offset filter snr threshold') +##################################################################### + +#system parameters +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.") +##################################################################### + +#Facility declarations +MASTER = Application.Facility('master', + public_name='master', + module='isceobj.Sensor.MultiMode', + factory='createSensor', + args=('ALOS2', 'master'), + mandatory=True, + doc="master component") + +SLAVE = Application.Facility('slave', + public_name='slave', + module='isceobj.Sensor.MultiMode', + factory='createSensor', + args=('ALOS2','slave'), + mandatory=True, + doc="slave component") + +# RUN_UNWRAPPER = Application.Facility('runUnwrapper', +# public_name='Run unwrapper', +# module='isceobj.Alos2Proc', +# 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.Alos2Proc', +# factory='createUnwrap2Stage', +# args=(SELF(), DO_UNWRAP_2STAGE, UNWRAPPER_NAME), +# mandatory=False, +# doc="Unwrapping module") + +_INSAR = Application.Facility('_insar', + public_name='alos2proc', + module='isceobj.Alos2Proc', + factory='createAlos2Proc', + args = ('alos2AppContext',isceobj.createCatalog('alos2Proc')), + mandatory=False, + doc="Alos2Proc object") + + +## Common interface for all insar applications. +class Alos2InSAR(Application): + family = 'alos2insar' + parameter_list = (MASTER_DIR, + SLAVE_DIR, + MASTER_FRAMES, + SLAVE_FRAMES, + MASTER_POLARIZATION, + SLAVE_POLARIZATION, + STARTING_SWATH, + ENDING_SWATH, + DEM, + DEM_GEO, + WBD, + USE_VIRTUAL_FILE, + USE_GPU, + BURST_SYNCHRONIZATION_THRESHOLD, + CROP_SLC, + USE_WBD_FOR_NUMBER_OFFSETS, + NUMBER_RANGE_OFFSETS, + NUMBER_AZIMUTH_OFFSETS, + NUMBER_RANGE_LOOKS1, + NUMBER_AZIMUTH_LOOKS1, + NUMBER_RANGE_LOOKS2, + NUMBER_AZIMUTH_LOOKS2, + NUMBER_RANGE_LOOKS_SIM, + NUMBER_AZIMUTH_LOOKS_SIM, + SWATH_OFFSET_MATCHING, + FRAME_OFFSET_MATCHING, + FILTER_STRENGTH, + FILTER_WINSIZE, + FILTER_STEPSIZE, + REMOVE_MAGNITUDE_BEFORE_FILTERING, + WATERBODY_MASK_STARTING_STEP, + GEOCODE_LIST, + GEOCODE_BOUNDING_BOX, + GEOCODE_INTERP_METHOD, + #ionospheric correction parameters + DO_ION, + APPLY_ION, + NUMBER_RANGE_LOOKS_ION, + NUMBER_AZIMUTH_LOOKS_ION, + MASKED_AREAS_ION, + FIT_ION, + FILTERING_WINSIZE_MAX_ION, + FILTERING_WINSIZE_MIN_ION, + FILTER_SUBBAND_INT, + FILTER_STRENGTH_SUBBAND_INT, + FILTER_WINSIZE_SUBBAND_INT, + FILTER_STEPSIZE_SUBBAND_INT, + REMOVE_MAGNITUDE_BEFORE_FILTERING_SUBBAND_INT, + #dense offset parameters + DO_DENSE_OFFSET, + ESTIMATE_RESIDUAL_OFFSET, + DELETE_GEOMETRY_FILES, + OFFSET_WINDOW_WIDTH, + OFFSET_WINDOW_HEIGHT, + OFFSET_SEARCH_WINDOW_WIDTH, + OFFSET_SEARCH_WINDOW_HEIGHT, + OFFSET_SKIP_WIDTH, + OFFSET_SKIP_HEIGHT, + OFFSET_COVARIANCE_OVERSAMPLING_FACTOR, + OFFSET_COVARIANCE_OVERSAMPLING_WINDOWSIZE, + MASK_OFFSET_WITH_WBD, + DO_OFFSET_FILTERING, + OFFSET_FILTER_WINDOWSIZE, + OFFSET_FILTER_SNR_THRESHOLD, + #system parameters + PICKLE_DUMPER_DIR, + PICKLE_LOAD_DIR, + RENDERER) + + facility_list = (MASTER, + SLAVE, + #RUN_UNWRAPPER, + #RUN_UNWRAP_2STAGE, + _INSAR) + + _pickleObj = "_insar" + + def __init__(self, family='', name='',cmdline=None): + import isceobj + from isceobj.Alos2Proc import Alos2Proc + 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="alos2insar.log") + self._add_methods() + self._insarProcFact = Alos2Proc + return None + + + + def Usage(self): + print("Usages: ") + print("alos2App.py ") + print("alos2App.py --steps") + print("alos2App.py --help") + print("alos2App.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"] + ) + + 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.MultiMode 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 = Alos2Proc.createPreprocessor(self) + self.runDownloadDem = Alos2Proc.createDownloadDem(self) + self.runPrepareSlc = Alos2Proc.createPrepareSlc(self) + self.runSlcOffset = Alos2Proc.createSlcOffset(self) + self.runFormInterferogram = Alos2Proc.createFormInterferogram(self) + self.runSwathOffset = Alos2Proc.createSwathOffset(self) + self.runSwathMosaic = Alos2Proc.createSwathMosaic(self) + self.runFrameOffset = Alos2Proc.createFrameOffset(self) + self.runFrameMosaic = Alos2Proc.createFrameMosaic(self) + self.runRdr2Geo = Alos2Proc.createRdr2Geo(self) + self.runGeo2Rdr = Alos2Proc.createGeo2Rdr(self) + self.runRdrDemOffset = Alos2Proc.createRdrDemOffset(self) + self.runRectRangeOffset = Alos2Proc.createRectRangeOffset(self) + self.runDiffInterferogram = Alos2Proc.createDiffInterferogram(self) + self.runLook = Alos2Proc.createLook(self) + self.runCoherence = Alos2Proc.createCoherence(self) + self.runIonSubband = Alos2Proc.createIonSubband(self) + self.runIonUwrap = Alos2Proc.createIonUwrap(self) + self.runIonFilt = Alos2Proc.createIonFilt(self) + self.runFilt = Alos2Proc.createFilt(self) + self.runUnwrapSnaphu = Alos2Proc.createUnwrapSnaphu(self) + self.runGeocode = Alos2Proc.createGeocode(self) + + #for dense offset + self.runSlcMosaic = Alos2Proc.createSlcMosaic(self) + self.runSlcMatch = Alos2Proc.createSlcMatch(self) + self.runDenseOffset = Alos2Proc.createDenseOffset(self) + self.runFiltOffset = Alos2Proc.createFiltOffset(self) + self.runGeocodeOffset = Alos2Proc.createGeocodeOffset(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""" + ) + ) + + self.step('download_dem', + func=self.runDownloadDem, + doc=( + """download DEM and water body""" + ) + ) + + ##Run prepare slc + self.step('prep_slc', func=self.runPrepareSlc, + doc=( + """prepare multi-mode SLC for InSAR processing""" + ) + ) + + ##Run slc offset + self.step('slc_offset', func=self.runSlcOffset, + doc=( + """estimate offset between slc pairs""" + ) + ) + + ##Run slc offset + self.step('form_int', func=self.runFormInterferogram, + doc=( + """form interferogram""" + ) + ) + + self.step('swath_offset', func=self.runSwathOffset, + doc=( + """estimate offset between adjacent swaths""" + ) + ) + + self.step('swath_mosaic', func=self.runSwathMosaic, + doc=( + """mosaic swaths""" + ) + ) + + self.step('frame_offset', func=self.runFrameOffset, + doc=( + """estimate offset between adjacent frames""" + ) + ) + + self.step('frame_mosaic', func=self.runFrameMosaic, + doc=( + """mosaic frames""" + ) + ) + + self.step('rdr2geo', func=self.runRdr2Geo, + doc=( + """compute lat/lon/hgt""" + ) + ) + + self.step('geo2rdr', func=self.runGeo2Rdr, + doc=( + """compute range and azimuth offsets""" + ) + ) + + self.step('rdrdem_offset', func=self.runRdrDemOffset, + doc=( + """estimate offsets between radar image and dem (simulated radar image)""" + ) + ) + + self.step('rect_rgoffset', func=self.runRectRangeOffset, + doc=( + """rectify range offset""" + ) + ) + + self.step('diff_int', func=self.runDiffInterferogram, + doc=( + """create differential interferogram""" + ) + ) + + self.step('look', func=self.runLook, + doc=( + """take looks""" + ) + ) + + self.step('coherence', func=self.runCoherence, + doc=( + """estimate coherence""" + ) + ) + + self.step('ion_subband', func=self.runIonSubband, + doc=( + """create subband interferograms for ionospheric correction""" + ) + ) + + self.step('ion_unwrap', func=self.runIonUwrap, + doc=( + """unwrap subband interferograms""" + ) + ) + + self.step('ion_filt', func=self.runIonFilt, + doc=( + """compute and filter ionospheric phase""" + ) + ) + + self.step('filt', func=self.runFilt, + doc=( + """filter interferogram""" + ) + ) + + self.step('unwrap', func=self.runUnwrapSnaphu, + doc=( + """unwrap interferogram""" + ) + ) + + self.step('geocode', func=self.runGeocode, + doc=( + """geocode final products""" + ) + ) + + #for dense offset + self.step('slc_mosaic', func=self.runSlcMosaic, + doc=( + """mosaic slcs""" + ) + ) + + self.step('slc_match', func=self.runSlcMatch, + doc=( + """match slc pair""" + ) + ) + + self.step('dense_offset', func=self.runDenseOffset, + doc=( + """estimate offset field""" + ) + ) + + self.step('filt_offset', func=self.runFiltOffset, + doc=( + """filt offset field""" + ) + ) + + self.step('geocode_offset', func=self.runGeocodeOffset, + doc=( + """geocode offset field""" + ) + ) + + + 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() + + self.runDownloadDem() + + self.runPrepareSlc() + + self.runSlcOffset() + + self.runFormInterferogram() + + self.runSwathOffset() + + self.runSwathMosaic() + + self.runFrameOffset() + + self.runFrameMosaic() + + self.runRdr2Geo() + + self.runGeo2Rdr() + + self.runRdrDemOffset() + + self.runRectRangeOffset() + + self.runDiffInterferogram() + + self.runLook() + + self.runCoherence() + + self.runIonSubband() + + self.runIonUwrap() + + self.runIonFilt() + + self.runFilt() + + self.runUnwrapSnaphu() + + self.runGeocode() + + #for dense offset + self.runSlcMosaic() + + self.runSlcMatch() + + self.runDenseOffset() + + self.runFiltOffset() + + self.runGeocodeOffset() + + + timeEnd = time.time() + logger.info("Total Time: %i seconds" %(timeEnd - timeStart)) + + self.renderProcDoc() + + return None + + + def updateParamemetersFromUser(self): + ''' + update these parameters in case users set them in the middle of processing + ''' + + if self.numberRangeLooks1 != None: + self._insar.numberRangeLooks1 = self.numberRangeLooks1 + if self.numberAzimuthLooks1 != None: + self._insar.numberAzimuthLooks1 = self.numberAzimuthLooks1 + + if self.numberRangeLooks2 != None: + self._insar.numberRangeLooks2 = self.numberRangeLooks2 + if self.numberAzimuthLooks2 != None: + self._insar.numberAzimuthLooks2 = self.numberAzimuthLooks2 + + if self.numberRangeLooksSim != None: + self._insar.numberRangeLooksSim = self.numberRangeLooksSim + if self.numberAzimuthLooksSim != None: + self._insar.numberAzimuthLooksSim = self.numberAzimuthLooksSim + + if self.numberRangeLooksIon != None: + self._insar.numberRangeLooksIon = self.numberRangeLooksIon + if self.numberAzimuthLooksIon != None: + self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon + + if self.dem != None: + self._insar.dem = self.dem + if self.demGeo != None: + self._insar.demGeo = self.demGeo + if self.wbd != None: + self._insar.wbd = self.wbd + + if self._insar.masterDate != None and self._insar.slaveDate != None and \ + self._insar.numberRangeLooks1 != None and self._insar.numberAzimuthLooks1 != None and \ + self._insar.numberRangeLooks2 != None and self._insar.numberAzimuthLooks2 != None: + self._insar.setFilename(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, + nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, + nrlks2=self._insar.numberRangeLooks2, nalks2=self._insar.numberAzimuthLooks2) + + +if __name__ == "__main__": + import sys + insar = Alos2InSAR(name="alos2App") + insar.configure() + insar.run() diff --git a/applications/alos2burstApp.py b/applications/alos2burstApp.py new file mode 100755 index 0000000..c2d1028 --- /dev/null +++ b/applications/alos2burstApp.py @@ -0,0 +1,1013 @@ +#!/usr/bin/env python3 + +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + + +import time +import os +import sys +import logging +import logging.config + +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 Alos2burstProc + +logging.config.fileConfig( + os.path.join(os.environ['ISCE_HOME'], 'defaults', 'logging', + 'logging.conf') +) + +logger = logging.getLogger('isce.insar') + + +MASTER_DIR = Application.Parameter('masterDir', + public_name='master directory', + default=None, + type=str, + mandatory=False, + doc="master data directory") + +SLAVE_DIR = Application.Parameter('slaveDir', + public_name='slave directory', + default=None, + type=str, + mandatory=False, + doc="slave data directory") + +MASTER_FRAMES = Application.Parameter('masterFrames', + public_name = 'master frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'master frames to process') + +SLAVE_FRAMES = Application.Parameter('slaveFrames', + public_name = 'slave frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'slave frames to process') + +MASTER_POLARIZATION = Application.Parameter('masterPolarization', + public_name='master polarization', + default='HH', + type=str, + mandatory=False, + doc="master polarization to process") + +SLAVE_POLARIZATION = Application.Parameter('slavePolarization', + public_name='slave polarization', + default='HH', + type=str, + mandatory=False, + doc="slave polarization to process") + +STARTING_SWATH = Application.Parameter('startingSwath', + public_name='starting swath', + default=None, + type=int, + mandatory=False, + doc="starting swath to process") + +ENDING_SWATH = Application.Parameter('endingSwath', + public_name='ending swath', + default=None, + type=int, + mandatory=False, + doc="ending swath to process") + +DEM = Application.Parameter('dem', + public_name='dem for coregistration', + default=None, + type=str, + mandatory=False, + doc='dem for coregistration file') + +DEM_GEO = Application.Parameter('demGeo', + public_name='dem for geocoding', + default=None, + type=str, + mandatory=False, + doc='dem for geocoding file') +#this water body is used to create water body in radar coordinate used in processing +#radar-coordinate water body is created three times in runRdr2Geo.py, runLook.py and runLookSd.py, respectively +#radar-coordinate water body is used in: +#(1) determining the number of offsets in slc offset estimation, and radar/dem offset estimation +#(2) masking filtered interferogram or unwrapped interferogram +#(3) masking filtered interferogram or unwrapped interferogram in sd processing +WBD = Application.Parameter('wbd', + public_name='water body', + default=None, + type=str, + mandatory=False, + doc='water body file') + +USE_VIRTUAL_FILE = Application.Parameter('useVirtualFile', + public_name = 'use virtual file', + default=True, + type=bool, + mandatory=False, + doc = 'use virtual file when possible to save space') + +USE_GPU = Application.Parameter('useGPU', + public_name='use GPU', + default=False, + type=bool, + mandatory=False, + doc='Allow App to use GPU when available') + +#always remove unsynchronized signal, since no extra computation required, and it does +#improve coherence (example: indonesia_sep_2018/d25r/180927-181011_burst_3subswaths) +BURST_SYNCHRONIZATION_THRESHOLD = Application.Parameter('burstSynchronizationThreshold', + public_name = 'burst synchronization threshold', + default = 100.0, + type=float, + mandatory = True, + doc = 'burst synchronization threshold in percentage') + +#for areas where no water body data available, turn this off, otherwise the program will use geometrical offset, which is not accuate enough +#if it still does not work, set "number of range offsets for slc matching" and "number of azimuth offsets for slc matching" +USE_WBD_FOR_NUMBER_OFFSETS = Application.Parameter('useWbdForNumberOffsets', + public_name = 'use water body to dertermine number of matching offsets', + default = True, + type = bool, + mandatory = False, + doc = 'use water body to dertermine number of matching offsets') + +NUMBER_RANGE_OFFSETS = Application.Parameter('numberRangeOffsets', + public_name = 'number of range offsets for slc matching', + default = None, + type = int, + mandatory = False, + container = list, + doc = 'number of range offsets for slc matching') + +NUMBER_AZIMUTH_OFFSETS = Application.Parameter('numberAzimuthOffsets', + public_name = 'number of azimuth offsets for slc matching', + default = None, + type = int, + mandatory = False, + container = list, + doc = 'number of azimuth offsets for slc matching') + +#these two parameters are always 1, not to be set by users +NUMBER_RANGE_LOOKS1 = Application.Parameter('numberRangeLooks1', + public_name='number of range looks 1', + default=None, + type=int, + mandatory=False, + doc="number of range looks when forming interferogram") + +NUMBER_AZIMUTH_LOOKS1 = Application.Parameter('numberAzimuthLooks1', + public_name='number of azimuth looks 1', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when forming interferogram") + +NUMBER_RANGE_LOOKS2 = Application.Parameter('numberRangeLooks2', + public_name='number of range looks 2', + default=None, + type=int, + mandatory=False, + doc="number of range looks for further multiple looking") + +NUMBER_AZIMUTH_LOOKS2 = Application.Parameter('numberAzimuthLooks2', + public_name='number of azimuth looks 2', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for further multiple looking") + +NUMBER_RANGE_LOOKS_SIM = Application.Parameter('numberRangeLooksSim', + public_name='number of range looks sim', + default=None, + type=int, + mandatory=False, + doc="number of range looks when simulating radar image") + +NUMBER_AZIMUTH_LOOKS_SIM = Application.Parameter('numberAzimuthLooksSim', + public_name='number of azimuth looks sim', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when simulating radar image") + +SWATH_OFFSET_MATCHING = Application.Parameter('swathOffsetMatching', + public_name = 'do matching when computing adjacent swath offset', + default=True, + type=bool, + mandatory=False, + doc = 'do matching when computing adjacent swath offset') + +FRAME_OFFSET_MATCHING = Application.Parameter('frameOffsetMatching', + public_name = 'do matching when computing adjacent frame offset', + default=True, + type=bool, + mandatory=False, + doc = 'do matching when computing adjacent frame offset') + +FILTER_STRENGTH = Application.Parameter('filterStrength', + public_name = 'interferogram filter strength', + default = 0.3, + type=float, + mandatory = True, + doc = 'interferogram filter strength (power spectrum filter)') + +FILTER_WINSIZE = Application.Parameter('filterWinsize', + public_name = 'interferogram filter window size', + default = 32, + type=int, + mandatory = False, + doc = 'interferogram filter window size') + +FILTER_STEPSIZE = Application.Parameter('filterStepsize', + public_name = 'interferogram filter step size', + default = 4, + type=int, + mandatory = False, + doc = 'interferogram filter step size') + +REMOVE_MAGNITUDE_BEFORE_FILTERING = Application.Parameter('removeMagnitudeBeforeFiltering', + public_name = 'remove magnitude before filtering', + default=True, + type=bool, + mandatory=False, + doc = 'remove magnitude before filtering') + +WATERBODY_MASK_STARTING_STEP = Application.Parameter('waterBodyMaskStartingStep', + public_name='water body mask starting step', + default='unwrap', + type=str, + mandatory=False, + doc='water body mask starting step: None, filt, unwrap') + +GEOCODE_LIST = Application.Parameter('geocodeList', + public_name = 'geocode file list', + default=None, + type=str, + container=list, + mandatory=False, + doc = 'geocode file list') + +GEOCODE_BOUNDING_BOX = Application.Parameter('bbox', + public_name = 'geocode bounding box', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'geocode bounding box') + +GEOCODE_INTERP_METHOD = Application.Parameter('geocodeInterpMethod', + public_name='geocode interpolation method', + default=None, + type=str, + mandatory=False, + doc='geocode interpolation method: sinc, bilinear, bicubic, nearest') +##################################################################### + +#ionospheric correction parameters +DO_ION = Application.Parameter('doIon', + public_name = 'do ionospheric phase estimation', + default = True, + type = bool, + mandatory = False, + doc = 'do ionospheric phase estimation') + +APPLY_ION = Application.Parameter('applyIon', + public_name = 'apply ionospheric phase correction', + default = True, + type = bool, + mandatory = False, + doc = 'apply ionospheric phase correction') + +NUMBER_RANGE_LOOKS_ION = Application.Parameter('numberRangeLooksIon', + public_name='number of range looks ion', + default=None, + type=int, + mandatory=False, + doc="number of range looks for ionospheric correction") + +NUMBER_AZIMUTH_LOOKS_ION = Application.Parameter('numberAzimuthLooksIon', + public_name='number of azimuth looks ion', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for ionospheric correction") + +MASKED_AREAS_ION = Application.Parameter('maskedAreasIon', + 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') + +FIT_ION = Application.Parameter('fitIon', + public_name = 'apply polynomial fit before filtering ionosphere phase', + default = True, + type = bool, + mandatory = False, + doc = 'apply polynomial fit before filtering ionosphere phase') + +FILTERING_WINSIZE_MAX_ION = Application.Parameter('filteringWinsizeMaxIon', + public_name='maximum window size for filtering ionosphere phase', + default=151, + type=int, + mandatory=False, + doc='maximum window size for filtering ionosphere phase') + +FILTERING_WINSIZE_MIN_ION = Application.Parameter('filteringWinsizeMinIon', + public_name='minimum window size for filtering ionosphere phase', + default=41, + type=int, + mandatory=False, + doc='minimum window size for filtering ionosphere phase') + +FILTER_SUBBAND_INT = Application.Parameter('filterSubbandInt', + public_name = 'filter subband interferogram', + default = False, + type = bool, + mandatory = False, + doc = 'filter subband interferogram') + +FILTER_STRENGTH_SUBBAND_INT = Application.Parameter('filterStrengthSubbandInt', + public_name = 'subband interferogram filter strength', + default = 0.3, + type=float, + mandatory = True, + doc = 'subband interferogram filter strength (power spectrum filter)') + +FILTER_WINSIZE_SUBBAND_INT = Application.Parameter('filterWinsizeSubbandInt', + public_name = 'subband interferogram filter window size', + default = 32, + type=int, + mandatory = False, + doc = 'subband interferogram filter window size') + +FILTER_STEPSIZE_SUBBAND_INT = Application.Parameter('filterStepsizeSubbandInt', + public_name = 'subband interferogram filter step size', + default = 4, + type=int, + mandatory = False, + doc = 'subband interferogram filter step size') + +REMOVE_MAGNITUDE_BEFORE_FILTERING_SUBBAND_INT = Application.Parameter('removeMagnitudeBeforeFilteringSubbandInt', + public_name = 'remove magnitude before filtering subband interferogram', + default=True, + type=bool, + mandatory=False, + doc = 'remove magnitude before filtering subband interferogram') +##################################################################### + +#spectral diversity parameters +NUMBER_RANGE_LOOKS_SD = Application.Parameter('numberRangeLooksSd', + public_name='number of range looks sd', + default=None, + type=int, + mandatory=False, + doc="number of range looks for spectral diversity") + +NUMBER_AZIMUTH_LOOKS_SD = Application.Parameter('numberAzimuthLooksSd', + public_name='number of azimuth looks sd', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for spectral diversity") + +FILTER_STRENGTH_SD = Application.Parameter('filterStrengthSd', + public_name = 'interferogram filter strength SD', + default = 0.3, + type=float, + mandatory = False, + doc = 'interferogram filter strength for spectral diversity') + +FILTER_WINSIZE_SD = Application.Parameter('filterWinsizeSd', + public_name = 'interferogram filter window size SD', + default = 32, + type=int, + mandatory = False, + doc = 'interferogram filter window size for spectral diversity') + +FILTER_STEPSIZE_SD = Application.Parameter('filterStepsizeSd', + public_name = 'interferogram filter step size SD', + default = 4, + type=int, + mandatory = False, + doc = 'interferogram filter step size for spectral diversity') + +WATERBODY_MASK_STARTING_STEP_SD = Application.Parameter('waterBodyMaskStartingStepSd', + public_name='water body mask starting step SD', + default='unwrap', + type=str, + mandatory=False, + doc='water body mask starting step: None, filt, unwrap') + +UNION_SD = Application.Parameter('unionSd', + public_name = 'union when combining sd interferograms', + default = True, + type = bool, + mandatory = False, + doc = 'union or intersection when combining sd interferograms') + +GEOCODE_LIST_SD = Application.Parameter('geocodeListSd', + public_name = 'geocode file list SD', + default=None, + type=str, + container=list, + mandatory=False, + doc = 'geocode file list for SD') + +GEOCODE_INTERP_METHOD_SD = Application.Parameter('geocodeInterpMethodSd', + public_name='geocode interpolation method SD', + default=None, + type=str, + mandatory=False, + doc='geocode interpolation method for SD: sinc, bilinear, bicubic, nearest') +##################################################################### + +#system parameters +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.") +##################################################################### + +#Facility declarations +MASTER = Application.Facility('master', + public_name='master', + module='isceobj.Sensor.MultiMode', + factory='createSensor', + args=('ALOS2', 'master'), + mandatory=True, + doc="master component") + +SLAVE = Application.Facility('slave', + public_name='slave', + module='isceobj.Sensor.MultiMode', + factory='createSensor', + args=('ALOS2','slave'), + mandatory=True, + doc="slave component") + +# RUN_UNWRAPPER = Application.Facility('runUnwrapper', +# public_name='Run unwrapper', +# module='isceobj.Alos2burstProc', +# 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.Alos2burstProc', +# factory='createUnwrap2Stage', +# args=(SELF(), DO_UNWRAP_2STAGE, UNWRAPPER_NAME), +# mandatory=False, +# doc="Unwrapping module") + +_INSAR = Application.Facility('_insar', + public_name='alos2burstproc', + module='isceobj.Alos2burstProc', + factory='createAlos2burstProc', + args = ('alos2burstAppContext',isceobj.createCatalog('alos2burstProc')), + mandatory=False, + doc="Alos2burstProc object") + + +## Common interface for all insar applications. +class Alos2burstInSAR(Application): + family = 'alos2burstinsar' + parameter_list = (MASTER_DIR, + SLAVE_DIR, + MASTER_FRAMES, + SLAVE_FRAMES, + MASTER_POLARIZATION, + SLAVE_POLARIZATION, + STARTING_SWATH, + ENDING_SWATH, + DEM, + DEM_GEO, + WBD, + USE_VIRTUAL_FILE, + USE_GPU, + BURST_SYNCHRONIZATION_THRESHOLD, + USE_WBD_FOR_NUMBER_OFFSETS, + NUMBER_RANGE_OFFSETS, + NUMBER_AZIMUTH_OFFSETS, + NUMBER_RANGE_LOOKS1, + NUMBER_AZIMUTH_LOOKS1, + NUMBER_RANGE_LOOKS2, + NUMBER_AZIMUTH_LOOKS2, + NUMBER_RANGE_LOOKS_SIM, + NUMBER_AZIMUTH_LOOKS_SIM, + SWATH_OFFSET_MATCHING, + FRAME_OFFSET_MATCHING, + FILTER_STRENGTH, + FILTER_WINSIZE, + FILTER_STEPSIZE, + REMOVE_MAGNITUDE_BEFORE_FILTERING, + WATERBODY_MASK_STARTING_STEP, + GEOCODE_LIST, + GEOCODE_BOUNDING_BOX, + GEOCODE_INTERP_METHOD, + #ionospheric correction parameters + DO_ION, + APPLY_ION, + NUMBER_RANGE_LOOKS_ION, + NUMBER_AZIMUTH_LOOKS_ION, + MASKED_AREAS_ION, + FIT_ION, + FILTERING_WINSIZE_MAX_ION, + FILTERING_WINSIZE_MIN_ION, + FILTER_SUBBAND_INT, + FILTER_STRENGTH_SUBBAND_INT, + FILTER_WINSIZE_SUBBAND_INT, + FILTER_STEPSIZE_SUBBAND_INT, + REMOVE_MAGNITUDE_BEFORE_FILTERING_SUBBAND_INT, + #spectral diversity parameters + NUMBER_RANGE_LOOKS_SD, + NUMBER_AZIMUTH_LOOKS_SD, + FILTER_STRENGTH_SD, + FILTER_WINSIZE_SD, + FILTER_STEPSIZE_SD, + WATERBODY_MASK_STARTING_STEP_SD, + UNION_SD, + GEOCODE_LIST_SD, + GEOCODE_INTERP_METHOD_SD, + #system parameters + PICKLE_DUMPER_DIR, + PICKLE_LOAD_DIR, + RENDERER) + + facility_list = (MASTER, + SLAVE, + #RUN_UNWRAPPER, + #RUN_UNWRAP_2STAGE, + _INSAR) + + _pickleObj = "_insar" + + def __init__(self, family='', name='',cmdline=None): + import isceobj + from isceobj.Alos2burstProc import Alos2burstProc + 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="alos2burstinsar.log") + self._add_methods() + self._insarProcFact = Alos2burstProc + return None + + + + def Usage(self): + print("Usages: ") + print("alos2burstApp.py ") + print("alos2burstApp.py --steps") + print("alos2burstApp.py --help") + print("alos2burstApp.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"] + ) + + 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.MultiMode 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 = Alos2burstProc.createPreprocessor(self) + self.runExtractBurst = Alos2burstProc.createExtractBurst(self) + self.runDownloadDem = Alos2burstProc.createDownloadDem(self) + self.runCoregGeom = Alos2burstProc.createCoregGeom(self) + self.runCoregCc = Alos2burstProc.createCoregCc(self) + self.runCoregSd = Alos2burstProc.createCoregSd(self) + self.runSwathOffset = Alos2burstProc.createSwathOffset(self) + self.runSwathMosaic = Alos2burstProc.createSwathMosaic(self) + self.runFrameOffset = Alos2burstProc.createFrameOffset(self) + self.runFrameMosaic = Alos2burstProc.createFrameMosaic(self) + self.runRdr2Geo = Alos2burstProc.createRdr2Geo(self) + self.runGeo2Rdr = Alos2burstProc.createGeo2Rdr(self) + self.runRdrDemOffset = Alos2burstProc.createRdrDemOffset(self) + self.runRectRangeOffset = Alos2burstProc.createRectRangeOffset(self) + self.runDiffInterferogram = Alos2burstProc.createDiffInterferogram(self) + self.runLook = Alos2burstProc.createLook(self) + self.runCoherence = Alos2burstProc.createCoherence(self) + self.runIonSubband = Alos2burstProc.createIonSubband(self) + self.runIonUwrap = Alos2burstProc.createIonUwrap(self) + self.runIonFilt = Alos2burstProc.createIonFilt(self) + self.runFilt = Alos2burstProc.createFilt(self) + self.runUnwrapSnaphu = Alos2burstProc.createUnwrapSnaphu(self) + self.runGeocode = Alos2burstProc.createGeocode(self) + + #spectral diversity + self.runLookSd = Alos2burstProc.createLookSd(self) + self.runFiltSd = Alos2burstProc.createFiltSd(self) + self.runUnwrapSnaphuSd = Alos2burstProc.createUnwrapSnaphuSd(self) + self.runGeocodeSd = Alos2burstProc.createGeocodeSd(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 acquisitions + self.step('preprocess', func=self.runPreprocessor, + doc=( + """Preprocess the master and slave sensor data to raw images""" + ) + ) + + self.step('extract_burst', func=self.runExtractBurst, + doc=( + """extract bursts from full aperture images""" + ) + ) + + self.step('download_dem', func=self.runDownloadDem, + doc=( + """download DEM and water body""" + ) + ) + + self.step('coreg_geom', func=self.runCoregGeom, + doc=( + """coregistrater bursts based on geometric offsets""" + ) + ) + + self.step('coreg_cc', func=self.runCoregCc, + doc=( + """coregistrater bursts based on cross-correlation offsets""" + ) + ) + + self.step('coreg_sd', func=self.runCoregSd, + doc=( + """coregistrater bursts based on spectral diversity offsets""" + ) + ) + + self.step('swath_offset', func=self.runSwathOffset, + doc=( + """estimate offset between adjacent swaths""" + ) + ) + + self.step('swath_mosaic', func=self.runSwathMosaic, + doc=( + """mosaic swaths""" + ) + ) + + self.step('frame_offset', func=self.runFrameOffset, + doc=( + """estimate offset between adjacent frames""" + ) + ) + + self.step('frame_mosaic', func=self.runFrameMosaic, + doc=( + """mosaic frames""" + ) + ) + + self.step('rdr2geo', func=self.runRdr2Geo, + doc=( + """compute lat/lon/hgt""" + ) + ) + + self.step('geo2rdr', func=self.runGeo2Rdr, + doc=( + """compute range and azimuth offsets""" + ) + ) + + self.step('rdrdem_offset', func=self.runRdrDemOffset, + doc=( + """estimate offsets between radar image and dem (simulated radar image)""" + ) + ) + + self.step('rect_rgoffset', func=self.runRectRangeOffset, + doc=( + """rectify range offset""" + ) + ) + + self.step('diff_int', func=self.runDiffInterferogram, + doc=( + """create differential interferogram""" + ) + ) + + self.step('look', func=self.runLook, + doc=( + """take looks""" + ) + ) + + self.step('coherence', func=self.runCoherence, + doc=( + """estimate coherence""" + ) + ) + + self.step('ion_subband', func=self.runIonSubband, + doc=( + """create subband interferograms for ionospheric correction""" + ) + ) + + self.step('ion_unwrap', func=self.runIonUwrap, + doc=( + """unwrap subband interferograms""" + ) + ) + + self.step('ion_filt', func=self.runIonFilt, + doc=( + """compute and filter ionospheric phase""" + ) + ) + + self.step('filt', func=self.runFilt, + doc=( + """filter interferogram""" + ) + ) + + self.step('unwrap', func=self.runUnwrapSnaphu, + doc=( + """unwrap interferogram""" + ) + ) + + self.step('geocode', func=self.runGeocode, + doc=( + """geocode final products""" + ) + ) + + self.step('sd_look', func=self.runLookSd, + doc=( + """take looks for sd""" + ) + ) + + self.step('sd_filt', func=self.runFiltSd, + doc=( + """filter sd interferograms""" + ) + ) + + self.step('sd_unwrap', func=self.runUnwrapSnaphuSd, + doc=( + """unwrap sd interferograms""" + ) + ) + + self.step('sd_geocode', func=self.runGeocodeSd, + doc=( + """geocode final sd products""" + ) + ) + + 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() + + self.runExtractBurst() + + self.runDownloadDem() + + self.runCoregGeom() + + self.runCoregCc() + + self.runCoregSd() + + self.runSwathOffset() + + self.runSwathMosaic() + + self.runFrameOffset() + + self.runFrameMosaic() + + self.runRdr2Geo() + + self.runGeo2Rdr() + + self.runRdrDemOffset() + + self.runRectRangeOffset() + + self.runDiffInterferogram() + + self.runLook() + + self.runCoherence() + + self.runIonSubband() + + self.runIonUwrap() + + self.runIonFilt() + + self.runFilt() + + self.runUnwrapSnaphu() + + self.runGeocode() + + self.runLookSd() + + self.runFiltSd() + + self.runUnwrapSnaphuSd() + + self.runGeocodeSd() + + timeEnd = time.time() + logger.info("Total Time: %i seconds" %(timeEnd - timeStart)) + + self.renderProcDoc() + + return None + + + def updateParamemetersFromUser(self): + ''' + update these parameters in case users set them in the middle of processing + ''' + + if self.numberRangeLooks1 != None: + #force number of looks 1 to 1 + self.numberRangeLooks1 = 1 + self._insar.numberRangeLooks1 = self.numberRangeLooks1 + if self.numberAzimuthLooks1 != None: + self.numberAzimuthLooks1 = 1 + self._insar.numberAzimuthLooks1 = self.numberAzimuthLooks1 + + if self.numberRangeLooks2 != None: + self._insar.numberRangeLooks2 = self.numberRangeLooks2 + if self.numberAzimuthLooks2 != None: + self._insar.numberAzimuthLooks2 = self.numberAzimuthLooks2 + + if self.numberRangeLooksSim != None: + self._insar.numberRangeLooksSim = self.numberRangeLooksSim + if self.numberAzimuthLooksSim != None: + self._insar.numberAzimuthLooksSim = self.numberAzimuthLooksSim + + if self.numberRangeLooksIon != None: + self._insar.numberRangeLooksIon = self.numberRangeLooksIon + if self.numberAzimuthLooksIon != None: + self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon + + if self.numberRangeLooksSd != None: + self._insar.numberRangeLooksSd = self.numberRangeLooksSd + if self.numberAzimuthLooksSd != None: + self._insar.numberAzimuthLooksSd = self.numberAzimuthLooksSd + + if self.dem != None: + self._insar.dem = self.dem + if self.demGeo != None: + self._insar.demGeo = self.demGeo + if self.wbd != None: + self._insar.wbd = self.wbd + + if self._insar.masterDate != None and self._insar.slaveDate != None and \ + self._insar.numberRangeLooks1 != None and self._insar.numberAzimuthLooks1 != None and \ + self._insar.numberRangeLooks2 != None and self._insar.numberAzimuthLooks2 != None: + self._insar.setFilename(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, + nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, + nrlks2=self._insar.numberRangeLooks2, nalks2=self._insar.numberAzimuthLooks2) + + if self._insar.masterDate != None and self._insar.slaveDate != None and \ + self._insar.numberRangeLooks1 != None and self._insar.numberAzimuthLooks1 != None and \ + self._insar.numberRangeLooksSd != None and self._insar.numberAzimuthLooksSd != None: + self._insar.setFilenameSd(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, + nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, + nrlks_sd=self._insar.numberRangeLooksSd, nalks_sd=self._insar.numberAzimuthLooksSd, nsd=3) + + +if __name__ == "__main__": + import sys + insar = Alos2burstInSAR(name="alos2burstApp") + insar.configure() + insar.run() diff --git a/applications/wbd_with_correction.py b/applications/wbd_with_correction.py new file mode 100755 index 0000000..5ceccf0 --- /dev/null +++ b/applications/wbd_with_correction.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +# +# Author: Cunren Liang +# Copyright 2020 +# + + +import sys +import isce +from isceobj.Alos2Proc.runDownloadDem import download_wbd + + +if __name__=="__main__": + + if len(sys.argv) < 5: + print("usage: wbd_with_correction.py s n w e") + print("where s, n, w, e are latitude, longitude bounds in degrees") + sys.exit(0) + + snwe = list(map(float,sys.argv[1:])) + + download_wbd(snwe[0], snwe[1], snwe[2], snwe[3]) diff --git a/components/isceobj/Alos2Proc/Alos2Proc.py b/components/isceobj/Alos2Proc/Alos2Proc.py new file mode 100644 index 0000000..6552bb8 --- /dev/null +++ b/components/isceobj/Alos2Proc/Alos2Proc.py @@ -0,0 +1,949 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +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_DATE = Component.Parameter('masterDate', + public_name='master date', + default=None, + type=str, + mandatory=True, + doc='master acquistion date') + +SLAVE_DATE = Component.Parameter('slaveDate', + public_name='slave date', + default=None, + type=str, + mandatory=True, + doc='slave acquistion date') + +MODE_COMBINATION = Component.Parameter('modeCombination', + public_name='mode combination', + default=None, + type=int, + mandatory=True, + doc='mode combination') + +MASTER_FRAMES = Component.Parameter('masterFrames', + public_name = 'master frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'master frames to process') + +SLAVE_FRAMES = Component.Parameter('slaveFrames', + public_name = 'slave frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'slave frames to process') + +STARTING_SWATH = Component.Parameter('startingSwath', + public_name='starting swath', + default=1, + type=int, + mandatory=False, + doc="starting swath to process") + +ENDING_SWATH = Component.Parameter('endingSwath', + public_name='ending swath', + default=5, + type=int, + mandatory=False, + doc="ending swath to process") + +BURST_UNSYNCHRONIZED_TIME = Component.Parameter('burstUnsynchronizedTime', + public_name = 'burst unsynchronized time', + default = None, + type = float, + mandatory = False, + doc = 'burst unsynchronized time in second') + +BURST_SYNCHRONIZATION = Component.Parameter('burstSynchronization', + public_name = 'burst synchronization', + default = None, + type = float, + mandatory = False, + doc = 'average burst synchronization of all swaths and frames in percentage') + +SWATH_RANGE_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('swathRangeOffsetGeometricalMaster', + public_name = 'swath range offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from geometry master') + +SWATH_AZIMUTH_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('swathAzimuthOffsetGeometricalMaster', + public_name = 'swath azimuth offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from geometry master') + +SWATH_RANGE_OFFSET_MATCHING_MASTER = Component.Parameter('swathRangeOffsetMatchingMaster', + public_name = 'swath range offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from matching master') + +SWATH_AZIMUTH_OFFSET_MATCHING_MASTER = Component.Parameter('swathAzimuthOffsetMatchingMaster', + public_name = 'swath azimuth offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from matching master') + +SWATH_RANGE_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('swathRangeOffsetGeometricalSlave', + public_name = 'swath range offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from geometry slave') + +SWATH_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('swathAzimuthOffsetGeometricalSlave', + public_name = 'swath azimuth offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from geometry slave') + +SWATH_RANGE_OFFSET_MATCHING_SLAVE = Component.Parameter('swathRangeOffsetMatchingSlave', + public_name = 'swath range offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from matching slave') + +SWATH_AZIMUTH_OFFSET_MATCHING_SLAVE = Component.Parameter('swathAzimuthOffsetMatchingSlave', + public_name = 'swath azimuth offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from matching slave') + + + +FRAME_RANGE_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('frameRangeOffsetGeometricalMaster', + public_name = 'frame range offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from geometry master') + +FRAME_AZIMUTH_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('frameAzimuthOffsetGeometricalMaster', + public_name = 'frame azimuth offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from geometry master') + +FRAME_RANGE_OFFSET_MATCHING_MASTER = Component.Parameter('frameRangeOffsetMatchingMaster', + public_name = 'frame range offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from matching master') + +FRAME_AZIMUTH_OFFSET_MATCHING_MASTER = Component.Parameter('frameAzimuthOffsetMatchingMaster', + public_name = 'frame azimuth offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from matching master') + +FRAME_RANGE_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('frameRangeOffsetGeometricalSlave', + public_name = 'frame range offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from geometry slave') + +FRAME_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('frameAzimuthOffsetGeometricalSlave', + public_name = 'frame azimuth offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from geometry slave') + +FRAME_RANGE_OFFSET_MATCHING_SLAVE = Component.Parameter('frameRangeOffsetMatchingSlave', + public_name = 'frame range offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from matching slave') + +FRAME_AZIMUTH_OFFSET_MATCHING_SLAVE = Component.Parameter('frameAzimuthOffsetMatchingSlave', + public_name = 'frame azimuth offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from matching slave') + +NUMBER_RANGE_LOOKS1 = Component.Parameter('numberRangeLooks1', + public_name='number of range looks 1', + default=None, + type=int, + mandatory=False, + doc="number of range looks when forming interferogram") + +NUMBER_AZIMUTH_LOOKS1 = Component.Parameter('numberAzimuthLooks1', + public_name='number of azimuth looks 1', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when forming interferogram") + +NUMBER_RANGE_LOOKS2 = Component.Parameter('numberRangeLooks2', + public_name='number of range looks 2', + default=None, + type=int, + mandatory=False, + doc="number of range looks for further multiple looking") + +NUMBER_AZIMUTH_LOOKS2 = Component.Parameter('numberAzimuthLooks2', + public_name='number of azimuth looks 2', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for further multiple looking") + +NUMBER_RANGE_LOOKS_SIM = Component.Parameter('numberRangeLooksSim', + public_name='number of range looks sim', + default=None, + type=int, + mandatory=False, + doc="number of range looks when simulating radar image") + +NUMBER_AZIMUTH_LOOKS_SIM = Component.Parameter('numberAzimuthLooksSim', + public_name='number of azimuth looks sim', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when simulating radar image") + +NUMBER_RANGE_LOOKS_ION = Component.Parameter('numberRangeLooksIon', + public_name='number of range looks ion', + default=None, + type=int, + mandatory=False, + doc="number of range looks for ionospheric correction") + +NUMBER_AZIMUTH_LOOKS_ION = Component.Parameter('numberAzimuthLooksIon', + public_name='number of azimuth looks ion', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for ionospheric correction") + +SUBBAND_RADAR_WAVLENGTH = Component.Parameter('subbandRadarWavelength', + public_name='lower and upper radar wavelength for ionosphere correction', + default=None, + type=float, + mandatory=False, + container = list, + doc="lower and upper radar wavelength for ionosphere correction") + +RADAR_DEM_AFFINE_TRANSFORM = Component.Parameter('radarDemAffineTransform', + public_name = 'radar dem affine transform parameters', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'radar dem affine transform parameters') + + +MASTER_SLC = Component.Parameter('masterSlc', + public_name='master slc', + default=None, + type=str, + mandatory=False, + doc='master slc file') + +SLAVE_SLC = Component.Parameter('slaveSlc', + public_name='slave slc', + default=None, + type=str, + mandatory=False, + doc='slave slc file') + +MASTER_SWATH_OFFSET = Component.Parameter('masterSwathOffset', + public_name='master swath offset', + default=None, + type=str, + mandatory=False, + doc='master swath offset file') + +SLAVE_SWATH_OFFSET = Component.Parameter('slaveSwathOffset', + public_name='slave swath offset', + default=None, + type=str, + mandatory=False, + doc='slave swath offset file') + +MASTER_FRAME_OFFSET = Component.Parameter('masterFrameOffset', + public_name='master frame offset', + default=None, + type=str, + mandatory=False, + doc='master frame offset file') + +SLAVE_FRAME_OFFSET = Component.Parameter('slaveFrameOffset', + public_name='slave frame offset', + default=None, + type=str, + mandatory=False, + doc='slave frame offset file') + +MASTER_FRAME_PARAMETER = Component.Parameter('masterFrameParameter', + public_name='master frame parameter', + default=None, + type=str, + mandatory=False, + doc='master frame parameter file') + +SLAVE_FRAME_PARAMETER = Component.Parameter('slaveFrameParameter', + public_name='slave frame parameter', + default=None, + type=str, + mandatory=False, + doc='slave frame parameter file') + +MASTER_TRACK_PARAMETER = Component.Parameter('masterTrackParameter', + public_name='master track parameter', + default=None, + type=str, + mandatory=False, + doc='master track parameter file') + +SLAVE_TRACK_PARAMETER = Component.Parameter('slaveTrackParameter', + public_name='slave track parameter', + default=None, + type=str, + mandatory=False, + doc='slave track parameter file') + +DEM = Component.Parameter('dem', + public_name='dem for coregistration', + default=None, + type=str, + mandatory=False, + doc='dem for coregistration file') + +DEM_GEO = Component.Parameter('demGeo', + public_name='dem for geocoding', + default=None, + type=str, + mandatory=False, + doc='dem for geocoding file') + +WBD = Component.Parameter('wbd', + public_name='water body', + default=None, + type=str, + mandatory=False, + doc='water body file') + +WBD_OUT = Component.Parameter('wbdOut', + public_name='output water body', + default=None, + type=str, + mandatory=False, + doc='output water body file') + +INTERFEROGRAM = Component.Parameter('interferogram', + public_name='interferogram', + default=None, + type=str, + mandatory=False, + doc='interferogram file') + +AMPLITUDE = Component.Parameter('amplitude', + public_name='amplitude', + default=None, + type=str, + mandatory=False, + doc='amplitude file') + +DIFFERENTIAL_INTERFEROGRAM = Component.Parameter('differentialInterferogram', + public_name='differential interferogram', + default=None, + type=str, + mandatory=False, + doc='differential interferogram file') + +MULTILOOK_DIFFERENTIAL_INTERFEROGRAM = Component.Parameter('multilookDifferentialInterferogram', + public_name='multilook differential interferogram', + default=None, + type=str, + mandatory=False, + doc='multilook differential interferogram file') + +MULTILOOK_DIFFERENTIAL_INTERFEROGRAM_ORIGINAL = Component.Parameter('multilookDifferentialInterferogramOriginal', + public_name='original multilook differential interferogram', + default=None, + type=str, + mandatory=False, + doc='original multilook differential interferogram file') + +MULTILOOK_AMPLITUDE = Component.Parameter('multilookAmplitude', + public_name='multilook amplitude', + default=None, + type=str, + mandatory=False, + doc='multilook amplitude file') + +MULTILOOK_COHERENCE = Component.Parameter('multilookCoherence', + public_name='multilook coherence', + default=None, + type=str, + mandatory=False, + doc='multilook coherence file') + +MULTILOOK_PHSIG = Component.Parameter('multilookPhsig', + public_name='multilook phase sigma', + default=None, + type=str, + mandatory=False, + doc='multilook phase sigma file') + +FILTERED_INTERFEROGRAM = Component.Parameter('filteredInterferogram', + public_name='filtered interferogram', + default=None, + type=str, + mandatory=False, + doc='filtered interferogram file') + +UNWRAPPED_INTERFEROGRAM = Component.Parameter('unwrappedInterferogram', + public_name='unwrapped interferogram', + default=None, + type=str, + mandatory=False, + doc='unwrapped interferogram file') + +UNWRAPPED_MASKED_INTERFEROGRAM = Component.Parameter('unwrappedMaskedInterferogram', + public_name='unwrapped masked interferogram', + default=None, + type=str, + mandatory=False, + doc='unwrapped masked interferogram file') + +LATITUDE = Component.Parameter('latitude', + public_name='latitude', + default=None, + type=str, + mandatory=False, + doc='latitude file') + +LONGITUDE = Component.Parameter('longitude', + public_name='longitude', + default=None, + type=str, + mandatory=False, + doc='longitude file') + +HEIGHT = Component.Parameter('height', + public_name='height', + default=None, + type=str, + mandatory=False, + doc='height file') + +LOS = Component.Parameter('los', + public_name='los', + default=None, + type=str, + mandatory=False, + doc='los file') + +SIM = Component.Parameter('sim', + public_name='sim', + default=None, + type=str, + mandatory=False, + doc='sim file') + +MSK = Component.Parameter('msk', + public_name='msk', + default=None, + type=str, + mandatory=False, + doc='msk file') + +RANGE_OFFSET = Component.Parameter('rangeOffset', + public_name='range offset', + default=None, + type=str, + mandatory=False, + doc='range offset file') + +AZIMUTH_OFFSET = Component.Parameter('azimuthOffset', + public_name='azimuth offset', + default=None, + type=str, + mandatory=False, + doc='azimuth offset file') + + +MULTILOOK_LOS = Component.Parameter('multilookLos', + public_name='multilook los', + default=None, + type=str, + mandatory=False, + doc='multilook los file') + +MULTILOOK_MSK = Component.Parameter('multilookMsk', + public_name='multilook msk', + default=None, + type=str, + mandatory=False, + doc='multilook msk file') + +MULTILOOK_WBD_OUT = Component.Parameter('multilookWbdOut', + public_name='multilook wbdOut', + default=None, + type=str, + mandatory=False, + doc='multilook output water body file') + +MULTILOOK_LATITUDE = Component.Parameter('multilookLatitude', + public_name='multilook latitude', + default=None, + type=str, + mandatory=False, + doc='multilook latitude file') + +MULTILOOK_LONGITUDE = Component.Parameter('multilookLongitude', + public_name='multilook longitude', + default=None, + type=str, + mandatory=False, + doc='multilook longitude file') + +MULTILOOK_HEIGHT = Component.Parameter('multilookHeight', + public_name='multilook height', + default=None, + type=str, + mandatory=False, + doc='multilook height file') + +MULTILOOK_ION = Component.Parameter('multilookIon', + public_name='multilook ionospheric phase', + default=None, + type=str, + mandatory=False, + doc='multilook ionospheric phase file') + +RECT_RANGE_OFFSET = Component.Parameter('rectRangeOffset', + public_name='rectified range offset', + default=None, + type=str, + mandatory=False, + doc='rectified range offset file') + +GEO_INTERFEROGRAM = Component.Parameter('geoInterferogram', + public_name='geocoded interferogram', + default=None, + type=str, + mandatory=False, + doc='geocoded interferogram file') + +GEO_MASKED_INTERFEROGRAM = Component.Parameter('geoMaskedInterferogram', + public_name='geocoded masked interferogram', + default=None, + type=str, + mandatory=False, + doc='geocoded masked interferogram file') + +GEO_COHERENCE = Component.Parameter('geoCoherence', + public_name='geocoded coherence', + default=None, + type=str, + mandatory=False, + doc='geocoded coherence file') + +GEO_LOS = Component.Parameter('geoLos', + public_name='geocoded los', + default=None, + type=str, + mandatory=False, + doc='geocoded los file') + +GEO_ION = Component.Parameter('geoIon', + public_name='geocoded ionospheric phase', + default=None, + type=str, + mandatory=False, + doc='geocoded ionospheric phase file') +################################################################### + +#for dense offset +OFFSET_IMAGE_TOPOFFSET = Component.Parameter('offsetImageTopoffset', + public_name='offset image top offset', + default=None, + type=int, + mandatory=False, + doc="offset image top offset in samples") + +OFFSET_IMAGE_LEFTOFFSET = Component.Parameter('offsetImageLeftoffset', + public_name='offset image left offset', + default=None, + type=int, + mandatory=False, + doc="offset image left offset in samples") + +SLAVE_SLC_COREGISTERED = Component.Parameter('slaveSlcCoregistered', + public_name='coregistered slave slc', + default=None, + type=str, + mandatory=False, + doc='coregistered slave slc file') + +DENSE_OFFSET = Component.Parameter('denseOffset', + public_name='dense offset', + default=None, + type=str, + mandatory=False, + doc='dense offset file') + +DENSE_OFFSET_SNR = Component.Parameter('denseOffsetSnr', + public_name='dense offset snr', + default=None, + type=str, + mandatory=False, + doc='dense offset snr file') + +DENSE_OFFSET_COV = Component.Parameter('denseOffsetCov', + public_name='dense offset covariance', + default=None, + type=str, + mandatory=False, + doc='dense offset covariance file') + +DENSE_OFFSET_FILT = Component.Parameter('denseOffsetFilt', + public_name='filtered dense offset', + default=None, + type=str, + mandatory=False, + doc='filtered dense offset file') + +GEO_DENSE_OFFSET = Component.Parameter('GeoDenseOffset', + public_name='geocoded dense offset', + default=None, + type=str, + mandatory=False, + doc='geocoded dense offset file') + +GEO_DENSE_OFFSET_SNR = Component.Parameter('GeoDenseOffsetSnr', + public_name='geocoded dense offset snr', + default=None, + type=str, + mandatory=False, + doc='geocoded dense offset snr file') + +GEO_DENSE_OFFSET_FILT = Component.Parameter('GeoDenseOffsetFilt', + public_name='geocoded dense offset with filtering', + default=None, + type=str, + mandatory=False, + doc='geocoded dense offset with filtering') +################################################################### + +class Alos2Proc(Component): + """ + This class holds the properties, along with methods (setters and getters) + to modify and return their values. + """ + + parameter_list = (MASTER_DATE, + SLAVE_DATE, + MODE_COMBINATION, + MASTER_FRAMES, + SLAVE_FRAMES, + STARTING_SWATH, + ENDING_SWATH, + BURST_UNSYNCHRONIZED_TIME, + BURST_SYNCHRONIZATION, + SWATH_RANGE_OFFSET_GEOMETRICAL_MASTER, + SWATH_AZIMUTH_OFFSET_GEOMETRICAL_MASTER, + SWATH_RANGE_OFFSET_MATCHING_MASTER, + SWATH_AZIMUTH_OFFSET_MATCHING_MASTER, + SWATH_RANGE_OFFSET_GEOMETRICAL_SLAVE, + SWATH_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE, + SWATH_RANGE_OFFSET_MATCHING_SLAVE, + SWATH_AZIMUTH_OFFSET_MATCHING_SLAVE, + FRAME_RANGE_OFFSET_GEOMETRICAL_MASTER, + FRAME_AZIMUTH_OFFSET_GEOMETRICAL_MASTER, + FRAME_RANGE_OFFSET_MATCHING_MASTER, + FRAME_AZIMUTH_OFFSET_MATCHING_MASTER, + FRAME_RANGE_OFFSET_GEOMETRICAL_SLAVE, + FRAME_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE, + FRAME_RANGE_OFFSET_MATCHING_SLAVE, + FRAME_AZIMUTH_OFFSET_MATCHING_SLAVE, + NUMBER_RANGE_LOOKS1, + NUMBER_AZIMUTH_LOOKS1, + NUMBER_RANGE_LOOKS2, + NUMBER_AZIMUTH_LOOKS2, + NUMBER_RANGE_LOOKS_SIM, + NUMBER_AZIMUTH_LOOKS_SIM, + NUMBER_RANGE_LOOKS_ION, + NUMBER_AZIMUTH_LOOKS_ION, + SUBBAND_RADAR_WAVLENGTH, + RADAR_DEM_AFFINE_TRANSFORM, + MASTER_SLC, + SLAVE_SLC, + MASTER_SWATH_OFFSET, + SLAVE_SWATH_OFFSET, + MASTER_FRAME_OFFSET, + SLAVE_FRAME_OFFSET, + MASTER_FRAME_PARAMETER, + SLAVE_FRAME_PARAMETER, + MASTER_TRACK_PARAMETER, + SLAVE_TRACK_PARAMETER, + DEM, + DEM_GEO, + WBD, + WBD_OUT, + INTERFEROGRAM, + AMPLITUDE, + DIFFERENTIAL_INTERFEROGRAM, + MULTILOOK_DIFFERENTIAL_INTERFEROGRAM, + MULTILOOK_DIFFERENTIAL_INTERFEROGRAM_ORIGINAL, + MULTILOOK_AMPLITUDE, + MULTILOOK_COHERENCE, + MULTILOOK_PHSIG, + FILTERED_INTERFEROGRAM, + UNWRAPPED_INTERFEROGRAM, + UNWRAPPED_MASKED_INTERFEROGRAM, + LATITUDE, + LONGITUDE, + HEIGHT, + LOS, + SIM, + MSK, + RANGE_OFFSET, + AZIMUTH_OFFSET, + MULTILOOK_LOS, + MULTILOOK_MSK, + MULTILOOK_WBD_OUT, + MULTILOOK_LATITUDE, + MULTILOOK_LONGITUDE, + MULTILOOK_HEIGHT, + MULTILOOK_ION, + RECT_RANGE_OFFSET, + GEO_INTERFEROGRAM, + GEO_MASKED_INTERFEROGRAM, + GEO_COHERENCE, + GEO_LOS, + GEO_ION, + OFFSET_IMAGE_TOPOFFSET, + OFFSET_IMAGE_LEFTOFFSET, + SLAVE_SLC_COREGISTERED, + DENSE_OFFSET, + DENSE_OFFSET_SNR, + DENSE_OFFSET_COV, + DENSE_OFFSET_FILT, + GEO_DENSE_OFFSET, + GEO_DENSE_OFFSET_SNR, + GEO_DENSE_OFFSET_FILT) + + facility_list = () + + + family='alos2context' + + def __init__(self, name='', procDoc=None): + #self.updatePrivate() + + super().__init__(family=self.__class__.family, name=name) + self.procDoc = procDoc + return None + + def setFilename(self, masterDate, slaveDate, nrlks1, nalks1, nrlks2, nalks2): + + # if masterDate == None: + # masterDate = self.masterDate + # if slaveDate == None: + # slaveDate = self.slaveDate + # if nrlks1 == None: + # nrlks1 = self.numberRangeLooks1 + # if nalks1 == None: + # nalks1 = self.numberAzimuthLooks1 + # if nrlks2 == None: + # nrlks2 = self.numberRangeLooks2 + # if nalks2 == None: + # nalks2 = self.numberAzimuthLooks2 + + ms = masterDate + '-' + slaveDate + ml1 = '_{}rlks_{}alks'.format(nrlks1, nalks1) + ml2 = '_{}rlks_{}alks'.format(nrlks1*nrlks2, nalks1*nalks2) + + self.masterSlc = masterDate + '.slc' + self.slaveSlc = slaveDate + '.slc' + self.masterSwathOffset = 'swath_offset_' + masterDate + '.txt' + self.slaveSwathOffset = 'swath_offset_' + slaveDate + '.txt' + self.masterFrameOffset = 'frame_offset_' + masterDate + '.txt' + self.slaveFrameOffset = 'frame_offset_' + slaveDate + '.txt' + self.masterFrameParameter = masterDate + '.frame.xml' + self.slaveFrameParameter = slaveDate + '.frame.xml' + self.masterTrackParameter = masterDate + '.track.xml' + self.slaveTrackParameter = slaveDate + '.track.xml' + #self.dem = + #self.demGeo = + #self.wbd = + self.interferogram = ms + ml1 + '.int' + self.amplitude = ms + ml1 + '.amp' + self.differentialInterferogram = 'diff_' + ms + ml1 + '.int' + self.multilookDifferentialInterferogram = 'diff_' + ms + ml2 + '.int' + self.multilookDifferentialInterferogramOriginal = 'diff_' + ms + ml2 + '_ori.int' + self.multilookAmplitude = ms + ml2 + '.amp' + self.multilookCoherence = ms + ml2 + '.cor' + self.multilookPhsig = ms + ml2 + '.phsig' + self.filteredInterferogram = 'filt_' + ms + ml2 + '.int' + self.unwrappedInterferogram = 'filt_' + ms + ml2 + '.unw' + self.unwrappedMaskedInterferogram = 'filt_' + ms + ml2 + '_msk.unw' + self.latitude = ms + ml1 + '.lat' + self.longitude = ms + ml1 + '.lon' + self.height = ms + ml1 + '.hgt' + self.los = ms + ml1 + '.los' + self.sim = ms + ml1 + '.sim' + self.msk = ms + ml1 + '.msk' + self.wbdOut = ms + ml1 + '.wbd' + self.rangeOffset = ms + ml1 + '_rg.off' + self.azimuthOffset = ms + ml1 + '_az.off' + self.multilookLos = ms + ml2 + '.los' + self.multilookWbdOut = ms + ml2 + '.wbd' + self.multilookMsk = ms + ml2 + '.msk' + self.multilookLatitude = ms + ml2 + '.lat' + self.multilookLongitude = ms + ml2 + '.lon' + self.multilookHeight = ms + ml2 + '.hgt' + self.multilookIon = ms + ml2 + '.ion' + self.rectRangeOffset = ms + ml1 + '_rg_rect.off' + self.geoInterferogram = 'filt_' + ms + ml2 + '.unw.geo' + self.geoMaskedInterferogram = 'filt_' + ms + ml2 + '_msk.unw.geo' + self.geoCoherence = ms + ml2 + '.cor.geo' + self.geoLos = ms + ml2 + '.los.geo' + #dense offset field + self.slaveSlcCoregistered = slaveDate + '_coreg.slc' + self.denseOffset = ms + '_denseoffset.off' + self.denseOffsetSnr = ms + '_denseoffset.snr' + self.denseOffsetCov = ms + '_denseoffset.cov' + self.denseOffsetFilt = 'filt_' + ms + '_denseoffset.off' + self.GeoDenseOffset = ms + '_denseoffset.off.geo' + self.GeoDenseOffsetSnr = ms + '_denseoffset.snr.geo' + self.GeoDenseOffsetFilt = 'filt_' + ms + '_denseoffset.off.geo' + self.geoIon = ms + ml2 + '.ion.geo' + + + 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 loadTrack(self, master=True): + ''' + Load the track using Product Manager. + ''' + if master: + track = self.loadProduct(self.masterTrackParameter) + else: + track = self.loadProduct(self.slaveTrackParameter) + + track.frames = [] + for i, frameNumber in enumerate(self.masterFrames): + os.chdir('f{}_{}'.format(i+1, frameNumber)) + if master: + track.frames.append(self.loadProduct(self.masterFrameParameter)) + else: + track.frames.append(self.loadProduct(self.slaveFrameParameter)) + os.chdir('../') + + return track + + + def saveTrack(self, track, master=True): + ''' + Save the track to XML files using Product Manager. + ''' + if master: + self.saveProduct(track, self.masterTrackParameter) + else: + self.saveProduct(track, self.slaveTrackParameter) + + for i, frameNumber in enumerate(self.masterFrames): + os.chdir('f{}_{}'.format(i+1, frameNumber)) + if master: + self.saveProduct(track.frames[i], self.masterFrameParameter) + else: + self.saveProduct(track.frames[i], self.slaveFrameParameter) + os.chdir('../') + + return None + + + 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 + diff --git a/components/isceobj/Alos2Proc/Alos2ProcPublic.py b/components/isceobj/Alos2Proc/Alos2ProcPublic.py new file mode 100644 index 0000000..56780cf --- /dev/null +++ b/components/isceobj/Alos2Proc/Alos2ProcPublic.py @@ -0,0 +1,1195 @@ +#!/usr/bin/env python3 + +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + + +def runCmd(cmd, silent=0): + import os + + if silent == 0: + print("{}".format(cmd)) + status = os.system(cmd) + if status != 0: + raise Exception('error when running:\n{}\n'.format(cmd)) + + +def find_vrt_keyword(xmlfile, keyword): + from xml.etree.ElementTree import ElementTree + + value = None + xmlx = ElementTree(file=open(xmlfile,'r')).getroot() + #try 10 times + for i in range(10): + path='' + for j in range(i): + path += '*/' + value0 = xmlx.find(path+keyword) + if value0 != None: + value = value0.text + break + + return value + + +def find_vrt_file(xmlfile, keyword, relative_path=True): + ''' + find file in vrt in another directory + xmlfile: vrt file + relative_path: True: return relative (to current directory) path of the file + False: return absolute path of the file + ''' + import os + #get absolute directory of xmlfile + xmlfile_dir = os.path.dirname(os.path.abspath(xmlfile)) + #find source file path + file = find_vrt_keyword(xmlfile, keyword) + #get absolute path of source file + file = os.path.abspath(os.path.join(xmlfile_dir, file)) + #get relative path of source file + if relative_path: + file = os.path.relpath(file, './') + return file + + +def create_xml(fileName, width, length, fileType): + import isceobj + + if fileType == 'slc': + image = isceobj.createSlcImage() + elif fileType == 'int': + image = isceobj.createIntImage() + elif fileType == 'amp': + image = isceobj.createAmpImage() + elif fileType == 'cor': + image = isceobj.createOffsetImage() + elif fileType == 'rmg' or fileType == 'unw': + image = isceobj.Image.createUnwImage() + elif fileType == 'byte': + image = isceobj.createImage() + image.setDataType('BYTE') + elif fileType == 'float': + image = isceobj.createImage() + image.setDataType('FLOAT') + elif fileType == 'double': + image = isceobj.createImage() + image.setDataType('DOUBLE') + + else: + raise Exception('format not supported yet!\n') + + image.setFilename(fileName) + image.extraFilename = fileName + '.vrt' + image.setWidth(width) + image.setLength(length) + + #image.setAccessMode('read') + #image.createImage() + image.renderHdr() + #image.finalizeImage() + + +def multilook_v1(data, nalks, nrlks): + ''' + doing multiple looking + ATTENSION: original array changed after running this function + ''' + + (length, width)=data.shape + width2 = int(width/nrlks) + length2 = int(length/nalks) + + for i in range(1, nalks): + data[0:length2*nalks:nalks, :] += data[i:length2*nalks:nalks, :] + for i in range(1, nrlks): + data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks] += data[0:length2*nalks:nalks, i:width2*nrlks:nrlks] + + return data[0:length2*nalks:nalks, 0:width2*nrlks:nrlks] / nrlks / nalks + + +def multilook(data, nalks, nrlks): + ''' + doing multiple looking + ''' + import numpy as np + + (length, width)=data.shape + width2 = int(width/nrlks) + length2 = int(length/nalks) + + data2=np.zeros((length2, width), dtype=data.dtype) + for i in range(0, nalks): + data2 += data[i:length2*nalks:nalks, :] + for i in range(1, nrlks): + data2[:, 0:width2*nrlks:nrlks] += data2[:, i:width2*nrlks:nrlks] + + return data2[:, 0:width2*nrlks:nrlks] / nrlks / nalks + + +def cal_coherence_1(inf, win=5): + ''' + Compute coherence using scipy convolve 2D. Same as "def cal_coherence(inf, win=5):" in funcs.py in insarzd + + #still use standard coherence estimation equation, but with magnitude removed. + #for example, equation (2) in + #H. Zebker and K. Chen, Accurate Estimation of Correlation in InSAR Observations, + #IEEE GEOSCIENCE AND REMOTE SENSING LETTERS, VOL. 2, NO. 2, APRIL 2005. + ''' + import numpy as np + import scipy.signal as ss + + filt = np.ones((win,win))/ (1.0*win*win) + flag = ss.convolve2d((inf!=0), filt, mode='same') + angle = inf / (np.absolute(inf)+(inf==0)) + cor = ss.convolve2d(angle, filt, mode='same') + cor = np.absolute(cor) + #remove incomplete convolution result + cor[np.nonzero(flag < 0.999)] = 0.0 + #print(np.max(cor), np.min(cor)) + #cor.astype(np.float32).tofile(f) + + return cor + + + +def computeOffsetFromOrbit(masterSwath, masterTrack, slaveSwath, slaveTrack, masterSample, masterLine): + ''' + compute range and azimuth offsets using orbit. all range/azimuth indexes start with 0 + masterSample: master sample where offset is computed, no need to be integer + masterLine: master line where offset is computed, no need to be integer + ''' + import datetime + + pointingDirection = {'right': -1, 'left' :1} + + #compute a pair of range and azimuth offsets using geometry + #using Piyush's code for computing range and azimuth offsets + midRange = masterSwath.startingRange + masterSwath.rangePixelSize * masterSample + midSensingStart = masterSwath.sensingStart + datetime.timedelta(seconds = masterLine / masterSwath.prf) + llh = masterTrack.orbit.rdr2geo(midSensingStart, midRange, side=pointingDirection[masterTrack.pointingDirection]) + slvaz, slvrng = slaveTrack.orbit.geo2rdr(llh, side=pointingDirection[masterTrack.pointingDirection]) + ###Translate to offsets + #at this point, slave range pixel size and prf should be the same as those of master + rgoff = ((slvrng - slaveSwath.startingRange) / masterSwath.rangePixelSize) - masterSample + azoff = ((slvaz - slaveSwath.sensingStart).total_seconds() * masterSwath.prf) - masterLine + + return (rgoff, azoff) + + +def overlapFrequency(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] + + +def readOffset(filename): + from isceobj.Location.Offset import OffsetField,Offset + + with open(filename, 'r') as f: + lines = f.readlines() + # 0 1 2 3 4 5 6 7 + #retstr = "%s %s %s %s %s %s %s %s" % (self.x,self.dx,self.y,self.dy,self.snr, self.sigmax, self.sigmay, self.sigmaxy) + + offsets = OffsetField() + for linex in lines: + #linexl = re.split('\s+', linex) + #detect blank lines with only spaces and tabs + if linex.strip() == '': + continue + + linexl = linex.split() + offset = Offset() + #offset.setCoordinate(int(linexl[0]),int(linexl[2])) + offset.setCoordinate(float(linexl[0]),float(linexl[2])) + offset.setOffset(float(linexl[1]),float(linexl[3])) + offset.setSignalToNoise(float(linexl[4])) + offset.setCovariance(float(linexl[5]),float(linexl[6]),float(linexl[7])) + offsets.addOffset(offset) + + return offsets + + +def writeOffset(offset, fileName): + + offsetsPlain = '' + for offsetx in offset: + offsetsPlainx = "{}".format(offsetx) + offsetsPlainx = offsetsPlainx.split() + offsetsPlain = offsetsPlain + "{:8d} {:10.3f} {:8d} {:12.3f} {:11.5f} {:11.6f} {:11.6f} {:11.6f}\n".format( + int(float(offsetsPlainx[0])), + float(offsetsPlainx[1]), + int(float(offsetsPlainx[2])), + float(offsetsPlainx[3]), + float(offsetsPlainx[4]), + float(offsetsPlainx[5]), + float(offsetsPlainx[6]), + float(offsetsPlainx[7]) + ) + + offsetFile = fileName + with open(offsetFile, 'w') as f: + f.write(offsetsPlain) + + +def reformatGeometricalOffset(rangeOffsetFile, azimuthOffsetFile, reformatedOffsetFile, rangeStep=1, azimuthStep=1, maximumNumberOfOffsets=10000): + ''' + reformat geometrical offset as ampcor output format + ''' + import numpy as np + import isceobj + + img = isceobj.createImage() + img.load(rangeOffsetFile+'.xml') + width = img.width + length = img.length + + step = int(np.sqrt(width*length/maximumNumberOfOffsets) + 0.5) + if step == 0: + step = 1 + + rgoff = np.fromfile(rangeOffsetFile, dtype=np.float32).reshape(length, width) + azoff = np.fromfile(azimuthOffsetFile, dtype=np.float32).reshape(length, width) + + offsetsPlain = '' + for i in range(0, length, step): + for j in range(0, width, step): + if (rgoff[i][j] == -999999.0) or (azoff[i][j] == -999999.0): + continue + + offsetsPlain = offsetsPlain + "{:8d} {:10.3f} {:8d} {:12.3f} {:11.5f} {:11.6f} {:11.6f} {:11.6f}\n".format( + int(j*rangeStep+1), + float(rgoff[i][j]), + int(i*azimuthStep+1), + float(azoff[i][j]), + float(22.00015), + float(0.000273), + float(0.002126), + float(0.000013) + ) + with open(reformatedOffsetFile, 'w') as f: + f.write(offsetsPlain) + + return + + +def cullOffsets(offsets): + import isceobj + from iscesys.StdOEL.StdOELPy import create_writer + + distances = (10,5,3,3,3,3,3,3) + #numCullOffsetsLimits = (100, 75, 50, 50, 50, 50, 50, 50) + numCullOffsetsLimits = (50, 40, 30, 30, 30, 30, 30, 30) + + refinedOffsets = offsets + for i, (distance, numCullOffsetsLimit) in enumerate(zip(distances, numCullOffsetsLimits)): + + cullOff = isceobj.createOffoutliers() + cullOff.wireInputPort(name='offsets', object=refinedOffsets) + cullOff.setSNRThreshold(2.0) + cullOff.setDistance(distance) + + #set the tag used in the outfile. each message is precided by this tag + #is the writer is not of "file" type the call has no effect + stdWriter = create_writer("log", "", True, filename="offoutliers.log") + stdWriter.setFileTag("offoutliers", "log") + stdWriter.setFileTag("offoutliers", "err") + stdWriter.setFileTag("offoutliers", "out") + cullOff.setStdWriter(stdWriter) + + #run it + cullOff.offoutliers() + + refinedOffsets = cullOff.getRefinedOffsetField() + numLeft = len(refinedOffsets._offsets) + print('Number of offsets left after %2dth culling: %5d'%(i, numLeft)) + if numLeft < numCullOffsetsLimit: + refinedOffsets = None + + stdWriter.finalize() + + return refinedOffsets + + +def cullOffsetsRoipac(offsets, numThreshold=50): + ''' + cull offsets using fortran program from ROI_PAC + numThreshold: minmum number of offsets left + ''' + import os + from contrib.alos2proc_f.alos2proc_f import fitoff + from isceobj.Alos2Proc.Alos2ProcPublic import readOffset + from isceobj.Alos2Proc.Alos2ProcPublic import writeOffset + + offsetFile = 'offset.off' + cullOffsetFile = 'cull.off' + writeOffset(offsets, offsetFile) + + #try different parameters to cull offsets + breakFlag = 0 + for maxrms in [0.08, 0.16, 0.24]: + for nsig in [1.5, 1.4, 1.3, 1.2, 1.1, 1.0, 0.9]: + fitoff(offsetFile, cullOffsetFile, nsig, maxrms, numThreshold) + + #check number of matching points left + with open(cullOffsetFile, 'r') as ff: + numCullOffsets = sum(1 for linex in ff) + if numCullOffsets < numThreshold: + print('offsets culling with nsig {} maxrms {}: {} left after culling, too few points'.format(nsig, maxrms, numCullOffsets)) + else: + print('offsets culling with nsig {} maxrms {}: {} left after culling, success'.format(nsig, maxrms, numCullOffsets)) + breakFlag = 1 + break + + if breakFlag == 1: + break + + if numCullOffsets < numThreshold: + refinedOffsets = None + else: + refinedOffsets = readOffset(cullOffsetFile) + + os.remove(offsetFile) + os.remove(cullOffsetFile) + + return refinedOffsets + + +def meanOffset(offsets): + + rangeOffset = 0.0 + azimuthOffset = 0.0 + i = 0 + for offsetx in offsets: + i += 1 + rangeOffset += offsetx.dx + azimuthOffset += offsetx.dy + + rangeOffset /= i + azimuthOffset /= i + + return (rangeOffset, azimuthOffset) + + +def fitOffset(inputOffset, order=1, axis='range'): + '''fit a polynomial to the offset + order=0 also works, output is mean offset + ''' + import numpy as np + index = [] + offset = [] + for a in inputOffset: + if axis=='range': + index.append(a.x) + offset.append(a.dx) + else: + index.append(a.y) + offset.append(a.dy) + + p = np.polyfit(index, offset, order) + + return list(p[::-1]) + + +def topo(swath, track, demFile, latFile, lonFile, hgtFile, losFile=None, incFile=None, mskFile=None, numberRangeLooks=1, numberAzimuthLooks=1, multilookTimeOffset=True): + import datetime + import isceobj + from zerodop.topozero import createTopozero + from isceobj.Planet.Planet import Planet + + pointingDirection = {'right': -1, 'left' :1} + + demImage = isceobj.createDemImage() + demImage.load(demFile + '.xml') + demImage.setAccessMode('read') + + #####Run Topo + planet = Planet(pname='Earth') + topo = createTopozero() + topo.slantRangePixelSpacing = numberRangeLooks * swath.rangePixelSize + topo.prf = 1.0 / (numberAzimuthLooks * swath.azimuthLineInterval) + topo.radarWavelength = track.radarWavelength + topo.orbit = track.orbit + topo.width = int(swath.numberOfSamples/numberRangeLooks) + topo.length = int(swath.numberOfLines/numberAzimuthLooks) + topo.wireInputPort(name='dem', object=demImage) + topo.wireInputPort(name='planet', object=planet) + topo.numberRangeLooks = 1 #must be set as 1 + topo.numberAzimuthLooks = 1 #must be set as 1 Cunren + topo.lookSide = pointingDirection[track.pointingDirection] + if multilookTimeOffset == True: + topo.sensingStart = swath.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0/swath.prf) + topo.rangeFirstSample = swath.startingRange + (numberRangeLooks-1.0)/2.0 * swath.rangePixelSize + else: + topo.sensingStart = swath.sensingStart + topo.rangeFirstSample = swath.startingRange + topo.demInterpolationMethod='BIQUINTIC' + + topo.latFilename = latFile + topo.lonFilename = lonFile + topo.heightFilename = hgtFile + if losFile != None: + topo.losFilename = losFile + if incFile != None: + topo.incFilename = incFile + if mskFile != None: + topo.maskFilename = mskFile + + topo.topo() + + return list(topo.snwe) + + +def geo2rdr(swath, track, latFile, lonFile, hgtFile, rangeOffsetFile, azimuthOffsetFile, numberRangeLooks=1, numberAzimuthLooks=1, multilookTimeOffset=True): + import datetime + import isceobj + from zerodop.geo2rdr import createGeo2rdr + from isceobj.Planet.Planet import Planet + + pointingDirection = {'right': -1, 'left' :1} + + latImage = isceobj.createImage() + latImage.load(latFile + '.xml') + latImage.setAccessMode('read') + + lonImage = isceobj.createImage() + lonImage.load(lonFile + '.xml') + lonImage.setAccessMode('read') + + hgtImage = isceobj.createDemImage() + hgtImage.load(hgtFile + '.xml') + hgtImage.setAccessMode('read') + + planet = Planet(pname='Earth') + + topo = createGeo2rdr() + topo.configure() + topo.slantRangePixelSpacing = numberRangeLooks * swath.rangePixelSize + topo.prf = 1.0 / (numberAzimuthLooks * swath.azimuthLineInterval) + topo.radarWavelength = track.radarWavelength + topo.orbit = track.orbit + topo.width = int(swath.numberOfSamples/numberRangeLooks) + topo.length = int(swath.numberOfLines/numberAzimuthLooks) + topo.demLength = hgtImage.length + topo.demWidth = hgtImage.width + topo.wireInputPort(name='planet', object=planet) + topo.numberRangeLooks = 1 + topo.numberAzimuthLooks = 1 #must be set to be 1 + topo.lookSide = pointingDirection[track.pointingDirection] + if multilookTimeOffset == True: + topo.sensingStart = swath.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*swath.azimuthLineInterval) + topo.rangeFirstSample = swath.startingRange + (numberRangeLooks-1.0)/2.0*swath.rangePixelSize + else: + topo.setSensingStart(swath.sensingStart) + topo.rangeFirstSample = swath.startingRange + topo.dopplerCentroidCoeffs = [0.] #we are using zero doppler geometry + topo.demImage = hgtImage + topo.latImage = latImage + topo.lonImage = lonImage + topo.rangeOffsetImageName = rangeOffsetFile + topo.azimuthOffsetImageName = azimuthOffsetFile + topo.geo2rdr() + + return + + +def waterBodyRadar(latFile, lonFile, wbdFile, wbdOutFile): + ''' + create water boday in radar coordinates + ''' + import numpy as np + import isceobj + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + demImage = isceobj.createDemImage() + demImage.load(wbdFile + '.xml') + #demImage.setAccessMode('read') + wbd=np.memmap(wbdFile, dtype='byte', mode='r', shape=(demImage.length, demImage.width)) + + image = isceobj.createImage() + image.load(latFile+'.xml') + width = image.width + length = image.length + + latFp = open(latFile, 'rb') + lonFp = open(lonFile, 'rb') + wbdOutFp = open(wbdOutFile, 'wb') + print("create water body in radar coordinates...") + for i in range(length): + if (((i+1)%200) == 0): + print("processing line %6d of %6d" % (i+1, length), end='\r', flush=True) + wbdOut = np.zeros(width, dtype='byte')-2 + lat = np.fromfile(latFp, dtype=np.float64, count=width) + lon = np.fromfile(lonFp, dtype=np.float64, count=width) + #indexes start with zero + lineIndex = np.int32((lat - demImage.firstLatitude) / demImage.deltaLatitude + 0.5) + sampleIndex = np.int32((lon - demImage.firstLongitude) / demImage.deltaLongitude + 0.5) + inboundIndex = np.logical_and( + np.logical_and(lineIndex>=0, lineIndex<=demImage.length-1), + np.logical_and(sampleIndex>=0, sampleIndex<=demImage.width-1) + ) + #keep SRTM convention. water body. (0) --- land; (-1) --- water; (-2 or other value) --- no data. + wbdOut = wbd[(lineIndex[inboundIndex], sampleIndex[inboundIndex])] + wbdOut.astype(np.int8).tofile(wbdOutFp) + print("processing line %6d of %6d" % (length, length)) + #create_xml(wbdOutFile, width, length, 'byte') + + image = isceobj.createImage() + image.setDataType('BYTE') + image.addDescription('water body. (0) --- land; (-1) --- water; (-2) --- no data.') + image.setFilename(wbdOutFile) + image.extraFilename = wbdOutFile + '.vrt' + image.setWidth(width) + image.setLength(length) + image.renderHdr() + + del wbd, demImage, image + latFp.close() + lonFp.close() + wbdOutFp.close() + + +def renameFile(oldname, newname): + import os + import isceobj + img = isceobj.createImage() + img.load(oldname + '.xml') + img.setFilename(newname) + img.extraFilename = newname+'.vrt' + img.renderHdr() + + os.rename(oldname, newname) + os.remove(oldname + '.xml') + os.remove(oldname + '.vrt') + + +def cal_coherence(inf, win=5, edge=0): + ''' + compute coherence uisng only interferogram (phase). + This routine still follows the regular equation for computing coherence, + but assumes the amplitudes of master and slave are one, so that coherence + can be computed using phase only. + + inf: interferogram + win: window size + edge: 0: remove all non-full convolution samples + + 1: remove samples computed from less than half convolution + (win=5 used to illustration below) + * * * + * * * + * * * + * * * + * * * + + 2: remove samples computed from less than quater convolution + (win=5 used to illustration below) + * * * + * * * + * * * + + 3: remove non-full convolution samples on image edges + + 4: keep all samples + ''' + import numpy as np + import scipy.signal as ss + + if win % 2 != 1: + raise Exception('window size must be odd!') + hwin = np.int(np.around((win - 1) / 2)) + + filt = np.ones((win, win)) + amp = np.absolute(inf) + + cnt = ss.convolve2d((amp!=0), filt, mode='same') + cor = ss.convolve2d(inf/(amp + (amp==0)), filt, mode='same') + cor = (amp!=0) * np.absolute(cor) / (cnt + (cnt==0)) + + #trim edges + if edge == 0: + num = win * win + cor[np.nonzero(cnt < num)] = 0.0 + elif edge == 1: + num = win * (hwin+1) + cor[np.nonzero(cnt < num)] = 0.0 + elif edge == 2: + num = (hwin+1) * (hwin+1) + cor[np.nonzero(cnt < num)] = 0.0 + elif edge == 3: + cor[0:hwin, :] = 0.0 + cor[-hwin:, :] = 0.0 + cor[:, 0:hwin] = 0.0 + cor[:, -hwin:] = 0.0 + else: + pass + + #print("coherence, max: {} min: {}".format(np.max(cor[np.nonzero(cor!=0)]), np.min(cor[np.nonzero(cor!=0)]))) + return cor + + +def snaphuUnwrap(track, t, wrapName, corName, unwrapName, nrlks, nalks, costMode = 'DEFO',initMethod = 'MST', defomax = 4.0, initOnly = False): + #runUnwrap(self, costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True) + ''' + track: track object + t: time for computing earth radius and altitude, normally mid azimuth time + wrapName: input interferogram + corName: input coherence file + unwrapName: output unwrapped interferogram + nrlks: number of range looks of the interferogram + nalks: number of azimuth looks of the interferogram + ''' + import datetime + import numpy as np + import isceobj + from contrib.Snaphu.Snaphu import Snaphu + from isceobj.Planet.Planet import Planet + + corImg = isceobj.createImage() + corImg.load(corName + '.xml') + width = corImg.width + length = corImg.length + + #get altitude + orbit = track.orbit + peg = orbit.interpolateOrbit(t, method='hermite') + refElp = Planet(pname='Earth').ellipsoid + llh = refElp.xyz_to_llh(peg.getPosition()) + hdg = orbit.getENUHeading(t) + refElp.setSCH(llh[0], llh[1], hdg) + earthRadius = refElp.pegRadCur + altitude = llh[2] + + rangeLooks = nrlks + azimuthLooks = nalks + azfact = 0.8 + rngfact = 0.8 + corrLooks = rangeLooks * azimuthLooks/(azfact*rngfact) + maxComponents = 20 + + snp = Snaphu() + snp.setInitOnly(initOnly) + snp.setInput(wrapName) + snp.setOutput(unwrapName) + snp.setWidth(width) + snp.setCostMode(costMode) + snp.setEarthRadius(earthRadius) + snp.setWavelength(track.radarWavelength) + snp.setAltitude(altitude) + snp.setCorrfile(corName) + snp.setInitMethod(initMethod) + snp.setCorrLooks(corrLooks) + snp.setMaxComponents(maxComponents) + snp.setDefoMaxCycles(defomax) + snp.setRangeLooks(rangeLooks) + snp.setAzimuthLooks(azimuthLooks) + if corImg.bands == 1: + snp.setCorFileFormat('FLOAT_DATA') + snp.prepare() + snp.unwrap() + + ######Render XML + outImage = isceobj.Image.createUnwImage() + outImage.setFilename(unwrapName) + outImage.setWidth(width) + outImage.setAccessMode('read') + outImage.renderVRT() + outImage.createImage() + outImage.finalizeImage() + outImage.renderHdr() + + #####Check if connected components was created + if snp.dumpConnectedComponents: + connImage = isceobj.Image.createImage() + connImage.setFilename(unwrapName+'.conncomp') + connImage.setWidth(width) + connImage.setAccessMode('read') + connImage.setDataType('BYTE') + connImage.renderVRT() + connImage.createImage() + connImage.finalizeImage() + connImage.renderHdr() + del connImage + + del corImg + del snp + del outImage + + #remove wired things in no-data area + amp=np.memmap(unwrapName, dtype='float32', mode='r+', shape=(length*2, width)) + wrap = np.fromfile(wrapName, dtype=np.complex64).reshape(length, width) + (amp[0:length*2:2, :])[np.nonzero(wrap==0)]=0 + (amp[1:length*2:2, :])[np.nonzero(wrap==0)]=0 + del amp + del wrap + + return + + +def snaphuUnwrapOriginal(wrapName, corName, ampName, unwrapName, costMode = 's', initMethod = 'mcf'): + ''' + unwrap interferogram using original snaphu program + ''' + import numpy as np + import isceobj + + corImg = isceobj.createImage() + corImg.load(corName + '.xml') + width = corImg.width + length = corImg.length + + #specify coherence file format in configure file + snaphuConfFile = 'snaphu.conf' + if corImg.bands == 1: + snaphuConf = '''CORRFILEFORMAT FLOAT_DATA +CONNCOMPFILE {} +MAXNCOMPS 20'''.format(unwrapName+'.conncomp') + + else: + snaphuConf = '''CORRFILEFORMAT FLOAT_DATA +CONNCOMPFILE {} +MAXNCOMPS 20'''.format(unwrapName+'.conncomp') + with open(snaphuConfFile, 'w') as f: + f.write(snaphuConf) + cmd = 'snaphu {} {} -f {} -{} -o {} -a {} -c {} -v --{}'.format( + wrapName, + width, + snaphuConfFile, + costMode, + unwrapName, + ampName, + corName, + initMethod + ) + runCmd(cmd) + create_xml(unwrapName, width, length, 'unw') + + connImage = isceobj.Image.createImage() + connImage.setFilename(unwrapName+'.conncomp') + connImage.setWidth(width) + connImage.setAccessMode('read') + connImage.setDataType('BYTE') + connImage.renderVRT() + connImage.createImage() + connImage.finalizeImage() + connImage.renderHdr() + del connImage + + #remove wired things in no-data area + amp=np.memmap(unwrapName, dtype='float32', mode='r+', shape=(length*2, width)) + wrap = np.fromfile(wrapName, dtype=np.complex64).reshape(length, width) + (amp[0:length*2:2, :])[np.nonzero(wrap==0)]=0 + (amp[1:length*2:2, :])[np.nonzero(wrap==0)]=0 + del amp + del wrap + + return + + +def getBboxGeo(track): + ''' + get bounding box in geo-coordinate + ''' + import numpy as np + + pointingDirection = {'right': -1, 'left' :1} + + bboxRdr = getBboxRdr(track) + + rangeMin = bboxRdr[0] + rangeMax = bboxRdr[1] + azimuthTimeMin = bboxRdr[2] + azimuthTimeMax = bboxRdr[3] + + #get bounding box using Piyush's code + hgtrange=[-500,9000] + ts = [azimuthTimeMin, azimuthTimeMax] + rngs = [rangeMin, rangeMax] + pos = [] + for ht in hgtrange: + for tim in ts: + for rng in rngs: + llh = track.orbit.rdr2geo(tim, rng, height=ht, side=pointingDirection[track.pointingDirection]) + pos.append(llh) + pos = np.array(pos) + # S N W E + bbox = [np.min(pos[:,0]), np.max(pos[:,0]), np.min(pos[:,1]), np.max(pos[:,1])] + + return bbox + + +def getBboxRdr(track): + ''' + get bounding box in radar-coordinate + ''' + import datetime + + numberOfFrames = len(track.frames) + numberOfSwaths = len(track.frames[0].swaths) + + sensingStartList = [] + sensingEndList = [] + startingRangeList = [] + endingRangeList = [] + for i in range(numberOfFrames): + for j in range(numberOfSwaths): + swath = track.frames[i].swaths[j] + sensingStartList.append(swath.sensingStart) + sensingEndList.append(swath.sensingStart + datetime.timedelta(seconds=(swath.numberOfLines-1) * swath.azimuthLineInterval)) + startingRangeList.append(swath.startingRange) + endingRangeList.append(swath.startingRange + (swath.numberOfSamples - 1) * swath.rangePixelSize) + azimuthTimeMin = min(sensingStartList) + azimuthTimeMax = max(sensingEndList) + azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0) + rangeMin = min(startingRangeList) + rangeMax = max(endingRangeList) + rangeMid = (rangeMin + rangeMax) / 2.0 + + bbox = [rangeMin, rangeMax, azimuthTimeMin, azimuthTimeMax] + + return bbox + + +def filterInterferogram(data, alpha, windowSize, stepSize): + ''' + a filter wrapper + ''' + import os + import numpy as np + from contrib.alos2filter.alos2filter import psfilt1 + + (length, width)=data.shape + data.astype(np.complex64).tofile('tmp1234.int') + psfilt1('tmp1234.int', 'filt_tmp1234.int', width, alpha, windowSize, stepSize) + + data2 = np.fromfile('filt_tmp1234.int', dtype=np.complex64).reshape(length, width) + os.remove('tmp1234.int') + os.remove('filt_tmp1234.int') + + return data2 + + + +################################################################### +# these are routines for burst-by-burst ScanSAR interferometry +################################################################### + +def mosaicBurstInterferogram(swath, burstPrefix, outputFile, numberOfLooksThreshold=1): + ''' + take a burst sequence and output mosaicked file + ''' + import numpy as np + + interferogram = np.zeros((swath.numberOfLines, swath.numberOfSamples), dtype=np.complex64) + cnt = np.zeros((swath.numberOfLines, swath.numberOfSamples), dtype=np.int8) + for i in range(swath.numberOfBursts): + burstFile = burstPrefix + '_%02d.int'%(i+1) + burstInterferogram = np.fromfile(burstFile, dtype=np.complex64).reshape(swath.burstSlcNumberOfLines, swath.burstSlcNumberOfSamples) + interferogram[0+swath.burstSlcFirstLineOffsets[i]:swath.burstSlcNumberOfLines+swath.burstSlcFirstLineOffsets[i], :] += burstInterferogram + cnt[0+swath.burstSlcFirstLineOffsets[i]:swath.burstSlcNumberOfLines+swath.burstSlcFirstLineOffsets[i], :] += (burstInterferogram!=0) + + #trim upper and lower edges with less number of looks + ############################################################################# + firstLine = 0 + for i in range(swath.numberOfLines): + if np.sum(cnt[i,:]>=numberOfLooksThreshold) > swath.numberOfSamples/2: + firstLine = i + break + lastLine = swath.numberOfLines - 1 + for i in range(swath.numberOfLines): + if np.sum(cnt[swath.numberOfLines-1-i,:]>=numberOfLooksThreshold) > swath.numberOfSamples/2: + lastLine = swath.numberOfLines-1-i + break + + interferogram[:firstLine,:]=0 + interferogram[lastLine+1:,:]=0 + + # if numberOfLooksThreshold!= None: + # interferogram[np.nonzero(cnt=numberOfLooksThreshold) > swath.numberOfSamples/2: + firstLine = i + break + lastLine = swath.numberOfLines - 1 + for i in range(swath.numberOfLines): + if np.sum(cnt[swath.numberOfLines-1-i,:]>=numberOfLooksThreshold) > swath.numberOfSamples/2: + lastLine = swath.numberOfLines-1-i + break + + amp[:firstLine,:]=0 + amp[lastLine+1:,:]=0 + + # if numberOfLooksThreshold!= None: + # amp[np.nonzero(cnt 0 + ka = -ka + t = tbase + index2*slaveSwath.azimuthLineInterval + deramp = np.exp(cj * np.pi * (-ka) * t**2) + + #compute reramp signal + index1 = np.matlib.repmat(np.arange(width), length, 1) + rgoffBurst + index2 = np.matlib.repmat(np.arange(length).reshape(length, 1), 1, width) + azoffBurst + ka = slaveSwath.azimuthFmrateVsPixel[3] * index1**3 + slaveSwath.azimuthFmrateVsPixel[2] * index1**2 + \ + slaveSwath.azimuthFmrateVsPixel[1] * index1 + slaveSwath.azimuthFmrateVsPixel[0] + #use the convention that ka > 0 + ka = -ka + t = tbase + index2*slaveSwath.azimuthLineInterval + reramp = np.exp(cj * np.pi * (ka) * t**2) + + + ########################################################################## + # 3. resample slave burst + ########################################################################## + #go to slave directory to do resampling + os.chdir(slaveBurstDir) + + #output offsets + rgoffBurstFile = "burst_rg.off" + azoffBurstFile = "burst_az.off" + rgoffBurst.astype(np.float32).tofile(rgoffBurstFile) + azoffBurst.astype(np.float32).tofile(azoffBurstFile) + + #deramp slave burst + slaveBurstDerampedFile = "slave.slc" + sburst = np.fromfile(slaveBurstSlc[iSlave], dtype=np.complex64).reshape(lengthSlave, widthSlave) + (deramp * sburst).astype(np.complex64).tofile(slaveBurstDerampedFile) + create_xml(slaveBurstDerampedFile, widthSlave, lengthSlave, 'slc') + + #resampled slave burst + slaveBurstResampFile = 'slave_resamp.slc' + + #resample slave burst + #now doppler has bigger impact now, as it's value is about 35 Hz (azimuth resampling frequency is now only 1/20 * PRF) + #we don't know if this doppler value is accurate or not, so we set it to zero, which seems to give best resampling result + #otherwise if it is not accurate and we still use it, it will significantly affect resampling result + dopplerVsPixel = slaveSwath.dopplerVsPixel + dopplerVsPixel = [0.0, 0.0, 0.0, 0.0] + + resamp(slaveBurstDerampedFile, slaveBurstResampFile, rgoffBurstFile, azoffBurstFile, width, length, 1.0/slaveSwath.azimuthLineInterval, dopplerVsPixel, + rgcoef=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + azcoef=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + azpos_off=0.0) + + #read resampled slave burst and reramp + sburstResamp = reramp * (np.fromfile(slaveBurstResampFile, dtype=np.complex64).reshape(length, width)) + + #clear up + os.remove(rgoffBurstFile) + os.remove(azoffBurstFile) + os.remove(slaveBurstDerampedFile) + os.remove(slaveBurstDerampedFile+'.vrt') + os.remove(slaveBurstDerampedFile+'.xml') + os.remove(slaveBurstResampFile) + os.remove(slaveBurstResampFile+'.vrt') + os.remove(slaveBurstResampFile+'.xml') + + os.chdir('../') + + + ########################################################################## + # 4. dump results + ########################################################################## + #dump resampled slave burst + os.chdir(slaveBurstResampledDir) + sburstResamp.astype(np.complex64).tofile(slaveBurstSlcResampled[i]) + create_xml(slaveBurstSlcResampled[i], width, length, 'slc') + os.chdir('../') + + #dump burst interferogram + mburst = np.fromfile(os.path.join(masterBurstDir, masterBurstSlc[i]), dtype=np.complex64).reshape(length, width) + os.chdir(interferogramDir) + (mburst * np.conj(sburstResamp)).astype(np.complex64).tofile(interferogram[i]) + create_xml(interferogram[i], width, length, 'int') + os.chdir('../') + + +def create_multi_index(width, rgl): + import numpy as np + #create index after multilooking + #assuming original index start with 0 + #applies to both range and azimuth direction + + widthm = int(width/rgl) + + #create range index: This applies to both odd and even cases, "rgl = 1" case, and "rgl = 2" case + start_rgindex = (rgl - 1.0) / 2.0 + rgindex0 = start_rgindex + np.arange(widthm) * rgl + + return rgindex0 + + +def create_multi_index2(width2, l1, l2): + import numpy as np + #for number of looks of l1 and l2 + #calculate the correponding index number of l2 in the l1 array + #applies to both range and azimuth direction + + return ((l2 - l1) / 2.0 + np.arange(width2) * l2) / l1 + + + + + + + + + + diff --git a/components/isceobj/Alos2Proc/Factories.py b/components/isceobj/Alos2Proc/Factories.py new file mode 100644 index 0000000..d450c46 --- /dev/null +++ b/components/isceobj/Alos2Proc/Factories.py @@ -0,0 +1,105 @@ +# +# Author: Piyush Agram +# Copyright 2016 +# + +# Path to the _RunWrapper factories +_PATH = "isceobj.Alos2Proc." + +## 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() == 'downsample_snaphu': + from .run_downsample_unwrapper import 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") +createDownloadDem = _factory("runDownloadDem") +createPrepareSlc = _factory("runPrepareSlc") +createSlcOffset = _factory("runSlcOffset") +createFormInterferogram = _factory("runFormInterferogram") +createSwathOffset = _factory("runSwathOffset") +createSwathMosaic = _factory("runSwathMosaic") +createFrameOffset = _factory("runFrameOffset") +createFrameMosaic = _factory("runFrameMosaic") +createRdr2Geo = _factory("runRdr2Geo") +createGeo2Rdr = _factory("runGeo2Rdr") +createRdrDemOffset = _factory("runRdrDemOffset") +createRectRangeOffset = _factory("runRectRangeOffset") +createDiffInterferogram = _factory("runDiffInterferogram") +createLook = _factory("runLook") +createCoherence = _factory("runCoherence") +createIonSubband = _factory("runIonSubband") +createIonUwrap = _factory("runIonUwrap") +createIonFilt = _factory("runIonFilt") +createFilt = _factory("runFilt") +createUnwrapSnaphu = _factory("runUnwrapSnaphu") +createGeocode = _factory("runGeocode") + +createSlcMosaic = _factory("runSlcMosaic") +createSlcMatch = _factory("runSlcMatch") +createDenseOffset = _factory("runDenseOffset") +createFiltOffset = _factory("runFiltOffset") +createGeocodeOffset = _factory("runGeocodeOffset") + + diff --git a/components/isceobj/Alos2Proc/SConscript b/components/isceobj/Alos2Proc/SConscript new file mode 100644 index 0000000..66748bb --- /dev/null +++ b/components/isceobj/Alos2Proc/SConscript @@ -0,0 +1,45 @@ +#! /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 = 'Alos2Proc' + +install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project) + +listFiles = ['__init__.py', 'Factories.py', 'Alos2Proc.py', 'Alos2ProcPublic.py', 'runPreprocessor.py', 'runDownloadDem.py', 'runPrepareSlc.py', 'runSlcOffset.py', 'runFormInterferogram.py', 'runSwathOffset.py', 'runSwathMosaic.py', 'runFrameOffset.py', 'runFrameMosaic.py', 'runRdr2Geo.py', 'runGeo2Rdr.py', 'runRdrDemOffset.py', 'runRectRangeOffset.py', 'runDiffInterferogram.py', 'runLook.py', 'runCoherence.py', 'runIonSubband.py', 'runIonUwrap.py', 'runIonFilt.py', 'runFilt.py', 'runUnwrapSnaphu.py', 'runGeocode.py', 'srtm_no_swbd_tiles.txt', 'srtm_tiles.txt', 'swbd_tiles.txt', 'runSlcMosaic.py', 'runSlcMatch.py', 'runDenseOffset.py', 'runFiltOffset.py', 'runGeocodeOffset.py', 'denseOffsetNote.txt'] +envisceobj.Install(install,listFiles) +envisceobj.Alias('install',install) diff --git a/components/isceobj/Alos2Proc/__init__.py b/components/isceobj/Alos2Proc/__init__.py new file mode 100644 index 0000000..cb3c392 --- /dev/null +++ b/components/isceobj/Alos2Proc/__init__.py @@ -0,0 +1,22 @@ +# +# Author: Piyush Agram +# Copyright 2016 +# + +from .Alos2Proc import * +from .Factories import * + +def getFactoriesInfo(): + return {'Alos2Proc': + {'args': + { + 'procDoc':{'value':None,'type':'Catalog','optional':True} + }, + 'factory':'createAlos2Proc' + } + + } + +def createAlos2Proc(name=None, procDoc= None): + from .Alos2Proc import Alos2Proc + return Alos2Proc(name = name,procDoc = procDoc) diff --git a/components/isceobj/Alos2Proc/denseOffsetNote.txt b/components/isceobj/Alos2Proc/denseOffsetNote.txt new file mode 100644 index 0000000..5db9fe7 --- /dev/null +++ b/components/isceobj/Alos2Proc/denseOffsetNote.txt @@ -0,0 +1,31 @@ +on the following paramters might be changed in the denseoffset steps: +======================================================================= + if self.frameOffsetMatching == False: + self._insar.frameRangeOffsetMatchingMaster = offsetMaster[2] + self._insar.frameAzimuthOffsetMatchingMaster = offsetMaster[3] + self._insar.frameRangeOffsetMatchingSlave = offsetSlave[2] + self._insar.frameAzimuthOffsetMatchingSlave = offsetSlave[3] + + +Therefore these denseoffset steps could be moved to after 'frame_mosaic' step + + + + + + + + + + + + + + + + + + + + + diff --git a/components/isceobj/Alos2Proc/runCoherence.py b/components/isceobj/Alos2Proc/runCoherence.py new file mode 100644 index 0000000..22048ef --- /dev/null +++ b/components/isceobj/Alos2Proc/runCoherence.py @@ -0,0 +1,131 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + +logger = logging.getLogger('isce.alos2insar.runCoherence') + +def runCoherence(self): + '''Extract images. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + #masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + numberRangeLooks = self._insar.numberRangeLooks1 * self._insar.numberRangeLooks2 + numberAzimuthLooks = self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooks2 + + #here we choose not to scale interferogram and amplitude + #scaleAmplitudeInterferogram + + #if (numberRangeLooks >= 5) and (numberAzimuthLooks >= 5): + if (numberRangeLooks * numberAzimuthLooks >= 9): + cmd = "imageMath.py -e='sqrt(b_0*b_1);abs(a)/(b_0+(b_0==0))/(b_1+(b_1==0))*(b_0!=0)*(b_1!=0)' --a={} --b={} -o {} -t float -s BIL".format( + self._insar.multilookDifferentialInterferogram, + self._insar.multilookAmplitude, + self._insar.multilookCoherence) + runCmd(cmd) + else: + #estimate coherence using a moving window + coherence(self._insar.multilookAmplitude, self._insar.multilookDifferentialInterferogram, self._insar.multilookCoherence, + method="cchz_wave", windowSize=5) + os.chdir('../') + + catalog.printToLog(logger, "runCoherence") + self._insar.procDoc.addAllFromCatalog(catalog) + + +from isceobj.Util.decorators import use_api +@use_api +def coherence(amplitudeFile, interferogramFile, coherenceFile, method="cchz_wave", windowSize=5): + ''' + compute coherence using a window + ''' + import operator + from mroipac.correlation.correlation import Correlation + + CORRELATION_METHOD = { + 'phase_gradient' : operator.methodcaller('calculateEffectiveCorrelation'), + 'cchz_wave' : operator.methodcaller('calculateCorrelation') + } + + ampImage = isceobj.createAmpImage() + ampImage.load(amplitudeFile + '.xml') + ampImage.setAccessMode('read') + ampImage.createImage() + + intImage = isceobj.createIntImage() + intImage.load(interferogramFile + '.xml') + intImage.setAccessMode('read') + intImage.createImage() + + #there is no coherence image in the isceobj/Image + cohImage = isceobj.createOffsetImage() + cohImage.setFilename(coherenceFile) + cohImage.setWidth(ampImage.width) + cohImage.setAccessMode('write') + cohImage.createImage() + + cor = Correlation() + cor.configure() + cor.wireInputPort(name='amplitude', object=ampImage) + cor.wireInputPort(name='interferogram', object=intImage) + cor.wireOutputPort(name='correlation', object=cohImage) + + cor.windowSize = windowSize + + cohImage.finalizeImage() + intImage.finalizeImage() + ampImage.finalizeImage() + + try: + CORRELATION_METHOD[method](cor) + except KeyError: + print("Unrecognized correlation method") + sys.exit(1) + pass + return None + + +def scaleAmplitudeInterferogram(amplitudeFile, interferogramFile, ratio=100000.0): + ''' + scale amplitude and interferogram, and balace the two channels of amplitude image + according to equation (2) in + Howard A. Zebker and Katherine Chen, Accurate Estimation of Correlation in InSAR Observations + IEEE GEOSCIENCE AND REMOTE SENSING LETTERS, VOL. 2, NO. 2, APRIL 2005. + the operation of the program does not affect coherence estimation + ''' + ampObj = isceobj.createImage() + ampObj.load(amplitudeFile+'.xml') + width = ampObj.width + length = ampObj.length + + inf = np.fromfile(interferogramFile, dtype=np.complex64).reshape(length, width) + amp = np.fromfile(amplitudeFile, dtype=np.complex64).reshape(length, width) + + flag = (inf!=0)*(amp.real!=0)*(amp.imag!=0) + nvalid = np.sum(flag, dtype=np.float64) + + mpwr1 = np.sqrt(np.sum(amp.real * amp.real * flag, dtype=np.float64) / nvalid) + mpwr2 = np.sqrt(np.sum(amp.imag * amp.imag * flag, dtype=np.float64) / nvalid) + + amp.real = amp.real / ratio + amp.imag = amp.imag / ratio * mpwr1 / mpwr2 + inf = inf / ratio / ratio * mpwr1 / mpwr2 + + amp.astype(np.complex64).tofile(inps.amp) + inf.astype(np.complex64).tofile(inps.inf) diff --git a/components/isceobj/Alos2Proc/runDenseOffset.py b/components/isceobj/Alos2Proc/runDenseOffset.py new file mode 100644 index 0000000..d878034 --- /dev/null +++ b/components/isceobj/Alos2Proc/runDenseOffset.py @@ -0,0 +1,327 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Util.decorators import use_api + +logger = logging.getLogger('isce.alos2insar.runDenseOffset') + +def runDenseOffset(self): + '''estimate offset fied + ''' + if not self.doDenseOffset: + return + if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)): + return + + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + denseOffsetDir = 'dense_offset' + if not os.path.exists(denseOffsetDir): + os.makedirs(denseOffsetDir) + os.chdir(denseOffsetDir) + + #masterTrack = self._insar.loadProduct(self._insar.masterTrackParameter) + #slaveTrack = self._insar.loadProduct(self._insar.slaveTrackParameter) + +######################################################################################### + + if self.useGPU and self._insar.hasGPU(): + runDenseOffsetGPU(self) + #define null value. Lijun said there is actually no such null value in GPU ampcor. + nullValue = -10000.0 + else: + runDenseOffsetCPU(self) + #define null value + nullValue = -10000.0 + + #null value set to zero + img = isceobj.createImage() + img.load(self._insar.denseOffset+'.xml') + width = img.width + length = img.length + offset=np.memmap(self._insar.denseOffset, dtype='float32', mode='r+', shape=(length*2, width)) + snr=np.memmap(self._insar.denseOffsetSnr, dtype='float32', mode='r+', shape=(length, width)) + offsetband1 = offset[0:length*2:2, :] + offsetband2 = offset[1:length*2:2, :] + index = np.nonzero(np.logical_or(offsetband1==nullValue, offsetband2==nullValue)) + offsetband1[index] = 0 + offsetband2[index] = 0 + snr[index] = 0 + del offset, offsetband1, offsetband2, snr + + #areas covered by water body set to zero + if self.maskOffsetWithWbd: + img = isceobj.createImage() + img.load('wbd.rdr.xml') + width0 = img.width + length0 = img.length + + img = isceobj.createImage() + img.load(self._insar.denseOffset+'.xml') + width = img.width + length = img.length + + #get water body mask + wbd0=np.memmap('wbd.rdr', dtype=np.int8, mode='r', shape=(length0, width0)) + wbd0=wbd0[0+self._insar.offsetImageTopoffset:length0:self.offsetSkipHeight, + 0+self._insar.offsetImageLeftoffset:width0:self.offsetSkipWidth] + wbd = np.zeros((length+100, width+100), dtype=np.int8) + wbd[0:wbd0.shape[0], 0:wbd0.shape[1]]=wbd0 + + #mask offset and snr + offset=np.memmap(self._insar.denseOffset, dtype='float32', mode='r+', shape=(length*2, width)) + snr=np.memmap(self._insar.denseOffsetSnr, dtype='float32', mode='r+', shape=(length, width)) + (offset[0:length*2:2, :])[np.nonzero(wbd[0:length, 0:width]==-1)]=0 + (offset[1:length*2:2, :])[np.nonzero(wbd[0:length, 0:width]==-1)]=0 + snr[np.nonzero(wbd[0:length, 0:width]==-1)]=0 + + del wbd0, wbd, offset, snr + + +######################################################################################### + + os.chdir('../') + catalog.printToLog(logger, "runDenseOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + +#@use_api +def runDenseOffsetCPU(self): + ''' + Estimate dense offset field between a pair of SLCs. + ''' + from mroipac.ampcor.DenseAmpcor import DenseAmpcor + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + + ####For this module currently, we need to create an actual file on disk + for infile in [self._insar.masterSlc, self._insar.slaveSlcCoregistered]: + if os.path.isfile(infile): + continue + cmd = 'gdal_translate -of ENVI {0}.vrt {0}'.format(infile) + runCmd(cmd) + + m = isceobj.createSlcImage() + m.load(self._insar.masterSlc + '.xml') + m.setAccessMode('READ') + + s = isceobj.createSlcImage() + s.load(self._insar.slaveSlcCoregistered + '.xml') + s.setAccessMode('READ') + + #objOffset.numberThreads = 1 + print('\n************* dense offset estimation parameters *************') + print('master SLC: %s' % (self._insar.masterSlc)) + print('slave SLC: %s' % (self._insar.slaveSlcCoregistered)) + print('dense offset estimation window width: %d' % (self.offsetWindowWidth)) + print('dense offset estimation window hight: %d' % (self.offsetWindowHeight)) + print('dense offset search window width: %d' % (self.offsetSearchWindowWidth)) + print('dense offset search window hight: %d' % (self.offsetSearchWindowHeight)) + print('dense offset skip width: %d' % (self.offsetSkipWidth)) + print('dense offset skip hight: %d' % (self.offsetSkipHeight)) + print('dense offset covariance surface oversample factor: %d' % (self.offsetCovarianceOversamplingFactor)) + print('dense offset covariance surface oversample window size: %d\n' % (self.offsetCovarianceOversamplingWindowsize)) + + + objOffset = DenseAmpcor(name='dense') + objOffset.configure() + + if m.dataType.startswith('C'): + objOffset.setImageDataType1('complex') + else: + objOffset.setImageDataType1('real') + if s.dataType.startswith('C'): + objOffset.setImageDataType2('complex') + else: + objOffset.setImageDataType2('real') + + objOffset.offsetImageName = self._insar.denseOffset + objOffset.snrImageName = self._insar.denseOffsetSnr + objOffset.covImageName = self._insar.denseOffsetCov + + objOffset.setWindowSizeWidth(self.offsetWindowWidth) + objOffset.setWindowSizeHeight(self.offsetWindowHeight) + #NOTE: actual number of resulting correlation pixels: self.offsetSearchWindowWidth*2+1 + objOffset.setSearchWindowSizeWidth(self.offsetSearchWindowWidth) + objOffset.setSearchWindowSizeHeight(self.offsetSearchWindowHeight) + objOffset.setSkipSampleAcross(self.offsetSkipWidth) + objOffset.setSkipSampleDown(self.offsetSkipHeight) + objOffset.setOversamplingFactor(self.offsetCovarianceOversamplingFactor) + objOffset.setZoomWindowSize(self.offsetCovarianceOversamplingWindowsize) + objOffset.setAcrossGrossOffset(0) + objOffset.setDownGrossOffset(0) + #these are azimuth scaling factor + #Matching Scale for Sample/Line Directions (-) = 1.000000551500 1.000002373200 + objOffset.setFirstPRF(1.0) + objOffset.setSecondPRF(1.0) + + objOffset.denseampcor(m, s) + + ### Store params for later + self._insar.offsetImageTopoffset = objOffset.locationDown[0][0] + self._insar.offsetImageLeftoffset = objOffset.locationAcross[0][0] + + #change band order + width=objOffset.offsetCols + length=objOffset.offsetLines + + offset1 = np.fromfile(self._insar.denseOffset, dtype=np.float32).reshape(length*2, width) + offset2 = np.zeros((length*2, width), dtype=np.float32) + offset2[0:length*2:2, :] = offset1[1:length*2:2, :] + offset2[1:length*2:2, :] = offset1[0:length*2:2, :] + + os.remove(self._insar.denseOffset) + os.remove(self._insar.denseOffset+'.vrt') + os.remove(self._insar.denseOffset+'.xml') + + offset2.astype(np.float32).tofile(self._insar.denseOffset) + outImg = isceobj.createImage() + outImg.setDataType('FLOAT') + outImg.setFilename(self._insar.denseOffset) + outImg.setBands(2) + outImg.scheme = 'BIL' + outImg.setWidth(width) + outImg.setLength(length) + outImg.addDescription('two-band pixel offset file. 1st band: range offset, 2nd band: azimuth offset') + outImg.setAccessMode('read') + outImg.renderHdr() + + return (objOffset.offsetCols, objOffset.offsetLines) + + +def runDenseOffsetGPU(self): + ''' + Estimate dense offset field between a pair of SLCs. + ''' + from contrib.PyCuAmpcor import PyCuAmpcor + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + ############################################################################################ + # #different from minyan's script: cuDenseOffsets.py: deramp method (0: mag, 1: complex) + # objOffset.derampMethod = 2 # + # #varying-gross-offset parameters not set + + # #not set in minyan's script: cuDenseOffsets.py + # objOffset.corrSurfaceZoomInWindow + # objOffset.grossOffsetAcrossStatic = 0 + # objOffset.grossOffsetDownStatic = 0 + ############################################################################################ + + + ####For this module currently, we need to create an actual file on disk + for infile in [self._insar.masterSlc, self._insar.slaveSlcCoregistered]: + if os.path.isfile(infile): + continue + cmd = 'gdal_translate -of ENVI {0}.vrt {0}'.format(infile) + runCmd(cmd) + + m = isceobj.createSlcImage() + m.load(self._insar.masterSlc + '.xml') + m.setAccessMode('READ') + + s = isceobj.createSlcImage() + s.load(self._insar.slaveSlcCoregistered + '.xml') + s.setAccessMode('READ') + + print('\n************* dense offset estimation parameters *************') + print('master SLC: %s' % (self._insar.masterSlc)) + print('slave SLC: %s' % (self._insar.slaveSlcCoregistered)) + print('dense offset estimation window width: %d' % (self.offsetWindowWidth)) + print('dense offset estimation window hight: %d' % (self.offsetWindowHeight)) + print('dense offset search window width: %d' % (self.offsetSearchWindowWidth)) + print('dense offset search window hight: %d' % (self.offsetSearchWindowHeight)) + print('dense offset skip width: %d' % (self.offsetSkipWidth)) + print('dense offset skip hight: %d' % (self.offsetSkipHeight)) + print('dense offset covariance surface oversample factor: %d' % (self.offsetCovarianceOversamplingFactor)) + print('dense offset covariance surface oversample window size: %d\n' % (self.offsetCovarianceOversamplingWindowsize)) + + + objOffset = PyCuAmpcor.PyCuAmpcor() + objOffset.algorithm = 0 + objOffset.deviceID = -1 + objOffset.nStreams = 2 + #original ampcor program in roi_pac uses phase gradient to deramp + objOffset.derampMethod = 2 + objOffset.masterImageName = self._insar.masterSlc + objOffset.masterImageHeight = m.length + objOffset.masterImageWidth = m.width + objOffset.slaveImageName = self._insar.slaveSlcCoregistered + objOffset.slaveImageHeight = s.length + objOffset.slaveImageWidth = s.width + objOffset.offsetImageName = self._insar.denseOffset + objOffset.snrImageName = self._insar.denseOffsetSnr + + objOffset.windowSizeWidth = self.offsetWindowWidth + objOffset.windowSizeHeight = self.offsetWindowHeight + #objOffset.halfSearchRangeAcross = int(self.offsetSearchWindowWidth / 2 + 0.5) + #objOffset.halfSearchRangeDown = int(self.offsetSearchWindowHeight / 2 + 0.5) + objOffset.halfSearchRangeAcross = self.offsetSearchWindowWidth + objOffset.halfSearchRangeDown = self.offsetSearchWindowHeight + objOffset.skipSampleDown = self.offsetSkipHeight + objOffset.skipSampleAcross = self.offsetSkipWidth + #Oversampling method for correlation surface(0=fft,1=sinc) + objOffset.corrSufaceOverSamplingMethod = 0 + objOffset.corrSurfaceOverSamplingFactor = self.offsetCovarianceOversamplingFactor + objOffset.corrSurfaceZoomInWindow = self.offsetCovarianceOversamplingWindowsize + objOffset.grossOffsetAcrossStatic = 0 + objOffset.grossOffsetDownStatic = 0 + + objOffset.masterStartPixelDownStatic = self.offsetWindowHeight//2 + objOffset.masterStartPixelAcrossStatic = self.offsetWindowWidth//2 + + objOffset.numberWindowDown = (m.length - 2*self.offsetSearchWindowHeight - self.offsetWindowHeight) // self.offsetSkipHeight + objOffset.numberWindowAcross = (m.width - 2*self.offsetSearchWindowWidth - self.offsetWindowWidth) // self.offsetSkipWidth + + # generic control + objOffset.numberWindowDownInChunk = 8 + objOffset.numberWindowAcrossInChunk = 8 + objOffset.mmapSize = 16 + + objOffset.setupParams() + objOffset.setConstantGrossOffset(0, 0) + objOffset.checkPixelInImageRange() + objOffset.runAmpcor() + + ### Store params for later + self._insar.offsetImageTopoffset = objOffset.halfSearchRangeDown + self._insar.offsetImageLeftoffset = objOffset.halfSearchRangeAcross + + + width = objOffset.numberWindowAcross + length = objOffset.numberWindowDown + offsetBIP = np.fromfile(objOffset.offsetImageName.decode('utf-8'), dtype=np.float32).reshape(length, width*2) + offsetBIL = np.zeros((length*2, width), dtype=np.float32) + offsetBIL[0:length*2:2, :] = offsetBIP[:, 1:width*2:2] + offsetBIL[1:length*2:2, :] = offsetBIP[:, 0:width*2:2] + os.remove(objOffset.offsetImageName.decode('utf-8')) + offsetBIL.astype(np.float32).tofile(objOffset.offsetImageName.decode('utf-8')) + + outImg = isceobj.createImage() + outImg.setDataType('FLOAT') + outImg.setFilename(objOffset.offsetImageName.decode('utf-8')) + outImg.setBands(2) + outImg.scheme = 'BIL' + outImg.setWidth(objOffset.numberWindowAcross) + outImg.setLength(objOffset.numberWindowDown) + outImg.addDescription('two-band pixel offset file. 1st band: range offset, 2nd band: azimuth offset') + outImg.setAccessMode('read') + outImg.renderHdr() + + snrImg = isceobj.createImage() + snrImg.setFilename( objOffset.snrImageName.decode('utf8')) + snrImg.setDataType('FLOAT') + snrImg.setBands(1) + snrImg.setWidth(objOffset.numberWindowAcross) + snrImg.setLength(objOffset.numberWindowDown) + snrImg.setAccessMode('read') + snrImg.renderHdr() + + return (objOffset.numberWindowAcross, objOffset.numberWindowDown) diff --git a/components/isceobj/Alos2Proc/runDiffInterferogram.py b/components/isceobj/Alos2Proc/runDiffInterferogram.py new file mode 100644 index 0000000..c8cf103 --- /dev/null +++ b/components/isceobj/Alos2Proc/runDiffInterferogram.py @@ -0,0 +1,41 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + +logger = logging.getLogger('isce.alos2insar.runDiffInterferogram') + +def runDiffInterferogram(self): + '''Extract images. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + rangePixelSize = self._insar.numberRangeLooks1 * masterTrack.rangePixelSize + radarWavelength = masterTrack.radarWavelength + + cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{}) * (b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, self._insar.interferogram, self._insar.rectRangeOffset, self._insar.differentialInterferogram) + runCmd(cmd) + + + os.chdir('../') + + catalog.printToLog(logger, "runDiffInterferogram") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2Proc/runDownloadDem.py b/components/isceobj/Alos2Proc/runDownloadDem.py new file mode 100644 index 0000000..d2fb367 --- /dev/null +++ b/components/isceobj/Alos2Proc/runDownloadDem.py @@ -0,0 +1,204 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo + +logger = logging.getLogger('isce.alos2insar.runDownloadDem') + +def runDownloadDem(self): + '''download DEM and water body + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + bboxGeo = getBboxGeo(masterTrack) + bbox = np.array(bboxGeo) + bboxStr = '{} {} {} {}'.format(np.int(np.floor(bbox[0])), np.int(np.ceil(bbox[1])), np.int(np.floor(bbox[2])), np.int(np.ceil(bbox[3]))) + + + #get 1 arcsecond dem for coregistration + if self.dem == None: + demDir = 'dem_1_arcsec' + if not os.path.exists(demDir): + os.makedirs(demDir) + os.chdir(demDir) + + downloadUrl = 'http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11' + cmd = 'dem.py -a stitch -b {} -k -s 1 -c -f -u {}'.format( + bboxStr, + downloadUrl + ) + runCmd(cmd) + cmd = 'fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f' + runCmd(cmd) + cmd = 'rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml' + runCmd(cmd) + os.chdir('../') + + self.dem = glob.glob(os.path.join(demDir, 'demLat_*_*_Lon_*_*.dem.wgs84'))[0] + + #get 3 arcsecond dem for geocoding + if self.demGeo == None: + demGeoDir = 'dem_3_arcsec' + if not os.path.exists(demGeoDir): + os.makedirs(demGeoDir) + os.chdir(demGeoDir) + + downloadUrl = 'http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11' + cmd = 'dem.py -a stitch -b {} -k -s 3 -c -f -u {}'.format( + bboxStr, + downloadUrl + ) + runCmd(cmd) + cmd = 'fixImageXml.py -i demLat_*_*_Lon_*_*.dem.wgs84 -f' + runCmd(cmd) + cmd = 'rm *.hgt* *.log demLat_*_*_Lon_*_*.dem demLat_*_*_Lon_*_*.dem.vrt demLat_*_*_Lon_*_*.dem.xml' + runCmd(cmd) + os.chdir('../') + + self.demGeo = glob.glob(os.path.join(demGeoDir, 'demLat_*_*_Lon_*_*.dem.wgs84'))[0] + + #get water body for masking interferogram + if self.wbd == None: + wbdDir = 'wbd_1_arcsec' + if not os.path.exists(wbdDir): + os.makedirs(wbdDir) + os.chdir(wbdDir) + + #cmd = 'wbd.py {}'.format(bboxStr) + #runCmd(cmd) + download_wbd(np.int(np.floor(bbox[0])), np.int(np.ceil(bbox[1])), np.int(np.floor(bbox[2])), np.int(np.ceil(bbox[3]))) + cmd = 'fixImageXml.py -i swbdLat_*_*_Lon_*_*.wbd -f' + runCmd(cmd) + cmd = 'rm *.log' + runCmd(cmd) + os.chdir('../') + + self.wbd = glob.glob(os.path.join(wbdDir, 'swbdLat_*_*_Lon_*_*.wbd'))[0] + + self._insar.dem = self.dem + self._insar.demGeo = self.demGeo + self._insar.wbd = self.wbd + + + catalog.printToLog(logger, "runDownloadDem") + self._insar.procDoc.addAllFromCatalog(catalog) + + + +def download_wbd(s, n, w, e): + ''' + download water body + water body. (0) --- land; (-1) --- water; (-2) --- no data. + + set no-value pixel inside of latitude [-56, 60] to -1 + set no-value pixel outside of latitidue [-56, 60] to -2 + + look at this figure for SRTM coverage: + https://www2.jpl.nasa.gov/srtm/images/SRTM_2-24-2016.gif + ''' + import os + import numpy as np + import isceobj + from iscesys.DataManager import createManager + + latMin = np.floor(s) + latMax = np.ceil(n) + lonMin = np.floor(w) + lonMax = np.ceil(e) + + ############################################################ + #1. download and stitch wbd + ############################################################ + sw = createManager('wbd') + sw.configure() + + outputFile = sw.defaultName([latMin,latMax,lonMin,lonMax]) + if os.path.exists(outputFile) and os.path.exists(outputFile+'.xml'): + print('water body file: {}'.format(outputFile)) + print('exists, do not download and correct') + return outputFile + + #download and stitch the SWBD tiles + sw.noFilling = False + sw._fillingValue = -1 + sw.stitch([latMin,latMax],[lonMin,lonMax]) + + + ############################################################ + #2. replace 'areas with SRTM but no SWBD' with zeros (land) + ############################################################ + print('post-process water body file') + + print('get SRTM tiles') + srtmListFile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'srtm_tiles.txt') + with open(srtmListFile) as f: + srtmList = f.readlines() + srtmList = [x[0:7] for x in srtmList] + + #get tiles that have SRTM DEM, but no SWBD, these are mostly tiles that do not have water body + print('get tiles with SRTM and without SWBD') + noSwbdListFile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'srtm_no_swbd_tiles.txt') + with open(noSwbdListFile) as f: + noSwbdList = f.readlines() + noSwbdList = [x[0:7] for x in noSwbdList] + + print('get SWBD tiles') + swbdListFile = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'swbd_tiles.txt') + with open(swbdListFile) as f: + swbdList = f.readlines() + swbdList = [x[0:7] for x in swbdList] + + + #read resulting mosaicked water body + wbdImage = isceobj.createDemImage() + wbdImage.load(outputFile+'.xml') + #using memmap instead, which should be faster, since we only have a few pixels to change + wbd=np.memmap(outputFile, dtype=np.int8, mode='r+', shape=(wbdImage.length, wbdImage.width)) + + #replace 'areas with SRTM but no SWBD' with zeros (land) + names, nlats, nlons = sw.createNameListFromBounds([latMin,latMax],[lonMin,lonMax]) + sign={'S':-1, 'N':1, 'W':-1, 'E':1} + for tile in names: + print('checking tile: {}'.format(tile)) + firstLatitude = sign[tile[0].upper()]*int(tile[1:3])+1 + firstLongitude = sign[tile[3].upper()]*int(tile[4:7]) + lineOffset = np.int32((firstLatitude - wbdImage.firstLatitude) / wbdImage.deltaLatitude + 0.5) + sampleOffset = np.int32((firstLongitude - wbdImage.firstLongitude) / wbdImage.deltaLongitude + 0.5) + + #first line/sample of mosaicked SWBD is integer lat/lon, but it does not include last integer lat/lon line/sample + #so here the size is 3600*3600 instead of 3601*3601 + + #assuming areas without swbd are water + if tile[0:7] not in swbdList: + wbd[0+lineOffset:3600+lineOffset, 0+sampleOffset:3600+sampleOffset] = -1 + #assuming areas with srtm and without swbd are land + if tile[0:7] in noSwbdList: + wbd[0+lineOffset:3600+lineOffset, 0+sampleOffset:3600+sampleOffset] = 0 + + + ############################################################ + #3. set values outside of lat[-56, 60] to -2 (no data) + ############################################################ + print('check water body file') + print('set areas outside of lat[-56, 60] to -2 (no data)') + for i in range(wbdImage.length): + lat = wbdImage.firstLatitude + wbdImage.deltaLatitude * i + if lat > 60.0 or lat < -56.0: + wbd[i, :] = -2 + del wbd, wbdImage + + + return outputFile diff --git a/components/isceobj/Alos2Proc/runFilt.py b/components/isceobj/Alos2Proc/runFilt.py new file mode 100644 index 0000000..f25f7ba --- /dev/null +++ b/components/isceobj/Alos2Proc/runFilt.py @@ -0,0 +1,171 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import shutil +import numpy as np + +import isceobj +from mroipac.filter.Filter import Filter +from contrib.alos2filter.alos2filter import psfilt1 +from mroipac.icu.Icu import Icu +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from isceobj.Alos2Proc.Alos2ProcPublic import renameFile +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2insar.runFilt') + +def runFilt(self): + '''filter interferogram + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + #masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + ############################################################ + # STEP 1. filter interferogram + ############################################################ + print('\nfilter interferogram: {}'.format(self._insar.multilookDifferentialInterferogram)) + + toBeFiltered = self._insar.multilookDifferentialInterferogram + if self.removeMagnitudeBeforeFiltering: + toBeFiltered = 'tmp.int' + cmd = "imageMath.py -e='a/(abs(a)+(a==0))' --a={} -o {} -t cfloat -s BSQ".format(self._insar.multilookDifferentialInterferogram, toBeFiltered) + runCmd(cmd) + + #if shutil.which('psfilt1') != None: + if True: + intImage = isceobj.createIntImage() + intImage.load(toBeFiltered + '.xml') + width = intImage.width + length = intImage.length + # cmd = "psfilt1 {int} {filtint} {width} {filterstrength} 64 16".format( + # int = toBeFiltered, + # filtint = self._insar.filteredInterferogram, + # width = width, + # filterstrength = self.filterStrength + # ) + # runCmd(cmd) + windowSize = self.filterWinsize + stepSize = self.filterStepsize + psfilt1(toBeFiltered, self._insar.filteredInterferogram, width, self.filterStrength, windowSize, stepSize) + create_xml(self._insar.filteredInterferogram, width, length, 'int') + else: + #original + intImage = isceobj.createIntImage() + intImage.load(toBeFiltered + '.xml') + intImage.setAccessMode('read') + intImage.createImage() + width = intImage.width + length = intImage.length + + #filtered + filtImage = isceobj.createIntImage() + filtImage.setFilename(self._insar.filteredInterferogram) + filtImage.setWidth(width) + filtImage.setAccessMode('write') + filtImage.createImage() + + #looks like the ps filtering program keep the original interferogram magnitude, which is bad for phase unwrapping? + filters = Filter() + filters.wireInputPort(name='interferogram',object=intImage) + filters.wireOutputPort(name='filtered interferogram',object=filtImage) + filters.goldsteinWerner(alpha=self.filterStrength) + intImage.finalizeImage() + filtImage.finalizeImage() + del intImage, filtImage, filters + + if self.removeMagnitudeBeforeFiltering: + os.remove(toBeFiltered) + os.remove(toBeFiltered + '.vrt') + os.remove(toBeFiltered + '.xml') + + #restore original magnitude + tmpFile = 'tmp.int' + renameFile(self._insar.filteredInterferogram, tmpFile) + cmd = "imageMath.py -e='a*abs(b)' --a={} --b={} -o {} -t cfloat -s BSQ".format(tmpFile, self._insar.multilookDifferentialInterferogram, self._insar.filteredInterferogram) + runCmd(cmd) + os.remove(tmpFile) + os.remove(tmpFile + '.vrt') + os.remove(tmpFile + '.xml') + + + ############################################################ + # STEP 2. create phase sigma using filtered interferogram + ############################################################ + print('\ncreate phase sigma using: {}'.format(self._insar.filteredInterferogram)) + + #recreate filtered image + filtImage = isceobj.createIntImage() + filtImage.load(self._insar.filteredInterferogram + '.xml') + filtImage.setAccessMode('read') + filtImage.createImage() + + #amplitude image + ampImage = isceobj.createAmpImage() + ampImage.load(self._insar.multilookAmplitude + '.xml') + ampImage.setAccessMode('read') + ampImage.createImage() + + #phase sigma correlation image + phsigImage = isceobj.createImage() + phsigImage.setFilename(self._insar.multilookPhsig) + phsigImage.setWidth(width) + phsigImage.dataType='FLOAT' + phsigImage.bands = 1 + phsigImage.setImageType('cor') + phsigImage.setAccessMode('write') + phsigImage.createImage() + + icu = Icu(name='insarapp_filter_icu') + icu.configure() + icu.unwrappingFlag = False + icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage) + + phsigImage.renderHdr() + + filtImage.finalizeImage() + ampImage.finalizeImage() + phsigImage.finalizeImage() + + del filtImage + del ampImage + del phsigImage + del icu + + + ############################################################ + # STEP 3. mask filtered interferogram using water body + ############################################################ + print('\nmask filtered interferogram using: {}'.format(self._insar.multilookWbdOut)) + + if self.waterBodyMaskStartingStep=='filt': + if not os.path.exists(self._insar.multilookWbdOut): + catalog.addItem('warning message', 'requested masking interferogram with water body, but water body does not exist', 'runFilt') + else: + wbd = np.fromfile(self._insar.multilookWbdOut, dtype=np.int8).reshape(length, width) + phsig=np.memmap(self._insar.multilookPhsig, dtype='float32', mode='r+', shape=(length, width)) + phsig[np.nonzero(wbd==-1)]=0 + del phsig + filt=np.memmap(self._insar.filteredInterferogram, dtype='complex64', mode='r+', shape=(length, width)) + filt[np.nonzero(wbd==-1)]=0 + del filt + del wbd + + + os.chdir('../') + + catalog.printToLog(logger, "runFilt") + self._insar.procDoc.addAllFromCatalog(catalog) + diff --git a/components/isceobj/Alos2Proc/runFiltOffset.py b/components/isceobj/Alos2Proc/runFiltOffset.py new file mode 100644 index 0000000..41ce541 --- /dev/null +++ b/components/isceobj/Alos2Proc/runFiltOffset.py @@ -0,0 +1,104 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import statistics +import numpy as np +from scipy.ndimage.filters import median_filter + +import isceobj + +logger = logging.getLogger('isce.alos2insar.runFiltOffset') + +def runFiltOffset(self): + '''filt offset fied + ''' + if not self.doDenseOffset: + return + if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)): + return + + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + denseOffsetDir = 'dense_offset' + if not os.path.exists(denseOffsetDir): + os.makedirs(denseOffsetDir) + os.chdir(denseOffsetDir) + + #masterTrack = self._insar.loadProduct(self._insar.masterTrackParameter) + #slaveTrack = self._insar.loadProduct(self._insar.slaveTrackParameter) + +######################################################################################### + + if not self.doOffsetFiltering: + print('offset field filtering is not requested.') + os.chdir('../') + catalog.printToLog(logger, "runFiltOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + return + + windowSize = self.offsetFilterWindowsize + nullValue = 0 + snrThreshold = self.offsetFilterSnrThreshold + + if windowSize < 3: + raise Exception('dense offset field filter window size must >= 3') + if windowSize % 2 != 1: + windowSize += 1 + print('dense offset field filter window size is not odd, changed to: {}'.format(windowSize)) + + print('\noffset filter parameters:') + print('**************************************') + print('filter window size: {}'.format(windowSize)) + print('filter null value: {}'.format(nullValue)) + print('filter snr threshold: {}\n'.format(snrThreshold)) + + + img = isceobj.createImage() + img.load(self._insar.denseOffset+'.xml') + width = img.width + length = img.length + + offset = np.fromfile(self._insar.denseOffset, dtype=np.float32).reshape(length*2, width) + snr = np.fromfile(self._insar.denseOffsetSnr, dtype=np.float32).reshape(length, width) + offsetFilt = np.zeros((length*2, width), dtype=np.float32) + + edge = int((windowSize-1)/2+0.5) + for k in range(2): + print('filtering band {} of {}'.format(k+1, 2)) + band = offset[k:length*2:2, :] + bandFilt = offsetFilt[k:length*2:2, :] + for i in range(0+edge, length-edge): + for j in range(0+edge, width-edge): + bandSub = band[i-edge:i+edge+1, j-edge:j+edge+1] + snrSub = snr[i-edge:i+edge+1, j-edge:j+edge+1] + #bandSubUsed is 1-d numpy array + bandSubUsed = bandSub[np.nonzero(np.logical_and(snrSub>snrThreshold, bandSub!=nullValue))] + if bandSubUsed.size == 0: + bandFilt[i, j] = nullValue + else: + bandFilt[i, j] = statistics.median(bandSubUsed) + + offsetFilt.astype(np.float32).tofile(self._insar.denseOffsetFilt) + outImg = isceobj.createImage() + outImg.setDataType('FLOAT') + outImg.setFilename(self._insar.denseOffsetFilt) + outImg.setBands(2) + outImg.scheme = 'BIL' + outImg.setWidth(width) + outImg.setLength(length) + outImg.addDescription('two-band pixel offset file. 1st band: range offset, 2nd band: azimuth offset') + outImg.setAccessMode('read') + outImg.renderHdr() + +######################################################################################### + + os.chdir('../') + catalog.printToLog(logger, "runFiltOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2Proc/runFormInterferogram.py b/components/isceobj/Alos2Proc/runFormInterferogram.py new file mode 100644 index 0000000..3c2b887 --- /dev/null +++ b/components/isceobj/Alos2Proc/runFormInterferogram.py @@ -0,0 +1,134 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +import stdproc +from iscesys.StdOEL.StdOELPy import create_writer +from isceobj.Alos2Proc.Alos2ProcPublic import readOffset +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + +logger = logging.getLogger('isce.alos2insar.runFormInterferogram') + +def runFormInterferogram(self): + '''form interferograms. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('forming interferogram frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + + ############################################# + #1. form interferogram + ############################################# + refinedOffsets = readOffset('cull.off') + intWidth = int(masterSwath.numberOfSamples / self._insar.numberRangeLooks1) + intLength = int(masterSwath.numberOfLines / self._insar.numberAzimuthLooks1) + dopplerVsPixel = [i/slaveSwath.prf for i in slaveSwath.dopplerVsPixel] + + #master slc + mSLC = isceobj.createSlcImage() + mSLC.load(self._insar.masterSlc+'.xml') + mSLC.setAccessMode('read') + mSLC.createImage() + + #slave slc + sSLC = isceobj.createSlcImage() + sSLC.load(self._insar.slaveSlc+'.xml') + sSLC.setAccessMode('read') + sSLC.createImage() + + #interferogram + interf = isceobj.createIntImage() + interf.setFilename(self._insar.interferogram) + interf.setWidth(intWidth) + interf.setAccessMode('write') + interf.createImage() + + #amplitdue + amplitude = isceobj.createAmpImage() + amplitude.setFilename(self._insar.amplitude) + amplitude.setWidth(intWidth) + amplitude.setAccessMode('write') + amplitude.createImage() + + #create a writer for resamp + stdWriter = create_writer("log", "", True, filename="resamp.log") + stdWriter.setFileTag("resamp", "log") + stdWriter.setFileTag("resamp", "err") + stdWriter.setFileTag("resamp", "out") + + + #set up resampling program now + #The setting has been compared with resamp_roi's setting in ROI_pac item by item. + #The two kinds of setting are exactly the same. The number of setting items are + #exactly the same + objResamp = stdproc.createResamp() + objResamp.wireInputPort(name='offsets', object=refinedOffsets) + objResamp.stdWriter = stdWriter + objResamp.setNumberFitCoefficients(6) + objResamp.setNumberRangeBin1(masterSwath.numberOfSamples) + objResamp.setNumberRangeBin2(slaveSwath.numberOfSamples) + objResamp.setStartLine(1) + objResamp.setNumberLines(masterSwath.numberOfLines) + objResamp.setFirstLineOffset(1) + objResamp.setDopplerCentroidCoefficients(dopplerVsPixel) + objResamp.setRadarWavelength(slaveTrack.radarWavelength) + objResamp.setSlantRangePixelSpacing(slaveSwath.rangePixelSize) + objResamp.setNumberRangeLooks(self._insar.numberRangeLooks1) + objResamp.setNumberAzimuthLooks(self._insar.numberAzimuthLooks1) + objResamp.setFlattenWithOffsetFitFlag(0) + objResamp.resamp(mSLC, sSLC, interf, amplitude) + + #finialize images + mSLC.finalizeImage() + sSLC.finalizeImage() + interf.finalizeImage() + amplitude.finalizeImage() + stdWriter.finalize() + + + ############################################# + #2. trim amplitude + ############################################# + # tmpAmplitude = 'tmp.amp' + # cmd = "imageMath.py -e='a_0*(a_1>0);a_1*(a_0>0)' --a={} -o={} -s BIP -t float".format( + # self._insar.amplitude, + # tmpAmplitude + # ) + # runCmd(cmd) + # os.remove(self._insar.amplitude) + # os.remove(tmpAmplitude+'.xml') + # os.remove(tmpAmplitude+'.vrt') + # os.rename(tmpAmplitude, self._insar.amplitude) + + #using memmap instead, which should be faster, since we only have a few pixels to change + amp=np.memmap(self._insar.amplitude, dtype='complex64', mode='r+', shape=(intLength, intWidth)) + index = np.nonzero( (np.real(amp)==0) + (np.imag(amp)==0) ) + amp[index]=0 + del amp + + os.chdir('../') + os.chdir('../') + + catalog.printToLog(logger, "runFormInterferogram") + self._insar.procDoc.addAllFromCatalog(catalog) diff --git a/components/isceobj/Alos2Proc/runFrameMosaic.py b/components/isceobj/Alos2Proc/runFrameMosaic.py new file mode 100644 index 0000000..4fa9871 --- /dev/null +++ b/components/isceobj/Alos2Proc/runFrameMosaic.py @@ -0,0 +1,552 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2insar.runFrameMosaic') + +def runFrameMosaic(self): + '''mosaic frames + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + mosaicDir = 'insar' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + numberOfFrames = len(masterTrack.frames) + if numberOfFrames == 1: + import shutil + frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.masterFrames[0])) + if not os.path.isfile(self._insar.interferogram): + os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + #shutil.copy2() can overwrite + shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + if not os.path.isfile(self._insar.amplitude): + os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + # os.rename(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + # os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # os.rename(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + # os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + #update track parameters + ######################################################### + #mosaic size + masterTrack.numberOfSamples = masterTrack.frames[0].numberOfSamples + masterTrack.numberOfLines = masterTrack.frames[0].numberOfLines + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + masterTrack.startingRange = masterTrack.frames[0].startingRange + masterTrack.rangeSamplingRate = masterTrack.frames[0].rangeSamplingRate + masterTrack.rangePixelSize = masterTrack.frames[0].rangePixelSize + #azimuth parameters + masterTrack.sensingStart = masterTrack.frames[0].sensingStart + masterTrack.prf = masterTrack.frames[0].prf + masterTrack.azimuthPixelSize = masterTrack.frames[0].azimuthPixelSize + masterTrack.azimuthLineInterval = masterTrack.frames[0].azimuthLineInterval + + #update track parameters, slave + ######################################################### + #mosaic size + slaveTrack.numberOfSamples = slaveTrack.frames[0].numberOfSamples + slaveTrack.numberOfLines = slaveTrack.frames[0].numberOfLines + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + slaveTrack.startingRange = slaveTrack.frames[0].startingRange + slaveTrack.rangeSamplingRate = slaveTrack.frames[0].rangeSamplingRate + slaveTrack.rangePixelSize = slaveTrack.frames[0].rangePixelSize + #azimuth parameters + slaveTrack.sensingStart = slaveTrack.frames[0].sensingStart + slaveTrack.prf = slaveTrack.frames[0].prf + slaveTrack.azimuthPixelSize = slaveTrack.frames[0].azimuthPixelSize + slaveTrack.azimuthLineInterval = slaveTrack.frames[0].azimuthLineInterval + + else: + #choose offsets + if self.frameOffsetMatching: + rangeOffsets = self._insar.frameRangeOffsetMatchingMaster + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster + else: + rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + inputInterferograms.append(os.path.join('../', frameDir, 'mosaic', self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', frameDir, 'mosaic', self._insar.amplitude)) + + #note that track parameters are updated after mosaicking + #mosaic amplitudes + frameMosaic(masterTrack, inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=False, resamplingMethod=0) + #mosaic interferograms + frameMosaic(masterTrack, inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=True, phaseCompensation=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'int') + + #update slave parameters here + #do not match for slave, always use geometrical + rangeOffsets = self._insar.frameRangeOffsetGeometricalSlave + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalSlave + frameMosaicParameters(slaveTrack, rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1) + + os.chdir('../') + #save parameter file + self._insar.saveProduct(masterTrack, self._insar.masterTrackParameter) + self._insar.saveProduct(slaveTrack, self._insar.slaveTrackParameter) + + catalog.printToLog(logger, "runFrameMosaic") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def frameMosaic(track, inputFiles, outputfile, rangeOffsets, azimuthOffsets, numberOfRangeLooks, numberOfAzimuthLooks, updateTrack=False, phaseCompensation=False, resamplingMethod=0): + ''' + mosaic frames + + track: track + inputFiles: input file list + output file: output mosaic file + rangeOffsets: range offsets + azimuthOffsets: azimuth offsets + numberOfRangeLooks: number of range looks of the input files + numberOfAzimuthLooks: number of azimuth looks of the input files + updateTrack: whether update track parameters + phaseCompensation: whether do phase compensation for each frame + resamplingMethod: 0: amp resampling. 1: int resampling. 2: slc resampling + ''' + import numpy as np + + from contrib.alos2proc_f.alos2proc_f import rect_with_looks + from contrib.alos2proc.alos2proc import resamp + from isceobj.Alos2Proc.runSwathMosaic import readImage + from isceobj.Alos2Proc.runSwathMosaic import findNonzero + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_file + from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_keyword + + numberOfFrames = len(track.frames) + frames = track.frames + + rectWidth = [] + rectLength = [] + for i in range(numberOfFrames): + infImg = isceobj.createImage() + infImg.load(inputFiles[i]+'.xml') + rectWidth.append(infImg.width) + rectLength.append(infImg.length) + + #convert original offset to offset for images with looks + #use list instead of np.array to make it consistent with the rest of the code + rangeOffsets1 = [i/numberOfRangeLooks for i in rangeOffsets] + azimuthOffsets1 = [i/numberOfAzimuthLooks for i in azimuthOffsets] + + #get offset relative to the first frame + rangeOffsets2 = [0.0] + azimuthOffsets2 = [0.0] + for i in range(1, numberOfFrames): + rangeOffsets2.append(0.0) + azimuthOffsets2.append(0.0) + for j in range(1, i+1): + rangeOffsets2[i] += rangeOffsets1[j] + azimuthOffsets2[i] += azimuthOffsets1[j] + + #resample each frame + rinfs = [] + for i, inf in enumerate(inputFiles): + rinfs.append("{}_{}{}".format(os.path.splitext(os.path.basename(inf))[0], i, os.path.splitext(os.path.basename(inf))[1])) + #do not resample first frame + if i == 0: + rinfs[i] = inf + else: + infImg = isceobj.createImage() + infImg.load(inf+'.xml') + rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i]) + azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i]) + + if resamplingMethod == 0: + rect_with_looks(inf, + rinfs[i], + infImg.width, infImg.length, + infImg.width, infImg.length, + 1.0, 0.0, + 0.0, 1.0, + rangeOffsets2Frac, azimuthOffsets2Frac, + 1,1, + 1,1, + 'COMPLEX', + 'Bilinear') + if infImg.getImageType() == 'amp': + create_xml(rinfs[i], infImg.width, infImg.length, 'amp') + else: + create_xml(rinfs[i], infImg.width, infImg.length, 'int') + + elif resamplingMethod == 1: + #decompose amplitude and phase + phaseFile = 'phase' + amplitudeFile = 'amplitude' + data = np.fromfile(inf, dtype=np.complex64).reshape(infImg.length, infImg.width) + phase = np.exp(np.complex64(1j) * np.angle(data)) + phase[np.nonzero(data==0)] = 0 + phase.astype(np.complex64).tofile(phaseFile) + amplitude = np.absolute(data) + amplitude.astype(np.float32).tofile(amplitudeFile) + + #resampling + phaseRectFile = 'phaseRect' + amplitudeRectFile = 'amplitudeRect' + rect_with_looks(phaseFile, + phaseRectFile, + infImg.width, infImg.length, + infImg.width, infImg.length, + 1.0, 0.0, + 0.0, 1.0, + rangeOffsets2Frac, azimuthOffsets2Frac, + 1,1, + 1,1, + 'COMPLEX', + 'Sinc') + rect_with_looks(amplitudeFile, + amplitudeRectFile, + infImg.width, infImg.length, + infImg.width, infImg.length, + 1.0, 0.0, + 0.0, 1.0, + rangeOffsets2Frac, azimuthOffsets2Frac, + 1,1, + 1,1, + 'REAL', + 'Bilinear') + + #recombine amplitude and phase + phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(infImg.length, infImg.width) + amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(infImg.length, infImg.width) + (phase*amplitude).astype(np.complex64).tofile(rinfs[i]) + + #tidy up + os.remove(phaseFile) + os.remove(amplitudeFile) + os.remove(phaseRectFile) + os.remove(amplitudeRectFile) + if infImg.getImageType() == 'amp': + create_xml(rinfs[i], infImg.width, infImg.length, 'amp') + else: + create_xml(rinfs[i], infImg.width, infImg.length, 'int') + else: + resamp(inf, + rinfs[i], + 'fake', + 'fake', + infImg.width, infImg.length, + frames[i].swaths[0].prf, + frames[i].swaths[0].dopplerVsPixel, + [rangeOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [azimuthOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) + create_xml(rinfs[i], infImg.width, infImg.length, 'slc') + + #determine output width and length + #actually no need to calculate in azimuth direction + xs = [] + xe = [] + ys = [] + ye = [] + for i in range(numberOfFrames): + if i == 0: + xs.append(0) + xe.append(rectWidth[i] - 1) + ys.append(0) + ye.append(rectLength[i] - 1) + else: + xs.append(0 - int(rangeOffsets2[i])) + xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i])) + ys.append(0 - int(azimuthOffsets2[i])) + ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i])) + + (xmin, xminIndex) = min((v,i) for i,v in enumerate(xs)) + (xmax, xmaxIndex) = max((v,i) for i,v in enumerate(xe)) + (ymin, yminIndex) = min((v,i) for i,v in enumerate(ys)) + (ymax, ymaxIndex) = max((v,i) for i,v in enumerate(ye)) + + outWidth = xmax - xmin + 1 + outLength = ymax - ymin + 1 + + + #prepare for mosaicing using numpy + xs = [x-xmin for x in xs] + xe = [x-xmin for x in xe] + ys = [y-ymin for y in ys] + ye = [y-ymin for y in ye] + + + #compute phase offset + if phaseCompensation: + phaseOffsetPolynomials = [np.array([0.0])] + for i in range(1, numberOfFrames): + upperframe = np.zeros((ye[i-1]-ys[i]+1, outWidth), dtype=np.complex128) + lowerframe = np.zeros((ye[i-1]-ys[i]+1, outWidth), dtype=np.complex128) + #upper frame + if os.path.isfile(rinfs[i-1]): + upperframe[:,xs[i-1]:xe[i-1]+1] = readImage(rinfs[i-1], rectWidth[i-1], rectLength[i-1], 0, rectWidth[i-1]-1, ys[i]-ys[i-1], ye[i-1]-ys[i-1]) + else: + upperframe[:,xs[i-1]:xe[i-1]+1] = readImageFromVrt(rinfs[i-1], 0, rectWidth[i-1]-1, ys[i]-ys[i-1], ye[i-1]-ys[i-1]) + #lower frame + if os.path.isfile(rinfs[i]): + lowerframe[:,xs[i]:xe[i]+1] = readImage(rinfs[i], rectWidth[i], rectLength[i], 0, rectWidth[i]-1, 0, ye[i-1]-ys[i]) + else: + lowerframe[:,xs[i]:xe[i]+1] = readImageFromVrt(rinfs[i], 0, rectWidth[i]-1, 0, ye[i-1]-ys[i]) + #get a polynomial + diff = np.sum(upperframe * np.conj(lowerframe), axis=0) + (firstLine, lastLine, firstSample, lastSample) = findNonzero(np.reshape(diff, (1, outWidth))) + #here i use mean value(deg=0) in case difference is around -pi or pi. + deg = 0 + p = np.polyfit(np.arange(firstSample, lastSample+1), np.angle(diff[firstSample:lastSample+1]), deg) + phaseOffsetPolynomials.append(p) + + + #check fit result + DEBUG = False + if DEBUG: + #create a dir and work in this dir + diffDir = 'frame_mosaic' + if not os.path.exists(diffDir): + os.makedirs(diffDir) + os.chdir(diffDir) + + #dump phase difference + diffFilename = 'phase_difference_frame{}-frame{}.int'.format(i, i+1) + (upperframe * np.conj(lowerframe)).astype(np.complex64).tofile(diffFilename) + create_xml(diffFilename, outWidth, ye[i-1]-ys[i]+1, 'int') + + #plot phase difference vs range + import matplotlib.pyplot as plt + x = np.arange(firstSample, lastSample+1) + y = np.angle(diff[firstSample:lastSample+1]) + plt.plot(x, y, label='original phase difference') + plt.plot(x, np.polyval(p, x), label='fitted phase difference') + plt.legend() + + plt.minorticks_on() + plt.tick_params('both', length=10, which='major') + plt.tick_params('both', length=5, which='minor') + + plt.xlabel('Range Sample Number [Samples]') + plt.ylabel('Phase Difference [Rad]') + plt.savefig('phase_difference_frame{}-frame{}.pdf'.format(i, i+1)) + + os.chdir('../') + + + #mosaic file + outFp = open(outputfile,'wb') + for i in range(numberOfFrames): + print('adding frame: {}'.format(i+1)) + + #phase offset in the polynomials + if phaseCompensation: + cJ = np.complex64(1j) + phaseOffset = np.ones(outWidth, dtype=np.complex64) + for j in range(i+1): + phaseOffset *= np.exp(cJ*np.polyval(phaseOffsetPolynomials[j], np.arange(outWidth))) + + #get start line number (starts with zero) + if i == 0: + ys1 = 0 + else: + ys1 = int((ye[i-1]+ys[i])/2.0) + 1 - ys[i] + #get end line number (start with zero) + if i == numberOfFrames-1: + ye1 = rectLength[i] - 1 + else: + ye1 = int((ye[i]+ys[i+1])/2.0) - ys[i] + + #get image format + inputimage = find_vrt_file(rinfs[i]+'.vrt', 'SourceFilename', relative_path=True) + byteorder = find_vrt_keyword(rinfs[i]+'.vrt', 'ByteOrder') + if byteorder == 'LSB': + swapByte = False + else: + swapByte = True + imageoffset = int(find_vrt_keyword(rinfs[i]+'.vrt', 'ImageOffset')) + lineoffset = int(find_vrt_keyword(rinfs[i]+'.vrt', 'LineOffset')) + + #read image + with open(inputimage,'rb') as fp: + for j in range(ys1, ye1+1): + fp.seek(imageoffset+j*lineoffset, 0) + data = np.zeros(outWidth, dtype=np.complex64) + if swapByte: + tmp = np.fromfile(fp, dtype='>f', count=2*rectWidth[i]) + cJ = np.complex64(1j) + data[xs[i]:xe[i]+1] = tmp[0::2] + cJ * tmp[1::2] + else: + data[xs[i]:xe[i]+1] = np.fromfile(fp, dtype=np.complex64, count=rectWidth[i]) + if phaseCompensation: + data *= phaseOffset + data.astype(np.complex64).tofile(outFp) + outFp.close() + + + #delete files. DO NOT DELETE THE FIRST ONE!!! + for i in range(numberOfFrames): + if i == 0: + continue + os.remove(rinfs[i]) + os.remove(rinfs[i]+'.vrt') + os.remove(rinfs[i]+'.xml') + + + #update frame parameters + if updateTrack: + #mosaic size + track.numberOfSamples = outWidth + track.numberOfLines = outLength + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + track.startingRange = frames[0].startingRange + (int(rangeOffsets2[0]) - int(rangeOffsets2[xminIndex])) * numberOfRangeLooks * frames[0].rangePixelSize + track.rangeSamplingRate = frames[0].rangeSamplingRate + track.rangePixelSize = frames[0].rangePixelSize + #azimuth parameters + track.sensingStart = frames[0].sensingStart + track.prf = frames[0].prf + track.azimuthPixelSize = frames[0].azimuthPixelSize + track.azimuthLineInterval = frames[0].azimuthLineInterval + + +def frameMosaicParameters(track, rangeOffsets, azimuthOffsets, numberOfRangeLooks, numberOfAzimuthLooks): + ''' + mosaic frames (this simplified version of frameMosaic to only update parameters) + + track: track + rangeOffsets: range offsets + azimuthOffsets: azimuth offsets + numberOfRangeLooks: number of range looks of the input files + numberOfAzimuthLooks: number of azimuth looks of the input files + ''' + + numberOfFrames = len(track.frames) + frames = track.frames + + rectWidth = [] + rectLength = [] + for i in range(numberOfFrames): + rectWidth.append(frames[i].numberOfSamples) + rectLength.append(frames[i].numberOfLines) + + #convert original offset to offset for images with looks + #use list instead of np.array to make it consistent with the rest of the code + rangeOffsets1 = [i/numberOfRangeLooks for i in rangeOffsets] + azimuthOffsets1 = [i/numberOfAzimuthLooks for i in azimuthOffsets] + + #get offset relative to the first frame + rangeOffsets2 = [0.0] + azimuthOffsets2 = [0.0] + for i in range(1, numberOfFrames): + rangeOffsets2.append(0.0) + azimuthOffsets2.append(0.0) + for j in range(1, i+1): + rangeOffsets2[i] += rangeOffsets1[j] + azimuthOffsets2[i] += azimuthOffsets1[j] + + #determine output width and length + #actually no need to calculate in azimuth direction + xs = [] + xe = [] + ys = [] + ye = [] + for i in range(numberOfFrames): + if i == 0: + xs.append(0) + xe.append(rectWidth[i] - 1) + ys.append(0) + ye.append(rectLength[i] - 1) + else: + xs.append(0 - int(rangeOffsets2[i])) + xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i])) + ys.append(0 - int(azimuthOffsets2[i])) + ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i])) + + (xmin, xminIndex) = min((v,i) for i,v in enumerate(xs)) + (xmax, xmaxIndex) = max((v,i) for i,v in enumerate(xe)) + (ymin, yminIndex) = min((v,i) for i,v in enumerate(ys)) + (ymax, ymaxIndex) = max((v,i) for i,v in enumerate(ye)) + + outWidth = xmax - xmin + 1 + outLength = ymax - ymin + 1 + + #update frame parameters + #mosaic size + track.numberOfSamples = outWidth + track.numberOfLines = outLength + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + track.startingRange = frames[0].startingRange + (int(rangeOffsets2[0]) - int(rangeOffsets2[xminIndex])) * numberOfRangeLooks * frames[0].rangePixelSize + track.rangeSamplingRate = frames[0].rangeSamplingRate + track.rangePixelSize = frames[0].rangePixelSize + #azimuth parameters + track.sensingStart = frames[0].sensingStart + track.prf = frames[0].prf + track.azimuthPixelSize = frames[0].azimuthPixelSize + track.azimuthLineInterval = frames[0].azimuthLineInterval + + +def readImageFromVrt(inputfile, startSample, endSample, startLine, endLine): + ''' + read a chunk of image + the indexes (startSample, endSample, startLine, endLine) are included and start with zero + + memmap is not used, because it is much slower + + tested against readImage in runSwathMosaic.py + ''' + import os + from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_keyword + from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_file + + inputimage = find_vrt_file(inputfile+'.vrt', 'SourceFilename', relative_path=True) + byteorder = find_vrt_keyword(inputfile+'.vrt', 'ByteOrder') + if byteorder == 'LSB': + swapByte = False + else: + swapByte = True + imageoffset = int(find_vrt_keyword(inputfile+'.vrt', 'ImageOffset')) + lineoffset = int(find_vrt_keyword(inputfile+'.vrt', 'LineOffset')) + + data = np.zeros((endLine-startLine+1, endSample-startSample+1), dtype=np.complex64) + with open(inputimage,'rb') as fp: + #fp.seek(imageoffset, 0) + #for i in range(endLine-startLine+1): + for i in range(startLine, endLine+1): + fp.seek(imageoffset+i*lineoffset+startSample*8, 0) + if swapByte: + tmp = np.fromfile(fp, dtype='>f', count=2*(endSample-startSample+1)) + cJ = np.complex64(1j) + data[i-startLine] = tmp[0::2] + cJ * tmp[1::2] + else: + data[i-startLine] = np.fromfile(fp, dtype=np.complex64, count=endSample-startSample+1) + return data diff --git a/components/isceobj/Alos2Proc/runFrameOffset.py b/components/isceobj/Alos2Proc/runFrameOffset.py new file mode 100644 index 0000000..89305d8 --- /dev/null +++ b/components/isceobj/Alos2Proc/runFrameOffset.py @@ -0,0 +1,287 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj + +logger = logging.getLogger('isce.alos2insar.runFrameOffset') + +def runFrameOffset(self): + '''estimate frame offsets. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + mosaicDir = 'insar' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if len(masterTrack.frames) > 1: + if (self._insar.modeCombination == 21) or \ + (self._insar.modeCombination == 22) or \ + (self._insar.modeCombination == 31) or \ + (self._insar.modeCombination == 32): + matchingMode=0 + else: + matchingMode=1 + + #compute swath offset + offsetMaster = frameOffset(masterTrack, self._insar.masterSlc, self._insar.masterFrameOffset, + crossCorrelation=self.frameOffsetMatching, matchingMode=matchingMode) + #only use geometrical offset for slave + offsetSlave = frameOffset(slaveTrack, self._insar.slaveSlc, self._insar.slaveFrameOffset, + crossCorrelation=False, matchingMode=matchingMode) + + self._insar.frameRangeOffsetGeometricalMaster = offsetMaster[0] + self._insar.frameAzimuthOffsetGeometricalMaster = offsetMaster[1] + self._insar.frameRangeOffsetGeometricalSlave = offsetSlave[0] + self._insar.frameAzimuthOffsetGeometricalSlave = offsetSlave[1] + if self.frameOffsetMatching: + self._insar.frameRangeOffsetMatchingMaster = offsetMaster[2] + self._insar.frameAzimuthOffsetMatchingMaster = offsetMaster[3] + #self._insar.frameRangeOffsetMatchingSlave = offsetSlave[2] + #self._insar.frameAzimuthOffsetMatchingSlave = offsetSlave[3] + + + os.chdir('../') + + catalog.printToLog(logger, "runFrameOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def frameOffset(track, image, outputfile, crossCorrelation=True, matchingMode=0): + ''' + compute frame offset + track: track object + image: image for doing matching + outputfile: output txt file for saving frame offset + crossCorrelation: whether do matching + matchingMode: how to match images. 0: ScanSAR full-aperture image, 1: regular image + ''' + + rangeOffsetGeometrical = [] + azimuthOffsetGeometrical = [] + rangeOffsetMatching = [] + azimuthOffsetMatching = [] + + for j in range(len(track.frames)): + frameNumber = track.frames[j].frameNumber + swathNumber = track.frames[j].swaths[0].swathNumber + swathDir = 'f{}_{}/s{}'.format(j+1, frameNumber, swathNumber) + + print('estimate offset frame {}'.format(frameNumber)) + + if j == 0: + rangeOffsetGeometrical.append(0.0) + azimuthOffsetGeometrical.append(0.0) + rangeOffsetMatching.append(0.0) + azimuthOffsetMatching.append(0.0) + swathDirLast = swathDir + continue + + image1 = os.path.join('../', swathDirLast, image) + image2 = os.path.join('../', swathDir, image) + #swath1 = frame.swaths[j-1] + #swath2 = frame.swaths[j] + swath1 = track.frames[j-1].swaths[0] + swath2 = track.frames[j].swaths[0] + + + #offset from geometry + offsetGeometrical = computeFrameOffset(swath1, swath2) + rangeOffsetGeometrical.append(offsetGeometrical[0]) + azimuthOffsetGeometrical.append(offsetGeometrical[1]) + + #offset from cross-correlation + if crossCorrelation: + offsetMatching = estimateFrameOffset(swath1, swath2, image1, image2, matchingMode=matchingMode) + if offsetMatching != None: + rangeOffsetMatching.append(offsetMatching[0]) + azimuthOffsetMatching.append(offsetMatching[1]) + else: + print('******************************************************************') + print('WARNING: bad matching offset, we are forced to use') + print(' geometrical offset for frame mosaicking') + print('******************************************************************') + rangeOffsetMatching.append(offsetGeometrical[0]) + azimuthOffsetMatching.append(offsetGeometrical[1]) + + swathDirLast = swathDir + + + if crossCorrelation: + offsetComp = "\n\ncomparision of offsets:\n\n" + offsetComp += "offset type i geometrical match difference\n" + offsetComp += "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + for i, (offset1, offset2) in enumerate(zip(rangeOffsetGeometrical, rangeOffsetMatching)): + offsetComp += "range offset {:2d} {:13.3f} {:13.3f} {:13.3f}\n".format(i, offset1, offset2, offset1 - offset2) + for i, (offset1, offset2) in enumerate(zip(azimuthOffsetGeometrical, azimuthOffsetMatching)): + offsetComp += "azimuth offset {:2d} {:13.3f} {:13.3f} {:13.3f}\n".format(i, offset1, offset2, offset1 - offset2) + + #write and report offsets + with open(outputfile, 'w') as f: + f.write(offsetComp) + print("{}".format(offsetComp)) + + + if crossCorrelation: + return (rangeOffsetGeometrical, azimuthOffsetGeometrical, rangeOffsetMatching, azimuthOffsetMatching) + else: + return (rangeOffsetGeometrical, azimuthOffsetGeometrical) + + +def computeFrameOffset(swath1, swath2): + + rangeOffset = -(swath2.startingRange - swath1.startingRange) / swath1.rangePixelSize + azimuthOffset = -((swath2.sensingStart - swath1.sensingStart).total_seconds()) / swath1.azimuthLineInterval + + return (rangeOffset, azimuthOffset) + + +def estimateFrameOffset(swath1, swath2, image1, image2, matchingMode=0): + ''' + estimate offset of two adjacent frames using matching + matchingMode: 0: ScanSAR full-aperture image + 1: regular image + ''' + import isceobj + from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsets + from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsetsRoipac + from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset + from mroipac.ampcor.Ampcor import Ampcor + + ########################################## + #2. match using ampcor + ########################################## + ampcor = Ampcor(name='insarapp_slcs_ampcor') + ampcor.configure() + + #mSLC = isceobj.createSlcImage() + mSLC = isceobj.createImage() + mSLC.load(image1+'.xml') + mSLC.setFilename(image1) + #mSLC.extraFilename = image1 + '.vrt' + mSLC.setAccessMode('read') + mSLC.createImage() + + #sSLC = isceobj.createSlcImage() + sSLC = isceobj.createImage() + sSLC.load(image2+'.xml') + sSLC.setFilename(image2) + #sSLC.extraFilename = image2 + '.vrt' + sSLC.setAccessMode('read') + sSLC.createImage() + + if mSLC.dataType.upper() == 'CFLOAT': + ampcor.setImageDataType1('complex') + ampcor.setImageDataType2('complex') + elif mSLC.dataType.upper() == 'FLOAT': + ampcor.setImageDataType1('real') + ampcor.setImageDataType2('real') + else: + raise Exception('file type not supported yet.') + + ampcor.setMasterSlcImage(mSLC) + ampcor.setSlaveSlcImage(sSLC) + + #MATCH REGION + #compute an offset at image center to use + rgoff = -(swath2.startingRange - swath1.startingRange) / swath1.rangePixelSize + azoff = -((swath2.sensingStart - swath1.sensingStart).total_seconds()) / swath1.azimuthLineInterval + rgoff = int(rgoff) + azoff = int(azoff) + #it seems that we cannot use 0, haven't look into the problem + if rgoff == 0: + rgoff = 1 + if azoff == 0: + azoff = 1 + firstSample = 1 + if rgoff < 0: + firstSample = int(35 - rgoff) + firstLine = 1 + if azoff < 0: + firstLine = int(35 - azoff) + ampcor.setAcrossGrossOffset(rgoff) + ampcor.setDownGrossOffset(azoff) + ampcor.setFirstSampleAcross(firstSample) + ampcor.setLastSampleAcross(mSLC.width) + ampcor.setNumberLocationAcross(30) + ampcor.setFirstSampleDown(firstLine) + ampcor.setLastSampleDown(mSLC.length) + ampcor.setNumberLocationDown(10) + + #MATCH PARAMETERS + #full-aperture mode + if matchingMode==0: + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(512) + #note this is the half width/length of search area, number of resulting correlation samples: 32*2+1 + ampcor.setSearchWindowSizeWidth(32) + ampcor.setSearchWindowSizeHeight(32) + #triggering full-aperture mode matching + ampcor.setWinsizeFilt(8) + ampcor.setOversamplingFactorFilt(64) + #regular mode + else: + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(64) + ampcor.setSearchWindowSizeWidth(32) + ampcor.setSearchWindowSizeHeight(32) + + #REST OF THE STUFF + ampcor.setAcrossLooks(1) + ampcor.setDownLooks(1) + ampcor.setOversamplingFactor(64) + ampcor.setZoomWindowSize(16) + #1. The following not set + #Matching Scale for Sample/Line Directions (-) = 1. 1. + #should add the following in Ampcor.py? + #if not set, in this case, Ampcor.py'value is also 1. 1. + #ampcor.setScaleFactorX(1.) + #ampcor.setScaleFactorY(1.) + + #MATCH THRESHOLDS AND DEBUG DATA + #2. The following not set + #in roi_pac the value is set to 0 1 + #in isce the value is set to 0.001 1000.0 + #SNR and Covariance Thresholds (-) = {s1} {s2} + #should add the following in Ampcor? + #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC + #ampcor.setThresholdSNR(0) + #ampcor.setThresholdCov(1) + ampcor.setDebugFlag(False) + ampcor.setDisplayFlag(False) + + #in summary, only two things not set which are indicated by 'The following not set' above. + + #run ampcor + ampcor.ampcor() + offsets = ampcor.getOffsetField() + #ampcorOffsetFile = 'ampcor.off' + #writeOffset(offsets, ampcorOffsetFile) + + #finalize image, and re-create it + #otherwise the file pointer is still at the end of the image + mSLC.finalizeImage() + sSLC.finalizeImage() + + + ############################################# + #3. cull offsets + ############################################# + #refinedOffsets = cullOffsets(offsets) + refinedOffsets = cullOffsetsRoipac(offsets, numThreshold=50) + + if refinedOffsets != None: + rangeOffset, azimuthOffset = meanOffset(refinedOffsets) + return (rangeOffset, azimuthOffset) + else: + return None diff --git a/components/isceobj/Alos2Proc/runGeo2Rdr.py b/components/isceobj/Alos2Proc/runGeo2Rdr.py new file mode 100644 index 0000000..2197261 --- /dev/null +++ b/components/isceobj/Alos2Proc/runGeo2Rdr.py @@ -0,0 +1,190 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj + +logger = logging.getLogger('isce.alos2insar.runGeo2Rdr') + +def runGeo2Rdr(self): + '''compute range and azimuth offsets + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + slaveTrack = self._insar.loadTrack(master=False) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + hasGPU= self.useGPU and self._insar.hasGPU() + if hasGPU: + geo2RdrGPU(slaveTrack, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.rangeOffset, self._insar.azimuthOffset) + else: + geo2RdrCPU(slaveTrack, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.rangeOffset, self._insar.azimuthOffset) + + os.chdir('../') + + catalog.printToLog(logger, "runGeo2Rdr") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def geo2RdrCPU(slaveTrack, numberRangeLooks, numberAzimuthLooks, latFile, lonFile, hgtFile, rangeOffsetFile, azimuthOffsetFile): + import datetime + from zerodop.geo2rdr import createGeo2rdr + from isceobj.Planet.Planet import Planet + + pointingDirection = {'right': -1, 'left' :1} + + latImage = isceobj.createImage() + latImage.load(latFile + '.xml') + latImage.setAccessMode('read') + + lonImage = isceobj.createImage() + lonImage.load(lonFile + '.xml') + lonImage.setAccessMode('read') + + demImage = isceobj.createDemImage() + demImage.load(hgtFile + '.xml') + demImage.setAccessMode('read') + + planet = Planet(pname='Earth') + + topo = createGeo2rdr() + topo.configure() + #set parameters + topo.slantRangePixelSpacing = numberRangeLooks * slaveTrack.rangePixelSize + topo.prf = 1.0 / (numberAzimuthLooks*slaveTrack.azimuthLineInterval) + topo.radarWavelength = slaveTrack.radarWavelength + topo.orbit = slaveTrack.orbit + topo.width = slaveTrack.numberOfSamples + topo.length = slaveTrack.numberOfLines + topo.demLength = demImage.length + topo.demWidth = demImage.width + topo.wireInputPort(name='planet', object=planet) + topo.numberRangeLooks = 1 # + topo.numberAzimuthLooks = 1 # must be set to be 1 + topo.lookSide = pointingDirection[slaveTrack.pointingDirection] + topo.setSensingStart(slaveTrack.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*slaveTrack.azimuthLineInterval)) + topo.rangeFirstSample = slaveTrack.startingRange + (numberRangeLooks-1.0)/2.0*slaveTrack.rangePixelSize + topo.dopplerCentroidCoeffs = [0.] # we are using zero doppler geometry + #set files + topo.latImage = latImage + topo.lonImage = lonImage + topo.demImage = demImage + topo.rangeOffsetImageName = rangeOffsetFile + topo.azimuthOffsetImageName = azimuthOffsetFile + #run it + topo.geo2rdr() + + return + + +def geo2RdrGPU(slaveTrack, numberRangeLooks, numberAzimuthLooks, latFile, lonFile, hgtFile, rangeOffsetFile, azimuthOffsetFile): + ''' + currently we cannot set left/right looking. + works for right looking, but left looking probably not supported. + ''' + + import datetime + from zerodop.GPUgeo2rdr.GPUgeo2rdr import PyGeo2rdr + from isceobj.Planet.Planet import Planet + from iscesys import DateTimeUtil as DTU + + latImage = isceobj.createImage() + latImage.load(latFile + '.xml') + latImage.setAccessMode('READ') + latImage.createImage() + + lonImage = isceobj.createImage() + lonImage.load(lonFile + '.xml') + lonImage.setAccessMode('READ') + lonImage.createImage() + + demImage = isceobj.createImage() + demImage.load(hgtFile + '.xml') + demImage.setAccessMode('READ') + demImage.createImage() + + #####Run Geo2rdr + planet = Planet(pname='Earth') + grdr = PyGeo2rdr() + + grdr.setRangePixelSpacing(numberRangeLooks * slaveTrack.rangePixelSize) + grdr.setPRF(1.0 / (numberAzimuthLooks*slaveTrack.azimuthLineInterval)) + grdr.setRadarWavelength(slaveTrack.radarWavelength) + + #CHECK IF THIS WORKS!!! + grdr.createOrbit(0, len(slaveTrack.orbit.stateVectors.list)) + count = 0 + for sv in slaveTrack.orbit.stateVectors.list: + td = DTU.seconds_since_midnight(sv.getTime()) + pos = sv.getPosition() + vel = sv.getVelocity() + + grdr.setOrbitVector(count, td, pos[0], pos[1], pos[2], vel[0], vel[1], vel[2]) + count += 1 + + grdr.setOrbitMethod(0) + grdr.setWidth(slaveTrack.numberOfSamples) + grdr.setLength(slaveTrack.numberOfLines) + grdr.setSensingStart(DTU.seconds_since_midnight(slaveTrack.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*slaveTrack.azimuthLineInterval))) + grdr.setRangeFirstSample(slaveTrack.startingRange + (numberRangeLooks-1.0)/2.0*slaveTrack.rangePixelSize) + grdr.setNumberRangeLooks(1) + grdr.setNumberAzimuthLooks(1) + grdr.setEllipsoidMajorSemiAxis(planet.ellipsoid.a) + grdr.setEllipsoidEccentricitySquared(planet.ellipsoid.e2) + + + grdr.createPoly(0, 0., 1.) + grdr.setPolyCoeff(0, 0.) + + grdr.setDemLength(demImage.getLength()) + grdr.setDemWidth(demImage.getWidth()) + grdr.setBistaticFlag(0) + + rangeOffsetImage = isceobj.createImage() + rangeOffsetImage.setFilename(rangeOffsetFile) + rangeOffsetImage.setAccessMode('write') + rangeOffsetImage.setDataType('FLOAT') + rangeOffsetImage.setCaster('write', 'DOUBLE') + rangeOffsetImage.setWidth(demImage.width) + rangeOffsetImage.createImage() + + azimuthOffsetImage = isceobj.createImage() + azimuthOffsetImage.setFilename(azimuthOffsetFile) + azimuthOffsetImage.setAccessMode('write') + azimuthOffsetImage.setDataType('FLOAT') + azimuthOffsetImage.setCaster('write', 'DOUBLE') + azimuthOffsetImage.setWidth(demImage.width) + azimuthOffsetImage.createImage() + + grdr.setLatAccessor(latImage.getImagePointer()) + grdr.setLonAccessor(lonImage.getImagePointer()) + grdr.setHgtAccessor(demImage.getImagePointer()) + grdr.setAzAccessor(0) + grdr.setRgAccessor(0) + grdr.setAzOffAccessor(azimuthOffsetImage.getImagePointer()) + grdr.setRgOffAccessor(rangeOffsetImage.getImagePointer()) + + grdr.geo2rdr() + + rangeOffsetImage.finalizeImage() + rangeOffsetImage.renderHdr() + + azimuthOffsetImage.finalizeImage() + azimuthOffsetImage.renderHdr() + latImage.finalizeImage() + lonImage.finalizeImage() + demImage.finalizeImage() + + return diff --git a/components/isceobj/Alos2Proc/runGeocode.py b/components/isceobj/Alos2Proc/runGeocode.py new file mode 100644 index 0000000..bf1e582 --- /dev/null +++ b/components/isceobj/Alos2Proc/runGeocode.py @@ -0,0 +1,124 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo + +logger = logging.getLogger('isce.alos2insar.runGeocode') + +def runGeocode(self): + '''geocode final products + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + demFile = os.path.abspath(self._insar.demGeo) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + #compute bounding box for geocoding + if self.bbox == None: + bbox = getBboxGeo(masterTrack) + else: + bbox = self.bbox + catalog.addItem('geocode bounding box', bbox, 'runGeocode') + + if self.geocodeList == None: + geocodeList = [self._insar.unwrappedInterferogram, + self._insar.unwrappedMaskedInterferogram, + self._insar.multilookCoherence, + self._insar.multilookLos] + if self.doIon: + geocodeList.append(self._insar.multilookIon) + else: + geocodeList = self.geocodeList + + numberRangeLooks = self._insar.numberRangeLooks1 * self._insar.numberRangeLooks2 + numberAzimuthLooks = self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooks2 + + for inputFile in geocodeList: + if self.geocodeInterpMethod == None: + img = isceobj.createImage() + img.load(inputFile + '.xml') + if img.dataType.upper() == 'CFLOAT': + interpMethod = 'sinc' + else: + interpMethod = 'bilinear' + else: + interpMethod = self.geocodeInterpMethod.lower() + + geocode(masterTrack, demFile, inputFile, bbox, numberRangeLooks, numberAzimuthLooks, interpMethod, 0, 0) + + + os.chdir('../') + + catalog.printToLog(logger, "runGeocode") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def geocode(track, demFile, inputFile, bbox, numberRangeLooks, numberAzimuthLooks, interpMethod, topShift, leftShift, addMultilookOffset=True): + import datetime + from zerodop.geozero import createGeozero + from isceobj.Planet.Planet import Planet + + pointingDirection = {'right': -1, 'left' :1} + + demImage = isceobj.createDemImage() + demImage.load(demFile + '.xml') + demImage.setAccessMode('read') + + inImage = isceobj.createImage() + inImage.load(inputFile + '.xml') + inImage.setAccessMode('read') + + planet = Planet(pname='Earth') + + topo = createGeozero() + topo.configure() + topo.slantRangePixelSpacing = numberRangeLooks * track.rangePixelSize + topo.prf = 1.0 / (numberAzimuthLooks*track.azimuthLineInterval) + topo.radarWavelength = track.radarWavelength + topo.orbit = track.orbit + topo.width = inImage.width + topo.length = inImage.length + topo.wireInputPort(name='dem', object=demImage) + topo.wireInputPort(name='planet', object=planet) + topo.wireInputPort(name='tobegeocoded', object=inImage) + topo.numberRangeLooks = 1 + topo.numberAzimuthLooks = 1 + topo.lookSide = pointingDirection[track.pointingDirection] + sensingStart = track.sensingStart + datetime.timedelta(seconds=topShift*track.azimuthLineInterval) + rangeFirstSample = track.startingRange + leftShift * track.rangePixelSize + if addMultilookOffset: + sensingStart += datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*track.azimuthLineInterval) + rangeFirstSample += (numberRangeLooks-1.0)/2.0*track.rangePixelSize + topo.setSensingStart(sensingStart) + topo.rangeFirstSample = rangeFirstSample + topo.method=interpMethod + topo.demCropFilename = 'crop.dem' + #looks like this does not work + #topo.geoFilename = outputName + topo.dopplerCentroidCoeffs = [0.] + #snwe list + topo.snwe = bbox + + topo.geocode() + + print('South: ', topo.minimumGeoLatitude) + print('North: ', topo.maximumGeoLatitude) + print('West: ', topo.minimumGeoLongitude) + print('East: ', topo.maximumGeoLongitude) + + return diff --git a/components/isceobj/Alos2Proc/runGeocodeOffset.py b/components/isceobj/Alos2Proc/runGeocodeOffset.py new file mode 100644 index 0000000..692d5a0 --- /dev/null +++ b/components/isceobj/Alos2Proc/runGeocodeOffset.py @@ -0,0 +1,64 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.runGeocode import geocode +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo + +logger = logging.getLogger('isce.alos2insar.runGeocodeOffset') + +def runGeocodeOffset(self): + '''geocode offset fied + ''' + if not self.doDenseOffset: + return + if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)): + return + + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + #use original track object to determine bbox + if self.bbox == None: + masterTrack = self._insar.loadTrack(master=True) + bbox = getBboxGeo(masterTrack) + else: + bbox = self.bbox + catalog.addItem('geocode bounding box', bbox, 'runGeocodeOffset') + + demFile = os.path.abspath(self._insar.demGeo) + + denseOffsetDir = 'dense_offset' + if not os.path.exists(denseOffsetDir): + os.makedirs(denseOffsetDir) + os.chdir(denseOffsetDir) + + masterTrack = self._insar.loadProduct(self._insar.masterTrackParameter) + #slaveTrack = self._insar.loadProduct(self._insar.slaveTrackParameter) + +######################################################################################### + #compute bounding box for geocoding + #if self.bbox == None: + # bbox = getBboxGeo(masterTrack) + #else: + # bbox = self.bbox + #catalog.addItem('geocode bounding box', bbox, 'runGeocodeOffset') + + geocodeList = [self._insar.denseOffset, self._insar.denseOffsetSnr] + if self.doOffsetFiltering: + geocodeList.append(self._insar.denseOffsetFilt) + + for inputFile in geocodeList: + interpMethod = 'nearest' + geocode(masterTrack, demFile, inputFile, bbox, self.offsetSkipWidth, self.offsetSkipHeight, interpMethod, self._insar.offsetImageTopoffset, self._insar.offsetImageLeftoffset, addMultilookOffset=False) +######################################################################################### + + os.chdir('../') + catalog.printToLog(logger, "runGeocodeOffset") + self._insar.procDoc.addAllFromCatalog(catalog) diff --git a/components/isceobj/Alos2Proc/runIonFilt.py b/components/isceobj/Alos2Proc/runIonFilt.py new file mode 100644 index 0000000..50ac3f6 --- /dev/null +++ b/components/isceobj/Alos2Proc/runIonFilt.py @@ -0,0 +1,599 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np +import numpy.matlib + +import isceobj + +logger = logging.getLogger('isce.alos2insar.runIonFilt') + +def runIonFilt(self): + '''compute and filter ionospheric phase + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + if not self.doIon: + catalog.printToLog(logger, "runIonFilt") + self._insar.procDoc.addAllFromCatalog(catalog) + return + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + from isceobj.Alos2Proc.runIonSubband import defineIonDir + ionDir = defineIonDir() + subbandPrefix = ['lower', 'upper'] + + ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal']) + if not os.path.exists(ionCalDir): + os.makedirs(ionCalDir) + os.chdir(ionCalDir) + + + ############################################################ + # STEP 1. compute ionospheric phase + ############################################################ + from isceobj.Constants import SPEED_OF_LIGHT + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + ################################### + #SET PARAMETERS HERE + #THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self) + corThresholdAdj = 0.85 + ################################### + + print('\ncomputing ionosphere') + #get files + ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, + self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon) + + lowerUnwfile = subbandPrefix[0]+ml2+'.unw' + upperUnwfile = subbandPrefix[1]+ml2+'.unw' + corfile = 'diff'+ml2+'.cor' + + #use image size from lower unwrapped interferogram + img = isceobj.createImage() + img.load(lowerUnwfile + '.xml') + width = img.width + length = img.length + + lowerUnw = (np.fromfile(lowerUnwfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] + upperUnw = (np.fromfile(upperUnwfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] + cor = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] + #amp = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[0:length*2:2, :] + + #masked out user-specified areas + if self.maskedAreasIon != None: + maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width) + for area in maskedAreas: + lowerUnw[area[0]:area[1], area[2]:area[3]] = 0 + upperUnw[area[0]:area[1], area[2]:area[3]] = 0 + cor[area[0]:area[1], area[2]:area[3]] = 0 + + #compute ionosphere + fl = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[0] + fu = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[1] + adjFlag = 1 + ionos = computeIonosphere(lowerUnw, upperUnw, cor, fl, fu, adjFlag, corThresholdAdj, 0) + + #dump ionosphere + ionfile = 'ion'+ml2+'.ion' + # ion = np.zeros((length*2, width), dtype=np.float32) + # ion[0:length*2:2, :] = amp + # ion[1:length*2:2, :] = ionos + # ion.astype(np.float32).tofile(ionfile) + # img.filename = ionfile + # img.extraFilename = ionfile + '.vrt' + # img.renderHdr() + + ionos.astype(np.float32).tofile(ionfile) + create_xml(ionfile, width, length, 'float') + + + ############################################################ + # STEP 2. filter ionospheric phase + ############################################################ + + ################################################# + #SET PARAMETERS HERE + #if applying polynomial fitting + #False: no fitting, True: with fitting + fit = self.fitIon + #gaussian filtering window size + size_max = self.filteringWinsizeMaxIon + size_min = self.filteringWinsizeMinIon + + #THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self) + corThresholdIon = 0.85 + ################################################# + + print('\nfiltering ionosphere') + ionfile = 'ion'+ml2+'.ion' + corfile = 'diff'+ml2+'.cor' + ionfiltfile = 'filt_ion'+ml2+'.ion' + + img = isceobj.createImage() + img.load(ionfile + '.xml') + width = img.width + length = img.length + #ion = (np.fromfile(ionfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] + ion = np.fromfile(ionfile, dtype=np.float32).reshape(length, width) + cor = (np.fromfile(corfile, dtype=np.float32).reshape(length*2, width))[1:length*2:2, :] + #amp = (np.fromfile(ionfile, dtype=np.float32).reshape(length*2, width))[0:length*2:2, :] + + #masked out user-specified areas + if self.maskedAreasIon != None: + maskedAreas = reformatMaskedAreas(self.maskedAreasIon, length, width) + for area in maskedAreas: + ion[area[0]:area[1], area[2]:area[3]] = 0 + cor[area[0]:area[1], area[2]:area[3]] = 0 + + #remove possible wired values in coherence + cor[np.nonzero(cor<0)] = 0.0 + cor[np.nonzero(cor>1)] = 0.0 + + # #applying water body mask here + # waterBodyFile = 'wbd'+ml2+'.wbd' + # if os.path.isfile(waterBodyFile): + # print('applying water body mask to coherence used to compute ionospheric phase') + # wbd = np.fromfile(waterBodyFile, dtype=np.int8).reshape(length, width) + # cor[np.nonzero(wbd!=0)] = 0.00001 + + if fit: + ion_fit = weight_fitting(ion, cor, width, length, 1, 1, 1, 1, 2, corThresholdIon) + ion -= ion_fit * (ion!=0) + + #minimize the effect of low coherence pixels + #cor[np.nonzero( (cor<0.85)*(cor!=0) )] = 0.00001 + #filt = adaptive_gaussian(ion, cor, size_max, size_min) + #cor**14 should be a good weight to use. 22-APR-2018 + filt = adaptive_gaussian(ion, cor**14, size_max, size_min) + + if fit: + filt += ion_fit * (filt!=0) + + # ion = np.zeros((length*2, width), dtype=np.float32) + # ion[0:length*2:2, :] = amp + # ion[1:length*2:2, :] = filt + # ion.astype(np.float32).tofile(ionfiltfile) + # img.filename = ionfiltfile + # img.extraFilename = ionfiltfile + '.vrt' + # img.renderHdr() + + filt.astype(np.float32).tofile(ionfiltfile) + create_xml(ionfiltfile, width, length, 'float') + + + ############################################################ + # STEP 3. resample ionospheric phase + ############################################################ + from contrib.alos2proc_f.alos2proc_f import rect + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + from scipy.interpolate import interp1d + import shutil + + ################################################# + #SET PARAMETERS HERE + #interpolation method + interpolationMethod = 1 + ################################################# + + print('\ninterpolate ionosphere') + + ml3 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooks2, + self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2) + + ionfiltfile = 'filt_ion'+ml2+'.ion' + #ionrectfile = 'filt_ion'+ml3+'.ion' + ionrectfile = self._insar.multilookIon + + img = isceobj.createImage() + img.load(ionfiltfile + '.xml') + width2 = img.width + length2 = img.length + + img = isceobj.createImage() + img.load(os.path.join('../../', ionDir['insar'], self._insar.multilookDifferentialInterferogram) + '.xml') + width3 = img.width + length3 = img.length + + #number of range looks output + nrlo = self._insar.numberRangeLooks1*self._insar.numberRangeLooks2 + #number of range looks input + nrli = self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon + #number of azimuth looks output + nalo = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2 + #number of azimuth looks input + nali = self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon + + if (self._insar.numberRangeLooks2 != self._insar.numberRangeLooksIon) or \ + (self._insar.numberAzimuthLooks2 != self._insar.numberAzimuthLooksIon): + #this should be faster using fortran + if interpolationMethod == 0: + rect(ionfiltfile, ionrectfile, + width2,length2, + width3,length3, + nrlo/nrli, 0.0, + 0.0, nalo/nali, + (nrlo-nrli)/(2.0*nrli), + (nalo-nali)/(2.0*nali), + 'REAL','Bilinear') + #finer, but slower method + else: + ionfilt = np.fromfile(ionfiltfile, dtype=np.float32).reshape(length2, width2) + index2 = np.linspace(0, width2-1, num=width2, endpoint=True) + index3 = np.linspace(0, width3-1, num=width3, endpoint=True) * nrlo/nrli + (nrlo-nrli)/(2.0*nrli) + ionrect = np.zeros((length3, width3), dtype=np.float32) + for i in range(length2): + f = interp1d(index2, ionfilt[i,:], kind='cubic', fill_value="extrapolate") + ionrect[i, :] = f(index3) + + index2 = np.linspace(0, length2-1, num=length2, endpoint=True) + index3 = np.linspace(0, length3-1, num=length3, endpoint=True) * nalo/nali + (nalo-nali)/(2.0*nali) + for j in range(width3): + f = interp1d(index2, ionrect[0:length2, j], kind='cubic', fill_value="extrapolate") + ionrect[:, j] = f(index3) + ionrect.astype(np.float32).tofile(ionrectfile) + del ionrect + create_xml(ionrectfile, width3, length3, 'float') + + os.rename(ionrectfile, os.path.join('../../insar', ionrectfile)) + os.rename(ionrectfile+'.vrt', os.path.join('../../insar', ionrectfile)+'.vrt') + os.rename(ionrectfile+'.xml', os.path.join('../../insar', ionrectfile)+'.xml') + os.chdir('../../insar') + else: + shutil.copyfile(ionfiltfile, os.path.join('../../insar', ionrectfile)) + os.chdir('../../insar') + create_xml(ionrectfile, width3, length3, 'float') + #now we are in 'insar' + + + ############################################################ + # STEP 4. correct interferogram + ############################################################ + from isceobj.Alos2Proc.Alos2ProcPublic import renameFile + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + + if self.applyIon: + print('\ncorrect interferogram') + if os.path.isfile(self._insar.multilookDifferentialInterferogramOriginal): + print('original interferogram: {} is already here, do not rename: {}'.format(self._insar.multilookDifferentialInterferogramOriginal, self._insar.multilookDifferentialInterferogram)) + else: + print('renaming {} to {}'.format(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal)) + renameFile(self._insar.multilookDifferentialInterferogram, self._insar.multilookDifferentialInterferogramOriginal) + + cmd = "imageMath.py -e='a*exp(-1.0*J*b)' --a={} --b={} -s BIP -t cfloat -o {}".format( + self._insar.multilookDifferentialInterferogramOriginal, + self._insar.multilookIon, + self._insar.multilookDifferentialInterferogram) + runCmd(cmd) + else: + print('\nionospheric phase estimation finished, but correction of interfeorgram not requested') + + os.chdir('../') + + catalog.printToLog(logger, "runIonFilt") + self._insar.procDoc.addAllFromCatalog(catalog) + + + +def computeIonosphere(lowerUnw, upperUnw, cor, fl, fu, adjFlag, corThresholdAdj, dispersive): + ''' + This routine computes ionosphere and remove the relative phase unwrapping errors + + lowerUnw: lower band unwrapped interferogram + upperUnw: upper band unwrapped interferogram + cor: coherence + fl: lower band center frequency + fu: upper band center frequency + adjFlag: method for removing relative phase unwrapping errors + 0: mean value + 1: polynomial + corThresholdAdj: coherence threshold of samples used in removing relative phase unwrapping errors + dispersive: compute dispersive or non-dispersive + 0: dispersive + 1: non-dispersive + ''' + + #use image size from lower unwrapped interferogram + (length, width)=lowerUnw.shape + +########################################################################################## + # ADJUST PHASE USING MEAN VALUE + # #ajust phase of upper band to remove relative phase unwrapping errors + # flag = (lowerUnw!=0)*(cor>=ionParam.corThresholdAdj) + # index = np.nonzero(flag!=0) + # mv = np.mean((lowerUnw - upperUnw)[index], dtype=np.float64) + # print('mean value of phase difference: {}'.format(mv)) + # flag2 = (lowerUnw!=0) + # index2 = np.nonzero(flag2) + # #phase for adjustment + # unwd = ((lowerUnw - upperUnw)[index2] - mv) / (2.0*np.pi) + # unw_adj = np.around(unwd) * (2.0*np.pi) + # #ajust phase of upper band + # upperUnw[index2] += unw_adj + # unw_diff = lowerUnw - upperUnw + # print('after adjustment:') + # print('max phase difference: {}'.format(np.amax(unw_diff))) + # print('min phase difference: {}'.format(np.amin(unw_diff))) +########################################################################################## + #adjust phase using mean value + if adjFlag == 0: + flag = (lowerUnw!=0)*(cor>=corThresholdAdj) + index = np.nonzero(flag!=0) + mv = np.mean((lowerUnw - upperUnw)[index], dtype=np.float64) + print('mean value of phase difference: {}'.format(mv)) + diff = mv + #adjust phase using a surface + else: + diff = weight_fitting(lowerUnw - upperUnw, cor, width, length, 1, 1, 1, 1, 2, corThresholdAdj) + + flag2 = (lowerUnw!=0) + index2 = np.nonzero(flag2) + #phase for adjustment + unwd = ((lowerUnw - upperUnw) - diff)[index2] / (2.0*np.pi) + unw_adj = np.around(unwd) * (2.0*np.pi) + #ajust phase of upper band + upperUnw[index2] += unw_adj + + unw_diff = (lowerUnw - upperUnw)[index2] + print('after adjustment:') + print('max phase difference: {}'.format(np.amax(unw_diff))) + print('min phase difference: {}'.format(np.amin(unw_diff))) + print('max-min: {}'.format(np.amax(unw_diff) - np.amin(unw_diff) )) + + #ionosphere + #fl = SPEED_OF_LIGHT / ionParam.radarWavelengthLower + #fu = SPEED_OF_LIGHT / ionParam.radarWavelengthUpper + f0 = (fl + fu) / 2.0 + + #dispersive + if dispersive == 0: + ionos = fl * fu * (lowerUnw * fu - upperUnw * fl) / f0 / (fu**2 - fl**2) + #non-dispersive phase + else: + ionos = f0 * (upperUnw*fu - lowerUnw * fl) / (fu**2 - fl**2) + + return ionos + + +def fit_surface(x, y, z, wgt, order): + # x: x coordinate, a column vector + # y: y coordinate, a column vector + # z: z coordinate, a column vector + # wgt: weight of the data points, a column vector + + + #number of data points + m = x.shape[0] + l = np.ones((m,1), dtype=np.float64) + +# #create polynomial +# if order == 1: +# #order of estimated coefficents: 1, x, y +# a1 = np.concatenate((l, x, y), axis=1) +# elif order == 2: +# #order of estimated coefficents: 1, x, y, x*y, x**2, y**2 +# a1 = np.concatenate((l, x, y, x*y, x**2, y**2), axis=1) +# elif order == 3: +# #order of estimated coefficents: 1, x, y, x*y, x**2, y**2, x**2*y, y**2*x, x**3, y**3 +# a1 = np.concatenate((l, x, y, x*y, x**2, y**2, x**2*y, y**2*x, x**3, y**3), axis=1) +# else: +# raise Exception('order not supported yet\n') + + if order < 1: + raise Exception('order must be larger than 1.\n') + + #create polynomial + a1 = l; + for i in range(1, order+1): + for j in range(i+1): + a1 = np.concatenate((a1, x**(i-j)*y**(j)), axis=1) + + #number of variable to be estimated + n = a1.shape[1] + + #do the least squares + a = a1 * np.matlib.repmat(np.sqrt(wgt), 1, n) + b = z * np.sqrt(wgt) + c = np.linalg.lstsq(a, b, rcond=-1)[0] + + #type: + return c + + +def cal_surface(x, y, c, order): + #x: x coordinate, a row vector + #y: y coordinate, a column vector + #c: coefficients of polynomial from fit_surface + #order: order of polynomial + + if order < 1: + raise Exception('order must be larger than 1.\n') + + #number of lines + length = y.shape[0] + #number of columns, if row vector, only one element in the shape tuple + #width = x.shape[1] + width = x.shape[0] + + x = np.matlib.repmat(x, length, 1) + y = np.matlib.repmat(y, 1, width) + z = c[0] * np.ones((length,width), dtype=np.float64) + + index = 0 + for i in range(1, order+1): + for j in range(i+1): + index += 1 + z += c[index] * x**(i-j)*y**(j) + + return z + + +def weight_fitting(ionos, cor, width, length, nrli, nali, nrlo, nalo, order, coth): + ''' + ionos: input ionospheric phase + cor: coherence of the interferogram + width: file width + length: file length + nrli: number of range looks of the input interferograms + nali: number of azimuth looks of the input interferograms + nrlo: number of range looks of the output ionosphere phase + nalo: number of azimuth looks of the ioutput ionosphere phase + order: the order of the polynomial for fitting ionosphere phase estimates + coth: coherence threshhold for ionosphere phase estimation + ''' + + from isceobj.Alos2Proc.Alos2ProcPublic import create_multi_index2 + + lengthi = int(length/nali) + widthi = int(width/nrli) + lengtho = int(length/nalo) + widtho = int(width/nrlo) + + #calculate output index + rgindex = create_multi_index2(widtho, nrli, nrlo) + azindex = create_multi_index2(lengtho, nali, nalo) + + #convert coherence to weight + cor = cor**2/(1.009-cor**2) + + #look for data to use + flag = (cor>coth)*(ionos!=0) + point_index = np.nonzero(flag) + m = point_index[0].shape[0] + + #calculate input index matrix + x0=np.matlib.repmat(np.arange(widthi), lengthi, 1) + y0=np.matlib.repmat(np.arange(lengthi).reshape(lengthi, 1), 1, widthi) + + x = x0[point_index].reshape(m, 1) + y = y0[point_index].reshape(m, 1) + z = ionos[point_index].reshape(m, 1) + w = cor[point_index].reshape(m, 1) + + #convert to higher precision type before use + x=np.asfarray(x,np.float64) + y=np.asfarray(y,np.float64) + z=np.asfarray(z,np.float64) + w=np.asfarray(w,np.float64) + coeff = fit_surface(x, y, z, w, order) + + #convert to higher precision type before use + rgindex=np.asfarray(rgindex,np.float64) + azindex=np.asfarray(azindex,np.float64) + phase_fit = cal_surface(rgindex, azindex.reshape(lengtho, 1), coeff, order) + + #format: widtho, lengtho, single band float32 + return phase_fit + + +def gaussian(size, sigma, scale = 1.0): + + if size % 2 != 1: + raise Exception('size must be odd') + hsize = (size - 1) / 2 + x = np.arange(-hsize, hsize + 1) * scale + f = np.exp(-x**2/(2.0*sigma**2)) / (sigma * np.sqrt(2.0*np.pi)) + f2d=np.matlib.repmat(f, size, 1) * np.matlib.repmat(f.reshape(size, 1), 1, size) + + return f2d/np.sum(f2d) + + +def adaptive_gaussian(ionos, wgt, size_max, size_min): + ''' + This program performs Gaussian filtering with adaptive window size. + ionos: ionosphere + wgt: weight + size_max: maximum window size + size_min: minimum window size + ''' + import scipy.signal as ss + + length = (ionos.shape)[0] + width = (ionos.shape)[1] + flag = (ionos!=0) * (wgt!=0) + ionos *= flag + wgt *= flag + + size_num = 100 + size = np.linspace(size_min, size_max, num=size_num, endpoint=True) + std = np.zeros((length, width, size_num)) + flt = np.zeros((length, width, size_num)) + out = np.zeros((length, width, 1)) + + #calculate filterd image and standard deviation + #sigma of window size: size_max + sigma = size_max / 2.0 + for i in range(size_num): + size2 = np.int(np.around(size[i])) + if size2 % 2 == 0: + size2 += 1 + if (i+1) % 10 == 0: + print('min win: %4d, max win: %4d, current win: %4d'%(np.int(np.around(size_min)), np.int(np.around(size_max)), size2)) + g2d = gaussian(size2, sigma*size2/size_max, scale=1.0) + scale = ss.fftconvolve(wgt, g2d, mode='same') + flt[:, :, i] = ss.fftconvolve(ionos*wgt, g2d, mode='same') / (scale + (scale==0)) + #variance of resulting filtered sample + scale = scale**2 + var = ss.fftconvolve(wgt, g2d**2, mode='same') / (scale + (scale==0)) + #in case there is a large area without data where scale is very small, which leads to wired values in variance + var[np.nonzero(var<0)] = 0 + std[:, :, i] = np.sqrt(var) + + std_mv = np.mean(std[np.nonzero(std!=0)], dtype=np.float64) + diff_max = np.amax(np.absolute(std - std_mv)) + std_mv + 1 + std[np.nonzero(std==0)] = diff_max + + index = np.nonzero(np.ones((length, width))) + ((np.argmin(np.absolute(std - std_mv), axis=2)).reshape(length*width), ) + out = flt[index] + out = out.reshape((length, width)) + + #remove artifacts due to varying wgt + size_smt = size_min + if size_smt % 2 == 0: + size_smt += 1 + g2d = gaussian(size_smt, size_smt/2.0, scale=1.0) + scale = ss.fftconvolve((out!=0), g2d, mode='same') + out2 = ss.fftconvolve(out, g2d, mode='same') / (scale + (scale==0)) + + return out2 + + +def reformatMaskedAreas(maskedAreas, length, width): + ''' + reformat masked areas coordinates that are ready to use + 'maskedAreas' 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 with -1, the program will use firstLine/lastLine/firstColumn/ + lastColumn instead. + + output is a 2-D list containing the corresponding python-list/array-format indexes. + ''' + numberOfAreas = len(maskedAreas) + maskedAreasReformated = [[0, length, 0, width] for i in range(numberOfAreas)] + + for i in range(numberOfAreas): + if maskedAreas[i][0] != -1: + maskedAreasReformated[i][0] = maskedAreas[i][0] - 1 + if maskedAreas[i][1] != -1: + maskedAreasReformated[i][1] = maskedAreas[i][1] + if maskedAreas[i][2] != -1: + maskedAreasReformated[i][2] = maskedAreas[i][2] - 1 + if maskedAreas[i][3] != -1: + maskedAreasReformated[i][3] = maskedAreas[i][3] + if (not (0 <= maskedAreasReformated[i][0] <= length-1)) or \ + (not (1 <= maskedAreasReformated[i][1] <= length)) or \ + (not (0 <= maskedAreasReformated[i][2] <= width-1)) or \ + (not (1 <= maskedAreasReformated[i][3] <= width)) or \ + (not (maskedAreasReformated[i][1]-maskedAreasReformated[i][0]>=1)) or \ + (not (maskedAreasReformated[i][3]-maskedAreasReformated[i][2]>=1)): + raise Exception('area {} masked out in ionospheric phase estimation not correct'.format(i+1)) + + return maskedAreasReformated diff --git a/components/isceobj/Alos2Proc/runIonSubband.py b/components/isceobj/Alos2Proc/runIonSubband.py new file mode 100644 index 0000000..2c71183 --- /dev/null +++ b/components/isceobj/Alos2Proc/runIonSubband.py @@ -0,0 +1,457 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Constants import SPEED_OF_LIGHT + +logger = logging.getLogger('isce.alos2insar.runIonSubband') + +def runIonSubband(self): + '''create subband interferograms + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + if not self.doIon: + catalog.printToLog(logger, "runIonSubband") + self._insar.procDoc.addAllFromCatalog(catalog) + return + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + #using 1/3, 1/3, 1/3 band split + radarWavelength = masterTrack.radarWavelength + rangeBandwidth = masterTrack.frames[0].swaths[0].rangeBandwidth + rangeSamplingRate = masterTrack.frames[0].swaths[0].rangeSamplingRate + radarWavelengthLower = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength - rangeBandwidth / 3.0) + radarWavelengthUpper = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength + rangeBandwidth / 3.0) + subbandRadarWavelength = [radarWavelengthLower, radarWavelengthUpper] + subbandBandWidth = [rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate] + subbandFrequencyCenter = [-rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate] + + subbandPrefix = ['lower', 'upper'] + + ''' + ionDir = { + ionDir['swathMosaic'] : 'mosaic', + ionDir['insar'] : 'insar', + ionDir['ion'] : 'ion', + ionDir['subband'] : ['lower', 'upper'], + ionDir['ionCal'] : 'ion_cal' + } + ''' + #define upper level directory names + ionDir = defineIonDir() + + + self._insar.subbandRadarWavelength = subbandRadarWavelength + + + ############################################################ + # STEP 1. create directories + ############################################################ + #create and enter 'ion' directory + #after finishing each step, we are in this directory + if not os.path.exists(ionDir['ion']): + os.makedirs(ionDir['ion']) + os.chdir(ionDir['ion']) + + #create insar processing directories + for k in range(2): + subbandDir = ionDir['subband'][k] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + fullDir = os.path.join(subbandDir, frameDir, swathDir) + if not os.path.exists(fullDir): + os.makedirs(fullDir) + + #create ionospheric phase directory + if not os.path.exists(ionDir['ionCal']): + os.makedirs(ionDir['ionCal']) + + + ############################################################ + # STEP 2. create subband interferograms + ############################################################ + import numpy as np + import stdproc + from iscesys.StdOEL.StdOELPy import create_writer + from isceobj.Alos2Proc.Alos2ProcPublic import readOffset + from contrib.alos2proc.alos2proc import rg_filter + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + #filter master and slave images + for slcx in [self._insar.masterSlc, self._insar.slaveSlc]: + slc = os.path.join('../', frameDir, swathDir, slcx) + slcLower = os.path.join(ionDir['subband'][0], frameDir, swathDir, slcx) + slcUpper = os.path.join(ionDir['subband'][1], frameDir, swathDir, slcx) + rg_filter(slc, 2, + [slcLower, slcUpper], + subbandBandWidth, + subbandFrequencyCenter, + 257, 2048, 0.1, 0, 0.0) + #resample + for k in range(2): + os.chdir(os.path.join(ionDir['subband'][k], frameDir, swathDir)) + #recreate xml file to remove the file path + #can also use fixImageXml.py? + for x in [self._insar.masterSlc, self._insar.slaveSlc]: + img = isceobj.createSlcImage() + img.load(x + '.xml') + img.setFilename(x) + img.extraFilename = x + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + + ############################################# + #1. form interferogram + ############################################# + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + refinedOffsets = readOffset(os.path.join('../../../../', frameDir, swathDir, 'cull.off')) + intWidth = int(masterSwath.numberOfSamples / self._insar.numberRangeLooks1) + intLength = int(masterSwath.numberOfLines / self._insar.numberAzimuthLooks1) + dopplerVsPixel = [i/slaveSwath.prf for i in slaveSwath.dopplerVsPixel] + + #master slc + mSLC = isceobj.createSlcImage() + mSLC.load(self._insar.masterSlc+'.xml') + mSLC.setAccessMode('read') + mSLC.createImage() + + #slave slc + sSLC = isceobj.createSlcImage() + sSLC.load(self._insar.slaveSlc+'.xml') + sSLC.setAccessMode('read') + sSLC.createImage() + + #interferogram + interf = isceobj.createIntImage() + interf.setFilename(self._insar.interferogram) + interf.setWidth(intWidth) + interf.setAccessMode('write') + interf.createImage() + + #amplitdue + amplitude = isceobj.createAmpImage() + amplitude.setFilename(self._insar.amplitude) + amplitude.setWidth(intWidth) + amplitude.setAccessMode('write') + amplitude.createImage() + + #create a writer for resamp + stdWriter = create_writer("log", "", True, filename="resamp.log") + stdWriter.setFileTag("resamp", "log") + stdWriter.setFileTag("resamp", "err") + stdWriter.setFileTag("resamp", "out") + + + #set up resampling program now + #The setting has been compared with resamp_roi's setting in ROI_pac item by item. + #The two kinds of setting are exactly the same. The number of setting items are + #exactly the same + objResamp = stdproc.createResamp() + objResamp.wireInputPort(name='offsets', object=refinedOffsets) + objResamp.stdWriter = stdWriter + objResamp.setNumberFitCoefficients(6) + objResamp.setNumberRangeBin1(masterSwath.numberOfSamples) + objResamp.setNumberRangeBin2(slaveSwath.numberOfSamples) + objResamp.setStartLine(1) + objResamp.setNumberLines(masterSwath.numberOfLines) + objResamp.setFirstLineOffset(1) + objResamp.setDopplerCentroidCoefficients(dopplerVsPixel) + objResamp.setRadarWavelength(subbandRadarWavelength[k]) + objResamp.setSlantRangePixelSpacing(slaveSwath.rangePixelSize) + objResamp.setNumberRangeLooks(self._insar.numberRangeLooks1) + objResamp.setNumberAzimuthLooks(self._insar.numberAzimuthLooks1) + objResamp.setFlattenWithOffsetFitFlag(0) + objResamp.resamp(mSLC, sSLC, interf, amplitude) + + #finialize images + mSLC.finalizeImage() + sSLC.finalizeImage() + interf.finalizeImage() + amplitude.finalizeImage() + stdWriter.finalize() + + ############################################# + #2. trim amplitude + ############################################# + #using memmap instead, which should be faster, since we only have a few pixels to change + amp=np.memmap(self._insar.amplitude, dtype='complex64', mode='r+', shape=(intLength, intWidth)) + index = np.nonzero( (np.real(amp)==0) + (np.imag(amp)==0) ) + amp[index]=0 + + #Deletion flushes memory changes to disk before removing the object: + del amp + + ############################################# + #3. delete subband slcs + ############################################# + os.remove(self._insar.masterSlc) + os.remove(self._insar.masterSlc + '.vrt') + os.remove(self._insar.masterSlc + '.xml') + os.remove(self._insar.slaveSlc) + os.remove(self._insar.slaveSlc + '.vrt') + os.remove(self._insar.slaveSlc + '.xml') + + os.chdir('../../../') + + + ############################################################ + # STEP 3. mosaic swaths + ############################################################ + from isceobj.Alos2Proc.runSwathMosaic import swathMosaic + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + for k in range(2): + os.chdir(ionDir['subband'][k]) + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = ionDir['swathMosaic'] + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if not ( + ((self._insar.modeCombination == 21) or \ + (self._insar.modeCombination == 22) or \ + (self._insar.modeCombination == 31) or \ + (self._insar.modeCombination == 32)) + and + (self._insar.endingSwath-self._insar.startingSwath+1 > 1) + ): + import shutil + swathDir = 's{}'.format(masterTrack.frames[i].swaths[0].swathNumber) + + # if not os.path.isfile(self._insar.interferogram): + # os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # if not os.path.isfile(self._insar.amplitude): + # os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + #no need to update frame parameters here + os.chdir('../') + #no need to save parameter file here + os.chdir('../') + + continue + + #choose offsets + numberOfFrames = len(masterTrack.frames) + numberOfSwaths = len(masterTrack.frames[i].swaths) + if self.swathOffsetMatching: + #no need to do this as the API support 2-d list + #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetMatchingMaster + azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster + + else: + #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster + + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude)) + + #note that frame parameters are updated after mosaicking, here no need to update parameters + #mosaic amplitudes + swathMosaic(masterTrack.frames[i], inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, resamplingMethod=0) + #mosaic interferograms + swathMosaic(masterTrack.frames[i], inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=False, phaseCompensation=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'int') + + #update slave frame parameters here, here no need to update parameters + os.chdir('../') + #save parameter file, here no need to save parameter file + os.chdir('../') + os.chdir('../') + + + ############################################################ + # STEP 4. mosaic frames + ############################################################ + from isceobj.Alos2Proc.runFrameMosaic import frameMosaic + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + for k in range(2): + os.chdir(ionDir['subband'][k]) + + mosaicDir = ionDir['insar'] + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + numberOfFrames = len(masterTrack.frames) + if numberOfFrames == 1: + import shutil + frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.masterFrames[0])) + # if not os.path.isfile(self._insar.interferogram): + # os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + # #shutil.copy2() can overwrite + # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # if not os.path.isfile(self._insar.amplitude): + # os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + os.rename(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + os.rename(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + #update track parameters, no need to update track parameters here + + else: + #choose offsets + if self.frameOffsetMatching: + rangeOffsets = self._insar.frameRangeOffsetMatchingMaster + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster + else: + rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + inputInterferograms.append(os.path.join('../', frameDir, 'mosaic', self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', frameDir, 'mosaic', self._insar.amplitude)) + + #note that track parameters are updated after mosaicking + #mosaic amplitudes + frameMosaic(masterTrack, inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=False, resamplingMethod=0) + #mosaic interferograms + frameMosaic(masterTrack, inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'int') + + #update slave parameters here, no need to update slave parameters here + + os.chdir('../') + #save parameter file, no need to save parameter file here + os.chdir('../') + + + ############################################################ + # STEP 5. clear frame processing files + ############################################################ + import shutil + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + + for k in range(2): + os.chdir(ionDir['subband'][k]) + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + shutil.rmtree(frameDir) + #cmd = 'rm -rf {}'.format(frameDir) + #runCmd(cmd) + os.chdir('../') + + + ############################################################ + # STEP 6. create differential interferograms + ############################################################ + import numpy as np + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + + for k in range(2): + os.chdir(ionDir['subband'][k]) + + insarDir = ionDir['insar'] + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + rangePixelSize = self._insar.numberRangeLooks1 * masterTrack.rangePixelSize + radarWavelength = subbandRadarWavelength[k] + rectRangeOffset = os.path.join('../../../', insarDir, self._insar.rectRangeOffset) + + cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{}) * (b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, self._insar.interferogram, rectRangeOffset, self._insar.differentialInterferogram) + runCmd(cmd) + + os.chdir('../../') + + + os.chdir('../') + catalog.printToLog(logger, "runIonSubband") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def defineIonDir(): + ''' + define directory names for ionospheric correction + ''' + + ionDir = { + #swath mosaicking directory + 'swathMosaic' : 'mosaic', + #final insar processing directory + 'insar' : 'insar', + #ionospheric correction directory + 'ion' : 'ion', + #subband directory + 'subband' : ['lower', 'upper'], + #final ionospheric phase calculation directory + 'ionCal' : 'ion_cal' + } + + return ionDir + + +def defineIonFilenames(): + pass + + + + + + + diff --git a/components/isceobj/Alos2Proc/runIonUwrap.py b/components/isceobj/Alos2Proc/runIonUwrap.py new file mode 100644 index 0000000..683422d --- /dev/null +++ b/components/isceobj/Alos2Proc/runIonUwrap.py @@ -0,0 +1,213 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import datetime +import numpy as np + +import isceobj + +logger = logging.getLogger('isce.alos2insar.runIonUwrap') + +def runIonUwrap(self): + '''unwrap subband interferograms + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + if not self.doIon: + catalog.printToLog(logger, "runIonUwrap") + self._insar.procDoc.addAllFromCatalog(catalog) + return + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + from isceobj.Alos2Proc.runIonSubband import defineIonDir + ionDir = defineIonDir() + subbandPrefix = ['lower', 'upper'] + + ionCalDir = os.path.join(ionDir['ion'], ionDir['ionCal']) + if not os.path.exists(ionCalDir): + os.makedirs(ionCalDir) + os.chdir(ionCalDir) + + + ############################################################ + # STEP 1. take looks + ############################################################ + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + from contrib.alos2proc.alos2proc import look + + ml2 = '_{}rlks_{}alks'.format(self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, + self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon) + + for k in range(2): + fullbandDir = os.path.join('../../', ionDir['insar']) + subbandDir = os.path.join('../', ionDir['subband'][k], ionDir['insar']) + prefix = subbandPrefix[k] + + amp = isceobj.createImage() + amp.load(os.path.join(subbandDir, self._insar.amplitude)+'.xml') + width = amp.width + length = amp.length + width2 = int(width / self._insar.numberRangeLooksIon) + length2 = int(length / self._insar.numberAzimuthLooksIon) + + #take looks + look(os.path.join(subbandDir, self._insar.differentialInterferogram), prefix+ml2+'.int', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 4, 0, 1) + create_xml(prefix+ml2+'.int', width2, length2, 'int') + look(os.path.join(subbandDir, self._insar.amplitude), prefix+ml2+'.amp', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 4, 1, 1) + create_xml(prefix+ml2+'.amp', width2, length2, 'amp') + + # #water body + # if k == 0: + # wbdOutFile = os.path.join(fullbandDir, self._insar.wbdOut) + # if os.path.isfile(wbdOutFile): + # look(wbdOutFile, 'wbd'+ml2+'.wbd', width, self._insar.numberRangeLooksIon, self._insar.numberAzimuthLooksIon, 0, 0, 1) + # create_xml('wbd'+ml2+'.wbd', width2, length2, 'byte') + + + ############################################################ + # STEP 2. compute coherence + ############################################################ + from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence + + lowerbandInterferogramFile = subbandPrefix[0]+ml2+'.int' + upperbandInterferogramFile = subbandPrefix[1]+ml2+'.int' + lowerbandAmplitudeFile = subbandPrefix[0]+ml2+'.amp' + upperbandAmplitudeFile = subbandPrefix[1]+ml2+'.amp' + lowerbandCoherenceFile = subbandPrefix[0]+ml2+'.cor' + upperbandCoherenceFile = subbandPrefix[1]+ml2+'.cor' + coherenceFile = 'diff'+ml2+'.cor' + + lowerint = np.fromfile(lowerbandInterferogramFile, dtype=np.complex64).reshape(length2, width2) + upperint = np.fromfile(upperbandInterferogramFile, dtype=np.complex64).reshape(length2, width2) + loweramp = np.fromfile(lowerbandAmplitudeFile, dtype=np.float32).reshape(length2, width2*2) + upperamp = np.fromfile(upperbandAmplitudeFile, dtype=np.float32).reshape(length2, width2*2) + + #compute coherence only using interferogram + #here I use differential interferogram of lower and upper band interferograms + #so that coherence is not affected by fringes + cord = cal_coherence(lowerint*np.conjugate(upperint), win=3, edge=4) + cor = np.zeros((length2*2, width2), dtype=np.float32) + cor[0:length2*2:2, :] = np.sqrt( (np.absolute(lowerint)+np.absolute(upperint))/2.0 ) + cor[1:length2*2:2, :] = cord + cor.astype(np.float32).tofile(coherenceFile) + create_xml(coherenceFile, width2, length2, 'cor') + + #create lower and upper band coherence files + #lower + amp1 = loweramp[:, 0:width2*2:2] + amp2 = loweramp[:, 1:width2*2:2] + cor[1:length2*2:2, :] = np.absolute(lowerint)/(amp1+(amp1==0))/(amp2+(amp2==0))*(amp1!=0)*(amp2!=0) + cor.astype(np.float32).tofile(lowerbandCoherenceFile) + create_xml(lowerbandCoherenceFile, width2, length2, 'cor') + + #upper + amp1 = upperamp[:, 0:width2*2:2] + amp2 = upperamp[:, 1:width2*2:2] + cor[1:length2*2:2, :] = np.absolute(upperint)/(amp1+(amp1==0))/(amp2+(amp2==0))*(amp1!=0)*(amp2!=0) + cor.astype(np.float32).tofile(upperbandCoherenceFile) + create_xml(upperbandCoherenceFile, width2, length2, 'cor') + + + ############################################################ + # STEP 3. filtering subband interferograms + ############################################################ + from contrib.alos2filter.alos2filter import psfilt1 + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + from mroipac.icu.Icu import Icu + + if self.filterSubbandInt: + for k in range(2): + toBeFiltered = 'tmp.int' + if self.removeMagnitudeBeforeFilteringSubbandInt: + cmd = "imageMath.py -e='a/(abs(a)+(a==0))' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered) + else: + #scale the inteferogram, otherwise its magnitude is too large for filtering + cmd = "imageMath.py -e='a/100000.0' --a={} -o {} -t cfloat -s BSQ".format(subbandPrefix[k]+ml2+'.int', toBeFiltered) + runCmd(cmd) + + intImage = isceobj.createIntImage() + intImage.load(toBeFiltered + '.xml') + width = intImage.width + length = intImage.length + + windowSize = self.filterWinsizeSubbandInt + stepSize = self.filterStepsizeSubbandInt + psfilt1(toBeFiltered, 'filt_'+subbandPrefix[k]+ml2+'.int', width, self.filterStrengthSubbandInt, windowSize, stepSize) + create_xml('filt_'+subbandPrefix[k]+ml2+'.int', width, length, 'int') + + os.remove(toBeFiltered) + os.remove(toBeFiltered + '.vrt') + os.remove(toBeFiltered + '.xml') + + #create phase sigma for phase unwrapping + #recreate filtered image + filtImage = isceobj.createIntImage() + filtImage.load('filt_'+subbandPrefix[k]+ml2+'.int' + '.xml') + filtImage.setAccessMode('read') + filtImage.createImage() + + #amplitude image + ampImage = isceobj.createAmpImage() + ampImage.load(subbandPrefix[k]+ml2+'.amp' + '.xml') + ampImage.setAccessMode('read') + ampImage.createImage() + + #phase sigma correlation image + phsigImage = isceobj.createImage() + phsigImage.setFilename(subbandPrefix[k]+ml2+'.phsig') + phsigImage.setWidth(width) + phsigImage.dataType='FLOAT' + phsigImage.bands = 1 + phsigImage.setImageType('cor') + phsigImage.setAccessMode('write') + phsigImage.createImage() + + icu = Icu(name='insarapp_filter_icu') + icu.configure() + icu.unwrappingFlag = False + icu.icu(intImage = filtImage, ampImage=ampImage, phsigImage=phsigImage) + + phsigImage.renderHdr() + + filtImage.finalizeImage() + ampImage.finalizeImage() + phsigImage.finalizeImage() + + + ############################################################ + # STEP 4. phase unwrapping + ############################################################ + from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap + + for k in range(2): + tmid = masterTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*masterTrack.azimuthLineInterval+ + masterTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*masterTrack.azimuthLineInterval) + + if self.filterSubbandInt: + toBeUnwrapped = 'filt_'+subbandPrefix[k]+ml2+'.int' + coherenceFile = subbandPrefix[k]+ml2+'.phsig' + else: + toBeUnwrapped = subbandPrefix[k]+ml2+'.int' + coherenceFile = 'diff'+ml2+'.cor' + + snaphuUnwrap(masterTrack, tmid, + toBeUnwrapped, + coherenceFile, + subbandPrefix[k]+ml2+'.unw', + self._insar.numberRangeLooks1*self._insar.numberRangeLooksIon, + self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksIon, + costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True) + + + os.chdir('../../') + catalog.printToLog(logger, "runIonUwrap") + self._insar.procDoc.addAllFromCatalog(catalog) + diff --git a/components/isceobj/Alos2Proc/runLook.py b/components/isceobj/Alos2Proc/runLook.py new file mode 100644 index 0000000..fd559e5 --- /dev/null +++ b/components/isceobj/Alos2Proc/runLook.py @@ -0,0 +1,70 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml +from contrib.alos2proc.alos2proc import look +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar + +logger = logging.getLogger('isce.alos2insar.runLook') + +def runLook(self): + '''take looks + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + #masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + wbdFile = os.path.abspath(self._insar.wbd) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + amp = isceobj.createImage() + amp.load(self._insar.amplitude+'.xml') + width = amp.width + length = amp.length + width2 = int(width / self._insar.numberRangeLooks2) + length2 = int(length / self._insar.numberAzimuthLooks2) + + if not ((self._insar.numberRangeLooks2 == 1) and (self._insar.numberAzimuthLooks2 == 1)): + #take looks + look(self._insar.differentialInterferogram, self._insar.multilookDifferentialInterferogram, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 4, 0, 1) + look(self._insar.amplitude, self._insar.multilookAmplitude, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 4, 1, 1) + look(self._insar.latitude, self._insar.multilookLatitude, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 3, 0, 1) + look(self._insar.longitude, self._insar.multilookLongitude, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 3, 0, 1) + look(self._insar.height, self._insar.multilookHeight, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 3, 0, 1) + #creat xml + create_xml(self._insar.multilookDifferentialInterferogram, width2, length2, 'int') + create_xml(self._insar.multilookAmplitude, width2, length2, 'amp') + create_xml(self._insar.multilookLatitude, width2, length2, 'double') + create_xml(self._insar.multilookLongitude, width2, length2, 'double') + create_xml(self._insar.multilookHeight, width2, length2, 'double') + #los has two bands, use look program in isce instead + cmd = "looks.py -i {} -o {} -r {} -a {}".format(self._insar.los, self._insar.multilookLos, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2) + runCmd(cmd) + + #water body + #this looking operation has no problems where there is only water and land, but there is also possible no-data area + #look(self._insar.wbdOut, self._insar.multilookWbdOut, width, self._insar.numberRangeLooks2, self._insar.numberAzimuthLooks2, 0, 0, 1) + #create_xml(self._insar.multilookWbdOut, width2, length2, 'byte') + #use waterBodyRadar instead to avoid the problems of no-data pixels in water body + waterBodyRadar(self._insar.multilookLatitude, self._insar.multilookLongitude, wbdFile, self._insar.multilookWbdOut) + + + os.chdir('../') + + catalog.printToLog(logger, "runLook") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2Proc/runPrepareSlc.py b/components/isceobj/Alos2Proc/runPrepareSlc.py new file mode 100644 index 0000000..bee70db --- /dev/null +++ b/components/isceobj/Alos2Proc/runPrepareSlc.py @@ -0,0 +1,466 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import datetime +import numpy as np + +import isceobj +from isceobj.Constants import SPEED_OF_LIGHT +from isceobj.Alos2Proc.Alos2ProcPublic import overlapFrequency +from contrib.alos2proc.alos2proc import rg_filter +from contrib.alos2proc.alos2proc import resamp +from contrib.alos2proc.alos2proc import mbf + +logger = logging.getLogger('isce.alos2insar.runPrepareSlc') + +def runPrepareSlc(self): + '''Extract images. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + + #################################################### + #1. crop slc + #################################################### + #for ScanSAR-stripmap interferometry, we always crop slcs + #for other cases, up to users + if ((self._insar.modeCombination == 31) or (self._insar.modeCombination == 32)) or (self.cropSlc): + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('cropping frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + #crop master + cropSlc(masterTrack.orbit, masterSwath, self._insar.masterSlc, slaveTrack.orbit, slaveSwath, edge=0, useVirtualFile=self.useVirtualFile) + #crop slave, since slave may go through resampling, we set edge=9 + #cropSlc(slaveTrack.orbit, slaveSwath, self._insar.slaveSlc, masterTrack.orbit, masterSwath, edge=9, useVirtualFile=self.useVirtualFile) + cropSlc(slaveTrack.orbit, slaveSwath, self._insar.slaveSlc, masterTrack.orbit, masterSwath, edge=0, useVirtualFile=self.useVirtualFile) + + os.chdir('../') + os.chdir('../') + + + #################################################### + #2. range-filter slc + #################################################### + #compute filtering parameters, radarwavelength and range bandwidth should be the same across all swaths and frames + centerfreq1 = SPEED_OF_LIGHT / masterTrack.radarWavelength + bandwidth1 = masterTrack.frames[0].swaths[0].rangeBandwidth + centerfreq2 = SPEED_OF_LIGHT / slaveTrack.radarWavelength + bandwidth2 = slaveTrack.frames[0].swaths[0].rangeBandwidth + overlapfreq = overlapFrequency(centerfreq1, bandwidth1, centerfreq2, bandwidth2) + + if overlapfreq == None: + raise Exception('there is no overlap bandwidth in range') + overlapbandwidth = overlapfreq[1] - overlapfreq[0] + if overlapbandwidth < 3e6: + print('overlap bandwidth: {}, percentage: {}%'.format(overlapbandwidth, 100.0*overlapbandwidth/bandwidth1)) + raise Exception('there is not enough overlap bandwidth in range') + centerfreq = (overlapfreq[1] + overlapfreq[0]) / 2.0 + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('range filtering frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + # #compute filtering parameters + # centerfreq1 = SPEED_OF_LIGHT / masterTrack.radarWavelength + # bandwidth1 = masterSwath.rangeBandwidth + # centerfreq2 = SPEED_OF_LIGHT / slaveTrack.radarWavelength + # bandwidth2 = slaveSwath.rangeBandwidth + # overlapfreq = overlapFrequency(centerfreq1, bandwidth1, centerfreq2, bandwidth2) + + # if overlapfreq == None: + # raise Exception('there is no overlap bandwidth in range') + # overlapbandwidth = overlapfreq[1] - overlapfreq[0] + # if overlapbandwidth < 3e6: + # print('overlap bandwidth: {}, percentage: {}%'.format(overlapbandwidth, 100.0*overlapbandwidth/bandwidth1)) + # raise Exception('there is not enough overlap bandwidth in range') + # centerfreq = (overlapfreq[1] + overlapfreq[0]) / 2.0 + + #filter master + if abs(centerfreq1 - centerfreq) < 1.0 and (bandwidth1 - 1.0) < overlapbandwidth: + print('no need to range filter {}'.format(self._insar.masterSlc)) + else: + print('range filter {}'.format(self._insar.masterSlc)) + tmpSlc = 'tmp.slc' + rg_filter(self._insar.masterSlc, 1, [tmpSlc], [overlapbandwidth / masterSwath.rangeSamplingRate], + [(centerfreq - centerfreq1) / masterSwath.rangeSamplingRate], + 257, 2048, 0.1, 0, 0.0) + + if os.path.isfile(self._insar.masterSlc): + os.remove(self._insar.masterSlc) + os.remove(self._insar.masterSlc+'.vrt') + os.remove(self._insar.masterSlc+'.xml') + + img = isceobj.createSlcImage() + img.load(tmpSlc + '.xml') + #remove original + os.remove(tmpSlc + '.vrt') + os.remove(tmpSlc + '.xml') + os.rename(tmpSlc, self._insar.masterSlc) + #creat new + img.setFilename(self._insar.masterSlc) + img.extraFilename = self._insar.masterSlc + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + + masterTrack.radarWavelength = SPEED_OF_LIGHT/centerfreq + masterSwath.rangeBandwidth = overlapbandwidth + + #filter slave + if abs(centerfreq2 - centerfreq) < 1.0 and (bandwidth2 - 1.0) < overlapbandwidth: + print('no need to range filter {}'.format(self._insar.slaveSlc)) + else: + print('range filter {}'.format(self._insar.slaveSlc)) + tmpSlc = 'tmp.slc' + rg_filter(self._insar.slaveSlc, 1, [tmpSlc], [overlapbandwidth / slaveSwath.rangeSamplingRate], + [(centerfreq - centerfreq2) / slaveSwath.rangeSamplingRate], + 257, 2048, 0.1, 0, 0.0) + + if os.path.isfile(self._insar.slaveSlc): + os.remove(self._insar.slaveSlc) + os.remove(self._insar.slaveSlc+'.vrt') + os.remove(self._insar.slaveSlc+'.xml') + + img = isceobj.createSlcImage() + img.load(tmpSlc + '.xml') + #remove original + os.remove(tmpSlc + '.vrt') + os.remove(tmpSlc + '.xml') + os.rename(tmpSlc, self._insar.slaveSlc) + #creat new + img.setFilename(self._insar.slaveSlc) + img.extraFilename = self._insar.slaveSlc + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + + slaveTrack.radarWavelength = SPEED_OF_LIGHT/centerfreq + slaveSwath.rangeBandwidth = overlapbandwidth + + os.chdir('../') + os.chdir('../') + + + #################################################### + #3. equalize sample size + #################################################### + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('equalize sample size frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + if abs(masterSwath.rangeSamplingRate - slaveSwath.rangeSamplingRate) < 1.0 and abs(masterSwath.prf - slaveSwath.prf) < 1.0: + print('no need to resample {}.'.format(self._insar.slaveSlc)) + else: + outWidth = round(slaveSwath.numberOfSamples / slaveSwath.rangeSamplingRate * masterSwath.rangeSamplingRate) + outLength = round(slaveSwath.numberOfLines / slaveSwath.prf * masterSwath.prf) + + tmpSlc = 'tmp.slc' + resamp(self._insar.slaveSlc, tmpSlc, 'fake', 'fake', outWidth, outLength, slaveSwath.prf, slaveSwath.dopplerVsPixel, + rgcoef=[0.0, (1.0/masterSwath.rangeSamplingRate) / (1.0/slaveSwath.rangeSamplingRate) - 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + azcoef=[0.0, 0.0, (1.0/masterSwath.prf) / (1.0/slaveSwath.prf) - 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + azpos_off=0.0) + + if os.path.isfile(self._insar.slaveSlc): + os.remove(self._insar.slaveSlc) + os.remove(self._insar.slaveSlc+'.vrt') + os.remove(self._insar.slaveSlc+'.xml') + + img = isceobj.createSlcImage() + img.load(tmpSlc + '.xml') + #remove original + os.remove(tmpSlc + '.vrt') + os.remove(tmpSlc + '.xml') + os.rename(tmpSlc, self._insar.slaveSlc) + #creat new + img.setFilename(self._insar.slaveSlc) + img.extraFilename = self._insar.slaveSlc + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + + #update parameters + #update doppler and azfmrate first + index2 = np.arange(outWidth) + index = np.arange(outWidth) * (1.0/masterSwath.rangeSamplingRate) / (1.0/slaveSwath.rangeSamplingRate) + dop = np.polyval(slaveSwath.dopplerVsPixel[::-1], index) + p = np.polyfit(index2, dop, 3) + slaveSwath.dopplerVsPixel = [p[3], p[2], p[1], p[0]] + + azfmrate = np.polyval(slaveSwath.azimuthFmrateVsPixel[::-1], index) + p = np.polyfit(index2, azfmrate, 3) + slaveSwath.azimuthFmrateVsPixel = [p[3], p[2], p[1], p[0]] + + slaveSwath.numberOfSamples = outWidth + slaveSwath.numberOfLines = outLength + + slaveSwath.prf = masterSwath.prf + slaveSwath.rangeSamplingRate = masterSwath.rangeSamplingRate + slaveSwath.rangePixelSize = masterSwath.rangePixelSize + slaveSwath.azimuthPixelSize = masterSwath.azimuthPixelSize + slaveSwath.azimuthLineInterval = masterSwath.azimuthLineInterval + slaveSwath.prfFraction = masterSwath.prfFraction + + os.chdir('../') + os.chdir('../') + + + #################################################### + #4. mbf + #################################################### + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('azimuth filter frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + #using Piyush's code for computing range and azimuth offsets + midRange = masterSwath.startingRange + masterSwath.rangePixelSize * masterSwath.numberOfSamples * 0.5 + midSensingStart = masterSwath.sensingStart + datetime.timedelta(seconds = masterSwath.numberOfLines * 0.5 / masterSwath.prf) + llh = masterTrack.orbit.rdr2geo(midSensingStart, midRange) + slvaz, slvrng = slaveTrack.orbit.geo2rdr(llh) + ###Translate to offsets + #at this point, slave range pixel size and prf should be the same as those of master + rgoff = ((slvrng - slaveSwath.startingRange) / masterSwath.rangePixelSize) - masterSwath.numberOfSamples * 0.5 + azoff = ((slvaz - slaveSwath.sensingStart).total_seconds() * masterSwath.prf) - masterSwath.numberOfLines * 0.5 + + #filter master + if not ((self._insar.modeCombination == 21) and (self._insar.burstSynchronization <= self.burstSynchronizationThreshold)): + print('no need to azimuth filter {}.'.format(self._insar.masterSlc)) + else: + index = np.arange(masterSwath.numberOfSamples) + rgoff + dop = np.polyval(slaveSwath.dopplerVsPixel[::-1], index) + p = np.polyfit(index-rgoff, dop, 3) + dopplerVsPixelSlave = [p[3], p[2], p[1], p[0]] + + tmpSlc = 'tmp.slc' + mbf(self._insar.masterSlc, tmpSlc, masterSwath.prf, 1.0, + masterSwath.burstLength, masterSwath.burstCycleLength-masterSwath.burstLength, + self._insar.burstUnsynchronizedTime * masterSwath.prf, + (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf, + masterSwath.azimuthFmrateVsPixel, masterSwath.dopplerVsPixel, dopplerVsPixelSlave) + + if os.path.isfile(self._insar.masterSlc): + os.remove(self._insar.masterSlc) + os.remove(self._insar.masterSlc+'.vrt') + os.remove(self._insar.masterSlc+'.xml') + + img = isceobj.createSlcImage() + img.load(tmpSlc + '.xml') + #remove original + os.remove(tmpSlc + '.vrt') + os.remove(tmpSlc + '.xml') + os.rename(tmpSlc, self._insar.masterSlc) + #creat new + img.setFilename(self._insar.masterSlc) + img.extraFilename = self._insar.masterSlc + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + + #filter slave + if not( + ((self._insar.modeCombination == 21) and (self._insar.burstSynchronization <= self.burstSynchronizationThreshold)) or \ + (self._insar.modeCombination == 31) + ): + print('no need to azimuth filter {}.'.format(self._insar.slaveSlc)) + else: + index = np.arange(slaveSwath.numberOfSamples) - rgoff + dop = np.polyval(masterSwath.dopplerVsPixel[::-1], index) + p = np.polyfit(index+rgoff, dop, 3) + dopplerVsPixelMaster = [p[3], p[2], p[1], p[0]] + + tmpSlc = 'tmp.slc' + mbf(self._insar.slaveSlc, tmpSlc, slaveSwath.prf, 1.0, + slaveSwath.burstLength, slaveSwath.burstCycleLength-slaveSwath.burstLength, + -self._insar.burstUnsynchronizedTime * slaveSwath.prf, + (slaveSwath.burstStartTime - slaveSwath.sensingStart).total_seconds() * slaveSwath.prf, + slaveSwath.azimuthFmrateVsPixel, slaveSwath.dopplerVsPixel, dopplerVsPixelMaster) + + if os.path.isfile(self._insar.slaveSlc): + os.remove(self._insar.slaveSlc) + os.remove(self._insar.slaveSlc+'.vrt') + os.remove(self._insar.slaveSlc+'.xml') + + img = isceobj.createSlcImage() + img.load(tmpSlc + '.xml') + #remove original + os.remove(tmpSlc + '.vrt') + os.remove(tmpSlc + '.xml') + os.rename(tmpSlc, self._insar.slaveSlc) + #creat new + img.setFilename(self._insar.slaveSlc) + img.extraFilename = self._insar.slaveSlc + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + + os.chdir('../') + os.chdir('../') + + #in case parameters changed + self._insar.saveTrack(masterTrack, master=True) + self._insar.saveTrack(slaveTrack, master=False) + + catalog.printToLog(logger, "runPrepareSlc") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def cropSlc(orbit, swath, slc, orbit2, swath2, edge=0, useVirtualFile=True): + from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_keyword + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + ''' + orbit: orbit of the image to be cropped + swath: swath of the image to be cropped + slc: image to be cropped + orbit2: orbit of the other image + swath2: swath of the other image + ''' + + #find topleft and lowerright corners + #all indices start with 0 + corner = [] + for x in [[0, 0], [swath2.numberOfLines -1, swath2.numberOfSamples-1]]: + line2 = x[0] + sample2 = x[1] + rg2 = swath2.startingRange + swath2.rangePixelSize * sample2 + az2 = swath2.sensingStart + datetime.timedelta(seconds = line2 / swath2.prf) + llh2 = orbit2.rdr2geo(az2, rg2) + az, rg = orbit.geo2rdr(llh2) + line = (az - swath.sensingStart).total_seconds() * swath.prf + sample = (rg - swath.startingRange) / swath.rangePixelSize + corner.append([line, sample]) + + #image (to be cropped) bounds + firstLine = 0 + lastLine = swath.numberOfLines-1 + firstSample = 0 + lastSample = swath.numberOfSamples-1 + + #the othe image bounds in image (to be cropped) + #add edge + #edge = 9 + firstLine2 = int(corner[0][0] - edge) + lastLine2 = int(corner[1][0] + edge) + firstSample2 = int(corner[0][1] - edge) + lastSample2 = int(corner[1][1] + edge) + + #image (to be cropped) output bounds + firstLine3 = max(firstLine, firstLine2) + lastLine3 = min(lastLine, lastLine2) + firstSample3 = max(firstSample, firstSample2) + lastSample3 = min(lastSample, lastSample2) + numberOfSamples3 = lastSample3-firstSample3+1 + numberOfLines3 = lastLine3-firstLine3+1 + + #check if there is overlap + if lastLine3 - firstLine3 +1 < 1000: + raise Exception('azimuth overlap < 1000 lines, not enough area for InSAR\n') + if lastSample3 - firstSample3 +1 < 1000: + raise Exception('range overlap < 1000 samples, not enough area for InSAR\n') + + #check if there is a need to crop image + if abs(firstLine3-firstLine) < 100 and abs(lastLine3-lastLine) < 100 and \ + abs(firstSample3-firstSample) < 100 and abs(lastSample3-lastSample) < 100: + print('no need to crop {}. nothing is done by crop.'.format(slc)) + return + + #crop image + if useVirtualFile: + #vrt + SourceFilename = find_vrt_keyword(slc+'.vrt', 'SourceFilename') + ImageOffset = int(find_vrt_keyword(slc+'.vrt', 'ImageOffset')) + PixelOffset = int(find_vrt_keyword(slc+'.vrt', 'PixelOffset')) + LineOffset = int(find_vrt_keyword(slc+'.vrt', 'LineOffset')) + + #overwrite vrt and xml + img = isceobj.createImage() + img.load(slc+'.xml') + img.width = numberOfSamples3 + img.length = numberOfLines3 + img.renderHdr() + + #overrite vrt + with open(slc+'.vrt', 'w') as fid: + fid.write(''' + + {2} + MSB + {3} + 8 + {4} + +'''.format(numberOfSamples3, + numberOfLines3, + SourceFilename, + ImageOffset + firstLine3*LineOffset + firstSample3*8, + LineOffset)) + else: + #read and crop data + with open(slc, 'rb') as f: + f.seek(firstLine3 * swath.numberOfSamples * np.dtype(np.complex64).itemsize, 0) + data = np.fromfile(f, dtype=np.complex64, count=numberOfLines3 * swath.numberOfSamples)\ + .reshape(numberOfLines3,swath.numberOfSamples) + data2 = data[:, firstSample3:lastSample3+1] + #overwrite original + data2.astype(np.complex64).tofile(slc) + + #creat new vrt and xml + os.remove(slc + '.xml') + os.remove(slc + '.vrt') + create_xml(slc, numberOfSamples3, numberOfLines3, 'slc') + + #update parameters + #update doppler and azfmrate first + dop = np.polyval(swath.dopplerVsPixel[::-1], np.arange(swath.numberOfSamples)) + dop3 = dop[firstSample3:lastSample3+1] + p = np.polyfit(np.arange(numberOfSamples3), dop3, 3) + swath.dopplerVsPixel = [p[3], p[2], p[1], p[0]] + + azfmrate = np.polyval(swath.azimuthFmrateVsPixel[::-1], np.arange(swath.numberOfSamples)) + azfmrate3 = azfmrate[firstSample3:lastSample3+1] + p = np.polyfit(np.arange(numberOfSamples3), azfmrate3, 3) + swath.azimuthFmrateVsPixel = [p[3], p[2], p[1], p[0]] + + swath.numberOfSamples = numberOfSamples3 + swath.numberOfLines = numberOfLines3 + + swath.startingRange += firstSample3 * swath.rangePixelSize + swath.sensingStart += datetime.timedelta(seconds = firstLine3 / swath.prf) + + #no need to update frame and track, as parameters requiring changes are determined + #in swath and frame mosaicking, which is not yet done at this point. + diff --git a/components/isceobj/Alos2Proc/runPreprocessor.py b/components/isceobj/Alos2Proc/runPreprocessor.py new file mode 100644 index 0000000..8652a01 --- /dev/null +++ b/components/isceobj/Alos2Proc/runPreprocessor.py @@ -0,0 +1,598 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +import numpy as np + +import isceobj +import isceobj.Sensor.MultiMode as MultiMode +from isceobj.Planet.Planet import Planet +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo + +logger = logging.getLogger('isce.alos2insar.runPreprocessor') + +def runPreprocessor(self): + '''Extract images. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + + + #find files + #actually no need to use absolute path any longer, since we are able to find file from vrt now. 27-JAN-2020, CRL. + #denseoffset may still need absolute path when making links + self.masterDir = os.path.abspath(self.masterDir) + self.slaveDir = os.path.abspath(self.slaveDir) + + ledFilesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'LED-ALOS2*-*-*'))) + imgFilesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*-*-*'.format(self.masterPolarization.upper())))) + + ledFilesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'LED-ALOS2*-*-*'))) + imgFilesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*-*-*'.format(self.slavePolarization.upper())))) + + firstFrameMaster = ledFilesMaster[0].split('-')[-3][-4:] + firstFrameSlave = ledFilesSlave[0].split('-')[-3][-4:] + firstFrameImagesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.masterPolarization.upper(), firstFrameMaster)))) + firstFrameImagesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.slavePolarization.upper(), firstFrameSlave)))) + + + #determin operation mode + masterMode = os.path.basename(ledFilesMaster[0]).split('-')[-1][0:3] + slaveMode = os.path.basename(ledFilesSlave[0]).split('-')[-1][0:3] + 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'] + + #usable combinations + if (masterMode in spotlightModes) and (slaveMode in spotlightModes): + self._insar.modeCombination = 0 + elif (masterMode in stripmapModes) and (slaveMode in stripmapModes): + self._insar.modeCombination = 1 + elif (masterMode in scansarNominalModes) and (slaveMode in scansarNominalModes): + self._insar.modeCombination = 21 + elif (masterMode in scansarWideModes) and (slaveMode in scansarWideModes): + self._insar.modeCombination = 22 + elif (masterMode in scansarNominalModes) and (slaveMode in stripmapModes): + self._insar.modeCombination = 31 + elif (masterMode in scansarWideModes) and (slaveMode in stripmapModes): + self._insar.modeCombination = 32 + else: + print('\n\nthis mode combination is not possible') + print('note that for ScanSAR-stripmap, ScanSAR must be master\n\n') + raise Exception('mode combination not supported') + +# pixel size from real data processing. azimuth pixel size may change a bit as +# the antenna points to a different swath and therefore uses a different PRF. + +# MODE RANGE PIXEL SIZE (LOOKS) AZIMUTH PIXEL SIZE (LOOKS) +# ------------------------------------------------------------------- +# SPT [SBS] +# 1.4304222392897463 (2) 0.9351804642158579 (4) +# SM1 [UBS,UBD] +# 1.4304222392897463 (2) 1.8291988125114438 (2) +# SM2 [HBS,HBD,HBQ] +# 2.8608444785794984 (2) 3.0672373839847196 (2) +# SM3 [FBS,FBD,FBQ] +# 4.291266717869248 (2) 3.2462615913656667 (4) + +# WD1 [WBS,WBD] [WWS,WWD] +# 8.582533435738496 (1) 2.6053935830031887 (14) +# 8.582533435738496 (1) 2.092362043327227 (14) +# 8.582533435738496 (1) 2.8817632034495717 (14) +# 8.582533435738496 (1) 3.054362492601842 (14) +# 8.582533435738496 (1) 2.4582084463356977 (14) + +# WD2 [VBS,VBD] +# 8.582533435738496 (1) 2.9215796012950728 (14) +# 8.582533435738496 (1) 3.088859074497863 (14) +# 8.582533435738496 (1) 2.8792293071133073 (14) +# 8.582533435738496 (1) 3.0592146044234854 (14) +# 8.582533435738496 (1) 2.8818767752199137 (14) +# 8.582533435738496 (1) 3.047038521027477 (14) +# 8.582533435738496 (1) 2.898816222039108 (14) + + #determine default number of looks: + self._insar.numberRangeLooks1 = self.numberRangeLooks1 + self._insar.numberAzimuthLooks1 = self.numberAzimuthLooks1 + self._insar.numberRangeLooks2 = self.numberRangeLooks2 + self._insar.numberAzimuthLooks2 = self.numberAzimuthLooks2 + #the following two will be automatically determined by runRdrDemOffset.py + self._insar.numberRangeLooksSim = self.numberRangeLooksSim + self._insar.numberAzimuthLooksSim = self.numberAzimuthLooksSim + self._insar.numberRangeLooksIon = self.numberRangeLooksIon + self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon + + if self._insar.numberRangeLooks1 == None: + if masterMode in ['SBS']: + self._insar.numberRangeLooks1 = 2 + elif masterMode in ['UBS', 'UBD']: + self._insar.numberRangeLooks1 = 2 + elif masterMode in ['HBS', 'HBD', 'HBQ']: + self._insar.numberRangeLooks1 = 2 + elif masterMode in ['FBS', 'FBD', 'FBQ']: + self._insar.numberRangeLooks1 = 2 + elif masterMode in ['WBS', 'WBD']: + self._insar.numberRangeLooks1 = 1 + elif masterMode in ['WWS', 'WWD']: + self._insar.numberRangeLooks1 = 2 + elif masterMode in ['VBS', 'VBD']: + self._insar.numberRangeLooks1 = 1 + else: + raise Exception('unknow acquisition mode') + + if self._insar.numberAzimuthLooks1 == None: + if masterMode in ['SBS']: + self._insar.numberAzimuthLooks1 = 4 + elif masterMode in ['UBS', 'UBD']: + self._insar.numberAzimuthLooks1 = 2 + elif masterMode in ['HBS', 'HBD', 'HBQ']: + self._insar.numberAzimuthLooks1 = 2 + elif masterMode in ['FBS', 'FBD', 'FBQ']: + self._insar.numberAzimuthLooks1 = 4 + elif masterMode in ['WBS', 'WBD']: + self._insar.numberAzimuthLooks1 = 14 + elif masterMode in ['WWS', 'WWD']: + self._insar.numberAzimuthLooks1 = 14 + elif masterMode in ['VBS', 'VBD']: + self._insar.numberAzimuthLooks1 = 14 + else: + raise Exception('unknow acquisition mode') + + if self._insar.numberRangeLooks2 == None: + if masterMode in spotlightModes: + self._insar.numberRangeLooks2 = 4 + elif masterMode in stripmapModes: + self._insar.numberRangeLooks2 = 4 + elif masterMode in scansarModes: + self._insar.numberRangeLooks2 = 5 + else: + raise Exception('unknow acquisition mode') + + if self._insar.numberAzimuthLooks2 == None: + if masterMode in spotlightModes: + self._insar.numberAzimuthLooks2 = 4 + elif masterMode in stripmapModes: + self._insar.numberAzimuthLooks2 = 4 + elif masterMode in scansarModes: + self._insar.numberAzimuthLooks2 = 2 + else: + raise Exception('unknow acquisition mode') + + if self._insar.numberRangeLooksIon == None: + if masterMode in spotlightModes: + self._insar.numberRangeLooksIon = 16 + elif masterMode in stripmapModes: + self._insar.numberRangeLooksIon = 16 + elif masterMode in scansarModes: + self._insar.numberRangeLooksIon = 40 + else: + raise Exception('unknow acquisition mode') + + if self._insar.numberAzimuthLooksIon == None: + if masterMode in spotlightModes: + self._insar.numberAzimuthLooksIon = 16 + elif masterMode in stripmapModes: + self._insar.numberAzimuthLooksIon = 16 + elif masterMode in scansarModes: + self._insar.numberAzimuthLooksIon = 16 + else: + raise Exception('unknow acquisition mode') + + + #define processing file names + self._insar.masterDate = os.path.basename(ledFilesMaster[0]).split('-')[2] + self._insar.slaveDate = os.path.basename(ledFilesSlave[0]).split('-')[2] + self._insar.setFilename(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, nrlks2=self._insar.numberRangeLooks2, nalks2=self._insar.numberAzimuthLooks2) + + + #find frame numbers + if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32): + if (self.masterFrames == None) or (self.slaveFrames == None): + raise Exception('for ScanSAR-stripmap inteferometry, you must set master and slave frame numbers') + #if not set, find frames automatically + if self.masterFrames == None: + self.masterFrames = [] + for led in ledFilesMaster: + frameNumber = os.path.basename(led).split('-')[1][-4:] + if frameNumber not in self.masterFrames: + self.masterFrames.append(frameNumber) + if self.slaveFrames == None: + self.slaveFrames = [] + for led in ledFilesSlave: + frameNumber = os.path.basename(led).split('-')[1][-4:] + if frameNumber not in self.slaveFrames: + self.slaveFrames.append(frameNumber) + #sort frames + self.masterFrames = sorted(self.masterFrames) + self.slaveFrames = sorted(self.slaveFrames) + #check number of frames + if len(self.masterFrames) != len(self.slaveFrames): + raise Exception('number of frames in master dir is not equal to number of frames \ + in slave dir. please set frame number manually') + + + #find swath numbers (if not ScanSAR-ScanSAR, compute valid swaths) + if (self._insar.modeCombination == 0) or (self._insar.modeCombination == 1): + self.startingSwath = 1 + self.endingSwath = 1 + + if self._insar.modeCombination == 21: + if self.startingSwath == None: + self.startingSwath = 1 + if self.endingSwath == None: + self.endingSwath = 5 + + if self._insar.modeCombination == 22: + if self.startingSwath == None: + self.startingSwath = 1 + if self.endingSwath == None: + self.endingSwath = 7 + + #determine starting and ending swaths for ScanSAR-stripmap, user's settings are overwritten + #use first frame to check overlap + if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32): + if self._insar.modeCombination == 31: + numberOfSwaths = 5 + else: + numberOfSwaths = 7 + overlapSubswaths = [] + for i in range(numberOfSwaths): + overlapRatio = check_overlap(ledFilesMaster[0], firstFrameImagesMaster[i], ledFilesSlave[0], firstFrameImagesSlave[0]) + if overlapRatio > 1.0 / 4.0: + overlapSubswaths.append(i+1) + if overlapSubswaths == []: + raise Exception('There is no overlap area between the ScanSAR-stripmap pair') + self.startingSwath = int(overlapSubswaths[0]) + self.endingSwath = int(overlapSubswaths[-1]) + + #save the valid frames and swaths for future processing + self._insar.masterFrames = self.masterFrames + self._insar.slaveFrames = self.slaveFrames + self._insar.startingSwath = self.startingSwath + self._insar.endingSwath = self.endingSwath + + + ################################################## + #1. create directories and read data + ################################################## + self.master.configure() + self.slave.configure() + self.master.track.configure() + self.slave.track.configure() + for i, (masterFrame, slaveFrame) in enumerate(zip(self._insar.masterFrames, self._insar.slaveFrames)): + #frame number starts with 1 + frameDir = 'f{}_{}'.format(i+1, masterFrame) + if not os.path.exists(frameDir): + os.makedirs(frameDir) + os.chdir(frameDir) + + #attach a frame to master and slave + frameObjMaster = MultiMode.createFrame() + frameObjSlave = MultiMode.createFrame() + frameObjMaster.configure() + frameObjSlave.configure() + self.master.track.frames.append(frameObjMaster) + self.slave.track.frames.append(frameObjSlave) + + #swath number starts with 1 + for j in range(self._insar.startingSwath, self._insar.endingSwath+1): + print('processing frame {} swath {}'.format(masterFrame, j)) + + swathDir = 's{}'.format(j) + if not os.path.exists(swathDir): + os.makedirs(swathDir) + os.chdir(swathDir) + + #attach a swath to master and slave + swathObjMaster = MultiMode.createSwath() + swathObjSlave = MultiMode.createSwath() + swathObjMaster.configure() + swathObjSlave.configure() + self.master.track.frames[-1].swaths.append(swathObjMaster) + self.slave.track.frames[-1].swaths.append(swathObjSlave) + + #setup master + self.master.leaderFile = sorted(glob.glob(os.path.join(self.masterDir, 'LED-ALOS2*{}-*-*'.format(masterFrame))))[0] + if masterMode in scansarModes: + self.master.imageFile = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.masterPolarization.upper(), masterFrame, j))))[0] + else: + self.master.imageFile = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.masterPolarization.upper(), masterFrame))))[0] + self.master.outputFile = self._insar.masterSlc + self.master.useVirtualFile = self.useVirtualFile + #read master + (imageFDR, imageData)=self.master.readImage() + (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.master.readLeader() + self.master.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.master.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.master.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + + #setup slave + self.slave.leaderFile = sorted(glob.glob(os.path.join(self.slaveDir, 'LED-ALOS2*{}-*-*'.format(slaveFrame))))[0] + if slaveMode in scansarModes: + self.slave.imageFile = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.slavePolarization.upper(), slaveFrame, j))))[0] + else: + self.slave.imageFile = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.slavePolarization.upper(), slaveFrame))))[0] + self.slave.outputFile = self._insar.slaveSlc + self.slave.useVirtualFile = self.useVirtualFile + #read slave + (imageFDR, imageData)=self.slave.readImage() + (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.slave.readLeader() + self.slave.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.slave.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.slave.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + + os.chdir('../') + self._insar.saveProduct(self.master.track.frames[-1], self._insar.masterFrameParameter) + self._insar.saveProduct(self.slave.track.frames[-1], self._insar.slaveFrameParameter) + os.chdir('../') + self._insar.saveProduct(self.master.track, self._insar.masterTrackParameter) + self._insar.saveProduct(self.slave.track, self._insar.slaveTrackParameter) + + + ################################################## + #2. compute burst synchronization + ################################################## + #burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights + #in one frame, real unsynchronized time is the same for all swaths + unsynTime = 0 + #real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime)) + #synTime = 0 + synPercentage = 0 + + numberOfFrames = len(self._insar.masterFrames) + numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1 + + for i, frameNumber in enumerate(self._insar.masterFrames): + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + masterSwath = self.master.track.frames[i].swaths[j] + slaveSwath = self.slave.track.frames[i].swaths[j] + #using Piyush's code for computing range and azimuth offsets + midRange = masterSwath.startingRange + masterSwath.rangePixelSize * masterSwath.numberOfSamples * 0.5 + midSensingStart = masterSwath.sensingStart + datetime.timedelta(seconds = masterSwath.numberOfLines * 0.5 / masterSwath.prf) + llh = self.master.track.orbit.rdr2geo(midSensingStart, midRange) + slvaz, slvrng = self.slave.track.orbit.geo2rdr(llh) + ###Translate to offsets + #note that slave range pixel size and prf might be different from master, here we assume there is a virtual slave with same + #range pixel size and prf + rgoff = ((slvrng - slaveSwath.startingRange) / masterSwath.rangePixelSize) - masterSwath.numberOfSamples * 0.5 + azoff = ((slvaz - slaveSwath.sensingStart).total_seconds() * masterSwath.prf) - masterSwath.numberOfLines * 0.5 + + #compute burst synchronization + #burst parameters for ScanSAR wide mode not estimed yet + if self._insar.modeCombination == 21: + scburstStartLine = (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf + azoff + #slave burst start times corresponding to master burst start times (100% synchronization) + scburstStartLines = np.arange(scburstStartLine - 100000*masterSwath.burstCycleLength, \ + scburstStartLine + 100000*masterSwath.burstCycleLength, \ + masterSwath.burstCycleLength) + dscburstStartLines = -((slaveSwath.burstStartTime - slaveSwath.sensingStart).total_seconds() * slaveSwath.prf - scburstStartLines) + #find the difference with minimum absolute value + unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))] + if np.absolute(unsynLines) >= slaveSwath.burstLength: + synLines = 0 + if unsynLines > 0: + unsynLines = slaveSwath.burstLength + else: + unsynLines = -slaveSwath.burstLength + else: + synLines = slaveSwath.burstLength - np.absolute(unsynLines) + + unsynTime += unsynLines / masterSwath.prf + synPercentage += synLines / masterSwath.burstLength * 100.0 + + catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / masterSwath.burstLength * 100.0), 'runPreprocessor') + + ############################################################################################ + #illustration of the sign of the number of unsynchronized lines (unsynLines) + #The convention is the same as ampcor offset, that is, + # slaveLineNumber = masterLineNumber + unsynLines + # + # |-----------------------| ------------ + # | | ^ + # | | | + # | | | unsynLines < 0 + # | | | + # | | \ / + # | | |-----------------------| + # | | | | + # | | | | + # |-----------------------| | | + # Master Burst | | + # | | + # | | + # | | + # | | + # |-----------------------| + # Slave Burst + # + # + ############################################################################################ + + ##burst parameters for ScanSAR wide mode not estimed yet + elif self._insar.modeCombination == 31: + #scansar is master + scburstStartLine = (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf + azoff + #slave burst start times corresponding to master burst start times (100% synchronization) + for k in range(-100000, 100000): + saz_burstx = scburstStartLine + masterSwath.burstCycleLength * k + st_burstx = slaveSwath.sensingStart + datetime.timedelta(seconds=saz_burstx / masterSwath.prf) + if saz_burstx >= 0.0 and saz_burstx <= slaveSwath.numberOfLines -1: + slaveSwath.burstStartTime = st_burstx + slaveSwath.burstLength = masterSwath.burstLength + slaveSwath.burstCycleLength = masterSwath.burstCycleLength + slaveSwath.swathNumber = masterSwath.swathNumber + break + #unsynLines = 0 + #synLines = masterSwath.burstLength + #unsynTime += unsynLines / masterSwath.prf + #synPercentage += synLines / masterSwath.burstLength * 100.0 + catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runPreprocessor') + else: + pass + + #overwrite original frame parameter file + if self._insar.modeCombination == 31: + frameDir = 'f{}_{}'.format(i+1, frameNumber) + self._insar.saveProduct(self.slave.track.frames[i], os.path.join(frameDir, self._insar.slaveFrameParameter)) + + #getting average + if self._insar.modeCombination == 21: + unsynTime /= numberOfFrames*numberOfSwaths + synPercentage /= numberOfFrames*numberOfSwaths + elif self._insar.modeCombination == 31: + unsynTime = 0. + synPercentage = 100. + else: + pass + + #record results + if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31): + self._insar.burstUnsynchronizedTime = unsynTime + self._insar.burstSynchronization = synPercentage + catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runPreprocessor') + + + ################################################## + #3. compute baseline + ################################################## + #only compute baseline at four corners and center of the master track + bboxRdr = getBboxRdr(self.master.track) + + rangeMin = bboxRdr[0] + rangeMax = bboxRdr[1] + azimuthTimeMin = bboxRdr[2] + azimuthTimeMax = bboxRdr[3] + + azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0) + rangeMid = (rangeMin + rangeMax) / 2.0 + + points = [[azimuthTimeMin, rangeMin], + [azimuthTimeMin, rangeMax], + [azimuthTimeMax, rangeMin], + [azimuthTimeMax, rangeMax], + [azimuthTimeMid, rangeMid]] + + Bpar = [] + Bperp = [] + #modify Piyush's code for computing baslines + refElp = Planet(pname='Earth').ellipsoid + for x in points: + masterSV = self.master.track.orbit.interpolate(x[0], method='hermite') + target = self.master.track.orbit.rdr2geo(x[0], x[1]) + + slvTime, slvrng = self.slave.track.orbit.geo2rdr(target) + slaveSV = self.slave.track.orbit.interpolateOrbit(slvTime, method='hermite') + + targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist()) + mxyz = np.array(masterSV.getPosition()) + mvel = np.array(masterSV.getVelocity()) + sxyz = np.array(slaveSV.getPosition()) + + aa = np.linalg.norm(sxyz-mxyz) + costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa) + + Bpar.append(aa*costheta) + + perp = aa * np.sqrt(1 - costheta*costheta) + direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel)) + Bperp.append(direction*perp) + + catalog.addItem('parallel baseline at upperleft of master track', Bpar[0], 'runPreprocessor') + catalog.addItem('parallel baseline at upperright of master track', Bpar[1], 'runPreprocessor') + catalog.addItem('parallel baseline at lowerleft of master track', Bpar[2], 'runPreprocessor') + catalog.addItem('parallel baseline at lowerright of master track', Bpar[3], 'runPreprocessor') + catalog.addItem('parallel baseline at center of master track', Bpar[4], 'runPreprocessor') + + catalog.addItem('perpendicular baseline at upperleft of master track', Bperp[0], 'runPreprocessor') + catalog.addItem('perpendicular baseline at upperright of master track', Bperp[1], 'runPreprocessor') + catalog.addItem('perpendicular baseline at lowerleft of master track', Bperp[2], 'runPreprocessor') + catalog.addItem('perpendicular baseline at lowerright of master track', Bperp[3], 'runPreprocessor') + catalog.addItem('perpendicular baseline at center of master track', Bperp[4], 'runPreprocessor') + + + ################################################## + #4. compute bounding box + ################################################## + masterBbox = getBboxGeo(self.master.track) + slaveBbox = getBboxGeo(self.slave.track) + + catalog.addItem('master bounding box', masterBbox, 'runPreprocessor') + catalog.addItem('slave bounding box', slaveBbox, 'runPreprocessor') + + + catalog.printToLog(logger, "runPreprocessor") + self._insar.procDoc.addAllFromCatalog(catalog) + + + +def check_overlap(ldr_m, img_m, ldr_s, img_s): + from isceobj.Constants import SPEED_OF_LIGHT + + rangeSamplingRateMaster, widthMaster, nearRangeMaster = read_param_for_checking_overlap(ldr_m, img_m) + rangeSamplingRateSlave, widthSlave, nearRangeSlave = read_param_for_checking_overlap(ldr_s, img_s) + + farRangeMaster = nearRangeMaster + (widthMaster-1) * 0.5 * SPEED_OF_LIGHT / rangeSamplingRateMaster + farRangeSlave = nearRangeSlave + (widthSlave-1) * 0.5 * SPEED_OF_LIGHT / rangeSamplingRateSlave + + #This should be good enough, although precise image offsets are not used. + if farRangeMaster <= nearRangeSlave: + overlapRatio = 0.0 + elif farRangeSlave <= nearRangeMaster: + overlapRatio = 0.0 + else: + # 0 1 2 3 + ranges = np.array([nearRangeMaster, farRangeMaster, nearRangeSlave, farRangeSlave]) + rangesIndex = np.argsort(ranges) + overlapRatio = ranges[rangesIndex[2]]-ranges[rangesIndex[1]] / (farRangeMaster-nearRangeMaster) + + return overlapRatio + + +def read_param_for_checking_overlap(leader_file, image_file): + from isceobj.Sensor import xmlPrefix + import isceobj.Sensor.CEOS as CEOS + + #read from leader file + fsampConst = { 104: 1.047915957140240E+08, + 52: 5.239579785701190E+07, + 34: 3.493053190467460E+07, + 17: 1.746526595233730E+07 } + + fp = open(leader_file,'rb') + leaderFDR = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/leader_file.xml'),dataFile=fp) + leaderFDR.parse() + fp.seek(leaderFDR.getEndOfRecordPosition()) + sceneHeaderRecord = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/scene_record.xml'),dataFile=fp) + sceneHeaderRecord.parse() + fp.seek(sceneHeaderRecord.getEndOfRecordPosition()) + + fsamplookup = int(sceneHeaderRecord.metadata['Range sampling rate in MHz']) + rangeSamplingRate = fsampConst[fsamplookup] + fp.close() + #print('{}'.format(rangeSamplingRate)) + + #read from image file + fp = open(image_file, 'rb') + imageFDR = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/image_file.xml'), dataFile=fp) + imageFDR.parse() + fp.seek(imageFDR.getEndOfRecordPosition()) + imageData = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/image_record.xml'), dataFile=fp) + imageData.parseFast() + + width = imageFDR.metadata['Number of pixels per line per SAR channel'] + near_range = imageData.metadata['Slant range to 1st data sample'] + fp.close() + #print('{}'.format(width)) + #print('{}'.format(near_range)) + + return (rangeSamplingRate, width, near_range) + + diff --git a/components/isceobj/Alos2Proc/runRdr2Geo.py b/components/isceobj/Alos2Proc/runRdr2Geo.py new file mode 100644 index 0000000..73a4a70 --- /dev/null +++ b/components/isceobj/Alos2Proc/runRdr2Geo.py @@ -0,0 +1,230 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar + +logger = logging.getLogger('isce.alos2insar.runRdr2Geo') + +def runRdr2Geo(self): + '''compute lat/lon/hgt + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + demFile = os.path.abspath(self._insar.dem) + wbdFile = os.path.abspath(self._insar.wbd) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + if self.useGPU and self._insar.hasGPU(): + topoGPU(masterTrack, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, demFile, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.los) + else: + snwe = topoCPU(masterTrack, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, demFile, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.los) + waterBodyRadar(self._insar.latitude, self._insar.longitude, wbdFile, self._insar.wbdOut) + + os.chdir('../') + + catalog.printToLog(logger, "runRdr2Geo") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def topoCPU(masterTrack, numberRangeLooks, numberAzimuthLooks, demFile, latFile, lonFile, hgtFile, losFile): + import datetime + import isceobj + from zerodop.topozero import createTopozero + from isceobj.Planet.Planet import Planet + + pointingDirection = {'right': -1, 'left' :1} + + demImage = isceobj.createDemImage() + demImage.load(demFile + '.xml') + demImage.setAccessMode('read') + + planet = Planet(pname='Earth') + + topo = createTopozero() + topo.slantRangePixelSpacing = numberRangeLooks * masterTrack.rangePixelSize + topo.prf = 1.0 / (numberAzimuthLooks*masterTrack.azimuthLineInterval) + topo.radarWavelength = masterTrack.radarWavelength + topo.orbit = masterTrack.orbit + topo.width = masterTrack.numberOfSamples + topo.length = masterTrack.numberOfLines + topo.wireInputPort(name='dem', object=demImage) + topo.wireInputPort(name='planet', object=planet) + topo.numberRangeLooks = 1 #must be set as 1 + topo.numberAzimuthLooks = 1 #must be set as 1 Cunren + topo.lookSide = pointingDirection[masterTrack.pointingDirection] + topo.sensingStart = masterTrack.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*masterTrack.azimuthLineInterval) + topo.rangeFirstSample = masterTrack.startingRange + (numberRangeLooks-1.0)/2.0*masterTrack.rangePixelSize + topo.demInterpolationMethod='BIQUINTIC' + + topo.latFilename = latFile + topo.lonFilename = lonFile + topo.heightFilename = hgtFile + topo.losFilename = losFile + #topo.incFilename = incName + #topo.maskFilename = mskName + + topo.topo() + + return list(topo.snwe) + + +def topoGPU(masterTrack, numberRangeLooks, numberAzimuthLooks, demFile, latFile, lonFile, hgtFile, losFile): + ''' + Try with GPU module. + ''' + import datetime + import numpy as np + from isceobj.Planet.Planet import Planet + from zerodop.GPUtopozero.GPUtopozero import PyTopozero + from isceobj.Util.Poly2D import Poly2D + from iscesys import DateTimeUtil as DTU + + pointingDirection = {'right': -1, 'left' :1} + + #creat poynomials + polyDoppler = Poly2D(name='topsApp_dopplerPoly') + polyDoppler.setWidth(masterTrack.numberOfSamples) + polyDoppler.setLength(masterTrack.numberOfLines) + polyDoppler.setNormRange(1.0) + polyDoppler.setNormAzimuth(1.0) + polyDoppler.setMeanRange(0.0) + polyDoppler.setMeanAzimuth(0.0) + polyDoppler.initPoly(rangeOrder=0,azimuthOrder=0, coeffs=[[0.]]) + polyDoppler.createPoly2D() + + slantRangeImage = Poly2D() + slantRangeImage.setWidth(masterTrack.numberOfSamples) + slantRangeImage.setLength(masterTrack.numberOfLines) + slantRangeImage.setNormRange(1.0) + slantRangeImage.setNormAzimuth(1.0) + slantRangeImage.setMeanRange(0.) + slantRangeImage.setMeanAzimuth(0.) + slantRangeImage.initPoly(rangeOrder=1,azimuthOrder=0, + coeffs=[[masterTrack.startingRange + (numberRangeLooks-1.0)/2.0*masterTrack.rangePixelSize,numberRangeLooks * masterTrack.rangePixelSize]]) + slantRangeImage.createPoly2D() + + #creat images + latImage = isceobj.createImage() + latImage.initImage(latFile, 'write', masterTrack.numberOfSamples, 'DOUBLE') + latImage.createImage() + + lonImage = isceobj.createImage() + lonImage.initImage(lonFile, 'write', masterTrack.numberOfSamples, 'DOUBLE') + lonImage.createImage() + + losImage = isceobj.createImage() + losImage.initImage(losFile, 'write', masterTrack.numberOfSamples, 'FLOAT', bands=2, scheme='BIL') + losImage.setCaster('write', 'DOUBLE') + losImage.createImage() + + heightImage = isceobj.createImage() + heightImage.initImage(hgtFile, 'write', masterTrack.numberOfSamples, 'DOUBLE') + heightImage.createImage() + + demImage = isceobj.createDemImage() + demImage.load(demFile + '.xml') + demImage.setCaster('read', 'FLOAT') + demImage.createImage() + + #compute a few things + t0 = masterTrack.sensingStart + datetime.timedelta(seconds=(numberAzimuthLooks-1.0)/2.0*masterTrack.azimuthLineInterval) + orb = masterTrack.orbit + pegHdg = np.radians( orb.getENUHeading(t0)) + elp = Planet(pname='Earth').ellipsoid + + #call gpu topo + topo = PyTopozero() + topo.set_firstlat(demImage.getFirstLatitude()) + topo.set_firstlon(demImage.getFirstLongitude()) + topo.set_deltalat(demImage.getDeltaLatitude()) + topo.set_deltalon(demImage.getDeltaLongitude()) + topo.set_major(elp.a) + topo.set_eccentricitySquared(elp.e2) + topo.set_rSpace(numberRangeLooks * masterTrack.rangePixelSize) + topo.set_r0(masterTrack.startingRange + (numberRangeLooks-1.0)/2.0*masterTrack.rangePixelSize) + topo.set_pegHdg(pegHdg) + topo.set_prf(1.0 / (numberAzimuthLooks*masterTrack.azimuthLineInterval)) + topo.set_t0(DTU.seconds_since_midnight(t0)) + topo.set_wvl(masterTrack.radarWavelength) + topo.set_thresh(.05) + topo.set_demAccessor(demImage.getImagePointer()) + topo.set_dopAccessor(polyDoppler.getPointer()) + topo.set_slrngAccessor(slantRangeImage.getPointer()) + topo.set_latAccessor(latImage.getImagePointer()) + topo.set_lonAccessor(lonImage.getImagePointer()) + topo.set_losAccessor(losImage.getImagePointer()) + topo.set_heightAccessor(heightImage.getImagePointer()) + topo.set_incAccessor(0) + topo.set_maskAccessor(0) + topo.set_numIter(25) + topo.set_idemWidth(demImage.getWidth()) + topo.set_idemLength(demImage.getLength()) + topo.set_ilrl(pointingDirection[masterTrack.pointingDirection]) + topo.set_extraIter(10) + topo.set_length(masterTrack.numberOfLines) + topo.set_width(masterTrack.numberOfSamples) + topo.set_nRngLooks(1) + topo.set_nAzLooks(1) + topo.set_demMethod(5) # BIQUINTIC METHOD + topo.set_orbitMethod(0) # HERMITE + + # Need to simplify orbit stuff later + nvecs = len(orb._stateVectors) + topo.set_orbitNvecs(nvecs) + topo.set_orbitBasis(1) # Is this ever different? + topo.createOrbit() # Initializes the empty orbit to the right allocated size + count = 0 + for sv in orb._stateVectors: + td = DTU.seconds_since_midnight(sv.getTime()) + pos = sv.getPosition() + vel = sv.getVelocity() + topo.set_orbitVector(count,td,pos[0],pos[1],pos[2],vel[0],vel[1],vel[2]) + count += 1 + + topo.runTopo() + + #tidy up + latImage.addDescription('Pixel-by-pixel latitude in degrees.') + latImage.finalizeImage() + latImage.renderHdr() + + lonImage.addDescription('Pixel-by-pixel longitude in degrees.') + lonImage.finalizeImage() + lonImage.renderHdr() + + heightImage.addDescription('Pixel-by-pixel height in meters.') + heightImage.finalizeImage() + heightImage.renderHdr() + + descr = '''Two channel Line-Of-Sight geometry image (all angles in degrees). Represents vector drawn from target to platform. + Channel 1: Incidence angle measured from vertical at target (always +ve). + Channel 2: Azimuth angle measured from North in Anti-clockwise direction.''' + losImage.setImageType('bil') + losImage.addDescription(descr) + losImage.finalizeImage() + losImage.renderHdr() + + demImage.finalizeImage() + + if slantRangeImage: + try: + slantRangeImage.finalizeImage() + except: + pass + + diff --git a/components/isceobj/Alos2Proc/runRdrDemOffset.py b/components/isceobj/Alos2Proc/runRdrDemOffset.py new file mode 100644 index 0000000..43630c9 --- /dev/null +++ b/components/isceobj/Alos2Proc/runRdrDemOffset.py @@ -0,0 +1,322 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from mroipac.ampcor.Ampcor import Ampcor +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from contrib.alos2proc.alos2proc import look +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml +from isceobj.Alos2Proc.Alos2ProcPublic import writeOffset +from contrib.alos2proc_f.alos2proc_f import fitoff + +logger = logging.getLogger('isce.alos2insar.runRdrDemOffset') + +def runRdrDemOffset(self): + '''estimate between radar image and dem + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + demFile = os.path.abspath(self._insar.dem) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + rdrDemDir = 'rdr_dem_offset' + if not os.path.exists(rdrDemDir): + os.makedirs(rdrDemDir) + os.chdir(rdrDemDir) + + ################################################################################################## + #compute dem pixel size + demImage = isceobj.createDemImage() + demImage.load(demFile + '.xml') + #DEM pixel size in meters (appoximate value) + demDeltaLon = abs(demImage.getDeltaLongitude()) / 0.0002777777777777778 * 30.0 + demDeltaLat = abs(demImage.getDeltaLatitude()) / 0.0002777777777777778 * 30.0 + + #number of looks to take in range + if self._insar.numberRangeLooksSim == None: + if self._insar.numberRangeLooks1 * masterTrack.rangePixelSize > demDeltaLon: + self._insar.numberRangeLooksSim = 1 + else: + self._insar.numberRangeLooksSim = int(demDeltaLon / (self._insar.numberRangeLooks1 * masterTrack.rangePixelSize) + 0.5) + #number of looks to take in azimuth + if self._insar.numberAzimuthLooksSim == None: + if self._insar.numberAzimuthLooks1 * masterTrack.azimuthPixelSize > demDeltaLat: + self._insar.numberAzimuthLooksSim = 1 + else: + self._insar.numberAzimuthLooksSim = int(demDeltaLat / (self._insar.numberAzimuthLooks1 * masterTrack.azimuthPixelSize) + 0.5) + + #simulate a radar image using dem + simulateRadar(os.path.join('../', self._insar.height), self._insar.sim, scale=3.0, offset=100.0) + sim = isceobj.createImage() + sim.load(self._insar.sim+'.xml') + + #take looks + if (self._insar.numberRangeLooksSim == 1) and (self._insar.numberAzimuthLooksSim == 1): + simLookFile = self._insar.sim + ampLookFile = 'amp_{}rlks_{}alks.float'.format(self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, + self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1) + cmd = "imageMath.py -e='sqrt(a_0*a_0+a_1*a_1)' --a={} -o {} -t float".format(os.path.join('../', self._insar.amplitude), ampLookFile) + runCmd(cmd) + else: + simLookFile = 'sim_{}rlks_{}alks.float'.format(self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, + self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1) + ampLookFile = 'amp_{}rlks_{}alks.float'.format(self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, + self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1) + ampTmpFile = 'amp_tmp.float' + look(self._insar.sim, simLookFile, sim.width, self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, 2, 0, 1) + look(os.path.join('../', self._insar.amplitude), ampTmpFile, sim.width, self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, 4, 1, 1) + + width = int(sim.width/self._insar.numberRangeLooksSim) + length = int(sim.length/self._insar.numberAzimuthLooksSim) + create_xml(simLookFile, width, length, 'float') + create_xml(ampTmpFile, width, length, 'amp') + + cmd = "imageMath.py -e='sqrt(a_0*a_0+a_1*a_1)' --a={} -o {} -t float".format(ampTmpFile, ampLookFile) + runCmd(cmd) + os.remove(ampTmpFile) + os.remove(ampTmpFile+'.vrt') + os.remove(ampTmpFile+'.xml') + + #initial number of offsets to use + numberOfOffsets = 800 + #compute land ratio to further determine the number of offsets to use + wbd=np.memmap(os.path.join('../', self._insar.wbdOut), dtype='byte', mode='r', shape=(sim.length, sim.width)) + landRatio = np.sum(wbd[0:sim.length:10, 0:sim.width:10]!=-1) / int(sim.length/10) / int(sim.width/10) + del wbd + if (landRatio <= 0.00125): + print('\n\nWARNING: land area too small for estimating offsets between radar and dem') + print('do not estimate offsets between radar and dem\n\n') + self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] + catalog.addItem('warning message', 'land area too small for estimating offsets between radar and dem', 'runRdrDemOffset') + + catalog.printToLog(logger, "runRdrDemOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + return + + #total number of offsets to use + numberOfOffsets /= landRatio + #allocate number of offsets in range/azimuth according to image width/length + width = int(sim.width/self._insar.numberRangeLooksSim) + length = int(sim.length/self._insar.numberAzimuthLooksSim) + #number of offsets to use in range/azimuth + numberOfOffsetsRange = int(np.sqrt(numberOfOffsets * width / length)) + numberOfOffsetsAzimuth = int(length / width * np.sqrt(numberOfOffsets * width / length)) + + #this should be better? + numberOfOffsetsRange = int(np.sqrt(numberOfOffsets)) + numberOfOffsetsAzimuth = int(np.sqrt(numberOfOffsets)) + + + if numberOfOffsetsRange > int(width/2): + numberOfOffsetsRange = int(width/2) + if numberOfOffsetsAzimuth > int(length/2): + numberOfOffsetsAzimuth = int(length/2) + + if numberOfOffsetsRange < 10: + numberOfOffsetsRange = 10 + if numberOfOffsetsAzimuth < 10: + numberOfOffsetsAzimuth = 10 + + catalog.addItem('number of range offsets', '{}'.format(numberOfOffsetsRange), 'runRdrDemOffset') + catalog.addItem('number of azimuth offsets', '{}'.format(numberOfOffsetsAzimuth), 'runRdrDemOffset') + + #matching + ampcor = Ampcor(name='insarapp_slcs_ampcor') + ampcor.configure() + + mMag = isceobj.createImage() + mMag.load(ampLookFile+'.xml') + mMag.setAccessMode('read') + mMag.createImage() + + sMag = isceobj.createImage() + sMag.load(simLookFile+'.xml') + sMag.setAccessMode('read') + sMag.createImage() + + ampcor.setImageDataType1('real') + ampcor.setImageDataType2('real') + + ampcor.setMasterSlcImage(mMag) + ampcor.setSlaveSlcImage(sMag) + + #MATCH REGION + rgoff = 0 + azoff = 0 + #it seems that we cannot use 0, haven't look into the problem + if rgoff == 0: + rgoff = 1 + if azoff == 0: + azoff = 1 + firstSample = 1 + if rgoff < 0: + firstSample = int(35 - rgoff) + firstLine = 1 + if azoff < 0: + firstLine = int(35 - azoff) + ampcor.setAcrossGrossOffset(rgoff) + ampcor.setDownGrossOffset(azoff) + ampcor.setFirstSampleAcross(firstSample) + ampcor.setLastSampleAcross(width) + ampcor.setNumberLocationAcross(numberOfOffsetsRange) + ampcor.setFirstSampleDown(firstLine) + ampcor.setLastSampleDown(length) + ampcor.setNumberLocationDown(numberOfOffsetsAzimuth) + + #MATCH PARAMETERS + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(64) + #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1 + ampcor.setSearchWindowSizeWidth(16) + ampcor.setSearchWindowSizeHeight(16) + + #REST OF THE STUFF + ampcor.setAcrossLooks(1) + ampcor.setDownLooks(1) + ampcor.setOversamplingFactor(64) + ampcor.setZoomWindowSize(16) + #1. The following not set + #Matching Scale for Sample/Line Directions (-) = 1. 1. + #should add the following in Ampcor.py? + #if not set, in this case, Ampcor.py'value is also 1. 1. + #ampcor.setScaleFactorX(1.) + #ampcor.setScaleFactorY(1.) + + #MATCH THRESHOLDS AND DEBUG DATA + #2. The following not set + #in roi_pac the value is set to 0 1 + #in isce the value is set to 0.001 1000.0 + #SNR and Covariance Thresholds (-) = {s1} {s2} + #should add the following in Ampcor? + #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC + #ampcor.setThresholdSNR(0) + #ampcor.setThresholdCov(1) + ampcor.setDebugFlag(False) + ampcor.setDisplayFlag(False) + + #in summary, only two things not set which are indicated by 'The following not set' above. + + #run ampcor + ampcor.ampcor() + offsets = ampcor.getOffsetField() + ampcorOffsetFile = 'ampcor.off' + cullOffsetFile = 'cull.off' + affineTransformFile = 'affine_transform.txt' + writeOffset(offsets, ampcorOffsetFile) + + #finalize image, and re-create it + #otherwise the file pointer is still at the end of the image + mMag.finalizeImage() + sMag.finalizeImage() + + # #cull offsets + # import io + # from contextlib import redirect_stdout + # f = io.StringIO() + # with redirect_stdout(f): + # fitoff(ampcorOffsetFile, cullOffsetFile, 1.5, .5, 50) + # s = f.getvalue() + # #print(s) + # with open(affineTransformFile, 'w') as f: + # f.write(s) + + #cull offsets + import subprocess + proc = subprocess.Popen(["python3", "-c", "import isce; from contrib.alos2proc_f.alos2proc_f import fitoff; fitoff('ampcor.off', 'cull.off', 1.5, .5, 50)"], stdout=subprocess.PIPE) + out = proc.communicate()[0] + with open(affineTransformFile, 'w') as f: + f.write(out.decode('utf-8')) + + #check number of offsets left + with open(cullOffsetFile, 'r') as f: + numCullOffsets = sum(1 for linex in f) + if numCullOffsets < 50: + print('\n\nWARNING: too few points left after culling, {} left'.format(numCullOffsets)) + print('do not estimate offsets between radar and dem\n\n') + self._insar.radarDemAffineTransform = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] + catalog.addItem('warning message', 'too few points left after culling, {} left'.format(numCullOffsets), 'runRdrDemOffset') + + catalog.printToLog(logger, "runRdrDemOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + return + + #read affine transform parameters + with open(affineTransformFile) as f: + lines = f.readlines() + i = 0 + for linex in lines: + if 'Affine Matrix ' in linex: + m11 = float(lines[i + 2].split()[0]) + m12 = float(lines[i + 2].split()[1]) + m21 = float(lines[i + 3].split()[0]) + m22 = float(lines[i + 3].split()[1]) + t1 = float(lines[i + 7].split()[0]) + t2 = float(lines[i + 7].split()[1]) + break + i += 1 + + self._insar.radarDemAffineTransform = [m11, m12, m21, m22, t1, t2] + ################################################################################################## + + os.chdir('../../') + + + catalog.printToLog(logger, "runRdrDemOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def simulateRadar(hgtfile, simfile, scale=3.0, offset=100.0): + ''' + simulate a radar image by computing gradient of a dem image. + ''' + import numpy as np + import isceobj + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + #set chunk length here for efficient processing + ############################################### + chunk_length = 1000 + ############################################### + + hgt = isceobj.createImage() + hgt.load(hgtfile+'.xml') + + chunk_width = hgt.width + num_chunk = int(hgt.length/chunk_length) + chunk_length_last = hgt.length - num_chunk * chunk_length + + simData = np.zeros((chunk_length, chunk_width), dtype=np.float32) + + hgtfp = open(hgtfile,'rb') + simfp = open(simfile,'wb') + + print("simulating a radar image using topography") + for i in range(num_chunk): + print("processing chunk %6d of %6d" % (i+1, num_chunk), end='\r', flush=True) + hgtData = np.fromfile(hgtfp, dtype=np.float64, count=chunk_length*chunk_width).reshape(chunk_length, chunk_width) + simData[:, 0:chunk_width-1] = scale * np.diff(hgtData, axis=1) + offset + simData.astype(np.float32).tofile(simfp) + + print("processing chunk %6d of %6d" % (num_chunk, num_chunk)) + if chunk_length_last != 0: + hgtData = np.fromfile(hgtfp, dtype=np.float64, count=chunk_length_last*chunk_width).reshape(chunk_length_last, chunk_width) + simData[0:chunk_length_last, 0:chunk_width-1] = scale * np.diff(hgtData, axis=1) + offset + (simData[0:chunk_length_last, :]).astype(np.float32).tofile(simfp) + + hgtfp.close() + simfp.close() + create_xml(simfile, hgt.width, hgt.length, 'float') diff --git a/components/isceobj/Alos2Proc/runRectRangeOffset.py b/components/isceobj/Alos2Proc/runRectRangeOffset.py new file mode 100644 index 0000000..fea2b81 --- /dev/null +++ b/components/isceobj/Alos2Proc/runRectRangeOffset.py @@ -0,0 +1,57 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from contrib.alos2proc_f.alos2proc_f import rect_with_looks +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2insar.runRectRangeOffset') + +def runRectRangeOffset(self): + '''rectify range offset + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + #rectify + rgoff = isceobj.createImage() + rgoff.load(self._insar.rangeOffset+'.xml') + + if self._insar.radarDemAffineTransform == [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]: + if not os.path.isfile(self._insar.rectRangeOffset): + os.symlink(self._insar.rangeOffset, self._insar.rectRangeOffset) + create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float') + else: + rect_with_looks(self._insar.rangeOffset, + self._insar.rectRangeOffset, + rgoff.width, rgoff.length, + rgoff.width, rgoff.length, + self._insar.radarDemAffineTransform[0], self._insar.radarDemAffineTransform[1], + self._insar.radarDemAffineTransform[2], self._insar.radarDemAffineTransform[3], + self._insar.radarDemAffineTransform[4], self._insar.radarDemAffineTransform[5], + self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1, + self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + 'REAL', + 'Bilinear') + create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float') + + os.chdir('../') + + catalog.printToLog(logger, "runRectRangeOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2Proc/runSlcMatch.py b/components/isceobj/Alos2Proc/runSlcMatch.py new file mode 100644 index 0000000..ab3ed0f --- /dev/null +++ b/components/isceobj/Alos2Proc/runSlcMatch.py @@ -0,0 +1,273 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.runRdr2Geo import topoCPU +from isceobj.Alos2Proc.runRdr2Geo import topoGPU +from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrCPU +from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrGPU +from contrib.alos2proc.alos2proc import resamp +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml +from isceobj.Alos2Proc.Alos2ProcPublic import renameFile +from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar +from mroipac.ampcor.Ampcor import Ampcor +from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset +from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsetsRoipac + +logger = logging.getLogger('isce.alos2insar.runSlcMatch') + +def runSlcMatch(self): + '''match a pair of SLCs + ''' + if not self.doDenseOffset: + return + if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)): + return + + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + demFile = os.path.abspath(self._insar.dem) + wbdFile = os.path.abspath(self._insar.wbd) + + denseOffsetDir = 'dense_offset' + if not os.path.exists(denseOffsetDir): + os.makedirs(denseOffsetDir) + os.chdir(denseOffsetDir) + + masterTrack = self._insar.loadProduct(self._insar.masterTrackParameter) + slaveTrack = self._insar.loadProduct(self._insar.slaveTrackParameter) + +######################################################################################### + + + ################################################## + # compute geometric offsets + ################################################## + if self.useGPU and self._insar.hasGPU(): + topoGPU(masterTrack, 1, 1, demFile, + 'lat.rdr', 'lon.rdr', 'hgt.rdr', 'los.rdr') + geo2RdrGPU(slaveTrack, 1, 1, + 'lat.rdr', 'lon.rdr', 'hgt.rdr', 'rg.off', 'az.off') + else: + topoCPU(masterTrack, 1, 1, demFile, + 'lat.rdr', 'lon.rdr', 'hgt.rdr', 'los.rdr') + geo2RdrCPU(slaveTrack, 1, 1, + 'lat.rdr', 'lon.rdr', 'hgt.rdr', 'rg.off', 'az.off') + + + ################################################## + # resample SLC + ################################################## + #SlaveSlcResampled = os.path.splitext(self._insar.slaveSlc)[0]+'_resamp'+os.path.splitext(self._insar.slaveSlc)[1] + SlaveSlcResampled = self._insar.slaveSlcCoregistered + rangeOffsets2Frac = 0.0 + azimuthOffsets2Frac = 0.0 + resamp(self._insar.slaveSlc, + SlaveSlcResampled, + 'rg.off', + 'az.off', + masterTrack.numberOfSamples, masterTrack.numberOfLines, + slaveTrack.prf, + slaveTrack.dopplerVsPixel, + [rangeOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [azimuthOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) + create_xml(SlaveSlcResampled, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'slc') + + + if self.estimateResidualOffset: + + numberOfOffsets = 800 + rangeStep = 50 + + length = masterTrack.numberOfLines + width = masterTrack.numberOfSamples + waterBodyRadar('lat.rdr', 'lon.rdr', wbdFile, 'wbd.rdr') + wbd=np.memmap('wbd.rdr', dtype=np.int8, mode='r', shape=(length, width)) + azimuthStep = int(length/width*rangeStep+0.5) + landRatio = np.sum(wbd[0:length:azimuthStep,0:width:rangeStep]!=-1)/(int(length/azimuthStep)*int(width/rangeStep)) + del wbd + + if (landRatio <= 0.00125): + print('\n\nWARNING: land area too small for estimating residual slc offsets') + print('do not estimate residual offsets\n\n') + catalog.addItem('warning message', 'land area too small for estimating residual slc offsets', 'runSlcMatch') + else: + numberOfOffsets /= landRatio + #we use equal number of offsets in range and azimuth here + numberOfOffsetsRange = int(np.sqrt(numberOfOffsets)+0.5) + numberOfOffsetsAzimuth = int(np.sqrt(numberOfOffsets)+0.5) + if numberOfOffsetsRange > int(width/2): + numberOfOffsetsRange = int(width/2) + if numberOfOffsetsAzimuth > int(length/2): + numberOfOffsetsAzimuth = int(length/2) + if numberOfOffsetsRange < 10: + numberOfOffsetsRange = 10 + if numberOfOffsetsAzimuth < 10: + numberOfOffsetsAzimuth = 10 + + + ########################################## + #2. match using ampcor + ########################################## + ampcor = Ampcor(name='insarapp_slcs_ampcor') + ampcor.configure() + + mSLC = isceobj.createSlcImage() + mSLC.load(self._insar.masterSlc+'.xml') + mSLC.setAccessMode('read') + mSLC.createImage() + + sSLC = isceobj.createSlcImage() + sSLC.load(SlaveSlcResampled+'.xml') + sSLC.setAccessMode('read') + sSLC.createImage() + + ampcor.setImageDataType1('complex') + ampcor.setImageDataType2('complex') + + ampcor.setMasterSlcImage(mSLC) + ampcor.setSlaveSlcImage(sSLC) + + #MATCH REGION + #compute an offset at image center to use + rgoff = 0.0 + azoff = 0.0 + #it seems that we cannot use 0, haven't look into the problem + if rgoff == 0: + rgoff = 1 + if azoff == 0: + azoff = 1 + firstSample = 1 + if rgoff < 0: + firstSample = int(35 - rgoff) + firstLine = 1 + if azoff < 0: + firstLine = int(35 - azoff) + ampcor.setAcrossGrossOffset(rgoff) + ampcor.setDownGrossOffset(azoff) + ampcor.setFirstSampleAcross(firstSample) + ampcor.setLastSampleAcross(mSLC.width) + ampcor.setNumberLocationAcross(numberOfOffsetsRange) + ampcor.setFirstSampleDown(firstLine) + ampcor.setLastSampleDown(mSLC.length) + ampcor.setNumberLocationDown(numberOfOffsetsAzimuth) + + #MATCH PARAMETERS + #full-aperture mode + if (self._insar.modeCombination == 21) or \ + (self._insar.modeCombination == 22) or \ + (self._insar.modeCombination == 31) or \ + (self._insar.modeCombination == 32): + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(512) + #note this is the half width/length of search area, number of resulting correlation samples: 32*2+1 + ampcor.setSearchWindowSizeWidth(32) + ampcor.setSearchWindowSizeHeight(32) + #triggering full-aperture mode matching + ampcor.setWinsizeFilt(8) + ampcor.setOversamplingFactorFilt(64) + #regular mode + else: + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(64) + ampcor.setSearchWindowSizeWidth(16) + ampcor.setSearchWindowSizeHeight(16) + + #REST OF THE STUFF + ampcor.setAcrossLooks(1) + ampcor.setDownLooks(1) + ampcor.setOversamplingFactor(64) + ampcor.setZoomWindowSize(16) + #1. The following not set + #Matching Scale for Sample/Line Directions (-) = 1. 1. + #should add the following in Ampcor.py? + #if not set, in this case, Ampcor.py'value is also 1. 1. + #ampcor.setScaleFactorX(1.) + #ampcor.setScaleFactorY(1.) + + #MATCH THRESHOLDS AND DEBUG DATA + #2. The following not set + #in roi_pac the value is set to 0 1 + #in isce the value is set to 0.001 1000.0 + #SNR and Covariance Thresholds (-) = {s1} {s2} + #should add the following in Ampcor? + #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC + #ampcor.setThresholdSNR(0) + #ampcor.setThresholdCov(1) + ampcor.setDebugFlag(False) + ampcor.setDisplayFlag(False) + + #in summary, only two things not set which are indicated by 'The following not set' above. + + #run ampcor + ampcor.ampcor() + offsets = ampcor.getOffsetField() + mSLC.finalizeImage() + sSLC.finalizeImage() + + + #3. cull offsets + refinedOffsets = cullOffsetsRoipac(offsets, numThreshold=50) + if refinedOffsets == None: + print('\n\nWARNING: too few offsets left for slc residual offset estimation') + print('do not estimate residual offsets\n\n') + catalog.addItem('warning message', 'too few offsets left for slc residual offset estimation', 'runSlcMatch') + else: + rangeOffset, azimuthOffset = meanOffset(refinedOffsets) + os.remove(SlaveSlcResampled) + os.remove(SlaveSlcResampled+'.vrt') + os.remove(SlaveSlcResampled+'.xml') + + rangeOffsets2Frac = rangeOffset + azimuthOffsets2Frac = azimuthOffset + resamp(self._insar.slaveSlc, + SlaveSlcResampled, + 'rg.off', + 'az.off', + masterTrack.numberOfSamples, masterTrack.numberOfLines, + slaveTrack.prf, + slaveTrack.dopplerVsPixel, + [rangeOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + [azimuthOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) + create_xml(SlaveSlcResampled, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'slc') + + catalog.addItem('number of offsets range', numberOfOffsetsRange, 'runSlcMatch') + catalog.addItem('number of offsets azimuth', numberOfOffsetsAzimuth, 'runSlcMatch') + catalog.addItem('range residual offset after geometric coregistration', rangeOffset, 'runSlcMatch') + catalog.addItem('azimuth residual offset after geometric coregistration', azimuthOffset, 'runSlcMatch') + + + + + if self.deleteGeometryFiles: + os.remove('lat.rdr') + os.remove('lat.rdr.vrt') + os.remove('lat.rdr.xml') + os.remove('lon.rdr') + os.remove('lon.rdr.vrt') + os.remove('lon.rdr.xml') + os.remove('hgt.rdr') + os.remove('hgt.rdr.vrt') + os.remove('hgt.rdr.xml') + os.remove('los.rdr') + os.remove('los.rdr.vrt') + os.remove('los.rdr.xml') + # if os.path.isfile('wbd.rdr'): + # os.remove('wbd.rdr') + # os.remove('wbd.rdr.vrt') + # os.remove('wbd.rdr.xml') + +######################################################################################### + + os.chdir('../') + catalog.printToLog(logger, "runSlcMatch") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2Proc/runSlcMosaic.py b/components/isceobj/Alos2Proc/runSlcMosaic.py new file mode 100644 index 0000000..c3d9e57 --- /dev/null +++ b/components/isceobj/Alos2Proc/runSlcMosaic.py @@ -0,0 +1,182 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.runFrameOffset import frameOffset +from isceobj.Alos2Proc.runFrameMosaic import frameMosaic +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2insar.runSlcMosaic') + +def runSlcMosaic(self): + '''mosaic SLCs + ''' + if not self.doDenseOffset: + print('\ndense offset not requested, skip this and the remaining steps...') + return + if not ((self._insar.modeCombination == 0) or (self._insar.modeCombination == 1)): + print('dense offset only support spotligh-spotlight and stripmap-stripmap pairs') + return + + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + denseOffsetDir = 'dense_offset' + if not os.path.exists(denseOffsetDir): + os.makedirs(denseOffsetDir) + os.chdir(denseOffsetDir) + + + ################################################## + # estimate master and slave frame offsets + ################################################## + if len(masterTrack.frames) > 1: + matchingMode=1 + + #if master offsets from matching are not already computed + if self.frameOffsetMatching == False: + offsetMaster = frameOffset(masterTrack, self._insar.masterSlc, self._insar.masterFrameOffset, + crossCorrelation=True, matchingMode=matchingMode) + offsetSlave = frameOffset(slaveTrack, self._insar.slaveSlc, self._insar.slaveFrameOffset, + crossCorrelation=True, matchingMode=matchingMode) + if self.frameOffsetMatching == False: + self._insar.frameRangeOffsetMatchingMaster = offsetMaster[2] + self._insar.frameAzimuthOffsetMatchingMaster = offsetMaster[3] + self._insar.frameRangeOffsetMatchingSlave = offsetSlave[2] + self._insar.frameAzimuthOffsetMatchingSlave = offsetSlave[3] + + + ################################################## + # mosaic slc + ################################################## + numberOfFrames = len(masterTrack.frames) + if numberOfFrames == 1: + import shutil + #frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.masterFrames[0])) + frameDir = os.path.join('f1_{}/s{}'.format(self._insar.masterFrames[0], self._insar.startingSwath)) + if not os.path.isfile(self._insar.masterSlc): + if os.path.isfile(os.path.join('../', frameDir, self._insar.masterSlc)): + os.symlink(os.path.join('../', frameDir, self._insar.masterSlc), self._insar.masterSlc) + #shutil.copy2() can overwrite + shutil.copy2(os.path.join('../', frameDir, self._insar.masterSlc+'.vrt'), self._insar.masterSlc+'.vrt') + shutil.copy2(os.path.join('../', frameDir, self._insar.masterSlc+'.xml'), self._insar.masterSlc+'.xml') + if not os.path.isfile(self._insar.slaveSlc): + if os.path.isfile(os.path.join('../', frameDir, self._insar.slaveSlc)): + os.symlink(os.path.join('../', frameDir, self._insar.slaveSlc), self._insar.slaveSlc) + shutil.copy2(os.path.join('../', frameDir, self._insar.slaveSlc+'.vrt'), self._insar.slaveSlc+'.vrt') + shutil.copy2(os.path.join('../', frameDir, self._insar.slaveSlc+'.xml'), self._insar.slaveSlc+'.xml') + + #update track parameters + ######################################################### + #mosaic size + masterTrack.numberOfSamples = masterTrack.frames[0].swaths[0].numberOfSamples + masterTrack.numberOfLines = masterTrack.frames[0].swaths[0].numberOfLines + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + masterTrack.startingRange = masterTrack.frames[0].swaths[0].startingRange + masterTrack.rangeSamplingRate = masterTrack.frames[0].swaths[0].rangeSamplingRate + masterTrack.rangePixelSize = masterTrack.frames[0].swaths[0].rangePixelSize + #azimuth parameters + masterTrack.sensingStart = masterTrack.frames[0].swaths[0].sensingStart + masterTrack.prf = masterTrack.frames[0].swaths[0].prf + masterTrack.azimuthPixelSize = masterTrack.frames[0].swaths[0].azimuthPixelSize + masterTrack.azimuthLineInterval = masterTrack.frames[0].swaths[0].azimuthLineInterval + + masterTrack.dopplerVsPixel = masterTrack.frames[0].swaths[0].dopplerVsPixel + + #update track parameters, slave + ######################################################### + #mosaic size + slaveTrack.numberOfSamples = slaveTrack.frames[0].swaths[0].numberOfSamples + slaveTrack.numberOfLines = slaveTrack.frames[0].swaths[0].numberOfLines + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + slaveTrack.startingRange = slaveTrack.frames[0].swaths[0].startingRange + slaveTrack.rangeSamplingRate = slaveTrack.frames[0].swaths[0].rangeSamplingRate + slaveTrack.rangePixelSize = slaveTrack.frames[0].swaths[0].rangePixelSize + #azimuth parameters + slaveTrack.sensingStart = slaveTrack.frames[0].swaths[0].sensingStart + slaveTrack.prf = slaveTrack.frames[0].swaths[0].prf + slaveTrack.azimuthPixelSize = slaveTrack.frames[0].swaths[0].azimuthPixelSize + slaveTrack.azimuthLineInterval = slaveTrack.frames[0].swaths[0].azimuthLineInterval + + slaveTrack.dopplerVsPixel = slaveTrack.frames[0].swaths[0].dopplerVsPixel + + else: + #mosaic master slc + ######################################################### + #choose offsets + rangeOffsets = self._insar.frameRangeOffsetMatchingMaster + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster + + #list of input files + slcs = [] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + swathDir = 's{}'.format(self._insar.startingSwath) + slcs.append(os.path.join('../', frameDir, swathDir, self._insar.masterSlc)) + + #note that track parameters are updated after mosaicking + #parameters update is checked, it is OK. + frameMosaic(masterTrack, slcs, self._insar.masterSlc, + rangeOffsets, azimuthOffsets, 1, 1, + updateTrack=True, phaseCompensation=True, resamplingMethod=2) + create_xml(self._insar.masterSlc, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'slc') + masterTrack.dopplerVsPixel = computeTrackDoppler(masterTrack) + + #mosaic slave slc + ######################################################### + #choose offsets + rangeOffsets = self._insar.frameRangeOffsetMatchingSlave + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingSlave + + #list of input files + slcs = [] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + swathDir = 's{}'.format(self._insar.startingSwath) + slcs.append(os.path.join('../', frameDir, swathDir, self._insar.slaveSlc)) + + #note that track parameters are updated after mosaicking + #parameters update is checked, it is OK. + frameMosaic(slaveTrack, slcs, self._insar.slaveSlc, + rangeOffsets, azimuthOffsets, 1, 1, + updateTrack=True, phaseCompensation=True, resamplingMethod=2) + create_xml(self._insar.slaveSlc, slaveTrack.numberOfSamples, slaveTrack.numberOfLines, 'slc') + slaveTrack.dopplerVsPixel = computeTrackDoppler(slaveTrack) + + + #save parameter file inside denseoffset directory + self._insar.saveProduct(masterTrack, self._insar.masterTrackParameter) + self._insar.saveProduct(slaveTrack, self._insar.slaveTrackParameter) + + + os.chdir('../') + catalog.printToLog(logger, "runSlcMosaic") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def computeTrackDoppler(track): + ''' + compute doppler for a track + ''' + numberOfFrames = len(track.frames) + dop = np.zeros(track.numberOfSamples) + for i in range(numberOfFrames): + index = track.startingRange + np.arange(track.numberOfSamples) * track.rangePixelSize + index = (index - track.frames[i].swaths[0].startingRange) / track.frames[i].swaths[0].rangePixelSize + dop = dop + np.polyval(track.frames[i].swaths[0].dopplerVsPixel[::-1], index) + + index1 = np.arange(track.numberOfSamples) + dop1 = dop/numberOfFrames + p = np.polyfit(index1, dop1, 3) + + return [p[3], p[2], p[1], p[0]] diff --git a/components/isceobj/Alos2Proc/runSlcOffset.py b/components/isceobj/Alos2Proc/runSlcOffset.py new file mode 100644 index 0000000..e052aea --- /dev/null +++ b/components/isceobj/Alos2Proc/runSlcOffset.py @@ -0,0 +1,275 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +import numpy as np + +import isceobj +import mroipac +from mroipac.ampcor.Ampcor import Ampcor +from isceobj.Alos2Proc.Alos2ProcPublic import topo +from isceobj.Alos2Proc.Alos2ProcPublic import geo2rdr +from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar +from isceobj.Alos2Proc.Alos2ProcPublic import reformatGeometricalOffset +from isceobj.Alos2Proc.Alos2ProcPublic import writeOffset +from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsets +from isceobj.Alos2Proc.Alos2ProcPublic import computeOffsetFromOrbit + +logger = logging.getLogger('isce.alos2insar.runSlcOffset') + +def runSlcOffset(self): + '''estimate SLC offsets + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + demFile = os.path.abspath(self._insar.dem) + wbdFile = os.path.abspath(self._insar.wbd) + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('estimating offset frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + ########################################## + #1. set number of matching points + ########################################## + #set initinial numbers + if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 22): + numberOfOffsetsRange = 10 + numberOfOffsetsAzimuth = 40 + else: + numberOfOffsetsRange = 20 + numberOfOffsetsAzimuth = 20 + + #change the initial numbers using water body + if self.useWbdForNumberOffsets and (self._insar.wbd != None): + numberRangeLooks=100 + numberAzimuthLooks=100 + #compute land ratio using topo module + topo(masterSwath, masterTrack, demFile, 'lat.rdr', 'lon.rdr', 'hgt.rdr', losFile='los.rdr', + incFile=None, mskFile=None, + numberRangeLooks=numberRangeLooks, numberAzimuthLooks=numberAzimuthLooks, multilookTimeOffset=False) + waterBodyRadar('lat.rdr', 'lon.rdr', wbdFile, 'wbd.rdr') + + wbdImg = isceobj.createImage() + wbdImg.load('wbd.rdr.xml') + width = wbdImg.width + length = wbdImg.length + + wbd = np.fromfile('wbd.rdr', dtype=np.byte).reshape(length, width) + landRatio = np.sum(wbd==0) / (length*width) + + if (landRatio <= 0.00125): + print('\n\nWARNING: land too small for estimating slc offsets at frame {}, swath {}'.format(frameNumber, swathNumber)) + print('proceed to use geometric offsets for forming interferogram') + print('but please consider not using this swath\n\n') + catalog.addItem('warning message', 'land too small for estimating slc offsets at frame {}, swath {}, use geometric offsets'.format(frameNumber, swathNumber), 'runSlcOffset') + + #compute geomtricla offsets + geo2rdr(slaveSwath, slaveTrack, 'lat.rdr', 'lon.rdr', 'hgt.rdr', 'rg.rdr', 'az.rdr', numberRangeLooks=numberRangeLooks, numberAzimuthLooks=numberAzimuthLooks, multilookTimeOffset=False) + reformatGeometricalOffset('rg.rdr', 'az.rdr', 'cull.off', rangeStep=numberRangeLooks, azimuthStep=numberAzimuthLooks, maximumNumberOfOffsets=2000) + + os.remove('lat.rdr') + os.remove('lat.rdr.vrt') + os.remove('lat.rdr.xml') + os.remove('lon.rdr') + os.remove('lon.rdr.vrt') + os.remove('lon.rdr.xml') + os.remove('hgt.rdr') + os.remove('hgt.rdr.vrt') + os.remove('hgt.rdr.xml') + os.remove('los.rdr') + os.remove('los.rdr.vrt') + os.remove('los.rdr.xml') + os.remove('wbd.rdr') + os.remove('wbd.rdr.vrt') + os.remove('wbd.rdr.xml') + + os.remove('rg.rdr') + os.remove('rg.rdr.vrt') + os.remove('rg.rdr.xml') + os.remove('az.rdr') + os.remove('az.rdr.vrt') + os.remove('az.rdr.xml') + + os.chdir('../') + continue + + + os.remove('lat.rdr') + os.remove('lat.rdr.vrt') + os.remove('lat.rdr.xml') + os.remove('lon.rdr') + os.remove('lon.rdr.vrt') + os.remove('lon.rdr.xml') + os.remove('hgt.rdr') + os.remove('hgt.rdr.vrt') + os.remove('hgt.rdr.xml') + os.remove('los.rdr') + os.remove('los.rdr.vrt') + os.remove('los.rdr.xml') + os.remove('wbd.rdr') + os.remove('wbd.rdr.vrt') + os.remove('wbd.rdr.xml') + + #put the results on a grid with a specified interval + interval = 0.2 + axisRatio = int(np.sqrt(landRatio)/interval)*interval + interval + if axisRatio > 1: + axisRatio = 1 + + numberOfOffsetsRange = int(numberOfOffsetsRange/axisRatio) + numberOfOffsetsAzimuth = int(numberOfOffsetsAzimuth/axisRatio) + else: + catalog.addItem('warning message', 'no water mask used to determine number of matching points. frame {} swath {}'.format(frameNumber, swathNumber), 'runSlcOffset') + + #user's settings + if self.numberRangeOffsets != None: + numberOfOffsetsRange = self.numberRangeOffsets[i][j] + if self.numberAzimuthOffsets != None: + numberOfOffsetsAzimuth = self.numberAzimuthOffsets[i][j] + + catalog.addItem('number of offsets range frame {} swath {}'.format(frameNumber, swathNumber), numberOfOffsetsRange, 'runSlcOffset') + catalog.addItem('number of offsets azimuth frame {} swath {}'.format(frameNumber, swathNumber), numberOfOffsetsAzimuth, 'runSlcOffset') + + ########################################## + #2. match using ampcor + ########################################## + ampcor = Ampcor(name='insarapp_slcs_ampcor') + ampcor.configure() + + mSLC = isceobj.createSlcImage() + mSLC.load(self._insar.masterSlc+'.xml') + mSLC.setAccessMode('read') + mSLC.createImage() + + sSLC = isceobj.createSlcImage() + sSLC.load(self._insar.slaveSlc+'.xml') + sSLC.setAccessMode('read') + sSLC.createImage() + + ampcor.setImageDataType1('complex') + ampcor.setImageDataType2('complex') + + ampcor.setMasterSlcImage(mSLC) + ampcor.setSlaveSlcImage(sSLC) + + #MATCH REGION + #compute an offset at image center to use + rgoff, azoff = computeOffsetFromOrbit(masterSwath, masterTrack, slaveSwath, slaveTrack, + masterSwath.numberOfSamples * 0.5, + masterSwath.numberOfLines * 0.5) + #it seems that we cannot use 0, haven't look into the problem + if rgoff == 0: + rgoff = 1 + if azoff == 0: + azoff = 1 + firstSample = 1 + if rgoff < 0: + firstSample = int(35 - rgoff) + firstLine = 1 + if azoff < 0: + firstLine = int(35 - azoff) + ampcor.setAcrossGrossOffset(rgoff) + ampcor.setDownGrossOffset(azoff) + ampcor.setFirstSampleAcross(firstSample) + ampcor.setLastSampleAcross(mSLC.width) + ampcor.setNumberLocationAcross(numberOfOffsetsRange) + ampcor.setFirstSampleDown(firstLine) + ampcor.setLastSampleDown(mSLC.length) + ampcor.setNumberLocationDown(numberOfOffsetsAzimuth) + + #MATCH PARAMETERS + #full-aperture mode + if (self._insar.modeCombination == 21) or \ + (self._insar.modeCombination == 22) or \ + (self._insar.modeCombination == 31) or \ + (self._insar.modeCombination == 32): + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(512) + #note this is the half width/length of search area, number of resulting correlation samples: 32*2+1 + ampcor.setSearchWindowSizeWidth(32) + ampcor.setSearchWindowSizeHeight(32) + #triggering full-aperture mode matching + ampcor.setWinsizeFilt(8) + ampcor.setOversamplingFactorFilt(64) + #regular mode + else: + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(64) + ampcor.setSearchWindowSizeWidth(32) + ampcor.setSearchWindowSizeHeight(32) + + #REST OF THE STUFF + ampcor.setAcrossLooks(1) + ampcor.setDownLooks(1) + ampcor.setOversamplingFactor(64) + ampcor.setZoomWindowSize(16) + #1. The following not set + #Matching Scale for Sample/Line Directions (-) = 1. 1. + #should add the following in Ampcor.py? + #if not set, in this case, Ampcor.py'value is also 1. 1. + #ampcor.setScaleFactorX(1.) + #ampcor.setScaleFactorY(1.) + + #MATCH THRESHOLDS AND DEBUG DATA + #2. The following not set + #in roi_pac the value is set to 0 1 + #in isce the value is set to 0.001 1000.0 + #SNR and Covariance Thresholds (-) = {s1} {s2} + #should add the following in Ampcor? + #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC + #ampcor.setThresholdSNR(0) + #ampcor.setThresholdCov(1) + ampcor.setDebugFlag(False) + ampcor.setDisplayFlag(False) + + #in summary, only two things not set which are indicated by 'The following not set' above. + + #run ampcor + ampcor.ampcor() + offsets = ampcor.getOffsetField() + ampcorOffsetFile = 'ampcor.off' + writeOffset(offsets, ampcorOffsetFile) + + #finalize image, and re-create it + #otherwise the file pointer is still at the end of the image + mSLC.finalizeImage() + sSLC.finalizeImage() + + ########################################## + #3. cull offsets + ########################################## + refinedOffsets = cullOffsets(offsets) + if refinedOffsets == None: + print('******************************************************************') + print('WARNING: There are not enough offsets left, so we are forced to') + print(' use offset without culling. frame {}, swath {}'.format(frameNumber, swathNumber)) + print('******************************************************************') + catalog.addItem('warning message', 'not enough offsets left, use offset without culling. frame {} swath {}'.format(frameNumber, swathNumber), 'runSlcOffset') + refinedOffsets = offsets + + cullOffsetFile = 'cull.off' + writeOffset(refinedOffsets, cullOffsetFile) + + os.chdir('../') + os.chdir('../') + + catalog.printToLog(logger, "runSlcOffset") + self._insar.procDoc.addAllFromCatalog(catalog) diff --git a/components/isceobj/Alos2Proc/runSwathMosaic.py b/components/isceobj/Alos2Proc/runSwathMosaic.py new file mode 100644 index 0000000..1af53f7 --- /dev/null +++ b/components/isceobj/Alos2Proc/runSwathMosaic.py @@ -0,0 +1,574 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2insar.runSwathMosaic') + +def runSwathMosaic(self): + '''mosaic subswaths + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = 'mosaic' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if not ( + ((self._insar.modeCombination == 21) or \ + (self._insar.modeCombination == 22) or \ + (self._insar.modeCombination == 31) or \ + (self._insar.modeCombination == 32)) + and + (self._insar.endingSwath-self._insar.startingSwath+1 > 1) + ): + import shutil + swathDir = 's{}'.format(masterTrack.frames[i].swaths[0].swathNumber) + + if not os.path.isfile(self._insar.interferogram): + os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + if not os.path.isfile(self._insar.amplitude): + os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + # os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + #update frame parameters + ######################################################### + frame = masterTrack.frames[i] + infImg = isceobj.createImage() + infImg.load(self._insar.interferogram+'.xml') + #mosaic size + frame.numberOfSamples = infImg.width + frame.numberOfLines = infImg.length + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + frame.startingRange = frame.swaths[0].startingRange + frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate + frame.rangePixelSize = frame.swaths[0].rangePixelSize + #azimuth parameters + frame.sensingStart = frame.swaths[0].sensingStart + frame.prf = frame.swaths[0].prf + frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize + frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval + + #update frame parameters, slave + ######################################################### + frame = slaveTrack.frames[i] + #mosaic size + frame.numberOfSamples = int(frame.swaths[0].numberOfSamples/self._insar.numberRangeLooks1) + frame.numberOfLines = int(frame.swaths[0].numberOfLines/self._insar.numberAzimuthLooks1) + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + frame.startingRange = frame.swaths[0].startingRange + frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate + frame.rangePixelSize = frame.swaths[0].rangePixelSize + #azimuth parameters + frame.sensingStart = frame.swaths[0].sensingStart + frame.prf = frame.swaths[0].prf + frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize + frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval + + os.chdir('../') + + #save parameter file + self._insar.saveProduct(masterTrack.frames[i], self._insar.masterFrameParameter) + self._insar.saveProduct(slaveTrack.frames[i], self._insar.slaveFrameParameter) + + os.chdir('../') + + continue + + #choose offsets + numberOfFrames = len(masterTrack.frames) + numberOfSwaths = len(masterTrack.frames[i].swaths) + if self.swathOffsetMatching: + #no need to do this as the API support 2-d list + #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetMatchingMaster + azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster + + else: + #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster + + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude)) + + #note that frame parameters are updated after mosaicking + #mosaic amplitudes + swathMosaic(masterTrack.frames[i], inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, resamplingMethod=0) + #mosaic interferograms + swathMosaic(masterTrack.frames[i], inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'int') + + #update slave frame parameters here + #no matching for slave, always use geometry + rangeOffsets = self._insar.swathRangeOffsetGeometricalSlave + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalSlave + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + swathMosaicParameters(slaveTrack.frames[i], rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1) + + os.chdir('../') + + #save parameter file + self._insar.saveProduct(masterTrack.frames[i], self._insar.masterFrameParameter) + self._insar.saveProduct(slaveTrack.frames[i], self._insar.slaveFrameParameter) + + os.chdir('../') + + catalog.printToLog(logger, "runSwathMosaic") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def swathMosaic(frame, inputFiles, outputfile, rangeOffsets, azimuthOffsets, numberOfRangeLooks, numberOfAzimuthLooks, updateFrame=False, phaseCompensation=False, pcRangeLooks=1, pcAzimuthLooks=4, filt=False, resamplingMethod=0): + ''' + mosaic swaths + + frame: frame + inputFiles: input file list + output file: output mosaic file + rangeOffsets: range offsets + azimuthOffsets: azimuth offsets + numberOfRangeLooks: number of range looks of the input files + numberOfAzimuthLooks: number of azimuth looks of the input files + phaseCompensation: whether do phase compensation for each swath + pcRangeLooks: number of range looks to take when compute swath phase difference + pcAzimuthLooks: number of azimuth looks to take when compute swath phase difference + filt: whether do filtering when compute swath phase difference + resamplingMethod: 0: amp resampling. 1: int resampling. + ''' + from contrib.alos2proc_f.alos2proc_f import rect_with_looks + from contrib.alos2proc.alos2proc import mosaicsubswath + from isceobj.Alos2Proc.Alos2ProcPublic import multilook + from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1 + from isceobj.Alos2Proc.Alos2ProcPublic import filterInterferogram + + numberOfSwaths = len(frame.swaths) + swaths = frame.swaths + + rangeScale = [] + azimuthScale = [] + rectWidth = [] + rectLength = [] + for i in range(numberOfSwaths): + rangeScale.append(swaths[0].rangePixelSize / swaths[i].rangePixelSize) + azimuthScale.append(swaths[0].azimuthLineInterval / swaths[i].azimuthLineInterval) + if i == 0: + rectWidth.append( int(swaths[i].numberOfSamples / numberOfRangeLooks) ) + rectLength.append( int(swaths[i].numberOfLines / numberOfAzimuthLooks) ) + else: + rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) ) + rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) ) + + #convert original offset to offset for images with looks + #use list instead of np.array to make it consistent with the rest of the code + rangeOffsets1 = [i/numberOfRangeLooks for i in rangeOffsets] + azimuthOffsets1 = [i/numberOfAzimuthLooks for i in azimuthOffsets] + + #get offset relative to the first frame + rangeOffsets2 = [0.0] + azimuthOffsets2 = [0.0] + for i in range(1, numberOfSwaths): + rangeOffsets2.append(0.0) + azimuthOffsets2.append(0.0) + for j in range(1, i+1): + rangeOffsets2[i] += rangeOffsets1[j] + azimuthOffsets2[i] += azimuthOffsets1[j] + + #resample each swath + rinfs = [] + for i, inf in enumerate(inputFiles): + rinfs.append("{}_{}{}".format(os.path.splitext(os.path.basename(inf))[0], i, os.path.splitext(os.path.basename(inf))[1])) + #do not resample first swath + if i == 0: + if os.path.isfile(rinfs[i]): + os.remove(rinfs[i]) + os.symlink(inf, rinfs[i]) + else: + infImg = isceobj.createImage() + infImg.load(inf+'.xml') + rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i]) + azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i]) + + + if resamplingMethod == 0: + rect_with_looks(inf, + rinfs[i], + infImg.width, infImg.length, + rectWidth[i], rectLength[i], + rangeScale[i], 0.0, + 0.0,azimuthScale[i], + rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i], + 1,1, + 1,1, + 'COMPLEX', + 'Bilinear') + elif resamplingMethod == 1: + #decompose amplitude and phase + phaseFile = 'phase' + amplitudeFile = 'amplitude' + data = np.fromfile(inf, dtype=np.complex64).reshape(infImg.length, infImg.width) + phase = np.exp(np.complex64(1j) * np.angle(data)) + phase[np.nonzero(data==0)] = 0 + phase.astype(np.complex64).tofile(phaseFile) + amplitude = np.absolute(data) + amplitude.astype(np.float32).tofile(amplitudeFile) + + #resampling + phaseRectFile = 'phaseRect' + amplitudeRectFile = 'amplitudeRect' + rect_with_looks(phaseFile, + phaseRectFile, + infImg.width, infImg.length, + rectWidth[i], rectLength[i], + rangeScale[i], 0.0, + 0.0,azimuthScale[i], + rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i], + 1,1, + 1,1, + 'COMPLEX', + 'Sinc') + rect_with_looks(amplitudeFile, + amplitudeRectFile, + infImg.width, infImg.length, + rectWidth[i], rectLength[i], + rangeScale[i], 0.0, + 0.0,azimuthScale[i], + rangeOffsets2Frac * rangeScale[i], azimuthOffsets2Frac * azimuthScale[i], + 1,1, + 1,1, + 'REAL', + 'Bilinear') + + #recombine amplitude and phase + phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(rectLength[i], rectWidth[i]) + amplitude = np.fromfile(amplitudeRectFile, dtype=np.float32).reshape(rectLength[i], rectWidth[i]) + (phase*amplitude).astype(np.complex64).tofile(rinfs[i]) + + #tidy up + os.remove(phaseFile) + os.remove(amplitudeFile) + os.remove(phaseRectFile) + os.remove(amplitudeRectFile) + + + #determine output width and length + #actually no need to calculate in range direction + xs = [] + xe = [] + ys = [] + ye = [] + for i in range(numberOfSwaths): + if i == 0: + xs.append(0) + xe.append(rectWidth[i] - 1) + ys.append(0) + ye.append(rectLength[i] - 1) + else: + xs.append(0 - int(rangeOffsets2[i])) + xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i])) + ys.append(0 - int(azimuthOffsets2[i])) + ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i])) + + (xmin, xminIndex) = min((v,i) for i,v in enumerate(xs)) + (xmax, xmaxIndex) = max((v,i) for i,v in enumerate(xe)) + (ymin, yminIndex) = min((v,i) for i,v in enumerate(ys)) + (ymax, ymaxIndex) = max((v,i) for i,v in enumerate(ye)) + + outWidth = xmax - xmin + 1 + outLength = ymax - ymin + 1 + + #prepare offset for mosaicing + rangeOffsets3 = [] + azimuthOffsets3 = [] + for i in range(numberOfSwaths): + azimuthOffsets3.append(int(azimuthOffsets2[i]) - int(azimuthOffsets2[yminIndex])) + if i != 0: + rangeOffsets3.append(int(rangeOffsets2[i]) - int(rangeOffsets2[i-1])) + else: + rangeOffsets3.append(0) + + + delta = int(30 / numberOfRangeLooks) + + #compute compensation phase for each swath + diffMean2 = [0.0 for i in range(numberOfSwaths)] + if phaseCompensation: + #compute swath phase offset + diffMean = [0.0] + for i in range(1, numberOfSwaths): + #all indexes start with zero, all the computed start/end sample/line indexes are included. + + #no need to add edge here, as we are going to find first/last nonzero sample/lines later + #edge = delta + edge = 0 + + #image i-1 + startSample1 = edge + 0 - int(rangeOffsets2[i]) + int(rangeOffsets2[i-1]) + endSample1 = -edge + rectWidth[i-1]-1 + startLine1 = edge + max(0 - int(azimuthOffsets2[i]) + int(azimuthOffsets2[i-1]), 0) + endLine1 = -edge + min(rectLength[i]-1 - int(azimuthOffsets2[i]) + int(azimuthOffsets2[i-1]), rectLength[i-1]-1) + data1 = readImage(rinfs[i-1], rectWidth[i-1], rectLength[i-1], startSample1, endSample1, startLine1, endLine1) + + #image i + startSample2 = edge + 0 + endSample2 = -edge + rectWidth[i-1]-1 - int(rangeOffsets2[i-1]) + int(rangeOffsets2[i]) + startLine2 = edge + max(0 - int(azimuthOffsets2[i-1]) + int(azimuthOffsets2[i]), 0) + endLine2 = -edge + min(rectLength[i-1]-1 - int(azimuthOffsets2[i-1]) + int(azimuthOffsets2[i]), rectLength[i]-1) + data2 = readImage(rinfs[i], rectWidth[i], rectLength[i], startSample2, endSample2, startLine2, endLine2) + + #remove edge due to incomplete covolution in resampling + edge = 9 + (startLine0, endLine0, startSample0, endSample0) = findNonzero( np.logical_and((data1!=0), (data2!=0)) ) + data1 = data1[startLine0+edge:endLine0+1-edge, startSample0+edge:endSample0+1-edge] + data2 = data2[startLine0+edge:endLine0+1-edge, startSample0+edge:endSample0+1-edge] + + #take looks + data1 = multilook(data1, pcAzimuthLooks, pcRangeLooks) + data2 = multilook(data2, pcAzimuthLooks, pcRangeLooks) + + #filter + if filt: + data1 /= (np.absolute(data1)+(data1==0)) + data2 /= (np.absolute(data2)+(data2==0)) + data1 = filterInterferogram(data1, 3.0, 64, 1) + data2 = filterInterferogram(data2, 3.0, 64, 1) + + + #get difference + corth = 0.87 + if filt: + corth = 0.90 + diffMean0 = 0.0 + for k in range(5): + dataDiff = data1 * np.conj(data2) + cor = cal_coherence_1(dataDiff, win=3) + index = np.nonzero(np.logical_and(cor>corth, dataDiff!=0)) + if index[0].size < 100: + diffMean0 = 0.0 + print('\n\nWARNING: too few high coherence pixels for swath phase difference estimation between swath {} and {}'.format(i-1, i)) + print(' : first swath swath number: 0\n\n') + break + angle = np.mean(np.angle(dataDiff[index]), dtype=np.float64) + diffMean0 += angle + data2 *= np.exp(np.complex64(1j) * angle) + print('phase offset: %15.12f rad after loop: %3d'%(diffMean0, k)) + + DEBUG=False + if DEBUG and (k==0): + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + (lengthxx, widthxx)=dataDiff.shape + filtnamePrefix = 'subswath{}_subswath{}_loop{}'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, k) + cor.astype(np.float32).tofile(filtnamePrefix+'.cor') + create_xml(filtnamePrefix+'.cor', widthxx, lengthxx, 'float') + dataDiff.astype(np.complex64).tofile(filtnamePrefix+'.int') + create_xml(filtnamePrefix+'.int', widthxx, lengthxx, 'int') + + diffMean.append(diffMean0) + print('phase offset: subswath{} - subswath{}: {}'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, diffMean0)) + + for i in range(1, numberOfSwaths): + for j in range(1, i+1): + diffMean2[i] += diffMean[j] + + + #mosaic swaths + diffflag = 1 + oflag = [0 for i in range(numberOfSwaths)] + mosaicsubswath(outputfile, outWidth, outLength, delta, diffflag, numberOfSwaths, + rinfs, rectWidth, rangeOffsets3, azimuthOffsets3, diffMean2, oflag) + #remove tmp files + for x in rinfs: + os.remove(x) + + + #update frame parameters + if updateFrame: + #mosaic size + frame.numberOfSamples = outWidth + frame.numberOfLines = outLength + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + frame.startingRange = frame.swaths[0].startingRange + frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate + frame.rangePixelSize = frame.swaths[0].rangePixelSize + #azimuth parameters + azimuthTimeOffset = - max([int(x) for x in azimuthOffsets2]) * numberOfAzimuthLooks * frame.swaths[0].azimuthLineInterval + frame.sensingStart = frame.swaths[0].sensingStart + datetime.timedelta(seconds = azimuthTimeOffset) + frame.prf = frame.swaths[0].prf + frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize + frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval + + +def swathMosaicParameters(frame, rangeOffsets, azimuthOffsets, numberOfRangeLooks, numberOfAzimuthLooks): + ''' + mosaic swaths (this is simplified version of swathMosaic to update parameters only) + + frame: frame + rangeOffsets: range offsets + azimuthOffsets: azimuth offsets + numberOfRangeLooks: number of range looks of the input files + numberOfAzimuthLooks: number of azimuth looks of the input files + ''' + + numberOfSwaths = len(frame.swaths) + swaths = frame.swaths + + rangeScale = [] + azimuthScale = [] + rectWidth = [] + rectLength = [] + for i in range(numberOfSwaths): + rangeScale.append(swaths[0].rangePixelSize / swaths[i].rangePixelSize) + azimuthScale.append(swaths[0].azimuthLineInterval / swaths[i].azimuthLineInterval) + if i == 0: + rectWidth.append( int(swaths[i].numberOfSamples / numberOfRangeLooks) ) + rectLength.append( int(swaths[i].numberOfLines / numberOfAzimuthLooks) ) + else: + rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) ) + rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) ) + + #convert original offset to offset for images with looks + #use list instead of np.array to make it consistent with the rest of the code + rangeOffsets1 = [i/numberOfRangeLooks for i in rangeOffsets] + azimuthOffsets1 = [i/numberOfAzimuthLooks for i in azimuthOffsets] + + #get offset relative to the first frame + rangeOffsets2 = [0.0] + azimuthOffsets2 = [0.0] + for i in range(1, numberOfSwaths): + rangeOffsets2.append(0.0) + azimuthOffsets2.append(0.0) + for j in range(1, i+1): + rangeOffsets2[i] += rangeOffsets1[j] + azimuthOffsets2[i] += azimuthOffsets1[j] + + #determine output width and length + #actually no need to calculate in range direction + xs = [] + xe = [] + ys = [] + ye = [] + for i in range(numberOfSwaths): + if i == 0: + xs.append(0) + xe.append(rectWidth[i] - 1) + ys.append(0) + ye.append(rectLength[i] - 1) + else: + xs.append(0 - int(rangeOffsets2[i])) + xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i])) + ys.append(0 - int(azimuthOffsets2[i])) + ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i])) + + (xmin, xminIndex) = min((v,i) for i,v in enumerate(xs)) + (xmax, xmaxIndex) = max((v,i) for i,v in enumerate(xe)) + (ymin, yminIndex) = min((v,i) for i,v in enumerate(ys)) + (ymax, ymaxIndex) = max((v,i) for i,v in enumerate(ye)) + + outWidth = xmax - xmin + 1 + outLength = ymax - ymin + 1 + + #update frame parameters + #mosaic size + frame.numberOfSamples = outWidth + frame.numberOfLines = outLength + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + frame.startingRange = frame.swaths[0].startingRange + frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate + frame.rangePixelSize = frame.swaths[0].rangePixelSize + #azimuth parameters + azimuthTimeOffset = - max([int(x) for x in azimuthOffsets2]) * numberOfAzimuthLooks * frame.swaths[0].azimuthLineInterval + frame.sensingStart = frame.swaths[0].sensingStart + datetime.timedelta(seconds = azimuthTimeOffset) + frame.prf = frame.swaths[0].prf + frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize + frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval + + +def readImage(inputfile, numberOfSamples, numberOfLines, startSample, endSample, startLine, endLine): + ''' + read a chunk of image + the indexes (startSample, endSample, startLine, endLine) are included and start with zero + + memmap is not used, because it is much slower + ''' + data = np.zeros((endLine-startLine+1, endSample-startSample+1), dtype=np.complex64) + with open(inputfile,'rb') as fp: + #for i in range(endLine-startLine+1): + for i in range(startLine, endLine+1): + fp.seek((i*numberOfSamples+startSample)*8, 0) + data[i-startLine] = np.fromfile(fp, dtype=np.complex64, count=endSample-startSample+1) + return data + + +def findNonzero_v1(data): + ''' + find the first/last non-zero line/sample + all indexes start from zero + ''' + indexes = np.nonzero(data) + + #first line last line first sample last sample + return (indexes[0][0], indexes[0][-1], indexes[1][0], indexes[1][-1]) + + +def findNonzero(data, lineRatio=0.5, sampleRatio=0.5): + ''' + find the first/last non-zero line/sample + all indexes start from zero + ''' + import numpy as np + + (length, width)=data.shape + + lineIndex = (np.nonzero(np.sum((data!=0), axis=1) > width*lineRatio))[0] + sampleIndex = (np.nonzero(np.sum((data!=0), axis=0) > length*sampleRatio))[0] + + #first line last line first sample last sample + return (lineIndex[0], lineIndex[-1], sampleIndex[0], sampleIndex[-1]) + + diff --git a/components/isceobj/Alos2Proc/runSwathOffset.py b/components/isceobj/Alos2Proc/runSwathOffset.py new file mode 100644 index 0000000..f66b5ed --- /dev/null +++ b/components/isceobj/Alos2Proc/runSwathOffset.py @@ -0,0 +1,390 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import multilook + + +logger = logging.getLogger('isce.alos2insar.runSwathOffset') + +def runSwathOffset(self): + '''estimate swath offsets. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = 'mosaic' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if not ( + ((self._insar.modeCombination == 21) or \ + (self._insar.modeCombination == 22) or \ + (self._insar.modeCombination == 31) or \ + (self._insar.modeCombination == 32)) + and + (self._insar.endingSwath-self._insar.startingSwath+1 > 1) + ): + + os.chdir('../../') + + continue + + #compute swath offset + offsetMaster = swathOffset(masterTrack.frames[i], self._insar.masterSlc, self._insar.masterSwathOffset, + crossCorrelation=self.swathOffsetMatching, numberOfAzimuthLooks=10) + #only use geometrical offset for slave + offsetSlave = swathOffset(slaveTrack.frames[i], self._insar.slaveSlc, self._insar.slaveSwathOffset, + crossCorrelation=False, numberOfAzimuthLooks=10) + + #initialization + if i == 0: + self._insar.swathRangeOffsetGeometricalMaster = [] + self._insar.swathAzimuthOffsetGeometricalMaster = [] + self._insar.swathRangeOffsetGeometricalSlave = [] + self._insar.swathAzimuthOffsetGeometricalSlave = [] + if self.swathOffsetMatching: + self._insar.swathRangeOffsetMatchingMaster = [] + self._insar.swathAzimuthOffsetMatchingMaster = [] + #self._insar.swathRangeOffsetMatchingSlave = [] + #self._insar.swathAzimuthOffsetMatchingSlave = [] + + #append list directly, as the API support 2-d list + self._insar.swathRangeOffsetGeometricalMaster.append(offsetMaster[0]) + self._insar.swathAzimuthOffsetGeometricalMaster.append(offsetMaster[1]) + self._insar.swathRangeOffsetGeometricalSlave.append(offsetSlave[0]) + self._insar.swathAzimuthOffsetGeometricalSlave.append(offsetSlave[1]) + if self.swathOffsetMatching: + self._insar.swathRangeOffsetMatchingMaster.append(offsetMaster[2]) + self._insar.swathAzimuthOffsetMatchingMaster.append(offsetMaster[3]) + #self._insar.swathRangeOffsetMatchingSlave.append(offsetSlave[2]) + #self._insar.swathAzimuthOffsetMatchingSlave.append(offsetSlave[3]) + + os.chdir('../../') + + catalog.printToLog(logger, "runSwathOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def swathOffset(frame, image, outputfile, crossCorrelation=True, numberOfAzimuthLooks=10): + ''' + compute swath offset + frame: frame object + image: image for doing matching + outputfile: output txt file for saving swath offset + crossCorrelation: whether do matching + numberOfAzimuthLooks: number of looks to take in azimuth before matching + ''' + + rangeOffsetGeometrical = [] + azimuthOffsetGeometrical = [] + rangeOffsetMatching = [] + azimuthOffsetMatching = [] + + for j in range(len(frame.swaths)): + frameNumber = frame.frameNumber + swathNumber = frame.swaths[j].swathNumber + swathDir = 's{}'.format(swathNumber) + + print('estimate offset frame {}, swath {}'.format(frameNumber, swathNumber)) + + if j == 0: + rangeOffsetGeometrical.append(0.0) + azimuthOffsetGeometrical.append(0.0) + rangeOffsetMatching.append(0.0) + azimuthOffsetMatching.append(0.0) + swathDirLast = swathDir + continue + + image1 = os.path.join('../', swathDirLast, image) + image2 = os.path.join('../', swathDir, image) + swath0 = frame.swaths[0] + swath1 = frame.swaths[j-1] + swath2 = frame.swaths[j] + + rangeScale1 = swath0.rangePixelSize / swath1.rangePixelSize + azimuthScale1 = swath0.azimuthLineInterval / swath1.azimuthLineInterval + rangeScale2 = swath0.rangePixelSize / swath2.rangePixelSize + azimuthScale2 = swath0.azimuthLineInterval / swath2.azimuthLineInterval + + #offset from geometry + offsetGeometrical = computeSwathOffset(swath1, swath2, rangeScale1, azimuthScale1) + rangeOffsetGeometrical.append(offsetGeometrical[0]) + azimuthOffsetGeometrical.append(offsetGeometrical[1]) + + #offset from cross-correlation + if crossCorrelation: + offsetMatching = estimateSwathOffset(swath1, swath2, image1, image2, rangeScale1, + azimuthScale1, rangeScale2, azimuthScale2, numberOfAzimuthLooks) + if offsetMatching != None: + rangeOffsetMatching.append(offsetMatching[0]) + azimuthOffsetMatching.append(offsetMatching[1]) + else: + print('******************************************************************') + print('WARNING: bad matching offset, we are forced to use') + print(' geometrical offset for swath mosaicking') + print('******************************************************************') + rangeOffsetMatching.append(offsetGeometrical[0]) + azimuthOffsetMatching.append(offsetGeometrical[1]) + + swathDirLast = swathDir + + + if crossCorrelation: + offsetComp = "\n\ncomparision of offsets:\n\n" + offsetComp += "offset type i geometrical match difference\n" + offsetComp += "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" + for i, (offset1, offset2) in enumerate(zip(rangeOffsetGeometrical, rangeOffsetMatching)): + offsetComp += "range offset {:2d} {:13.3f} {:13.3f} {:13.3f}\n".format(i, offset1, offset2, offset1 - offset2) + for i, (offset1, offset2) in enumerate(zip(azimuthOffsetGeometrical, azimuthOffsetMatching)): + offsetComp += "azimuth offset {:2d} {:13.3f} {:13.3f} {:13.3f}\n".format(i, offset1, offset2, offset1 - offset2) + + #write and report offsets + with open(outputfile, 'w') as f: + f.write(offsetComp) + print("{}".format(offsetComp)) + + + if crossCorrelation: + return (rangeOffsetGeometrical, azimuthOffsetGeometrical, rangeOffsetMatching, azimuthOffsetMatching) + else: + return (rangeOffsetGeometrical, azimuthOffsetGeometrical) + + +def computeSwathOffset(swath1, swath2, rangeScale1=1, azimuthScale1=1): + + rangeOffset = -(swath2.startingRange - swath1.startingRange) / swath1.rangePixelSize + azimuthOffset = -((swath2.sensingStart - swath1.sensingStart).total_seconds()) / swath1.azimuthLineInterval + + rangeOffset /= rangeScale1 + azimuthOffset /= azimuthScale1 + + return (rangeOffset, azimuthOffset) + + +def estimateSwathOffset(swath1, swath2, image1, image2, rangeScale1=1, azimuthScale1=1, rangeScale2=1, azimuthScale2=1, numberOfAzimuthLooks=10): + ''' + estimate offset of two adjacent swaths using matching + ''' + from osgeo import gdal + import isceobj + from contrib.alos2proc_f.alos2proc_f import rect_with_looks + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsets + from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset + from mroipac.ampcor.Ampcor import Ampcor + + + #processing image 1 + rangeOff1 = int((swath2.startingRange - swath1.startingRange) / swath1.rangePixelSize) + if rangeOff1 < 0: + rangeOff1 = 0 + numberOfSamples1 = swath1.numberOfSamples - rangeOff1 + + numberOfSamplesRect1 = int(numberOfSamples1/rangeScale1) + numberOfLinesRect1 = int(swath1.numberOfLines/azimuthScale1) + + numberOfSamplesLook1 = int(numberOfSamplesRect1/1) + numberOfLinesLook1 = int(numberOfLinesRect1/numberOfAzimuthLooks) + + #get magnitude image whether complex or not + #ReadAsArray: https://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html + ds = gdal.Open(image1 + '.vrt', gdal.GA_ReadOnly) + data = ds.ReadAsArray(rangeOff1, 0, numberOfSamples1, swath1.numberOfLines) + ds = None + (np.absolute(data)).astype(np.float32).tofile('image1.float') + + #rectify + if rangeScale1 == 1 and azimuthScale1 == 1: + os.rename('image1.float', 'image1_rect.float') + else: + rect_with_looks('image1.float', + 'image1_rect.float', + numberOfSamples1, swath1.numberOfLines, + numberOfSamplesRect1, numberOfLinesRect1, + rangeScale1, 0.0, + 0.0,azimuthScale1, + 0.0,0.0, + 1,1, + 1,1, + 'REAL', + 'Bilinear') + os.remove('image1.float') + + #take looks + if numberOfAzimuthLooks == 1: + os.rename('image1_rect.float', 'image1_look.float') + else: + data1 = np.fromfile('image1_rect.float', dtype=np.float32).reshape(numberOfLinesRect1, numberOfSamplesRect1) + data1 = np.sqrt(multilook(data1**2, numberOfAzimuthLooks, 1)) + data1.astype(np.float32).tofile('image1_look.float') + os.remove('image1_rect.float') + create_xml('image1_look.float', numberOfSamplesLook1, numberOfLinesLook1, 'float') + + + #processing image 2 + rangeOff2 = 0 + numberOfSamples2 = int((swath1.startingRange + swath1.rangePixelSize * (swath1.numberOfSamples - 1) - swath2.startingRange) / swath2.rangePixelSize) + 1 + if numberOfSamples2 > swath2.numberOfSamples: + numberOfSamples2 = swath2.numberOfSamples + + numberOfSamplesRect2 = int(numberOfSamples2/rangeScale2) + numberOfLinesRect2 = int(swath2.numberOfLines/azimuthScale2) + + numberOfSamplesLook2 = int(numberOfSamplesRect2/1) + numberOfLinesLook2 = int(numberOfLinesRect2/numberOfAzimuthLooks) + + #get magnitude image whether complex or not + ds = gdal.Open(image2 + '.vrt', gdal.GA_ReadOnly) + data = ds.ReadAsArray(rangeOff2, 0, numberOfSamples2, swath2.numberOfLines) + ds = None + (np.absolute(data)).astype(np.float32).tofile('image2.float') + + #rectify + if rangeScale2 == 1 and azimuthScale2 == 1: + os.rename('image2.float', 'image2_rect.float') + else: + rect_with_looks('image2.float', + 'image2_rect.float', + numberOfSamples2, swath2.numberOfLines, + numberOfSamplesRect2, numberOfLinesRect2, + rangeScale2, 0.0, + 0.0,azimuthScale2, + 0.0,0.0, + 1,1, + 1,1, + 'REAL', + 'Bilinear') + os.remove('image2.float') + + #take looks + if numberOfAzimuthLooks == 1: + os.rename('image2_rect.float', 'image2_look.float') + else: + data2 = np.fromfile('image2_rect.float', dtype=np.float32).reshape(numberOfLinesRect2, numberOfSamplesRect2) + data2 = np.sqrt(multilook(data2**2, numberOfAzimuthLooks, 1)) + data2.astype(np.float32).tofile('image2_look.float') + os.remove('image2_rect.float') + create_xml('image2_look.float', numberOfSamplesLook2, numberOfLinesLook2, 'float') + + + #matching + ampcor = Ampcor(name='insarapp_slcs_ampcor') + ampcor.configure() + + mMag = isceobj.createImage() + mMag.load('image1_look.float.xml') + mMag.setAccessMode('read') + mMag.createImage() + + sMag = isceobj.createImage() + sMag.load('image2_look.float.xml') + sMag.setAccessMode('read') + sMag.createImage() + + ampcor.setImageDataType1('real') + ampcor.setImageDataType2('real') + + ampcor.setMasterSlcImage(mMag) + ampcor.setSlaveSlcImage(sMag) + + #MATCH REGION + rgoff = 0 + azoff = int((swath1.sensingStart - swath2.sensingStart).total_seconds() / swath1.azimuthLineInterval / azimuthScale1 / numberOfAzimuthLooks) + #it seems that we cannot use 0, haven't look into the problem + if rgoff == 0: + rgoff = 1 + if azoff == 0: + azoff = 1 + firstSample = 1 + if rgoff < 0: + firstSample = int(35 - rgoff) + firstLine = 1 + if azoff < 0: + firstLine = int(35 - azoff) + ampcor.setAcrossGrossOffset(rgoff) + ampcor.setDownGrossOffset(azoff) + ampcor.setFirstSampleAcross(firstSample) + ampcor.setLastSampleAcross(numberOfSamplesLook1) + ampcor.setNumberLocationAcross(20) + ampcor.setFirstSampleDown(firstLine) + ampcor.setLastSampleDown(numberOfLinesLook1) + ampcor.setNumberLocationDown(100) + + #MATCH PARAMETERS + ampcor.setWindowSizeWidth(32) + ampcor.setWindowSizeHeight(32) + #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1 + ampcor.setSearchWindowSizeWidth(8) + ampcor.setSearchWindowSizeHeight(8) + + #REST OF THE STUFF + ampcor.setAcrossLooks(1) + ampcor.setDownLooks(1) + ampcor.setOversamplingFactor(64) + ampcor.setZoomWindowSize(16) + #1. The following not set + #Matching Scale for Sample/Line Directions (-) = 1. 1. + #should add the following in Ampcor.py? + #if not set, in this case, Ampcor.py'value is also 1. 1. + #ampcor.setScaleFactorX(1.) + #ampcor.setScaleFactorY(1.) + + #MATCH THRESHOLDS AND DEBUG DATA + #2. The following not set + #in roi_pac the value is set to 0 1 + #in isce the value is set to 0.001 1000.0 + #SNR and Covariance Thresholds (-) = {s1} {s2} + #should add the following in Ampcor? + #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC + #ampcor.setThresholdSNR(0) + #ampcor.setThresholdCov(1) + ampcor.setDebugFlag(False) + ampcor.setDisplayFlag(False) + + #in summary, only two things not set which are indicated by 'The following not set' above. + + #run ampcor + ampcor.ampcor() + offsets = ampcor.getOffsetField() + refinedOffsets = cullOffsets(offsets) + + #finalize image, and re-create it + #otherwise the file pointer is still at the end of the image + mMag.finalizeImage() + sMag.finalizeImage() + + os.remove('image1_look.float') + os.remove('image1_look.float.vrt') + os.remove('image1_look.float.xml') + os.remove('image2_look.float') + os.remove('image2_look.float.vrt') + os.remove('image2_look.float.xml') + + if refinedOffsets != None: + rangeOffset, azimuthOffset = meanOffset(refinedOffsets) + rangeOffset -= rangeOff1/rangeScale1 + azimuthOffset *= numberOfAzimuthLooks + return (rangeOffset, azimuthOffset) + else: + return None + + + + diff --git a/components/isceobj/Alos2Proc/runUnwrapSnaphu.py b/components/isceobj/Alos2Proc/runUnwrapSnaphu.py new file mode 100644 index 0000000..fb16b79 --- /dev/null +++ b/components/isceobj/Alos2Proc/runUnwrapSnaphu.py @@ -0,0 +1,91 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import shutil +import logging +import datetime +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap +from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrapOriginal +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + +logger = logging.getLogger('isce.alos2insar.runUnwrapSnaphu') + +def runUnwrapSnaphu(self): + '''unwrap filtered interferogram + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + insarDir = 'insar' + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + + ############################################################ + # STEP 1. unwrap interferogram + ############################################################ + if shutil.which('snaphu') != None: + print('\noriginal snaphu program found') + print('unwrap {} using original snaphu, rather than that in ISCE'.format(self._insar.filteredInterferogram)) + snaphuUnwrapOriginal(self._insar.filteredInterferogram, + self._insar.multilookPhsig, + self._insar.multilookAmplitude, + self._insar.unwrappedInterferogram, + costMode = 's', + initMethod = 'mcf') + else: + tmid = masterTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*masterTrack.azimuthLineInterval+ + masterTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*masterTrack.azimuthLineInterval) + snaphuUnwrap(masterTrack, tmid, + self._insar.filteredInterferogram, + self._insar.multilookPhsig, + self._insar.unwrappedInterferogram, + self._insar.numberRangeLooks1*self._insar.numberRangeLooks2, + self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooks2, + costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True) + + + ############################################################ + # STEP 2. mask using connected components + ############################################################ + cmd = "imageMath.py -e='a_0*(b>0);a_1*(b>0)' --a={} --b={} -s BIL -t float -o={}".format(self._insar.unwrappedInterferogram, self._insar.unwrappedInterferogram+'.conncomp', self._insar.unwrappedMaskedInterferogram) + runCmd(cmd) + + + ############################################################ + # STEP 3. mask using water body + ############################################################ + + if self.waterBodyMaskStartingStep=='unwrap': + wbdImage = isceobj.createImage() + wbdImage.load(self._insar.multilookWbdOut+'.xml') + width = wbdImage.width + length = wbdImage.length + if not os.path.exists(self._insar.multilookWbdOut): + catalog.addItem('warning message', 'requested masking interferogram with water body, but water body does not exist', 'runUnwrapSnaphu') + else: + wbd = np.fromfile(self._insar.multilookWbdOut, dtype=np.int8).reshape(length, width) + unw=np.memmap(self._insar.unwrappedInterferogram, dtype='float32', mode='r+', shape=(length*2, width)) + (unw[0:length*2:2, :])[np.nonzero(wbd==-1)]=0 + (unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0 + del unw + unw=np.memmap(self._insar.unwrappedMaskedInterferogram, dtype='float32', mode='r+', shape=(length*2, width)) + (unw[0:length*2:2, :])[np.nonzero(wbd==-1)]=0 + (unw[1:length*2:2, :])[np.nonzero(wbd==-1)]=0 + del unw, wbd + + os.chdir('../') + + catalog.printToLog(logger, "runUnwrapSnaphu") + self._insar.procDoc.addAllFromCatalog(catalog) + diff --git a/components/isceobj/Alos2Proc/srtm_no_swbd_tiles.txt b/components/isceobj/Alos2Proc/srtm_no_swbd_tiles.txt new file mode 100644 index 0000000..abb1039 --- /dev/null +++ b/components/isceobj/Alos2Proc/srtm_no_swbd_tiles.txt @@ -0,0 +1,2317 @@ +N00E014 +N00E015 +N00E022 +N00E023 +N00E026 +N00E029 +N00E038 +N00E039 +N00E040 +N00E041 +N01E010 +N01E011 +N01E014 +N01E029 +N01E036 +N01E037 +N01E038 +N01E039 +N01E040 +N01E041 +N02E012 +N02E017 +N02E024 +N02E025 +N02E026 +N02E028 +N02E029 +N02E030 +N02E034 +N02E035 +N02E038 +N02E039 +N02E040 +N02E041 +N02E042 +N02E043 +N02E044 +N03E012 +N03E013 +N03E014 +N03E017 +N03E019 +N03E021 +N03E030 +N03E034 +N03E037 +N03E039 +N03E040 +N03E041 +N03E042 +N03E043 +N03E044 +N03E045 +N04E014 +N04E027 +N04E028 +N04E029 +N04E030 +N04E032 +N04E033 +N04E037 +N04E039 +N04E042 +N04E043 +N04E044 +N04E045 +N04E046 +N05E014 +N05E015 +N05E016 +N05E018 +N05E020 +N05E025 +N05E026 +N05E027 +N05E028 +N05E029 +N05E030 +N05E032 +N05E033 +N05E034 +N05E035 +N05E039 +N05E040 +N05E041 +N05E042 +N05E043 +N05E044 +N05E045 +N05E046 +N05E047 +N05W009 +N06E014 +N06E015 +N06E018 +N06E019 +N06E020 +N06E023 +N06E024 +N06E026 +N06E027 +N06E028 +N06E029 +N06E032 +N06E035 +N06E039 +N06E040 +N06E042 +N06E043 +N06E044 +N06E045 +N06E046 +N06E047 +N06W003 +N06W009 +N07E011 +N07E012 +N07E019 +N07E020 +N07E021 +N07E022 +N07E023 +N07E024 +N07E025 +N07E026 +N07E027 +N07E032 +N07E037 +N07E040 +N07E041 +N07E042 +N07E043 +N07E044 +N07E045 +N07E046 +N07E047 +N07E048 +N07W002 +N07W003 +N08E001 +N08E011 +N08E012 +N08E020 +N08E021 +N08E022 +N08E023 +N08E024 +N08E025 +N08E031 +N08E035 +N08E036 +N08E041 +N08E042 +N08E043 +N08E044 +N08E045 +N08E046 +N08E047 +N08E048 +N08W004 +N08W009 +N08W010 +N09E019 +N09E021 +N09E022 +N09E024 +N09E025 +N09E026 +N09E034 +N09E036 +N09E039 +N09E043 +N09E044 +N09E045 +N09E046 +N09E047 +N09E048 +N09E049 +N09W004 +N09W005 +N09W008 +N09W009 +N09W011 +N10E001 +N10E002 +N10E003 +N10E018 +N10E020 +N10E021 +N10E023 +N10E024 +N10E025 +N10E026 +N10E027 +N10E028 +N10E031 +N10E033 +N10E034 +N10E041 +N10E042 +N10E048 +N10E049 +N10W008 +N10W009 +N10W012 +N11E002 +N11E011 +N11E012 +N11E014 +N11E016 +N11E017 +N11E018 +N11E021 +N11E024 +N11E025 +N11E026 +N11E027 +N11E028 +N11E030 +N11E031 +N11E033 +N11E038 +N11W007 +N11W008 +N12E016 +N12E018 +N12E019 +N12E020 +N12E022 +N12E023 +N12E025 +N12E026 +N12E027 +N12E028 +N12E029 +N12E031 +N12E035 +N12E036 +N12E038 +N12E040 +N12E041 +N12W010 +N12W012 +N12W013 +N13E011 +N13E016 +N13E017 +N13E019 +N13E021 +N13E023 +N13E024 +N13E026 +N13E027 +N13E028 +N13E029 +N13E031 +N13E035 +N13E036 +N13E037 +N13E038 +N13E044 +N14E007 +N14E008 +N14E009 +N14E010 +N14E011 +N14E012 +N14E013 +N14E014 +N14E016 +N14E017 +N14E018 +N14E019 +N14E020 +N14E021 +N14E023 +N14E024 +N14E025 +N14E026 +N14E028 +N14E029 +N14E030 +N14E031 +N14E034 +N14E036 +N14E037 +N14E038 +N14E044 +N14E045 +N14E046 +N14W003 +N14W008 +N14W009 +N14W010 +N14W014 +N14W015 +N15E003 +N15E004 +N15E006 +N15E007 +N15E008 +N15E009 +N15E010 +N15E011 +N15E012 +N15E013 +N15E014 +N15E015 +N15E016 +N15E017 +N15E018 +N15E019 +N15E020 +N15E021 +N15E022 +N15E023 +N15E024 +N15E025 +N15E026 +N15E027 +N15E028 +N15E029 +N15E030 +N15E031 +N15E034 +N15E035 +N15E036 +N15E037 +N15E043 +N15E044 +N15E046 +N15E047 +N15E048 +N15E049 +N15W006 +N15W007 +N15W009 +N15W010 +N15W015 +N16E002 +N16E003 +N16E004 +N16E005 +N16E006 +N16E007 +N16E008 +N16E009 +N16E010 +N16E011 +N16E012 +N16E013 +N16E014 +N16E015 +N16E016 +N16E017 +N16E018 +N16E019 +N16E020 +N16E021 +N16E022 +N16E023 +N16E024 +N16E025 +N16E026 +N16E027 +N16E028 +N16E029 +N16E030 +N16E031 +N16E034 +N16E035 +N16E036 +N16E037 +N16E038 +N16E043 +N16E044 +N16E045 +N16E046 +N16E047 +N16E048 +N16E049 +N16E050 +N16E051 +N16W005 +N16W006 +N16W007 +N16W008 +N16W009 +N16W010 +N16W011 +N16W012 +N17E000 +N17E001 +N17E002 +N17E003 +N17E004 +N17E005 +N17E006 +N17E007 +N17E008 +N17E009 +N17E010 +N17E011 +N17E012 +N17E013 +N17E014 +N17E015 +N17E016 +N17E017 +N17E018 +N17E019 +N17E020 +N17E021 +N17E022 +N17E023 +N17E024 +N17E025 +N17E026 +N17E027 +N17E028 +N17E029 +N17E030 +N17E032 +N17E034 +N17E035 +N17E036 +N17E037 +N17E044 +N17E045 +N17E046 +N17E047 +N17E048 +N17E049 +N17E050 +N17E051 +N17E052 +N17E053 +N17W003 +N17W004 +N17W005 +N17W006 +N17W007 +N17W008 +N17W009 +N17W010 +N17W011 +N17W012 +N17W016 +N18E000 +N18E001 +N18E002 +N18E003 +N18E004 +N18E005 +N18E006 +N18E007 +N18E008 +N18E009 +N18E010 +N18E011 +N18E012 +N18E013 +N18E014 +N18E015 +N18E016 +N18E017 +N18E018 +N18E019 +N18E021 +N18E022 +N18E023 +N18E024 +N18E025 +N18E026 +N18E027 +N18E028 +N18E029 +N18E034 +N18E035 +N18E036 +N18E043 +N18E044 +N18E045 +N18E046 +N18E047 +N18E048 +N18E049 +N18E050 +N18E051 +N18E052 +N18E053 +N18E054 +N18E055 +N18W001 +N18W002 +N18W003 +N18W004 +N18W005 +N18W006 +N18W007 +N18W008 +N18W009 +N18W010 +N18W011 +N18W012 +N18W014 +N18W015 +N18W016 +N19E000 +N19E001 +N19E002 +N19E003 +N19E004 +N19E005 +N19E006 +N19E007 +N19E008 +N19E009 +N19E010 +N19E011 +N19E012 +N19E013 +N19E014 +N19E015 +N19E016 +N19E017 +N19E018 +N19E019 +N19E021 +N19E022 +N19E023 +N19E024 +N19E025 +N19E026 +N19E027 +N19E028 +N19E029 +N19E031 +N19E034 +N19E035 +N19E036 +N19E043 +N19E044 +N19E045 +N19E046 +N19E047 +N19E048 +N19E049 +N19E050 +N19E051 +N19E052 +N19E053 +N19E054 +N19E055 +N19E056 +N19W001 +N19W002 +N19W003 +N19W004 +N19W005 +N19W006 +N19W007 +N19W008 +N19W009 +N19W010 +N19W011 +N19W012 +N19W013 +N19W014 +N19W015 +N19W016 +N20E000 +N20E001 +N20E002 +N20E003 +N20E004 +N20E005 +N20E006 +N20E007 +N20E008 +N20E009 +N20E010 +N20E011 +N20E012 +N20E013 +N20E014 +N20E015 +N20E016 +N20E017 +N20E018 +N20E019 +N20E020 +N20E021 +N20E022 +N20E023 +N20E024 +N20E025 +N20E026 +N20E027 +N20E028 +N20E029 +N20E031 +N20E032 +N20E033 +N20E034 +N20E035 +N20E036 +N20E042 +N20E043 +N20E044 +N20E045 +N20E046 +N20E047 +N20E048 +N20E049 +N20E050 +N20E051 +N20E052 +N20E053 +N20E054 +N20E055 +N20E056 +N20W001 +N20W002 +N20W003 +N20W004 +N20W005 +N20W006 +N20W007 +N20W008 +N20W009 +N20W010 +N20W011 +N20W012 +N20W013 +N20W014 +N20W015 +N20W016 +N21E000 +N21E001 +N21E002 +N21E003 +N21E004 +N21E005 +N21E006 +N21E007 +N21E008 +N21E009 +N21E010 +N21E011 +N21E012 +N21E013 +N21E014 +N21E015 +N21E016 +N21E017 +N21E018 +N21E019 +N21E020 +N21E021 +N21E022 +N21E023 +N21E024 +N21E025 +N21E026 +N21E027 +N21E028 +N21E029 +N21E032 +N21E033 +N21E034 +N21E035 +N21E040 +N21E041 +N21E042 +N21E043 +N21E044 +N21E045 +N21E046 +N21E047 +N21E048 +N21E049 +N21E050 +N21E051 +N21E052 +N21E053 +N21E054 +N21E055 +N21E056 +N21E057 +N21W001 +N21W002 +N21W003 +N21W004 +N21W005 +N21W006 +N21W007 +N21W008 +N21W009 +N21W010 +N21W011 +N21W012 +N21W013 +N21W014 +N21W015 +N21W016 +N22E000 +N22E001 +N22E002 +N22E003 +N22E004 +N22E005 +N22E006 +N22E007 +N22E008 +N22E009 +N22E010 +N22E011 +N22E012 +N22E013 +N22E014 +N22E015 +N22E016 +N22E017 +N22E018 +N22E019 +N22E020 +N22E021 +N22E022 +N22E023 +N22E024 +N22E025 +N22E026 +N22E027 +N22E028 +N22E029 +N22E030 +N22E034 +N22E040 +N22E041 +N22E042 +N22E043 +N22E044 +N22E045 +N22E046 +N22E047 +N22E048 +N22E049 +N22E050 +N22E051 +N22E052 +N22E053 +N22E054 +N22E055 +N22E056 +N22E057 +N22E058 +N22W001 +N22W002 +N22W003 +N22W004 +N22W005 +N22W006 +N22W007 +N22W008 +N22W009 +N22W010 +N22W011 +N22W012 +N22W013 +N22W014 +N22W015 +N22W016 +N23E000 +N23E001 +N23E002 +N23E003 +N23E004 +N23E005 +N23E006 +N23E007 +N23E008 +N23E009 +N23E010 +N23E011 +N23E012 +N23E013 +N23E014 +N23E015 +N23E016 +N23E017 +N23E018 +N23E019 +N23E020 +N23E021 +N23E022 +N23E023 +N23E024 +N23E025 +N23E026 +N23E027 +N23E028 +N23E029 +N23E034 +N23E039 +N23E040 +N23E041 +N23E042 +N23E044 +N23E045 +N23E046 +N23E047 +N23E048 +N23E049 +N23E050 +N23E053 +N23E054 +N23E055 +N23E056 +N23W001 +N23W002 +N23W003 +N23W004 +N23W005 +N23W006 +N23W007 +N23W008 +N23W009 +N23W010 +N23W011 +N23W012 +N23W013 +N23W014 +N23W015 +N24E000 +N24E001 +N24E002 +N24E003 +N24E004 +N24E005 +N24E006 +N24E007 +N24E008 +N24E009 +N24E010 +N24E011 +N24E012 +N24E013 +N24E014 +N24E015 +N24E016 +N24E017 +N24E018 +N24E019 +N24E020 +N24E021 +N24E022 +N24E023 +N24E024 +N24E025 +N24E026 +N24E027 +N24E028 +N24E029 +N24E030 +N24E031 +N24E033 +N24E039 +N24E040 +N24E041 +N24E042 +N24E043 +N24E044 +N24E045 +N24E047 +N24E048 +N24E049 +N24W001 +N24W002 +N24W003 +N24W004 +N24W005 +N24W006 +N24W007 +N24W008 +N24W009 +N24W010 +N24W011 +N24W012 +N24W013 +N24W014 +N25E000 +N25E001 +N25E002 +N25E003 +N25E004 +N25E005 +N25E006 +N25E007 +N25E008 +N25E009 +N25E010 +N25E011 +N25E012 +N25E013 +N25E014 +N25E015 +N25E016 +N25E017 +N25E018 +N25E019 +N25E020 +N25E021 +N25E022 +N25E023 +N25E024 +N25E025 +N25E026 +N25E027 +N25E028 +N25E029 +N25E030 +N25E031 +N25E033 +N25E038 +N25E039 +N25E040 +N25E041 +N25E042 +N25E043 +N25E044 +N25E045 +N25E046 +N25E047 +N25E048 +N25W001 +N25W002 +N25W003 +N25W004 +N25W005 +N25W006 +N25W007 +N25W008 +N25W009 +N25W010 +N25W011 +N25W012 +N25W013 +N25W014 +N26E000 +N26E001 +N26E002 +N26E003 +N26E004 +N26E005 +N26E006 +N26E007 +N26E008 +N26E009 +N26E010 +N26E011 +N26E012 +N26E013 +N26E014 +N26E015 +N26E016 +N26E017 +N26E018 +N26E019 +N26E020 +N26E021 +N26E022 +N26E023 +N26E024 +N26E025 +N26E026 +N26E027 +N26E028 +N26E029 +N26E030 +N26E037 +N26E038 +N26E039 +N26E040 +N26E041 +N26E042 +N26E043 +N26E044 +N26E045 +N26E046 +N26E047 +N26E048 +N26E058 +N26W001 +N26W002 +N26W003 +N26W004 +N26W005 +N26W006 +N26W007 +N26W008 +N26W009 +N26W010 +N26W011 +N26W012 +N26W013 +N27E000 +N27E001 +N27E002 +N27E003 +N27E004 +N27E005 +N27E006 +N27E007 +N27E008 +N27E009 +N27E010 +N27E011 +N27E012 +N27E013 +N27E015 +N27E016 +N27E017 +N27E018 +N27E019 +N27E020 +N27E021 +N27E022 +N27E023 +N27E024 +N27E025 +N27E026 +N27E027 +N27E028 +N27E029 +N27E032 +N27E036 +N27E037 +N27E038 +N27E039 +N27E040 +N27E041 +N27E042 +N27E043 +N27E044 +N27E045 +N27E046 +N27E047 +N27E054 +N27E059 +N27W001 +N27W002 +N27W003 +N27W004 +N27W005 +N27W006 +N27W007 +N27W008 +N27W009 +N27W010 +N27W011 +N27W012 +N28E000 +N28E001 +N28E002 +N28E003 +N28E004 +N28E005 +N28E006 +N28E007 +N28E008 +N28E009 +N28E010 +N28E011 +N28E012 +N28E013 +N28E014 +N28E015 +N28E016 +N28E017 +N28E020 +N28E022 +N28E023 +N28E024 +N28E025 +N28E027 +N28E028 +N28E029 +N28E037 +N28E038 +N28E039 +N28E040 +N28E041 +N28E042 +N28E043 +N28E044 +N28E045 +N28E046 +N28E052 +N28E053 +N28E054 +N28E055 +N28E056 +N28E059 +N28W001 +N28W002 +N28W003 +N28W004 +N28W005 +N28W006 +N28W007 +N28W008 +N28W009 +N28W010 +N29E000 +N29E001 +N29E002 +N29E003 +N29E004 +N29E005 +N29E006 +N29E007 +N29E008 +N29E009 +N29E010 +N29E011 +N29E012 +N29E013 +N29E014 +N29E015 +N29E016 +N29E018 +N29E020 +N29E021 +N29E022 +N29E023 +N29E027 +N29E028 +N29E029 +N29E037 +N29E038 +N29E040 +N29E041 +N29E042 +N29E044 +N29E045 +N29E046 +N29E056 +N29E057 +N29E058 +N29E059 +N29W001 +N29W002 +N29W003 +N29W004 +N29W005 +N29W006 +N29W007 +N29W008 +N29W009 +N30E000 +N30E001 +N30E003 +N30E004 +N30E005 +N30E006 +N30E007 +N30E008 +N30E009 +N30E010 +N30E011 +N30E012 +N30E013 +N30E014 +N30E015 +N30E016 +N30E021 +N30E022 +N30E023 +N30E024 +N30E025 +N30E026 +N30E027 +N30E033 +N30E034 +N30E036 +N30E037 +N30E038 +N30E039 +N30E040 +N30E041 +N30E042 +N30E043 +N30E044 +N30E045 +N30E051 +N30E053 +N30E057 +N30E058 +N30E059 +N30W001 +N30W002 +N30W003 +N30W004 +N30W005 +N30W006 +N31E000 +N31E001 +N31E002 +N31E003 +N31E004 +N31E006 +N31E007 +N31E008 +N31E009 +N31E010 +N31E011 +N31E012 +N31E013 +N31E014 +N31E021 +N31E022 +N31E023 +N31E036 +N31E037 +N31E038 +N31E039 +N31E040 +N31E041 +N31E043 +N31E052 +N31E053 +N31E054 +N31E056 +N31E057 +N31E058 +N31E059 +N31W001 +N31W002 +N31W004 +N32E000 +N32E001 +N32E002 +N32E003 +N32E004 +N32E005 +N32E006 +N32E007 +N32E008 +N32E009 +N32E010 +N32E037 +N32E038 +N32E041 +N32E042 +N32E054 +N32E055 +N32E056 +N32E057 +N32E058 +N32W001 +N32W004 +N33E000 +N33E001 +N33E002 +N33E003 +N33E004 +N33E007 +N33E040 +N33E041 +N33E047 +N33E048 +N33E050 +N33E051 +N33E053 +N33E054 +N33E055 +N33E056 +N33E057 +N33E059 +N33W003 +N33W004 +N34E001 +N34E002 +N34E004 +N34E007 +N34E037 +N34E039 +N34E046 +N34E047 +N34E048 +N34E049 +N34E056 +N34E057 +N34E059 +N34W004 +S01E026 +S01E027 +S01E028 +S01E040 +S02E020 +S02E035 +S02E038 +S02E039 +S03E012 +S03E013 +S03E020 +S03E022 +S03E023 +S03E038 +S03E039 +S04E013 +S04E014 +S04E023 +S04E027 +S04E031 +S05E027 +S05E028 +S05E036 +S05E037 +S06E015 +S07E015 +S07E018 +S07E028 +S07E032 +S07E033 +S07E034 +S08E018 +S08E020 +S08E023 +S09E016 +S09E018 +S09E019 +S09E022 +S09E023 +S10E017 +S10E020 +S10E021 +S10E022 +S10E031 +S10E038 +S11E018 +S11E019 +S11E020 +S11E021 +S11E024 +S11E035 +S11E037 +S11E038 +S12E016 +S12E018 +S13E014 +S13E023 +S13E024 +S13E035 +S13E039 +S14E024 +S14E025 +S14E026 +S14E036 +S14E037 +S15E018 +S15E020 +S15E021 +S15E024 +S15E036 +S16E014 +S16E015 +S16E020 +S16E021 +S16E024 +S16E036 +S16E037 +S16E038 +S17E012 +S17E013 +S17E016 +S17E017 +S17E018 +S17E019 +S17E020 +S17E024 +S17E025 +S18E012 +S18E013 +S18E017 +S18E018 +S18E022 +S18E033 +S19E013 +S19E014 +S19E018 +S19E019 +S19E024 +S20E014 +S20E016 +S20E017 +S20E019 +S20E021 +S20E024 +S20E026 +S21E014 +S21E019 +S21E020 +S21E021 +S21E023 +S21E033 +S22E019 +S22E020 +S22E021 +S22E022 +S23E015 +S23E019 +S23E020 +S23E021 +S23E023 +S23E024 +S23E025 +S23E034 +S24E015 +S24E018 +S24E019 +S25E015 +S25E016 +S25E018 +S25E019 +S25E045 +S26E015 +S26E016 +S26E017 +S26E019 +S26E021 +S26E022 +S26E023 +S27E016 +S27E021 +S27E022 +S28E016 +S29E020 +S31E018 +S32E019 +S16E131 +S16E132 +S17E125 +S17E126 +S17E129 +S17E130 +S17E131 +S17E132 +S17E134 +S17E135 +S18E125 +S18E127 +S18E129 +S18E130 +S18E131 +S18E132 +S18E134 +S18E136 +S18E137 +S18E143 +S19E130 +S19E131 +S19E136 +S19E138 +S20E122 +S20E123 +S20E126 +S20E127 +S20E130 +S20E131 +S20E132 +S20E133 +S20E138 +S20E142 +S20E143 +S21E120 +S21E121 +S21E122 +S21E123 +S21E124 +S21E125 +S21E126 +S21E128 +S21E129 +S21E130 +S21E132 +S21E135 +S21E136 +S21E141 +S22E119 +S22E126 +S22E127 +S22E128 +S22E130 +S22E131 +S22E132 +S22E135 +S22E136 +S22E137 +S22E138 +S22E139 +S22E142 +S23E116 +S23E117 +S23E118 +S23E119 +S23E120 +S23E124 +S23E125 +S23E126 +S23E129 +S23E130 +S23E131 +S23E134 +S23E135 +S23E136 +S23E137 +S23E139 +S23E146 +S24E116 +S24E117 +S24E118 +S24E121 +S24E124 +S24E125 +S24E126 +S24E127 +S24E130 +S24E132 +S24E135 +S24E139 +S24E143 +S24E144 +S24E146 +S25E117 +S25E118 +S25E119 +S25E122 +S25E123 +S25E125 +S25E127 +S25E135 +S25E137 +S25E141 +S25E142 +S25E143 +S25E144 +S25E145 +S25E146 +S26E116 +S26E117 +S26E118 +S26E123 +S26E124 +S26E125 +S26E126 +S26E127 +S26E129 +S26E130 +S26E134 +S26E135 +S26E136 +S26E142 +S26E145 +S26E146 +S26E147 +S27E116 +S27E119 +S27E124 +S27E127 +S27E128 +S27E129 +S27E130 +S27E131 +S27E133 +S27E134 +S27E136 +S27E142 +S27E145 +S28E115 +S28E119 +S28E122 +S28E125 +S28E126 +S28E127 +S28E130 +S28E131 +S28E134 +S29E115 +S29E117 +S29E123 +S29E125 +S29E126 +S29E127 +S29E130 +S29E131 +S30E119 +S30E123 +S31E123 +S31E124 +S31E125 +S31E128 +S31E129 +S31E130 +S32E125 +S32E126 +S32E127 +S32E146 +S33E145 +S33E146 +S34E139 +S34E143 +N01E113 +N01E114 +N01E115 +N01E116 +N02E115 +N03E115 +N04E116 +N19E103 +N20E103 +N22E093 +N22E102 +N25E070 +N25E093 +N26E060 +N26E063 +N26E064 +N26E065 +N26E066 +N26E070 +N27E060 +N27E062 +N27E063 +N27E064 +N27E065 +N27E066 +N27E098 +N28E060 +N28E061 +N28E062 +N28E063 +N28E064 +N28E065 +N28E066 +N28E067 +N28E071 +N28E074 +N28E075 +N29E060 +N29E063 +N29E064 +N29E065 +N29E066 +N29E068 +N29E081 +N29E102 +N30E060 +N30E063 +N30E064 +N30E065 +N30E066 +N30E068 +N30E069 +N30E079 +N30E098 +N30E100 +N31E060 +N31E062 +N31E063 +N31E064 +N31E065 +N31E066 +N31E067 +N31E068 +N31E069 +N31E078 +N31E097 +N31E098 +N32E060 +N32E061 +N32E062 +N32E063 +N32E064 +N32E066 +N32E067 +N32E068 +N32E069 +N32E070 +N32E095 +N32E100 +N32E107 +N33E060 +N33E061 +N33E062 +N33E063 +N33E064 +N33E065 +N33E066 +N33E067 +N33E069 +N33E098 +N34E062 +N34E063 +N34E065 +N34E073 +N34E100 +N34E103 +N34E104 +N35E003 +N35E008 +N35E048 +N35E049 +N35E053 +N35E054 +N35E057 +N35E058 +N35E060 +N35E062 +N35E063 +N35E067 +N36E047 +N36E048 +N36E055 +N36E057 +N36E058 +N36E061 +N36E063 +N36E064 +N36E066 +N36E069 +N36E076 +N36E077 +N36E079 +N36E080 +N36E107 +N37E043 +N37E044 +N37E047 +N37E056 +N37E057 +N37E060 +N37E070 +N37E075 +N37E076 +N37E084 +N37E085 +N37E087 +N38E036 +N38E046 +N38E055 +N38E078 +N38E079 +N38E080 +N38E082 +N38E083 +N38E084 +N38E087 +N38E088 +N38E103 +N39E031 +N39E036 +N39E039 +N39E057 +N39E058 +N39E060 +N39E061 +N39E080 +N39E081 +N39E082 +N39E083 +N39E084 +N39E085 +N39E086 +N39E089 +N39E090 +N39E091 +N39E092 +N39E093 +N39E096 +N39E097 +N39E103 +N39E106 +N40E056 +N40E060 +N40E084 +N40E088 +N40E089 +N40E090 +N40E091 +N40E092 +N40E101 +N40E105 +N41E042 +N41E079 +N41E088 +N41E089 +N41E090 +N41E092 +N41E094 +N41E095 +N41E096 +N41E097 +N41E098 +N41E099 +N41E102 +N41E103 +N41E104 +N41E105 +N42E054 +N42E055 +N42E062 +N42E064 +N42E065 +N42E066 +N42E081 +N42E088 +N42E090 +N42E095 +N42E096 +N42E097 +N42E098 +N42E099 +N42E102 +N42E103 +N42E104 +N42E105 +N42E106 +N42E107 +N43E054 +N43E056 +N43E057 +N43E063 +N43E064 +N43E065 +N43E095 +N43E096 +N43E097 +N43E098 +N43E099 +N43E100 +N43E101 +N43E102 +N43E103 +N43E106 +N43E108 +N44E073 +N44E090 +N44E092 +N44E093 +N44E095 +N44E097 +N44E100 +N44E101 +N44E102 +N44E107 +N45E072 +N45E087 +N45E088 +N45E089 +N45E090 +N45E091 +N45E093 +N45E096 +N45E107 +N45E120 +N46E120 +N46E136 +N47E024 +N47E061 +N47E077 +N47E078 +N47E082 +N47E096 +N47E128 +N47E136 +N47E137 +N48E103 +N48E120 +N48E121 +N48E122 +N48E131 +N48E137 +N48E138 +N49E059 +N49E121 +N49E122 +N49E131 +N49E132 +N49E138 +N49E139 +N50E086 +N50E109 +N50E110 +N50E120 +N50E121 +N50E122 +N50E123 +N50E124 +N50E125 +N50E133 +N50E134 +N50E135 +N50E139 +N51E121 +N51E123 +N51E124 +N51E125 +N52E114 +N52E121 +N52E122 +N52E123 +N52E124 +N52E134 +N53E104 +N53E115 +N53E117 +N53E118 +N53E131 +N53E134 +N54E104 +N54E117 +N54E121 +N54E122 +N54E123 +N54E124 +N55E096 +N55E104 +N55E126 +N55E127 +N55E128 +N55E129 +N56E088 +N56E091 +N56E100 +N57E075 +N57E092 +N57E137 +N58E046 +N58E103 +N58E139 +N59E046 +N59E047 +N59E094 +N59E095 +N59E098 +N59E101 +N59E115 +N59E123 +N59E124 +N59E130 +N59E140 +N60E004 +N60E005 +N60E006 +N60E007 +N60E008 +N60E009 +N60E010 +N60E011 +N60E012 +N60E013 +N60E014 +N60E015 +N60E016 +N60E017 +N60E018 +N60E019 +N60E020 +N60E021 +N60E022 +N60E023 +N60E024 +N60E025 +N60E026 +N60E027 +N60E028 +N60E029 +N60E030 +N60E031 +N60E032 +N60E033 +N60E034 +N60E035 +N60E036 +N60E037 +N60E038 +N60E039 +N60E040 +N60E041 +N60E042 +N60E043 +N60E044 +N60E045 +N60E046 +N60E047 +N60E048 +N60E049 +N60E050 +N60E051 +N60E052 +N60E053 +N60E054 +N60E055 +N60E056 +N60E057 +N60E058 +N60E059 +N60E060 +N60E061 +N60E062 +N60E063 +N60E064 +N60E065 +N60E066 +N60E067 +N60E068 +N60E069 +N60E070 +N60E071 +N60E072 +N60E073 +N60E074 +N60E075 +N60E076 +N60E077 +N60E078 +N60E079 +N60E080 +N60E081 +N60E082 +N60E083 +N60E084 +N60E085 +N60E086 +N60E087 +N60E088 +N60E089 +N60E090 +N60E091 +N60E092 +N60E093 +N60E094 +N60E095 +N60E096 +N60E097 +N60E098 +N60E099 +N60E100 +N60E101 +N60E102 +N60E103 +N60E104 +N60E105 +N60E106 +N60E107 +N60E108 +N60E109 +N60E110 +N60E111 +N60E112 +N60E113 +N60E114 +N60E115 +N60E116 +N60E117 +N60E118 +N60E119 +N60E120 +N60E121 +N60E122 +N60E123 +N60E124 +N60E125 +N60E126 +N60E127 +N60E128 +N60E129 +N60E130 +N60E131 +N60E132 +N60E133 +N60E134 +N60E135 +N60E136 +N60E137 +N60E138 +N60E139 +N60E140 +N60E141 +N60E142 +N60E143 +N60E144 +N60E145 +N60E146 +N60E147 +N60E148 +N60E149 +N60E150 +N60E151 +N60E152 +N60E153 +N60E154 +N60E155 +N60E156 +N60E159 +N60E160 +N60E161 +N60E162 +N60E163 +N60E164 +N60E165 +N60E166 +N60E167 +N60E168 +N60E169 +N60E170 +N60E171 +N60E172 +N60W001 +N60W002 +N60W003 +S01E113 +S02E111 +N20W089 +N25W107 +N27W107 +N28W102 +N28W109 +N29W103 +N30W101 +N30W102 +N30W103 +N30W105 +N30W106 +N32W114 +N35W116 +N35W117 +N36W113 +N37W104 +N37W115 +N37W117 +N38W102 +N38W111 +N38W114 +N43W108 +N60W043 +N60W044 +N60W045 +N60W046 +N60W047 +N60W048 +N60W049 +N60W064 +N60W065 +N60W066 +N60W068 +N60W069 +N60W070 +N60W071 +N60W072 +N60W073 +N60W074 +N60W075 +N60W076 +N60W077 +N60W078 +N60W079 +N60W095 +N60W096 +N60W097 +N60W098 +N60W099 +N60W100 +N60W101 +N60W102 +N60W103 +N60W104 +N60W105 +N60W106 +N60W107 +N60W108 +N60W109 +N60W110 +N60W111 +N60W112 +N60W113 +N60W114 +N60W115 +N60W116 +N60W117 +N60W118 +N60W119 +N60W120 +N60W121 +N60W122 +N60W123 +N60W124 +N60W125 +N60W126 +N60W127 +N60W128 +N60W129 +N60W130 +N60W131 +N60W132 +N60W133 +N60W134 +N60W135 +N60W136 +N60W137 +N60W138 +N60W139 +N60W140 +N60W141 +N60W142 +N60W143 +N60W144 +N60W145 +N60W146 +N60W147 +N60W148 +N60W149 +N60W150 +N60W151 +N60W152 +N60W153 +N60W154 +N60W155 +N60W156 +N60W157 +N60W158 +N60W159 +N60W160 +N60W161 +N60W162 +N60W163 +N60W164 +N60W165 +N60W166 +N60W167 +N60W168 +N60W173 +N60W174 +N00W065 +N00W066 +N01W056 +N01W057 +N01W059 +N01W060 +N01W065 +N01W074 +N02W054 +N02W055 +N02W057 +N02W063 +N02W064 +N02W065 +N03W057 +N03W065 +N03W072 +N04W060 +N04W061 +N04W064 +N06W066 +S01W055 +S01W056 +S05W051 +S06W052 +S06W054 +S06W070 +S07W046 +S07W073 +S07W074 +S08W057 +S08W060 +S09W046 +S09W047 +S09W055 +S09W056 +S09W057 +S09W072 +S09W074 +S10W047 +S10W072 +S11W064 +S11W065 +S11W070 +S11W073 +S12W064 +S15W061 +S15W069 +S17W053 +S18W060 +S19W052 +S19W061 +S19W062 +S20W060 +S20W062 +S20W065 +S21W061 +S21W062 +S21W063 +S21W070 +S22W061 +S22W070 +S23W061 +S24W056 +S26W063 +S26W070 +S29W067 +S29W071 +S30W068 +S30W071 +S32W068 +S34W070 diff --git a/components/isceobj/Alos2Proc/srtm_tiles.txt b/components/isceobj/Alos2Proc/srtm_tiles.txt new file mode 100644 index 0000000..9458c8c --- /dev/null +++ b/components/isceobj/Alos2Proc/srtm_tiles.txt @@ -0,0 +1,14546 @@ +N00E006 +N00E009 +N00E010 +N00E011 +N00E012 +N00E013 +N00E014 +N00E015 +N00E016 +N00E017 +N00E018 +N00E019 +N00E020 +N00E021 +N00E022 +N00E023 +N00E024 +N00E025 +N00E026 +N00E027 +N00E028 +N00E029 +N00E030 +N00E031 +N00E032 +N00E033 +N00E034 +N00E035 +N00E036 +N00E037 +N00E038 +N00E039 +N00E040 +N00E041 +N00E042 +N00E043 +N01E007 +N01E009 +N01E010 +N01E011 +N01E012 +N01E013 +N01E014 +N01E015 +N01E016 +N01E017 +N01E018 +N01E019 +N01E020 +N01E021 +N01E022 +N01E023 +N01E024 +N01E025 +N01E026 +N01E027 +N01E028 +N01E029 +N01E030 +N01E031 +N01E032 +N01E033 +N01E034 +N01E035 +N01E036 +N01E037 +N01E038 +N01E039 +N01E040 +N01E041 +N01E042 +N01E043 +N01E044 +N01E045 +N02E009 +N02E010 +N02E011 +N02E012 +N02E013 +N02E014 +N02E015 +N02E016 +N02E017 +N02E018 +N02E019 +N02E020 +N02E021 +N02E022 +N02E023 +N02E024 +N02E025 +N02E026 +N02E027 +N02E028 +N02E029 +N02E030 +N02E031 +N02E032 +N02E033 +N02E034 +N02E035 +N02E036 +N02E037 +N02E038 +N02E039 +N02E040 +N02E041 +N02E042 +N02E043 +N02E044 +N02E045 +N02E046 +N03E008 +N03E009 +N03E010 +N03E011 +N03E012 +N03E013 +N03E014 +N03E015 +N03E016 +N03E017 +N03E018 +N03E019 +N03E020 +N03E021 +N03E022 +N03E023 +N03E024 +N03E025 +N03E026 +N03E027 +N03E028 +N03E029 +N03E030 +N03E031 +N03E032 +N03E033 +N03E034 +N03E035 +N03E036 +N03E037 +N03E038 +N03E039 +N03E040 +N03E041 +N03E042 +N03E043 +N03E044 +N03E045 +N03E046 +N03E047 +N04E005 +N04E006 +N04E007 +N04E008 +N04E009 +N04E010 +N04E011 +N04E012 +N04E013 +N04E014 +N04E015 +N04E016 +N04E017 +N04E018 +N04E019 +N04E020 +N04E021 +N04E022 +N04E023 +N04E024 +N04E025 +N04E026 +N04E027 +N04E028 +N04E029 +N04E030 +N04E031 +N04E032 +N04E033 +N04E034 +N04E035 +N04E036 +N04E037 +N04E038 +N04E039 +N04E040 +N04E041 +N04E042 +N04E043 +N04E044 +N04E045 +N04E046 +N04E047 +N04E048 +N04W002 +N04W003 +N04W006 +N04W007 +N04W008 +N04W009 +N04W010 +N05E000 +N05E001 +N05E004 +N05E005 +N05E006 +N05E007 +N05E008 +N05E009 +N05E010 +N05E011 +N05E012 +N05E013 +N05E014 +N05E015 +N05E016 +N05E017 +N05E018 +N05E019 +N05E020 +N05E021 +N05E022 +N05E023 +N05E024 +N05E025 +N05E026 +N05E027 +N05E028 +N05E029 +N05E030 +N05E031 +N05E032 +N05E033 +N05E034 +N05E035 +N05E036 +N05E037 +N05E038 +N05E039 +N05E040 +N05E041 +N05E042 +N05E043 +N05E044 +N05E045 +N05E046 +N05E047 +N05E048 +N05W001 +N05W002 +N05W003 +N05W004 +N05W005 +N05W006 +N05W007 +N05W008 +N05W009 +N05W010 +N05W011 +N06E000 +N06E001 +N06E002 +N06E003 +N06E004 +N06E005 +N06E006 +N06E007 +N06E008 +N06E009 +N06E010 +N06E011 +N06E012 +N06E013 +N06E014 +N06E015 +N06E016 +N06E017 +N06E018 +N06E019 +N06E020 +N06E021 +N06E022 +N06E023 +N06E024 +N06E025 +N06E026 +N06E027 +N06E028 +N06E029 +N06E030 +N06E031 +N06E032 +N06E033 +N06E034 +N06E035 +N06E036 +N06E037 +N06E038 +N06E039 +N06E040 +N06E041 +N06E042 +N06E043 +N06E044 +N06E045 +N06E046 +N06E047 +N06E048 +N06E049 +N06W001 +N06W002 +N06W003 +N06W004 +N06W005 +N06W006 +N06W007 +N06W008 +N06W009 +N06W010 +N06W011 +N06W012 +N07E000 +N07E001 +N07E002 +N07E003 +N07E004 +N07E005 +N07E006 +N07E007 +N07E008 +N07E009 +N07E010 +N07E011 +N07E012 +N07E013 +N07E014 +N07E015 +N07E016 +N07E017 +N07E018 +N07E019 +N07E020 +N07E021 +N07E022 +N07E023 +N07E024 +N07E025 +N07E026 +N07E027 +N07E028 +N07E029 +N07E030 +N07E031 +N07E032 +N07E033 +N07E034 +N07E035 +N07E036 +N07E037 +N07E038 +N07E039 +N07E040 +N07E041 +N07E042 +N07E043 +N07E044 +N07E045 +N07E046 +N07E047 +N07E048 +N07E049 +N07W001 +N07W002 +N07W003 +N07W004 +N07W005 +N07W006 +N07W007 +N07W008 +N07W009 +N07W010 +N07W011 +N07W012 +N07W013 +N07W014 +N08E000 +N08E001 +N08E002 +N08E003 +N08E004 +N08E005 +N08E006 +N08E007 +N08E008 +N08E009 +N08E010 +N08E011 +N08E012 +N08E013 +N08E014 +N08E015 +N08E016 +N08E017 +N08E018 +N08E019 +N08E020 +N08E021 +N08E022 +N08E023 +N08E024 +N08E025 +N08E026 +N08E027 +N08E028 +N08E029 +N08E030 +N08E031 +N08E032 +N08E033 +N08E034 +N08E035 +N08E036 +N08E037 +N08E038 +N08E039 +N08E040 +N08E041 +N08E042 +N08E043 +N08E044 +N08E045 +N08E046 +N08E047 +N08E048 +N08E049 +N08E050 +N08W001 +N08W002 +N08W003 +N08W004 +N08W005 +N08W006 +N08W007 +N08W008 +N08W009 +N08W010 +N08W011 +N08W012 +N08W013 +N08W014 +N09E000 +N09E001 +N09E002 +N09E003 +N09E004 +N09E005 +N09E006 +N09E007 +N09E008 +N09E009 +N09E010 +N09E011 +N09E012 +N09E013 +N09E014 +N09E015 +N09E016 +N09E017 +N09E018 +N09E019 +N09E020 +N09E021 +N09E022 +N09E023 +N09E024 +N09E025 +N09E026 +N09E027 +N09E028 +N09E029 +N09E030 +N09E031 +N09E032 +N09E033 +N09E034 +N09E035 +N09E036 +N09E037 +N09E038 +N09E039 +N09E040 +N09E041 +N09E042 +N09E043 +N09E044 +N09E045 +N09E046 +N09E047 +N09E048 +N09E049 +N09E050 +N09W001 +N09W002 +N09W003 +N09W004 +N09W005 +N09W006 +N09W007 +N09W008 +N09W009 +N09W010 +N09W011 +N09W012 +N09W013 +N09W014 +N09W015 +N10E000 +N10E001 +N10E002 +N10E003 +N10E004 +N10E005 +N10E006 +N10E007 +N10E008 +N10E009 +N10E010 +N10E011 +N10E012 +N10E013 +N10E014 +N10E015 +N10E016 +N10E017 +N10E018 +N10E019 +N10E020 +N10E021 +N10E022 +N10E023 +N10E024 +N10E025 +N10E026 +N10E027 +N10E028 +N10E029 +N10E030 +N10E031 +N10E032 +N10E033 +N10E034 +N10E035 +N10E036 +N10E037 +N10E038 +N10E039 +N10E040 +N10E041 +N10E042 +N10E043 +N10E044 +N10E045 +N10E046 +N10E047 +N10E048 +N10E049 +N10E050 +N10E051 +N10W001 +N10W002 +N10W003 +N10W004 +N10W005 +N10W006 +N10W007 +N10W008 +N10W009 +N10W010 +N10W011 +N10W012 +N10W013 +N10W014 +N10W015 +N10W016 +N11E000 +N11E001 +N11E002 +N11E003 +N11E004 +N11E005 +N11E006 +N11E007 +N11E008 +N11E009 +N11E010 +N11E011 +N11E012 +N11E013 +N11E014 +N11E015 +N11E016 +N11E017 +N11E018 +N11E019 +N11E020 +N11E021 +N11E022 +N11E023 +N11E024 +N11E025 +N11E026 +N11E027 +N11E028 +N11E029 +N11E030 +N11E031 +N11E032 +N11E033 +N11E034 +N11E035 +N11E036 +N11E037 +N11E038 +N11E039 +N11E040 +N11E041 +N11E042 +N11E043 +N11E047 +N11E048 +N11E049 +N11E050 +N11E051 +N11W001 +N11W002 +N11W003 +N11W004 +N11W005 +N11W006 +N11W007 +N11W008 +N11W009 +N11W010 +N11W011 +N11W012 +N11W013 +N11W014 +N11W015 +N11W016 +N11W017 +N12E000 +N12E001 +N12E002 +N12E003 +N12E004 +N12E005 +N12E006 +N12E007 +N12E008 +N12E009 +N12E010 +N12E011 +N12E012 +N12E013 +N12E014 +N12E015 +N12E016 +N12E017 +N12E018 +N12E019 +N12E020 +N12E021 +N12E022 +N12E023 +N12E024 +N12E025 +N12E026 +N12E027 +N12E028 +N12E029 +N12E030 +N12E031 +N12E032 +N12E033 +N12E034 +N12E035 +N12E036 +N12E037 +N12E038 +N12E039 +N12E040 +N12E041 +N12E042 +N12E043 +N12E044 +N12E045 +N12E052 +N12E053 +N12E054 +N12W001 +N12W002 +N12W003 +N12W004 +N12W005 +N12W006 +N12W007 +N12W008 +N12W009 +N12W010 +N12W011 +N12W012 +N12W013 +N12W014 +N12W015 +N12W016 +N12W017 +N13E000 +N13E001 +N13E002 +N13E003 +N13E004 +N13E005 +N13E006 +N13E007 +N13E008 +N13E009 +N13E010 +N13E011 +N13E012 +N13E013 +N13E014 +N13E015 +N13E016 +N13E017 +N13E018 +N13E019 +N13E020 +N13E021 +N13E022 +N13E023 +N13E024 +N13E025 +N13E026 +N13E027 +N13E028 +N13E029 +N13E030 +N13E031 +N13E032 +N13E033 +N13E034 +N13E035 +N13E036 +N13E037 +N13E038 +N13E039 +N13E040 +N13E041 +N13E042 +N13E043 +N13E044 +N13E045 +N13E046 +N13E047 +N13E048 +N13W001 +N13W002 +N13W003 +N13W004 +N13W005 +N13W006 +N13W007 +N13W008 +N13W009 +N13W010 +N13W011 +N13W012 +N13W013 +N13W014 +N13W015 +N13W016 +N13W017 +N14E000 +N14E001 +N14E002 +N14E003 +N14E004 +N14E005 +N14E006 +N14E007 +N14E008 +N14E009 +N14E010 +N14E011 +N14E012 +N14E013 +N14E014 +N14E015 +N14E016 +N14E017 +N14E018 +N14E019 +N14E020 +N14E021 +N14E022 +N14E023 +N14E024 +N14E025 +N14E026 +N14E027 +N14E028 +N14E029 +N14E030 +N14E031 +N14E032 +N14E033 +N14E034 +N14E035 +N14E036 +N14E037 +N14E038 +N14E039 +N14E040 +N14E041 +N14E042 +N14E043 +N14E044 +N14E045 +N14E046 +N14E047 +N14E048 +N14E049 +N14E050 +N14W001 +N14W002 +N14W003 +N14W004 +N14W005 +N14W006 +N14W007 +N14W008 +N14W009 +N14W010 +N14W011 +N14W012 +N14W013 +N14W014 +N14W015 +N14W016 +N14W017 +N14W018 +N14W024 +N14W025 +N15E000 +N15E001 +N15E002 +N15E003 +N15E004 +N15E005 +N15E006 +N15E007 +N15E008 +N15E009 +N15E010 +N15E011 +N15E012 +N15E013 +N15E014 +N15E015 +N15E016 +N15E017 +N15E018 +N15E019 +N15E020 +N15E021 +N15E022 +N15E023 +N15E024 +N15E025 +N15E026 +N15E027 +N15E028 +N15E029 +N15E030 +N15E031 +N15E032 +N15E033 +N15E034 +N15E035 +N15E036 +N15E037 +N15E038 +N15E039 +N15E040 +N15E041 +N15E042 +N15E043 +N15E044 +N15E045 +N15E046 +N15E047 +N15E048 +N15E049 +N15E050 +N15E051 +N15E052 +N15W001 +N15W002 +N15W003 +N15W004 +N15W005 +N15W006 +N15W007 +N15W008 +N15W009 +N15W010 +N15W011 +N15W012 +N15W013 +N15W014 +N15W015 +N15W016 +N15W017 +N15W018 +N15W023 +N15W024 +N15W025 +N16E000 +N16E001 +N16E002 +N16E003 +N16E004 +N16E005 +N16E006 +N16E007 +N16E008 +N16E009 +N16E010 +N16E011 +N16E012 +N16E013 +N16E014 +N16E015 +N16E016 +N16E017 +N16E018 +N16E019 +N16E020 +N16E021 +N16E022 +N16E023 +N16E024 +N16E025 +N16E026 +N16E027 +N16E028 +N16E029 +N16E030 +N16E031 +N16E032 +N16E033 +N16E034 +N16E035 +N16E036 +N16E037 +N16E038 +N16E039 +N16E040 +N16E041 +N16E042 +N16E043 +N16E044 +N16E045 +N16E046 +N16E047 +N16E048 +N16E049 +N16E050 +N16E051 +N16E052 +N16E053 +N16E054 +N16E055 +N16W001 +N16W002 +N16W003 +N16W004 +N16W005 +N16W006 +N16W007 +N16W008 +N16W009 +N16W010 +N16W011 +N16W012 +N16W013 +N16W014 +N16W015 +N16W016 +N16W017 +N16W023 +N16W025 +N16W026 +N17E000 +N17E001 +N17E002 +N17E003 +N17E004 +N17E005 +N17E006 +N17E007 +N17E008 +N17E009 +N17E010 +N17E011 +N17E012 +N17E013 +N17E014 +N17E015 +N17E016 +N17E017 +N17E018 +N17E019 +N17E020 +N17E021 +N17E022 +N17E023 +N17E024 +N17E025 +N17E026 +N17E027 +N17E028 +N17E029 +N17E030 +N17E031 +N17E032 +N17E033 +N17E034 +N17E035 +N17E036 +N17E037 +N17E038 +N17E039 +N17E041 +N17E042 +N17E043 +N17E044 +N17E045 +N17E046 +N17E047 +N17E048 +N17E049 +N17E050 +N17E051 +N17E052 +N17E053 +N17E054 +N17E055 +N17E056 +N17W001 +N17W002 +N17W003 +N17W004 +N17W005 +N17W006 +N17W007 +N17W008 +N17W009 +N17W010 +N17W011 +N17W012 +N17W013 +N17W014 +N17W015 +N17W016 +N17W017 +N17W025 +N17W026 +N18E000 +N18E001 +N18E002 +N18E003 +N18E004 +N18E005 +N18E006 +N18E007 +N18E008 +N18E009 +N18E010 +N18E011 +N18E012 +N18E013 +N18E014 +N18E015 +N18E016 +N18E017 +N18E018 +N18E019 +N18E020 +N18E021 +N18E022 +N18E023 +N18E024 +N18E025 +N18E026 +N18E027 +N18E028 +N18E029 +N18E030 +N18E031 +N18E032 +N18E033 +N18E034 +N18E035 +N18E036 +N18E037 +N18E038 +N18E040 +N18E041 +N18E042 +N18E043 +N18E044 +N18E045 +N18E046 +N18E047 +N18E048 +N18E049 +N18E050 +N18E051 +N18E052 +N18E053 +N18E054 +N18E055 +N18E056 +N18E057 +N18W001 +N18W002 +N18W003 +N18W004 +N18W005 +N18W006 +N18W007 +N18W008 +N18W009 +N18W010 +N18W011 +N18W012 +N18W013 +N18W014 +N18W015 +N18W016 +N18W017 +N19E000 +N19E001 +N19E002 +N19E003 +N19E004 +N19E005 +N19E006 +N19E007 +N19E008 +N19E009 +N19E010 +N19E011 +N19E012 +N19E013 +N19E014 +N19E015 +N19E016 +N19E017 +N19E018 +N19E019 +N19E020 +N19E021 +N19E022 +N19E023 +N19E024 +N19E025 +N19E026 +N19E027 +N19E028 +N19E029 +N19E030 +N19E031 +N19E032 +N19E033 +N19E034 +N19E035 +N19E036 +N19E037 +N19E038 +N19E039 +N19E040 +N19E041 +N19E042 +N19E043 +N19E044 +N19E045 +N19E046 +N19E047 +N19E048 +N19E049 +N19E050 +N19E051 +N19E052 +N19E053 +N19E054 +N19E055 +N19E056 +N19E057 +N19W001 +N19W002 +N19W003 +N19W004 +N19W005 +N19W006 +N19W007 +N19W008 +N19W009 +N19W010 +N19W011 +N19W012 +N19W013 +N19W014 +N19W015 +N19W016 +N19W017 +N20E000 +N20E001 +N20E002 +N20E003 +N20E004 +N20E005 +N20E006 +N20E007 +N20E008 +N20E009 +N20E010 +N20E011 +N20E012 +N20E013 +N20E014 +N20E015 +N20E016 +N20E017 +N20E018 +N20E019 +N20E020 +N20E021 +N20E022 +N20E023 +N20E024 +N20E025 +N20E026 +N20E027 +N20E028 +N20E029 +N20E030 +N20E031 +N20E032 +N20E033 +N20E034 +N20E035 +N20E036 +N20E037 +N20E039 +N20E040 +N20E041 +N20E042 +N20E043 +N20E044 +N20E045 +N20E046 +N20E047 +N20E048 +N20E049 +N20E050 +N20E051 +N20E052 +N20E053 +N20E054 +N20E055 +N20E056 +N20E057 +N20E058 +N20W001 +N20W002 +N20W003 +N20W004 +N20W005 +N20W006 +N20W007 +N20W008 +N20W009 +N20W010 +N20W011 +N20W012 +N20W013 +N20W014 +N20W015 +N20W016 +N20W017 +N20W018 +N21E000 +N21E001 +N21E002 +N21E003 +N21E004 +N21E005 +N21E006 +N21E007 +N21E008 +N21E009 +N21E010 +N21E011 +N21E012 +N21E013 +N21E014 +N21E015 +N21E016 +N21E017 +N21E018 +N21E019 +N21E020 +N21E021 +N21E022 +N21E023 +N21E024 +N21E025 +N21E026 +N21E027 +N21E028 +N21E029 +N21E030 +N21E031 +N21E032 +N21E033 +N21E034 +N21E035 +N21E036 +N21E037 +N21E038 +N21E039 +N21E040 +N21E041 +N21E042 +N21E043 +N21E044 +N21E045 +N21E046 +N21E047 +N21E048 +N21E049 +N21E050 +N21E051 +N21E052 +N21E053 +N21E054 +N21E055 +N21E056 +N21E057 +N21E058 +N21E059 +N21W001 +N21W002 +N21W003 +N21W004 +N21W005 +N21W006 +N21W007 +N21W008 +N21W009 +N21W010 +N21W011 +N21W012 +N21W013 +N21W014 +N21W015 +N21W016 +N21W017 +N21W018 +N22E000 +N22E001 +N22E002 +N22E003 +N22E004 +N22E005 +N22E006 +N22E007 +N22E008 +N22E009 +N22E010 +N22E011 +N22E012 +N22E013 +N22E014 +N22E015 +N22E016 +N22E017 +N22E018 +N22E019 +N22E020 +N22E021 +N22E022 +N22E023 +N22E024 +N22E025 +N22E026 +N22E027 +N22E028 +N22E029 +N22E030 +N22E031 +N22E032 +N22E033 +N22E034 +N22E035 +N22E036 +N22E038 +N22E039 +N22E040 +N22E041 +N22E042 +N22E043 +N22E044 +N22E045 +N22E046 +N22E047 +N22E048 +N22E049 +N22E050 +N22E051 +N22E052 +N22E053 +N22E054 +N22E055 +N22E056 +N22E057 +N22E058 +N22E059 +N22W001 +N22W002 +N22W003 +N22W004 +N22W005 +N22W006 +N22W007 +N22W008 +N22W009 +N22W010 +N22W011 +N22W012 +N22W013 +N22W014 +N22W015 +N22W016 +N22W017 +N23E000 +N23E001 +N23E002 +N23E003 +N23E004 +N23E005 +N23E006 +N23E007 +N23E008 +N23E009 +N23E010 +N23E011 +N23E012 +N23E013 +N23E014 +N23E015 +N23E016 +N23E017 +N23E018 +N23E019 +N23E020 +N23E021 +N23E022 +N23E023 +N23E024 +N23E025 +N23E026 +N23E027 +N23E028 +N23E029 +N23E030 +N23E031 +N23E032 +N23E033 +N23E034 +N23E035 +N23E036 +N23E038 +N23E039 +N23E040 +N23E041 +N23E042 +N23E043 +N23E044 +N23E045 +N23E046 +N23E047 +N23E048 +N23E049 +N23E050 +N23E051 +N23E052 +N23E053 +N23E054 +N23E055 +N23E056 +N23E057 +N23E058 +N23E059 +N23W001 +N23W002 +N23W003 +N23W004 +N23W005 +N23W006 +N23W007 +N23W008 +N23W009 +N23W010 +N23W011 +N23W012 +N23W013 +N23W014 +N23W015 +N23W016 +N23W017 +N24E000 +N24E001 +N24E002 +N24E003 +N24E004 +N24E005 +N24E006 +N24E007 +N24E008 +N24E009 +N24E010 +N24E011 +N24E012 +N24E013 +N24E014 +N24E015 +N24E016 +N24E017 +N24E018 +N24E019 +N24E020 +N24E021 +N24E022 +N24E023 +N24E024 +N24E025 +N24E026 +N24E027 +N24E028 +N24E029 +N24E030 +N24E031 +N24E032 +N24E033 +N24E034 +N24E035 +N24E037 +N24E038 +N24E039 +N24E040 +N24E041 +N24E042 +N24E043 +N24E044 +N24E045 +N24E046 +N24E047 +N24E048 +N24E049 +N24E050 +N24E051 +N24E052 +N24E053 +N24E054 +N24E055 +N24E056 +N24E057 +N24W001 +N24W002 +N24W003 +N24W004 +N24W005 +N24W006 +N24W007 +N24W008 +N24W009 +N24W010 +N24W011 +N24W012 +N24W013 +N24W014 +N24W015 +N24W016 +N25E000 +N25E001 +N25E002 +N25E003 +N25E004 +N25E005 +N25E006 +N25E007 +N25E008 +N25E009 +N25E010 +N25E011 +N25E012 +N25E013 +N25E014 +N25E015 +N25E016 +N25E017 +N25E018 +N25E019 +N25E020 +N25E021 +N25E022 +N25E023 +N25E024 +N25E025 +N25E026 +N25E027 +N25E028 +N25E029 +N25E030 +N25E031 +N25E032 +N25E033 +N25E034 +N25E036 +N25E037 +N25E038 +N25E039 +N25E040 +N25E041 +N25E042 +N25E043 +N25E044 +N25E045 +N25E046 +N25E047 +N25E048 +N25E049 +N25E050 +N25E051 +N25E052 +N25E054 +N25E055 +N25E056 +N25E057 +N25E058 +N25E059 +N25W001 +N25W002 +N25W003 +N25W004 +N25W005 +N25W006 +N25W007 +N25W008 +N25W009 +N25W010 +N25W011 +N25W012 +N25W013 +N25W014 +N25W015 +N26E000 +N26E001 +N26E002 +N26E003 +N26E004 +N26E005 +N26E006 +N26E007 +N26E008 +N26E009 +N26E010 +N26E011 +N26E012 +N26E013 +N26E014 +N26E015 +N26E016 +N26E017 +N26E018 +N26E019 +N26E020 +N26E021 +N26E022 +N26E023 +N26E024 +N26E025 +N26E026 +N26E027 +N26E028 +N26E029 +N26E030 +N26E031 +N26E032 +N26E033 +N26E034 +N26E035 +N26E036 +N26E037 +N26E038 +N26E039 +N26E040 +N26E041 +N26E042 +N26E043 +N26E044 +N26E045 +N26E046 +N26E047 +N26E048 +N26E049 +N26E050 +N26E051 +N26E053 +N26E054 +N26E055 +N26E056 +N26E057 +N26E058 +N26E059 +N26W001 +N26W002 +N26W003 +N26W004 +N26W005 +N26W006 +N26W007 +N26W008 +N26W009 +N26W010 +N26W011 +N26W012 +N26W013 +N26W014 +N26W015 +N27E000 +N27E001 +N27E002 +N27E003 +N27E004 +N27E005 +N27E006 +N27E007 +N27E008 +N27E009 +N27E010 +N27E011 +N27E012 +N27E013 +N27E014 +N27E015 +N27E016 +N27E017 +N27E018 +N27E019 +N27E020 +N27E021 +N27E022 +N27E023 +N27E024 +N27E025 +N27E026 +N27E027 +N27E028 +N27E029 +N27E030 +N27E031 +N27E032 +N27E033 +N27E034 +N27E035 +N27E036 +N27E037 +N27E038 +N27E039 +N27E040 +N27E041 +N27E042 +N27E043 +N27E044 +N27E045 +N27E046 +N27E047 +N27E048 +N27E049 +N27E050 +N27E051 +N27E052 +N27E053 +N27E054 +N27E055 +N27E056 +N27E057 +N27E058 +N27E059 +N27W001 +N27W002 +N27W003 +N27W004 +N27W005 +N27W006 +N27W007 +N27W008 +N27W009 +N27W010 +N27W011 +N27W012 +N27W013 +N27W014 +N27W016 +N27W017 +N27W018 +N27W019 +N28E000 +N28E001 +N28E002 +N28E003 +N28E004 +N28E005 +N28E006 +N28E007 +N28E008 +N28E009 +N28E010 +N28E011 +N28E012 +N28E013 +N28E014 +N28E015 +N28E016 +N28E017 +N28E018 +N28E019 +N28E020 +N28E021 +N28E022 +N28E023 +N28E024 +N28E025 +N28E026 +N28E027 +N28E028 +N28E029 +N28E030 +N28E031 +N28E032 +N28E033 +N28E034 +N28E035 +N28E036 +N28E037 +N28E038 +N28E039 +N28E040 +N28E041 +N28E042 +N28E043 +N28E044 +N28E045 +N28E046 +N28E047 +N28E048 +N28E050 +N28E051 +N28E052 +N28E053 +N28E054 +N28E055 +N28E056 +N28E057 +N28E058 +N28E059 +N28W001 +N28W002 +N28W003 +N28W004 +N28W005 +N28W006 +N28W007 +N28W008 +N28W009 +N28W010 +N28W011 +N28W012 +N28W013 +N28W014 +N28W015 +N28W016 +N28W017 +N28W018 +N28W019 +N29E000 +N29E001 +N29E002 +N29E003 +N29E004 +N29E005 +N29E006 +N29E007 +N29E008 +N29E009 +N29E010 +N29E011 +N29E012 +N29E013 +N29E014 +N29E015 +N29E016 +N29E017 +N29E018 +N29E019 +N29E020 +N29E021 +N29E022 +N29E023 +N29E024 +N29E025 +N29E026 +N29E027 +N29E028 +N29E029 +N29E030 +N29E031 +N29E032 +N29E033 +N29E034 +N29E035 +N29E036 +N29E037 +N29E038 +N29E039 +N29E040 +N29E041 +N29E042 +N29E043 +N29E044 +N29E045 +N29E046 +N29E047 +N29E048 +N29E049 +N29E050 +N29E051 +N29E052 +N29E053 +N29E054 +N29E055 +N29E056 +N29E057 +N29E058 +N29E059 +N29W001 +N29W002 +N29W003 +N29W004 +N29W005 +N29W006 +N29W007 +N29W008 +N29W009 +N29W010 +N29W011 +N29W014 +N30E000 +N30E001 +N30E002 +N30E003 +N30E004 +N30E005 +N30E006 +N30E007 +N30E008 +N30E009 +N30E010 +N30E011 +N30E012 +N30E013 +N30E014 +N30E015 +N30E016 +N30E017 +N30E018 +N30E019 +N30E020 +N30E021 +N30E022 +N30E023 +N30E024 +N30E025 +N30E026 +N30E027 +N30E028 +N30E029 +N30E030 +N30E031 +N30E032 +N30E033 +N30E034 +N30E035 +N30E036 +N30E037 +N30E038 +N30E039 +N30E040 +N30E041 +N30E042 +N30E043 +N30E044 +N30E045 +N30E046 +N30E047 +N30E048 +N30E049 +N30E050 +N30E051 +N30E052 +N30E053 +N30E054 +N30E055 +N30E056 +N30E057 +N30E058 +N30E059 +N30W001 +N30W002 +N30W003 +N30W004 +N30W005 +N30W006 +N30W007 +N30W008 +N30W009 +N30W010 +N30W016 +N30W017 +N31E000 +N31E001 +N31E002 +N31E003 +N31E004 +N31E005 +N31E006 +N31E007 +N31E008 +N31E009 +N31E010 +N31E011 +N31E012 +N31E013 +N31E014 +N31E015 +N31E016 +N31E017 +N31E019 +N31E020 +N31E021 +N31E022 +N31E023 +N31E024 +N31E025 +N31E026 +N31E027 +N31E028 +N31E029 +N31E030 +N31E031 +N31E032 +N31E033 +N31E034 +N31E035 +N31E036 +N31E037 +N31E038 +N31E039 +N31E040 +N31E041 +N31E042 +N31E043 +N31E044 +N31E045 +N31E046 +N31E047 +N31E048 +N31E049 +N31E050 +N31E051 +N31E052 +N31E053 +N31E054 +N31E055 +N31E056 +N31E057 +N31E058 +N31E059 +N31W001 +N31W002 +N31W003 +N31W004 +N31W005 +N31W006 +N31W007 +N31W008 +N31W009 +N31W010 +N32E000 +N32E001 +N32E002 +N32E003 +N32E004 +N32E005 +N32E006 +N32E007 +N32E008 +N32E009 +N32E010 +N32E011 +N32E012 +N32E013 +N32E014 +N32E015 +N32E019 +N32E020 +N32E021 +N32E022 +N32E023 +N32E024 +N32E034 +N32E035 +N32E036 +N32E037 +N32E038 +N32E039 +N32E040 +N32E041 +N32E042 +N32E043 +N32E044 +N32E045 +N32E046 +N32E047 +N32E048 +N32E049 +N32E050 +N32E051 +N32E052 +N32E053 +N32E054 +N32E055 +N32E056 +N32E057 +N32E058 +N32E059 +N32W001 +N32W002 +N32W003 +N32W004 +N32W005 +N32W006 +N32W007 +N32W008 +N32W009 +N32W010 +N32W017 +N32W018 +N33E000 +N33E001 +N33E002 +N33E003 +N33E004 +N33E005 +N33E006 +N33E007 +N33E008 +N33E009 +N33E010 +N33E011 +N33E035 +N33E036 +N33E037 +N33E038 +N33E039 +N33E040 +N33E041 +N33E042 +N33E043 +N33E044 +N33E045 +N33E046 +N33E047 +N33E048 +N33E049 +N33E050 +N33E051 +N33E052 +N33E053 +N33E054 +N33E055 +N33E056 +N33E057 +N33E058 +N33E059 +N33W001 +N33W002 +N33W003 +N33W004 +N33W005 +N33W006 +N33W007 +N33W008 +N33W009 +N33W017 +N34E000 +N34E001 +N34E002 +N34E003 +N34E004 +N34E005 +N34E006 +N34E007 +N34E008 +N34E009 +N34E010 +N34E011 +N34E023 +N34E024 +N34E025 +N34E026 +N34E032 +N34E033 +N34E034 +N34E035 +N34E036 +N34E037 +N34E038 +N34E039 +N34E040 +N34E041 +N34E042 +N34E043 +N34E044 +N34E045 +N34E046 +N34E047 +N34E048 +N34E049 +N34E050 +N34E051 +N34E052 +N34E053 +N34E054 +N34E055 +N34E056 +N34E057 +N34E058 +N34E059 +N34W001 +N34W002 +N34W003 +N34W004 +N34W005 +N34W006 +N34W007 +N36W026 +N37W025 +N37W026 +N38W028 +N38W029 +N39W028 +N39W029 +N39W032 +S01E006 +S01E008 +S01E009 +S01E010 +S01E011 +S01E012 +S01E013 +S01E014 +S01E015 +S01E016 +S01E017 +S01E018 +S01E019 +S01E020 +S01E021 +S01E022 +S01E023 +S01E024 +S01E025 +S01E026 +S01E027 +S01E028 +S01E029 +S01E030 +S01E031 +S01E032 +S01E033 +S01E034 +S01E035 +S01E036 +S01E037 +S01E038 +S01E039 +S01E040 +S01E041 +S01E042 +S02E005 +S02E008 +S02E009 +S02E010 +S02E011 +S02E012 +S02E013 +S02E014 +S02E015 +S02E016 +S02E017 +S02E018 +S02E019 +S02E020 +S02E021 +S02E022 +S02E023 +S02E024 +S02E025 +S02E026 +S02E027 +S02E028 +S02E029 +S02E030 +S02E031 +S02E032 +S02E033 +S02E034 +S02E035 +S02E036 +S02E037 +S02E038 +S02E039 +S02E040 +S02E041 +S02E042 +S03E009 +S03E010 +S03E011 +S03E012 +S03E013 +S03E014 +S03E015 +S03E016 +S03E017 +S03E018 +S03E019 +S03E020 +S03E021 +S03E022 +S03E023 +S03E024 +S03E025 +S03E026 +S03E027 +S03E028 +S03E029 +S03E030 +S03E031 +S03E032 +S03E033 +S03E034 +S03E035 +S03E036 +S03E037 +S03E038 +S03E039 +S03E040 +S03E041 +S04E010 +S04E011 +S04E012 +S04E013 +S04E014 +S04E015 +S04E016 +S04E017 +S04E018 +S04E019 +S04E020 +S04E021 +S04E022 +S04E023 +S04E024 +S04E025 +S04E026 +S04E027 +S04E028 +S04E029 +S04E030 +S04E031 +S04E032 +S04E033 +S04E034 +S04E035 +S04E036 +S04E037 +S04E038 +S04E039 +S04E040 +S04E055 +S05E011 +S05E012 +S05E013 +S05E014 +S05E015 +S05E016 +S05E017 +S05E018 +S05E019 +S05E020 +S05E021 +S05E022 +S05E023 +S05E024 +S05E025 +S05E026 +S05E027 +S05E028 +S05E029 +S05E030 +S05E031 +S05E032 +S05E033 +S05E034 +S05E035 +S05E036 +S05E037 +S05E038 +S05E039 +S05E053 +S05E055 +S06E011 +S06E012 +S06E013 +S06E014 +S06E015 +S06E016 +S06E017 +S06E018 +S06E019 +S06E020 +S06E021 +S06E022 +S06E023 +S06E024 +S06E025 +S06E026 +S06E027 +S06E028 +S06E029 +S06E030 +S06E031 +S06E032 +S06E033 +S06E034 +S06E035 +S06E036 +S06E037 +S06E038 +S06E039 +S06E053 +S06E055 +S07E012 +S07E013 +S07E014 +S07E015 +S07E016 +S07E017 +S07E018 +S07E019 +S07E020 +S07E021 +S07E022 +S07E023 +S07E024 +S07E025 +S07E026 +S07E027 +S07E028 +S07E029 +S07E030 +S07E031 +S07E032 +S07E033 +S07E034 +S07E035 +S07E036 +S07E037 +S07E038 +S07E039 +S07E052 +S07E053 +S08E012 +S08E013 +S08E014 +S08E015 +S08E016 +S08E017 +S08E018 +S08E019 +S08E020 +S08E021 +S08E022 +S08E023 +S08E024 +S08E025 +S08E026 +S08E027 +S08E028 +S08E029 +S08E030 +S08E031 +S08E032 +S08E033 +S08E034 +S08E035 +S08E036 +S08E037 +S08E038 +S08E039 +S08E052 +S08E056 +S09E013 +S09E014 +S09E015 +S09E016 +S09E017 +S09E018 +S09E019 +S09E020 +S09E021 +S09E022 +S09E023 +S09E024 +S09E025 +S09E026 +S09E027 +S09E028 +S09E029 +S09E030 +S09E031 +S09E032 +S09E033 +S09E034 +S09E035 +S09E036 +S09E037 +S09E038 +S09E039 +S10E012 +S10E013 +S10E014 +S10E015 +S10E016 +S10E017 +S10E018 +S10E019 +S10E020 +S10E021 +S10E022 +S10E023 +S10E024 +S10E025 +S10E026 +S10E027 +S10E028 +S10E029 +S10E030 +S10E031 +S10E032 +S10E033 +S10E034 +S10E035 +S10E036 +S10E037 +S10E038 +S10E039 +S10E046 +S10E047 +S10E050 +S10E051 +S11E013 +S11E014 +S11E015 +S11E016 +S11E017 +S11E018 +S11E019 +S11E020 +S11E021 +S11E022 +S11E023 +S11E024 +S11E025 +S11E026 +S11E027 +S11E028 +S11E029 +S11E030 +S11E031 +S11E032 +S11E033 +S11E034 +S11E035 +S11E036 +S11E037 +S11E038 +S11E039 +S11E040 +S11E047 +S11E051 +S11E056 +S12E013 +S12E014 +S12E015 +S12E016 +S12E017 +S12E018 +S12E019 +S12E020 +S12E021 +S12E022 +S12E023 +S12E024 +S12E025 +S12E026 +S12E027 +S12E028 +S12E029 +S12E030 +S12E031 +S12E032 +S12E033 +S12E034 +S12E035 +S12E036 +S12E037 +S12E038 +S12E039 +S12E040 +S12E043 +S12E047 +S12E049 +S13E012 +S13E013 +S13E014 +S13E015 +S13E016 +S13E017 +S13E018 +S13E019 +S13E020 +S13E021 +S13E022 +S13E023 +S13E024 +S13E025 +S13E026 +S13E027 +S13E028 +S13E029 +S13E030 +S13E031 +S13E032 +S13E033 +S13E034 +S13E035 +S13E036 +S13E037 +S13E038 +S13E039 +S13E040 +S13E043 +S13E044 +S13E045 +S13E048 +S13E049 +S14E012 +S14E013 +S14E014 +S14E015 +S14E016 +S14E017 +S14E018 +S14E019 +S14E020 +S14E021 +S14E022 +S14E023 +S14E024 +S14E025 +S14E026 +S14E027 +S14E028 +S14E029 +S14E030 +S14E031 +S14E032 +S14E033 +S14E034 +S14E035 +S14E036 +S14E037 +S14E038 +S14E039 +S14E040 +S14E045 +S14E047 +S14E048 +S14E049 +S14E050 +S15E012 +S15E013 +S15E014 +S15E015 +S15E016 +S15E017 +S15E018 +S15E019 +S15E020 +S15E021 +S15E022 +S15E023 +S15E024 +S15E025 +S15E026 +S15E027 +S15E028 +S15E029 +S15E030 +S15E031 +S15E032 +S15E033 +S15E034 +S15E035 +S15E036 +S15E037 +S15E038 +S15E039 +S15E040 +S15E047 +S15E048 +S15E049 +S15E050 +S16E011 +S16E012 +S16E013 +S16E014 +S16E015 +S16E016 +S16E017 +S16E018 +S16E019 +S16E020 +S16E021 +S16E022 +S16E023 +S16E024 +S16E025 +S16E026 +S16E027 +S16E028 +S16E029 +S16E030 +S16E031 +S16E032 +S16E033 +S16E034 +S16E035 +S16E036 +S16E037 +S16E038 +S16E039 +S16E040 +S16E045 +S16E046 +S16E047 +S16E048 +S16E049 +S16E050 +S16E054 +S17E011 +S17E012 +S17E013 +S17E014 +S17E015 +S17E016 +S17E017 +S17E018 +S17E019 +S17E020 +S17E021 +S17E022 +S17E023 +S17E024 +S17E025 +S17E026 +S17E027 +S17E028 +S17E029 +S17E030 +S17E031 +S17E032 +S17E033 +S17E034 +S17E035 +S17E036 +S17E037 +S17E038 +S17E039 +S17E040 +S17E043 +S17E044 +S17E045 +S17E046 +S17E047 +S17E048 +S17E049 +S17E050 +S17E059 +S18E011 +S18E012 +S18E013 +S18E014 +S18E015 +S18E016 +S18E017 +S18E018 +S18E019 +S18E020 +S18E021 +S18E022 +S18E023 +S18E024 +S18E025 +S18E026 +S18E027 +S18E028 +S18E029 +S18E030 +S18E031 +S18E032 +S18E033 +S18E034 +S18E035 +S18E036 +S18E037 +S18E038 +S18E039 +S18E042 +S18E043 +S18E044 +S18E045 +S18E046 +S18E047 +S18E048 +S18E049 +S19E011 +S19E012 +S19E013 +S19E014 +S19E015 +S19E016 +S19E017 +S19E018 +S19E019 +S19E020 +S19E021 +S19E022 +S19E023 +S19E024 +S19E025 +S19E026 +S19E027 +S19E028 +S19E029 +S19E030 +S19E031 +S19E032 +S19E033 +S19E034 +S19E035 +S19E036 +S19E037 +S19E043 +S19E044 +S19E045 +S19E046 +S19E047 +S19E048 +S19E049 +S20E012 +S20E013 +S20E014 +S20E015 +S20E016 +S20E017 +S20E018 +S20E019 +S20E020 +S20E021 +S20E022 +S20E023 +S20E024 +S20E025 +S20E026 +S20E027 +S20E028 +S20E029 +S20E030 +S20E031 +S20E032 +S20E033 +S20E034 +S20E035 +S20E044 +S20E045 +S20E046 +S20E047 +S20E048 +S20E049 +S20E057 +S20E063 +S21E013 +S21E014 +S21E015 +S21E016 +S21E017 +S21E018 +S21E019 +S21E020 +S21E021 +S21E022 +S21E023 +S21E024 +S21E025 +S21E026 +S21E027 +S21E028 +S21E029 +S21E030 +S21E031 +S21E032 +S21E033 +S21E034 +S21E035 +S21E043 +S21E044 +S21E045 +S21E046 +S21E047 +S21E048 +S21E055 +S21E057 +S22E013 +S22E014 +S22E015 +S22E016 +S22E017 +S22E018 +S22E019 +S22E020 +S22E021 +S22E022 +S22E023 +S22E024 +S22E025 +S22E026 +S22E027 +S22E028 +S22E029 +S22E030 +S22E031 +S22E032 +S22E033 +S22E034 +S22E035 +S22E043 +S22E044 +S22E045 +S22E046 +S22E047 +S22E048 +S22E055 +S23E014 +S23E015 +S23E016 +S23E017 +S23E018 +S23E019 +S23E020 +S23E021 +S23E022 +S23E023 +S23E024 +S23E025 +S23E026 +S23E027 +S23E028 +S23E029 +S23E030 +S23E031 +S23E032 +S23E033 +S23E034 +S23E035 +S23E040 +S23E043 +S23E044 +S23E045 +S23E046 +S23E047 +S23E048 +S24E014 +S24E015 +S24E016 +S24E017 +S24E018 +S24E019 +S24E020 +S24E021 +S24E022 +S24E023 +S24E024 +S24E025 +S24E026 +S24E027 +S24E028 +S24E029 +S24E030 +S24E031 +S24E032 +S24E033 +S24E034 +S24E035 +S24E043 +S24E044 +S24E045 +S24E046 +S24E047 +S25E014 +S25E015 +S25E016 +S25E017 +S25E018 +S25E019 +S25E020 +S25E021 +S25E022 +S25E023 +S25E024 +S25E025 +S25E026 +S25E027 +S25E028 +S25E029 +S25E030 +S25E031 +S25E032 +S25E033 +S25E034 +S25E035 +S25E043 +S25E044 +S25E045 +S25E046 +S25E047 +S26E014 +S26E015 +S26E016 +S26E017 +S26E018 +S26E019 +S26E020 +S26E021 +S26E022 +S26E023 +S26E024 +S26E025 +S26E026 +S26E027 +S26E028 +S26E029 +S26E030 +S26E031 +S26E032 +S26E033 +S26E034 +S26E044 +S26E045 +S26E046 +S26E047 +S27E014 +S27E015 +S27E016 +S27E017 +S27E018 +S27E019 +S27E020 +S27E021 +S27E022 +S27E023 +S27E024 +S27E025 +S27E026 +S27E027 +S27E028 +S27E029 +S27E030 +S27E031 +S27E032 +S28E015 +S28E016 +S28E017 +S28E018 +S28E019 +S28E020 +S28E021 +S28E022 +S28E023 +S28E024 +S28E025 +S28E026 +S28E027 +S28E028 +S28E029 +S28E030 +S28E031 +S28E032 +S29E015 +S29E016 +S29E017 +S29E018 +S29E019 +S29E020 +S29E021 +S29E022 +S29E023 +S29E024 +S29E025 +S29E026 +S29E027 +S29E028 +S29E029 +S29E030 +S29E031 +S29E032 +S30E016 +S30E017 +S30E018 +S30E019 +S30E020 +S30E021 +S30E022 +S30E023 +S30E024 +S30E025 +S30E026 +S30E027 +S30E028 +S30E029 +S30E030 +S30E031 +S31E017 +S31E018 +S31E019 +S31E020 +S31E021 +S31E022 +S31E023 +S31E024 +S31E025 +S31E026 +S31E027 +S31E028 +S31E029 +S31E030 +S32E017 +S32E018 +S32E019 +S32E020 +S32E021 +S32E022 +S32E023 +S32E024 +S32E025 +S32E026 +S32E027 +S32E028 +S32E029 +S32E030 +S33E017 +S33E018 +S33E019 +S33E020 +S33E021 +S33E022 +S33E023 +S33E024 +S33E025 +S33E026 +S33E027 +S33E028 +S33E029 +S34E017 +S34E018 +S34E019 +S34E020 +S34E021 +S34E022 +S34E023 +S34E024 +S34E025 +S34E026 +S34E027 +S35E018 +S35E019 +S35E020 +S35E021 +S35E022 +S35E023 +S35E024 +S35E025 +S11E119 +S11E120 +S11E121 +S11E122 +S11E123 +S11E124 +S11E132 +S11E133 +S11E141 +S11E142 +S11E143 +S11E147 +S11E148 +S11E149 +S11E150 +S11E151 +S11E152 +S11E153 +S11E161 +S11E162 +S11E165 +S11E166 +S11E179 +S11W140 +S11W151 +S11W161 +S11W162 +S11W166 +S12E122 +S12E130 +S12E131 +S12E132 +S12E133 +S12E134 +S12E135 +S12E136 +S12E141 +S12E142 +S12E143 +S12E144 +S12E151 +S12E152 +S12E153 +S12E154 +S12E159 +S12E160 +S12E166 +S12E169 +S12E170 +S12W152 +S12W166 +S12W172 +S13E122 +S13E123 +S13E130 +S13E131 +S13E132 +S13E133 +S13E134 +S13E135 +S13E136 +S13E141 +S13E142 +S13E143 +S13E168 +S13E176 +S13E177 +S14E125 +S14E126 +S14E127 +S14E129 +S14E130 +S14E131 +S14E132 +S14E133 +S14E134 +S14E135 +S14E136 +S14E141 +S14E142 +S14E143 +S14E144 +S14E166 +S14E167 +S14W164 +S14W172 +S14W173 +S14W177 +S15E121 +S15E123 +S15E124 +S15E125 +S15E126 +S15E127 +S15E128 +S15E129 +S15E130 +S15E131 +S15E132 +S15E133 +S15E134 +S15E135 +S15E136 +S15E141 +S15E142 +S15E143 +S15E144 +S15E145 +S15E166 +S15E167 +S15E168 +S15W139 +S15W142 +S15W145 +S15W146 +S15W147 +S15W148 +S15W149 +S15W169 +S15W170 +S15W171 +S15W172 +S15W178 +S15W179 +S16E123 +S16E124 +S16E125 +S16E126 +S16E127 +S16E128 +S16E129 +S16E130 +S16E131 +S16E132 +S16E133 +S16E134 +S16E135 +S16E136 +S16E137 +S16E141 +S16E142 +S16E143 +S16E144 +S16E145 +S16E166 +S16E167 +S16E168 +S16W141 +S16W143 +S16W145 +S16W146 +S16W147 +S16W148 +S16W149 +S16W155 +S16W174 +S16W176 +S16W180 +S17E122 +S17E123 +S17E124 +S17E125 +S17E126 +S17E127 +S17E128 +S17E129 +S17E130 +S17E131 +S17E132 +S17E133 +S17E134 +S17E135 +S17E136 +S17E137 +S17E138 +S17E139 +S17E140 +S17E141 +S17E142 +S17E143 +S17E144 +S17E145 +S17E146 +S17E149 +S17E150 +S17E167 +S17E168 +S17E177 +S17E178 +S17E179 +S17W141 +S17W142 +S17W143 +S17W144 +S17W145 +S17W146 +S17W147 +S17W150 +S17W151 +S17W152 +S17W153 +S17W154 +S17W155 +S17W180 +S18E118 +S18E119 +S18E122 +S18E123 +S18E124 +S18E125 +S18E126 +S18E127 +S18E128 +S18E129 +S18E130 +S18E131 +S18E132 +S18E133 +S18E134 +S18E135 +S18E136 +S18E137 +S18E138 +S18E139 +S18E140 +S18E141 +S18E142 +S18E143 +S18E144 +S18E145 +S18E146 +S18E148 +S18E155 +S18E168 +S18E176 +S18E177 +S18E178 +S18E179 +S18W139 +S18W141 +S18W142 +S18W143 +S18W144 +S18W145 +S18W146 +S18W149 +S18W150 +S18W151 +S18W179 +S18W180 +S19E121 +S19E122 +S19E123 +S19E124 +S19E125 +S19E126 +S19E127 +S19E128 +S19E129 +S19E130 +S19E131 +S19E132 +S19E133 +S19E134 +S19E135 +S19E136 +S19E137 +S19E138 +S19E139 +S19E140 +S19E141 +S19E142 +S19E143 +S19E144 +S19E145 +S19E146 +S19E162 +S19E163 +S19E168 +S19E169 +S19E177 +S19E178 +S19E179 +S19W137 +S19W138 +S19W139 +S19W140 +S19W141 +S19W142 +S19W143 +S19W160 +S19W164 +S19W170 +S19W174 +S19W175 +S19W179 +S19W180 +S20E118 +S20E119 +S20E120 +S20E121 +S20E122 +S20E123 +S20E124 +S20E125 +S20E126 +S20E127 +S20E128 +S20E129 +S20E130 +S20E131 +S20E132 +S20E133 +S20E134 +S20E135 +S20E136 +S20E137 +S20E138 +S20E139 +S20E140 +S20E141 +S20E142 +S20E143 +S20E144 +S20E145 +S20E146 +S20E147 +S20E148 +S20E158 +S20E163 +S20E169 +S20E170 +S20E177 +S20E178 +S20E179 +S20W139 +S20W140 +S20W141 +S20W142 +S20W145 +S20W146 +S20W158 +S20W159 +S20W170 +S20W175 +S20W176 +S20W179 +S20W180 +S21E115 +S21E116 +S21E117 +S21E118 +S21E119 +S21E120 +S21E121 +S21E122 +S21E123 +S21E124 +S21E125 +S21E126 +S21E127 +S21E128 +S21E129 +S21E130 +S21E131 +S21E132 +S21E133 +S21E134 +S21E135 +S21E136 +S21E137 +S21E138 +S21E139 +S21E140 +S21E141 +S21E142 +S21E143 +S21E144 +S21E145 +S21E146 +S21E147 +S21E148 +S21E149 +S21E150 +S21E154 +S21E163 +S21E164 +S21E165 +S21E166 +S21E167 +S21E169 +S21W139 +S21W140 +S21W144 +S21W158 +S21W159 +S21W175 +S21W176 +S21W179 +S22E113 +S22E114 +S22E115 +S22E116 +S22E117 +S22E118 +S22E119 +S22E120 +S22E121 +S22E122 +S22E123 +S22E124 +S22E125 +S22E126 +S22E127 +S22E128 +S22E129 +S22E130 +S22E131 +S22E132 +S22E133 +S22E134 +S22E135 +S22E136 +S22E137 +S22E138 +S22E139 +S22E140 +S22E141 +S22E142 +S22E143 +S22E144 +S22E145 +S22E146 +S22E147 +S22E148 +S22E149 +S22E150 +S22E151 +S22E152 +S22E153 +S22E154 +S22E155 +S22E158 +S22E164 +S22E165 +S22E166 +S22E167 +S22E168 +S22W136 +S22W137 +S22W139 +S22W140 +S22W141 +S22W155 +S22W158 +S22W160 +S22W175 +S22W176 +S22W179 +S23E113 +S23E114 +S23E115 +S23E116 +S23E117 +S23E118 +S23E119 +S23E120 +S23E121 +S23E122 +S23E123 +S23E124 +S23E125 +S23E126 +S23E127 +S23E128 +S23E129 +S23E130 +S23E131 +S23E132 +S23E133 +S23E134 +S23E135 +S23E136 +S23E137 +S23E138 +S23E139 +S23E140 +S23E141 +S23E142 +S23E143 +S23E144 +S23E145 +S23E146 +S23E147 +S23E148 +S23E149 +S23E150 +S23E152 +S23E155 +S23E165 +S23E166 +S23E167 +S23E168 +S23E171 +S23E172 +S23W135 +S23W137 +S23W139 +S23W152 +S23W153 +S23W177 +S24E113 +S24E114 +S24E115 +S24E116 +S24E117 +S24E118 +S24E119 +S24E120 +S24E121 +S24E122 +S24E123 +S24E124 +S24E125 +S24E126 +S24E127 +S24E128 +S24E129 +S24E130 +S24E131 +S24E132 +S24E133 +S24E134 +S24E135 +S24E136 +S24E137 +S24E138 +S24E139 +S24E140 +S24E141 +S24E142 +S24E143 +S24E144 +S24E145 +S24E146 +S24E147 +S24E148 +S24E149 +S24E150 +S24E151 +S24E152 +S24E155 +S24W131 +S24W135 +S24W136 +S24W138 +S24W148 +S24W150 +S25E113 +S25E114 +S25E115 +S25E116 +S25E117 +S25E118 +S25E119 +S25E120 +S25E121 +S25E122 +S25E123 +S25E124 +S25E125 +S25E126 +S25E127 +S25E128 +S25E129 +S25E130 +S25E131 +S25E132 +S25E133 +S25E134 +S25E135 +S25E136 +S25E137 +S25E138 +S25E139 +S25E140 +S25E141 +S25E142 +S25E143 +S25E144 +S25E145 +S25E146 +S25E147 +S25E148 +S25E149 +S25E150 +S25E151 +S25E152 +S25E153 +S25W125 +S25W129 +S26E112 +S26E113 +S26E114 +S26E115 +S26E116 +S26E117 +S26E118 +S26E119 +S26E120 +S26E121 +S26E122 +S26E123 +S26E124 +S26E125 +S26E126 +S26E127 +S26E128 +S26E129 +S26E130 +S26E131 +S26E132 +S26E133 +S26E134 +S26E135 +S26E136 +S26E137 +S26E138 +S26E139 +S26E140 +S26E141 +S26E142 +S26E143 +S26E144 +S26E145 +S26E146 +S26E147 +S26E148 +S26E149 +S26E150 +S26E151 +S26E152 +S26E153 +S26W131 +S27E113 +S27E114 +S27E115 +S27E116 +S27E117 +S27E118 +S27E119 +S27E120 +S27E121 +S27E122 +S27E123 +S27E124 +S27E125 +S27E126 +S27E127 +S27E128 +S27E129 +S27E130 +S27E131 +S27E132 +S27E133 +S27E134 +S27E135 +S27E136 +S27E137 +S27E138 +S27E139 +S27E140 +S27E141 +S27E142 +S27E143 +S27E144 +S27E145 +S27E146 +S27E147 +S27E148 +S27E149 +S27E150 +S27E151 +S27E152 +S27E153 +S27W106 +S28E113 +S28E114 +S28E115 +S28E116 +S28E117 +S28E118 +S28E119 +S28E120 +S28E121 +S28E122 +S28E123 +S28E124 +S28E125 +S28E126 +S28E127 +S28E128 +S28E129 +S28E130 +S28E131 +S28E132 +S28E133 +S28E134 +S28E135 +S28E136 +S28E137 +S28E138 +S28E139 +S28E140 +S28E141 +S28E142 +S28E143 +S28E144 +S28E145 +S28E146 +S28E147 +S28E148 +S28E149 +S28E150 +S28E151 +S28E152 +S28E153 +S28W110 +S28W144 +S28W145 +S29E113 +S29E114 +S29E115 +S29E116 +S29E117 +S29E118 +S29E119 +S29E120 +S29E121 +S29E122 +S29E123 +S29E124 +S29E125 +S29E126 +S29E127 +S29E128 +S29E129 +S29E130 +S29E131 +S29E132 +S29E133 +S29E134 +S29E135 +S29E136 +S29E137 +S29E138 +S29E139 +S29E140 +S29E141 +S29E142 +S29E143 +S29E144 +S29E145 +S29E146 +S29E147 +S29E148 +S29E149 +S29E150 +S29E151 +S29E152 +S29E153 +S30E114 +S30E115 +S30E116 +S30E117 +S30E118 +S30E119 +S30E120 +S30E121 +S30E122 +S30E123 +S30E124 +S30E125 +S30E126 +S30E127 +S30E128 +S30E129 +S30E130 +S30E131 +S30E132 +S30E133 +S30E134 +S30E135 +S30E136 +S30E137 +S30E138 +S30E139 +S30E140 +S30E141 +S30E142 +S30E143 +S30E144 +S30E145 +S30E146 +S30E147 +S30E148 +S30E149 +S30E150 +S30E151 +S30E152 +S30E153 +S31E114 +S31E115 +S31E116 +S31E117 +S31E118 +S31E119 +S31E120 +S31E121 +S31E122 +S31E123 +S31E124 +S31E125 +S31E126 +S31E127 +S31E128 +S31E129 +S31E130 +S31E131 +S31E132 +S31E133 +S31E134 +S31E135 +S31E136 +S31E137 +S31E138 +S31E139 +S31E140 +S31E141 +S31E142 +S31E143 +S31E144 +S31E145 +S31E146 +S31E147 +S31E148 +S31E149 +S31E150 +S31E151 +S31E152 +S31E153 +S32E115 +S32E116 +S32E117 +S32E118 +S32E119 +S32E120 +S32E121 +S32E122 +S32E123 +S32E124 +S32E125 +S32E126 +S32E127 +S32E128 +S32E129 +S32E130 +S32E131 +S32E132 +S32E133 +S32E134 +S32E135 +S32E136 +S32E137 +S32E138 +S32E139 +S32E140 +S32E141 +S32E142 +S32E143 +S32E144 +S32E145 +S32E146 +S32E147 +S32E148 +S32E149 +S32E150 +S32E151 +S32E152 +S32E153 +S32E159 +S33E115 +S33E116 +S33E117 +S33E118 +S33E119 +S33E120 +S33E121 +S33E122 +S33E123 +S33E124 +S33E125 +S33E126 +S33E127 +S33E128 +S33E132 +S33E133 +S33E134 +S33E135 +S33E136 +S33E137 +S33E138 +S33E139 +S33E140 +S33E141 +S33E142 +S33E143 +S33E144 +S33E145 +S33E146 +S33E147 +S33E148 +S33E149 +S33E150 +S33E151 +S33E152 +S34E114 +S34E115 +S34E116 +S34E117 +S34E118 +S34E119 +S34E120 +S34E121 +S34E122 +S34E123 +S34E124 +S34E134 +S34E135 +S34E136 +S34E137 +S34E138 +S34E139 +S34E140 +S34E141 +S34E142 +S34E143 +S34E144 +S34E145 +S34E146 +S34E147 +S34E148 +S34E149 +S34E150 +S34E151 +S35E114 +S35E115 +S35E116 +S35E117 +S35E118 +S35E119 +S35E120 +S35E121 +S35E122 +S35E123 +S35E134 +S35E135 +S35E136 +S35E137 +S35E138 +S35E139 +S35E140 +S35E141 +S35E142 +S35E143 +S35E144 +S35E145 +S35E146 +S35E147 +S35E148 +S35E149 +S35E150 +S35E151 +S36E116 +S36E117 +S36E118 +S36E135 +S36E136 +S36E137 +S36E138 +S36E139 +S36E140 +S36E141 +S36E142 +S36E143 +S36E144 +S36E145 +S36E146 +S36E147 +S36E148 +S36E149 +S36E150 +S37E136 +S37E137 +S37E139 +S37E140 +S37E141 +S37E142 +S37E143 +S37E144 +S37E145 +S37E146 +S37E147 +S37E148 +S37E149 +S37E150 +S38E139 +S38E140 +S38E141 +S38E142 +S38E143 +S38E144 +S38E145 +S38E146 +S38E147 +S38E148 +S38E149 +S38E150 +S39E140 +S39E141 +S39E142 +S39E143 +S39E144 +S39E145 +S39E146 +S39E147 +S40E143 +S40E144 +S40E146 +S40E147 +S40E148 +S41E143 +S41E144 +S41E145 +S41E146 +S41E147 +S41E148 +S42E144 +S42E145 +S42E146 +S42E147 +S42E148 +S43E145 +S43E146 +S43E147 +S43E148 +S44E145 +S44E146 +S44E147 +S44E148 +N00E072 +N00E073 +N00E097 +N00E098 +N00E099 +N00E100 +N00E101 +N00E102 +N00E103 +N00E104 +N00E106 +N00E107 +N00E108 +N00E109 +N00E110 +N00E111 +N00E112 +N00E113 +N00E114 +N00E115 +N00E116 +N00E117 +N00E118 +N00E119 +N00E120 +N00E121 +N00E122 +N00E123 +N00E124 +N00E126 +N00E127 +N00E128 +N00E129 +N00E130 +N00E131 +N00E134 +N00E172 +N00E173 +N00W177 +N01E073 +N01E097 +N01E098 +N01E099 +N01E100 +N01E101 +N01E102 +N01E103 +N01E104 +N01E106 +N01E107 +N01E108 +N01E109 +N01E110 +N01E111 +N01E112 +N01E113 +N01E114 +N01E115 +N01E116 +N01E117 +N01E118 +N01E119 +N01E120 +N01E121 +N01E122 +N01E124 +N01E125 +N01E126 +N01E127 +N01E128 +N01E131 +N01E154 +N01E172 +N01E173 +N01W158 +N02E072 +N02E073 +N02E095 +N02E096 +N02E097 +N02E098 +N02E099 +N02E100 +N02E101 +N02E102 +N02E103 +N02E104 +N02E105 +N02E106 +N02E107 +N02E108 +N02E109 +N02E111 +N02E112 +N02E113 +N02E114 +N02E115 +N02E116 +N02E117 +N02E118 +N02E125 +N02E127 +N02E128 +N02E131 +N02E173 +N02W158 +N03E072 +N03E073 +N03E095 +N03E096 +N03E097 +N03E098 +N03E099 +N03E100 +N03E101 +N03E102 +N03E103 +N03E105 +N03E106 +N03E107 +N03E108 +N03E112 +N03E113 +N03E114 +N03E115 +N03E116 +N03E117 +N03E125 +N03E126 +N03E131 +N03E154 +N03E172 +N03E173 +N03W160 +N04E072 +N04E073 +N04E095 +N04E096 +N04E097 +N04E098 +N04E100 +N04E101 +N04E102 +N04E103 +N04E107 +N04E108 +N04E113 +N04E114 +N04E115 +N04E116 +N04E117 +N04E118 +N04E119 +N04E125 +N04E126 +N04E127 +N04E131 +N04E132 +N04E168 +N04W161 +N05E072 +N05E073 +N05E080 +N05E094 +N05E095 +N05E096 +N05E097 +N05E100 +N05E101 +N05E102 +N05E103 +N05E114 +N05E115 +N05E116 +N05E117 +N05E118 +N05E119 +N05E120 +N05E121 +N05E124 +N05E125 +N05E126 +N05E132 +N05E153 +N05E157 +N05E162 +N05E163 +N05E168 +N05E169 +N05E172 +N05W163 +N06E072 +N06E073 +N06E079 +N06E080 +N06E081 +N06E093 +N06E095 +N06E099 +N06E100 +N06E101 +N06E102 +N06E115 +N06E116 +N06E117 +N06E118 +N06E120 +N06E121 +N06E122 +N06E123 +N06E124 +N06E125 +N06E126 +N06E134 +N06E143 +N06E149 +N06E151 +N06E152 +N06E157 +N06E158 +N06E159 +N06E160 +N06E169 +N06E171 +N06E172 +N06W163 +N07E072 +N07E073 +N07E079 +N07E080 +N07E081 +N07E093 +N07E098 +N07E099 +N07E100 +N07E113 +N07E116 +N07E117 +N07E118 +N07E121 +N07E122 +N07E123 +N07E124 +N07E125 +N07E126 +N07E134 +N07E143 +N07E144 +N07E145 +N07E146 +N07E147 +N07E149 +N07E151 +N07E152 +N07E155 +N07E157 +N07E158 +N07E168 +N07E171 +N08E073 +N08E076 +N08E077 +N08E078 +N08E079 +N08E080 +N08E081 +N08E092 +N08E093 +N08E097 +N08E098 +N08E099 +N08E100 +N08E104 +N08E105 +N08E106 +N08E111 +N08E116 +N08E117 +N08E118 +N08E122 +N08E123 +N08E124 +N08E125 +N08E126 +N08E134 +N08E137 +N08E140 +N08E144 +N08E146 +N08E147 +N08E149 +N08E150 +N08E151 +N08E152 +N08E154 +N08E165 +N08E166 +N08E167 +N08E168 +N08E170 +N08E171 +N09E076 +N09E077 +N09E078 +N09E079 +N09E080 +N09E092 +N09E097 +N09E098 +N09E099 +N09E100 +N09E102 +N09E103 +N09E104 +N09E105 +N09E106 +N09E109 +N09E117 +N09E118 +N09E119 +N09E120 +N09E121 +N09E122 +N09E123 +N09E124 +N09E125 +N09E126 +N09E138 +N09E139 +N09E140 +N09E145 +N09E160 +N09E165 +N09E166 +N09E167 +N09E169 +N09E170 +N10E072 +N10E073 +N10E075 +N10E076 +N10E077 +N10E078 +N10E079 +N10E092 +N10E097 +N10E098 +N10E099 +N10E102 +N10E103 +N10E104 +N10E105 +N10E106 +N10E107 +N10E108 +N10E114 +N10E115 +N10E118 +N10E119 +N10E120 +N10E121 +N10E122 +N10E123 +N10E124 +N10E125 +N10E126 +N10E139 +N10E165 +N10E166 +N10E168 +N10E169 +N10E170 +N11E072 +N11E073 +N11E075 +N11E076 +N11E077 +N11E078 +N11E079 +N11E092 +N11E093 +N11E097 +N11E098 +N11E099 +N11E102 +N11E103 +N11E104 +N11E105 +N11E106 +N11E107 +N11E108 +N11E109 +N11E114 +N11E115 +N11E119 +N11E120 +N11E121 +N11E122 +N11E123 +N11E124 +N11E125 +N11E162 +N11E165 +N11E166 +N11E167 +N11E169 +N12E074 +N12E075 +N12E076 +N12E077 +N12E078 +N12E079 +N12E080 +N12E092 +N12E093 +N12E097 +N12E098 +N12E099 +N12E100 +N12E101 +N12E102 +N12E103 +N12E104 +N12E105 +N12E106 +N12E107 +N12E108 +N12E109 +N12E119 +N12E120 +N12E121 +N12E122 +N12E123 +N12E124 +N12E125 +N12E170 +N13E074 +N13E075 +N13E076 +N13E077 +N13E078 +N13E079 +N13E080 +N13E092 +N13E093 +N13E094 +N13E097 +N13E098 +N13E099 +N13E100 +N13E101 +N13E102 +N13E103 +N13E104 +N13E105 +N13E106 +N13E107 +N13E108 +N13E109 +N13E120 +N13E121 +N13E122 +N13E123 +N13E124 +N13E144 +N14E074 +N14E075 +N14E076 +N14E077 +N14E078 +N14E079 +N14E080 +N14E093 +N14E097 +N14E098 +N14E099 +N14E100 +N14E101 +N14E102 +N14E103 +N14E104 +N14E105 +N14E106 +N14E107 +N14E108 +N14E109 +N14E120 +N14E121 +N14E122 +N14E123 +N14E124 +N14E145 +N14E168 +N14E169 +N15E073 +N15E074 +N15E075 +N15E076 +N15E077 +N15E078 +N15E079 +N15E080 +N15E081 +N15E094 +N15E095 +N15E097 +N15E098 +N15E099 +N15E100 +N15E101 +N15E102 +N15E103 +N15E104 +N15E105 +N15E106 +N15E107 +N15E108 +N15E109 +N15E111 +N15E119 +N15E120 +N15E121 +N15E122 +N15E145 +N16E073 +N16E074 +N16E075 +N16E076 +N16E077 +N16E078 +N16E079 +N16E080 +N16E081 +N16E082 +N16E094 +N16E095 +N16E096 +N16E097 +N16E098 +N16E099 +N16E100 +N16E101 +N16E102 +N16E103 +N16E104 +N16E105 +N16E106 +N16E107 +N16E108 +N16E111 +N16E112 +N16E119 +N16E120 +N16E121 +N16E122 +N16E145 +N16E146 +N17E073 +N17E074 +N17E075 +N17E076 +N17E077 +N17E078 +N17E079 +N17E080 +N17E081 +N17E082 +N17E083 +N17E094 +N17E095 +N17E096 +N17E097 +N17E098 +N17E099 +N17E100 +N17E101 +N17E102 +N17E103 +N17E104 +N17E105 +N17E106 +N17E107 +N17E120 +N17E121 +N17E122 +N17E145 +N18E072 +N18E073 +N18E074 +N18E075 +N18E076 +N18E077 +N18E078 +N18E079 +N18E080 +N18E081 +N18E082 +N18E083 +N18E084 +N18E093 +N18E094 +N18E095 +N18E096 +N18E097 +N18E098 +N18E099 +N18E100 +N18E101 +N18E102 +N18E103 +N18E104 +N18E105 +N18E106 +N18E108 +N18E109 +N18E110 +N18E120 +N18E121 +N18E122 +N18E145 +N19E072 +N19E073 +N19E074 +N19E075 +N19E076 +N19E077 +N19E078 +N19E079 +N19E080 +N19E081 +N19E082 +N19E083 +N19E084 +N19E085 +N19E086 +N19E092 +N19E093 +N19E094 +N19E095 +N19E096 +N19E097 +N19E098 +N19E099 +N19E100 +N19E101 +N19E102 +N19E103 +N19E104 +N19E105 +N19E106 +N19E108 +N19E109 +N19E110 +N19E111 +N19E121 +N19E122 +N19E145 +N19E166 +N20E070 +N20E071 +N20E072 +N20E073 +N20E074 +N20E075 +N20E076 +N20E077 +N20E078 +N20E079 +N20E080 +N20E081 +N20E082 +N20E083 +N20E084 +N20E085 +N20E086 +N20E087 +N20E092 +N20E093 +N20E094 +N20E095 +N20E096 +N20E097 +N20E098 +N20E099 +N20E100 +N20E101 +N20E102 +N20E103 +N20E104 +N20E105 +N20E106 +N20E107 +N20E109 +N20E110 +N20E116 +N20E121 +N20E122 +N20E136 +N20E144 +N20E145 +N21E069 +N21E070 +N21E071 +N21E072 +N21E073 +N21E074 +N21E075 +N21E076 +N21E077 +N21E078 +N21E079 +N21E080 +N21E081 +N21E082 +N21E083 +N21E084 +N21E085 +N21E086 +N21E087 +N21E088 +N21E089 +N21E090 +N21E091 +N21E092 +N21E093 +N21E094 +N21E095 +N21E096 +N21E097 +N21E098 +N21E099 +N21E100 +N21E101 +N21E102 +N21E103 +N21E104 +N21E105 +N21E106 +N21E107 +N21E108 +N21E109 +N21E110 +N21E111 +N21E112 +N21E113 +N21E114 +N21E120 +N21E121 +N22E068 +N22E069 +N22E070 +N22E071 +N22E072 +N22E073 +N22E074 +N22E075 +N22E076 +N22E077 +N22E078 +N22E079 +N22E080 +N22E081 +N22E082 +N22E083 +N22E084 +N22E085 +N22E086 +N22E087 +N22E088 +N22E089 +N22E090 +N22E091 +N22E092 +N22E093 +N22E094 +N22E095 +N22E096 +N22E097 +N22E098 +N22E099 +N22E100 +N22E101 +N22E102 +N22E103 +N22E104 +N22E105 +N22E106 +N22E107 +N22E108 +N22E109 +N22E110 +N22E111 +N22E112 +N22E113 +N22E114 +N22E115 +N22E116 +N22E120 +N22E121 +N23E067 +N23E068 +N23E069 +N23E070 +N23E071 +N23E072 +N23E073 +N23E074 +N23E075 +N23E076 +N23E077 +N23E078 +N23E079 +N23E080 +N23E081 +N23E082 +N23E083 +N23E084 +N23E085 +N23E086 +N23E087 +N23E088 +N23E089 +N23E090 +N23E091 +N23E092 +N23E093 +N23E094 +N23E095 +N23E096 +N23E097 +N23E098 +N23E099 +N23E100 +N23E101 +N23E102 +N23E103 +N23E104 +N23E105 +N23E106 +N23E107 +N23E108 +N23E109 +N23E110 +N23E111 +N23E112 +N23E113 +N23E114 +N23E115 +N23E116 +N23E117 +N23E119 +N23E120 +N23E121 +N24E066 +N24E067 +N24E068 +N24E069 +N24E070 +N24E071 +N24E072 +N24E073 +N24E074 +N24E075 +N24E076 +N24E077 +N24E078 +N24E079 +N24E080 +N24E081 +N24E082 +N24E083 +N24E084 +N24E085 +N24E086 +N24E087 +N24E088 +N24E089 +N24E090 +N24E091 +N24E092 +N24E093 +N24E094 +N24E095 +N24E096 +N24E097 +N24E098 +N24E099 +N24E100 +N24E101 +N24E102 +N24E103 +N24E104 +N24E105 +N24E106 +N24E107 +N24E108 +N24E109 +N24E110 +N24E111 +N24E112 +N24E113 +N24E114 +N24E115 +N24E116 +N24E117 +N24E118 +N24E119 +N24E120 +N24E121 +N24E122 +N24E123 +N24E124 +N24E125 +N24E131 +N24E141 +N24E153 +N25E060 +N25E061 +N25E062 +N25E063 +N25E064 +N25E065 +N25E066 +N25E067 +N25E068 +N25E069 +N25E070 +N25E071 +N25E072 +N25E073 +N25E074 +N25E075 +N25E076 +N25E077 +N25E078 +N25E079 +N25E080 +N25E081 +N25E082 +N25E083 +N25E084 +N25E085 +N25E086 +N25E087 +N25E088 +N25E089 +N25E090 +N25E091 +N25E092 +N25E093 +N25E094 +N25E095 +N25E096 +N25E097 +N25E098 +N25E099 +N25E100 +N25E101 +N25E102 +N25E103 +N25E104 +N25E105 +N25E106 +N25E107 +N25E108 +N25E109 +N25E110 +N25E111 +N25E112 +N25E113 +N25E114 +N25E115 +N25E116 +N25E117 +N25E118 +N25E119 +N25E121 +N25E122 +N25E123 +N25E124 +N25E131 +N25E141 +N26E060 +N26E061 +N26E062 +N26E063 +N26E064 +N26E065 +N26E066 +N26E067 +N26E068 +N26E069 +N26E070 +N26E071 +N26E072 +N26E073 +N26E074 +N26E075 +N26E076 +N26E077 +N26E078 +N26E079 +N26E080 +N26E081 +N26E082 +N26E083 +N26E084 +N26E085 +N26E086 +N26E087 +N26E088 +N26E089 +N26E090 +N26E091 +N26E092 +N26E093 +N26E094 +N26E095 +N26E096 +N26E097 +N26E098 +N26E099 +N26E100 +N26E101 +N26E102 +N26E103 +N26E104 +N26E105 +N26E106 +N26E107 +N26E108 +N26E109 +N26E110 +N26E111 +N26E112 +N26E113 +N26E114 +N26E115 +N26E116 +N26E117 +N26E118 +N26E119 +N26E120 +N26E126 +N26E127 +N26E128 +N26E142 +N27E060 +N27E061 +N27E062 +N27E063 +N27E064 +N27E065 +N27E066 +N27E067 +N27E068 +N27E069 +N27E070 +N27E071 +N27E072 +N27E073 +N27E074 +N27E075 +N27E076 +N27E077 +N27E078 +N27E079 +N27E080 +N27E081 +N27E082 +N27E083 +N27E084 +N27E085 +N27E086 +N27E087 +N27E088 +N27E089 +N27E090 +N27E091 +N27E092 +N27E093 +N27E094 +N27E095 +N27E096 +N27E097 +N27E098 +N27E099 +N27E100 +N27E101 +N27E102 +N27E103 +N27E104 +N27E105 +N27E106 +N27E107 +N27E108 +N27E109 +N27E110 +N27E111 +N27E112 +N27E113 +N27E114 +N27E115 +N27E116 +N27E117 +N27E118 +N27E119 +N27E120 +N27E121 +N27E127 +N27E128 +N27E129 +N27E140 +N27E142 +N28E060 +N28E061 +N28E062 +N28E063 +N28E064 +N28E065 +N28E066 +N28E067 +N28E068 +N28E069 +N28E070 +N28E071 +N28E072 +N28E073 +N28E074 +N28E075 +N28E076 +N28E077 +N28E078 +N28E079 +N28E080 +N28E081 +N28E082 +N28E083 +N28E084 +N28E085 +N28E086 +N28E087 +N28E088 +N28E089 +N28E090 +N28E091 +N28E092 +N28E093 +N28E094 +N28E095 +N28E096 +N28E097 +N28E098 +N28E099 +N28E100 +N28E101 +N28E102 +N28E103 +N28E104 +N28E105 +N28E106 +N28E107 +N28E108 +N28E109 +N28E110 +N28E111 +N28E112 +N28E113 +N28E114 +N28E115 +N28E116 +N28E117 +N28E118 +N28E119 +N28E120 +N28E121 +N28E122 +N28E128 +N28E129 +N28E130 +N29E060 +N29E061 +N29E062 +N29E063 +N29E064 +N29E065 +N29E066 +N29E067 +N29E068 +N29E069 +N29E070 +N29E071 +N29E072 +N29E073 +N29E074 +N29E075 +N29E076 +N29E077 +N29E078 +N29E079 +N29E080 +N29E081 +N29E082 +N29E083 +N29E084 +N29E085 +N29E086 +N29E087 +N29E088 +N29E089 +N29E090 +N29E091 +N29E092 +N29E093 +N29E094 +N29E095 +N29E096 +N29E097 +N29E098 +N29E099 +N29E100 +N29E101 +N29E102 +N29E103 +N29E104 +N29E105 +N29E106 +N29E107 +N29E108 +N29E109 +N29E110 +N29E111 +N29E112 +N29E113 +N29E114 +N29E115 +N29E116 +N29E117 +N29E118 +N29E119 +N29E120 +N29E121 +N29E122 +N29E129 +N29E140 +N30E060 +N30E061 +N30E062 +N30E063 +N30E064 +N30E065 +N30E066 +N30E067 +N30E068 +N30E069 +N30E070 +N30E071 +N30E072 +N30E073 +N30E074 +N30E075 +N30E076 +N30E077 +N30E078 +N30E079 +N30E080 +N30E081 +N30E082 +N30E083 +N30E084 +N30E085 +N30E086 +N30E087 +N30E088 +N30E089 +N30E090 +N30E091 +N30E092 +N30E093 +N30E094 +N30E095 +N30E096 +N30E097 +N30E098 +N30E099 +N30E100 +N30E101 +N30E102 +N30E103 +N30E104 +N30E105 +N30E106 +N30E107 +N30E108 +N30E109 +N30E110 +N30E111 +N30E112 +N30E113 +N30E114 +N30E115 +N30E116 +N30E117 +N30E118 +N30E119 +N30E120 +N30E121 +N30E122 +N30E129 +N30E130 +N30E131 +N30E140 +N31E060 +N31E061 +N31E062 +N31E063 +N31E064 +N31E065 +N31E066 +N31E067 +N31E068 +N31E069 +N31E070 +N31E071 +N31E072 +N31E073 +N31E074 +N31E075 +N31E076 +N31E077 +N31E078 +N31E079 +N31E080 +N31E081 +N31E082 +N31E083 +N31E084 +N31E085 +N31E086 +N31E087 +N31E088 +N31E089 +N31E090 +N31E091 +N31E092 +N31E093 +N31E094 +N31E095 +N31E096 +N31E097 +N31E098 +N31E099 +N31E100 +N31E101 +N31E102 +N31E103 +N31E104 +N31E105 +N31E106 +N31E107 +N31E108 +N31E109 +N31E110 +N31E111 +N31E112 +N31E113 +N31E114 +N31E115 +N31E116 +N31E117 +N31E118 +N31E119 +N31E120 +N31E121 +N31E122 +N31E128 +N31E129 +N31E130 +N31E131 +N31E139 +N31E140 +N32E060 +N32E061 +N32E062 +N32E063 +N32E064 +N32E065 +N32E066 +N32E067 +N32E068 +N32E069 +N32E070 +N32E071 +N32E072 +N32E073 +N32E074 +N32E075 +N32E076 +N32E077 +N32E078 +N32E079 +N32E080 +N32E081 +N32E082 +N32E083 +N32E084 +N32E085 +N32E086 +N32E087 +N32E088 +N32E089 +N32E090 +N32E091 +N32E092 +N32E093 +N32E094 +N32E095 +N32E096 +N32E097 +N32E098 +N32E099 +N32E100 +N32E101 +N32E102 +N32E103 +N32E104 +N32E105 +N32E106 +N32E107 +N32E108 +N32E109 +N32E110 +N32E111 +N32E112 +N32E113 +N32E114 +N32E115 +N32E116 +N32E117 +N32E118 +N32E119 +N32E120 +N32E121 +N32E128 +N32E129 +N32E130 +N32E131 +N32E132 +N32E133 +N32E139 +N33E060 +N33E061 +N33E062 +N33E063 +N33E064 +N33E065 +N33E066 +N33E067 +N33E068 +N33E069 +N33E070 +N33E071 +N33E072 +N33E073 +N33E074 +N33E075 +N33E076 +N33E077 +N33E078 +N33E079 +N33E080 +N33E081 +N33E082 +N33E083 +N33E084 +N33E085 +N33E086 +N33E087 +N33E088 +N33E089 +N33E090 +N33E091 +N33E092 +N33E093 +N33E094 +N33E095 +N33E096 +N33E097 +N33E098 +N33E099 +N33E100 +N33E101 +N33E102 +N33E103 +N33E104 +N33E105 +N33E106 +N33E107 +N33E108 +N33E109 +N33E110 +N33E111 +N33E112 +N33E113 +N33E114 +N33E115 +N33E116 +N33E117 +N33E118 +N33E119 +N33E120 +N33E126 +N33E128 +N33E129 +N33E130 +N33E131 +N33E132 +N33E133 +N33E134 +N33E135 +N33E136 +N33E138 +N33E139 +N34E060 +N34E061 +N34E062 +N34E063 +N34E064 +N34E065 +N34E066 +N34E067 +N34E068 +N34E069 +N34E070 +N34E071 +N34E072 +N34E073 +N34E074 +N34E075 +N34E076 +N34E077 +N34E078 +N34E079 +N34E080 +N34E081 +N34E082 +N34E083 +N34E084 +N34E085 +N34E086 +N34E087 +N34E088 +N34E089 +N34E090 +N34E091 +N34E092 +N34E093 +N34E094 +N34E095 +N34E096 +N34E097 +N34E098 +N34E099 +N34E100 +N34E101 +N34E102 +N34E103 +N34E104 +N34E105 +N34E106 +N34E107 +N34E108 +N34E109 +N34E110 +N34E111 +N34E112 +N34E113 +N34E114 +N34E115 +N34E116 +N34E117 +N34E118 +N34E119 +N34E120 +N34E125 +N34E126 +N34E127 +N34E128 +N34E129 +N34E130 +N34E131 +N34E132 +N34E133 +N34E134 +N34E135 +N34E136 +N34E137 +N34E138 +N34E139 +N35E000 +N35E001 +N35E002 +N35E003 +N35E004 +N35E005 +N35E006 +N35E007 +N35E008 +N35E009 +N35E010 +N35E011 +N35E012 +N35E014 +N35E023 +N35E024 +N35E025 +N35E026 +N35E027 +N35E032 +N35E033 +N35E034 +N35E035 +N35E036 +N35E037 +N35E038 +N35E039 +N35E040 +N35E041 +N35E042 +N35E043 +N35E044 +N35E045 +N35E046 +N35E047 +N35E048 +N35E049 +N35E050 +N35E051 +N35E052 +N35E053 +N35E054 +N35E055 +N35E056 +N35E057 +N35E058 +N35E059 +N35E060 +N35E061 +N35E062 +N35E063 +N35E064 +N35E065 +N35E066 +N35E067 +N35E068 +N35E069 +N35E070 +N35E071 +N35E072 +N35E073 +N35E074 +N35E075 +N35E076 +N35E077 +N35E078 +N35E079 +N35E080 +N35E081 +N35E082 +N35E083 +N35E084 +N35E085 +N35E086 +N35E087 +N35E088 +N35E089 +N35E090 +N35E091 +N35E092 +N35E093 +N35E094 +N35E095 +N35E096 +N35E097 +N35E098 +N35E099 +N35E100 +N35E101 +N35E102 +N35E103 +N35E104 +N35E105 +N35E106 +N35E107 +N35E108 +N35E109 +N35E110 +N35E111 +N35E112 +N35E113 +N35E114 +N35E115 +N35E116 +N35E117 +N35E118 +N35E119 +N35E120 +N35E125 +N35E126 +N35E127 +N35E128 +N35E129 +N35E132 +N35E133 +N35E134 +N35E135 +N35E136 +N35E137 +N35E138 +N35E139 +N35E140 +N35W001 +N35W002 +N35W003 +N35W004 +N35W005 +N35W006 +N35W007 +N36E000 +N36E001 +N36E002 +N36E003 +N36E004 +N36E005 +N36E006 +N36E007 +N36E008 +N36E009 +N36E010 +N36E011 +N36E012 +N36E014 +N36E015 +N36E021 +N36E022 +N36E023 +N36E024 +N36E025 +N36E026 +N36E027 +N36E028 +N36E029 +N36E030 +N36E031 +N36E032 +N36E033 +N36E034 +N36E035 +N36E036 +N36E037 +N36E038 +N36E039 +N36E040 +N36E041 +N36E042 +N36E043 +N36E044 +N36E045 +N36E046 +N36E047 +N36E048 +N36E049 +N36E050 +N36E051 +N36E052 +N36E053 +N36E054 +N36E055 +N36E056 +N36E057 +N36E058 +N36E059 +N36E060 +N36E061 +N36E062 +N36E063 +N36E064 +N36E065 +N36E066 +N36E067 +N36E068 +N36E069 +N36E070 +N36E071 +N36E072 +N36E073 +N36E074 +N36E075 +N36E076 +N36E077 +N36E078 +N36E079 +N36E080 +N36E081 +N36E082 +N36E083 +N36E084 +N36E085 +N36E086 +N36E087 +N36E088 +N36E089 +N36E090 +N36E091 +N36E092 +N36E093 +N36E094 +N36E095 +N36E096 +N36E097 +N36E098 +N36E099 +N36E100 +N36E101 +N36E102 +N36E103 +N36E104 +N36E105 +N36E106 +N36E107 +N36E108 +N36E109 +N36E110 +N36E111 +N36E112 +N36E113 +N36E114 +N36E115 +N36E116 +N36E117 +N36E118 +N36E119 +N36E120 +N36E121 +N36E122 +N36E125 +N36E126 +N36E127 +N36E128 +N36E129 +N36E132 +N36E133 +N36E135 +N36E136 +N36E137 +N36E138 +N36E139 +N36E140 +N36W002 +N36W003 +N36W004 +N36W005 +N36W006 +N36W007 +N36W008 +N36W009 +N37E006 +N37E007 +N37E008 +N37E009 +N37E010 +N37E011 +N37E012 +N37E013 +N37E014 +N37E015 +N37E016 +N37E020 +N37E021 +N37E022 +N37E023 +N37E024 +N37E025 +N37E026 +N37E027 +N37E028 +N37E029 +N37E030 +N37E031 +N37E032 +N37E033 +N37E034 +N37E035 +N37E036 +N37E037 +N37E038 +N37E039 +N37E040 +N37E041 +N37E042 +N37E043 +N37E044 +N37E045 +N37E046 +N37E047 +N37E048 +N37E049 +N37E050 +N37E053 +N37E054 +N37E055 +N37E056 +N37E057 +N37E058 +N37E059 +N37E060 +N37E061 +N37E062 +N37E063 +N37E064 +N37E065 +N37E066 +N37E067 +N37E068 +N37E069 +N37E070 +N37E071 +N37E072 +N37E073 +N37E074 +N37E075 +N37E076 +N37E077 +N37E078 +N37E079 +N37E080 +N37E081 +N37E082 +N37E083 +N37E084 +N37E085 +N37E086 +N37E087 +N37E088 +N37E089 +N37E090 +N37E091 +N37E092 +N37E093 +N37E094 +N37E095 +N37E096 +N37E097 +N37E098 +N37E099 +N37E100 +N37E101 +N37E102 +N37E103 +N37E104 +N37E105 +N37E106 +N37E107 +N37E108 +N37E109 +N37E110 +N37E111 +N37E112 +N37E113 +N37E114 +N37E115 +N37E116 +N37E117 +N37E118 +N37E119 +N37E120 +N37E121 +N37E122 +N37E124 +N37E125 +N37E126 +N37E127 +N37E128 +N37E129 +N37E130 +N37E131 +N37E136 +N37E137 +N37E138 +N37E139 +N37E140 +N37E141 +N37W001 +N37W002 +N37W003 +N37W004 +N37W005 +N37W006 +N37W007 +N37W008 +N37W009 +N38E000 +N38E001 +N38E008 +N38E009 +N38E012 +N38E013 +N38E014 +N38E015 +N38E016 +N38E017 +N38E020 +N38E021 +N38E022 +N38E023 +N38E024 +N38E025 +N38E026 +N38E027 +N38E028 +N38E029 +N38E030 +N38E031 +N38E032 +N38E033 +N38E034 +N38E035 +N38E036 +N38E037 +N38E038 +N38E039 +N38E040 +N38E041 +N38E042 +N38E043 +N38E044 +N38E045 +N38E046 +N38E047 +N38E048 +N38E049 +N38E053 +N38E054 +N38E055 +N38E056 +N38E057 +N38E058 +N38E059 +N38E060 +N38E061 +N38E062 +N38E063 +N38E064 +N38E065 +N38E066 +N38E067 +N38E068 +N38E069 +N38E070 +N38E071 +N38E072 +N38E073 +N38E074 +N38E075 +N38E076 +N38E077 +N38E078 +N38E079 +N38E080 +N38E081 +N38E082 +N38E083 +N38E084 +N38E085 +N38E086 +N38E087 +N38E088 +N38E089 +N38E090 +N38E091 +N38E092 +N38E093 +N38E094 +N38E095 +N38E096 +N38E097 +N38E098 +N38E099 +N38E100 +N38E101 +N38E102 +N38E103 +N38E104 +N38E105 +N38E106 +N38E107 +N38E108 +N38E109 +N38E110 +N38E111 +N38E112 +N38E113 +N38E114 +N38E115 +N38E116 +N38E117 +N38E118 +N38E120 +N38E121 +N38E124 +N38E125 +N38E126 +N38E127 +N38E128 +N38E138 +N38E139 +N38E140 +N38E141 +N38W001 +N38W002 +N38W003 +N38W004 +N38W005 +N38W006 +N38W007 +N38W008 +N38W009 +N38W010 +N39E000 +N39E001 +N39E002 +N39E003 +N39E004 +N39E008 +N39E009 +N39E015 +N39E016 +N39E017 +N39E018 +N39E019 +N39E020 +N39E021 +N39E022 +N39E023 +N39E024 +N39E025 +N39E026 +N39E027 +N39E028 +N39E029 +N39E030 +N39E031 +N39E032 +N39E033 +N39E034 +N39E035 +N39E036 +N39E037 +N39E038 +N39E039 +N39E040 +N39E041 +N39E042 +N39E043 +N39E044 +N39E045 +N39E046 +N39E047 +N39E048 +N39E049 +N39E052 +N39E053 +N39E054 +N39E055 +N39E056 +N39E057 +N39E058 +N39E059 +N39E060 +N39E061 +N39E062 +N39E063 +N39E064 +N39E065 +N39E066 +N39E067 +N39E068 +N39E069 +N39E070 +N39E071 +N39E072 +N39E073 +N39E074 +N39E075 +N39E076 +N39E077 +N39E078 +N39E079 +N39E080 +N39E081 +N39E082 +N39E083 +N39E084 +N39E085 +N39E086 +N39E087 +N39E088 +N39E089 +N39E090 +N39E091 +N39E092 +N39E093 +N39E094 +N39E095 +N39E096 +N39E097 +N39E098 +N39E099 +N39E100 +N39E101 +N39E102 +N39E103 +N39E104 +N39E105 +N39E106 +N39E107 +N39E108 +N39E109 +N39E110 +N39E111 +N39E112 +N39E113 +N39E114 +N39E115 +N39E116 +N39E117 +N39E118 +N39E119 +N39E121 +N39E122 +N39E123 +N39E124 +N39E125 +N39E126 +N39E127 +N39E128 +N39E139 +N39E140 +N39E141 +N39E142 +N39W001 +N39W002 +N39W003 +N39W004 +N39W005 +N39W006 +N39W007 +N39W008 +N39W009 +N39W010 +N40E000 +N40E003 +N40E004 +N40E008 +N40E009 +N40E012 +N40E013 +N40E014 +N40E015 +N40E016 +N40E017 +N40E018 +N40E019 +N40E020 +N40E021 +N40E022 +N40E023 +N40E024 +N40E025 +N40E026 +N40E027 +N40E028 +N40E029 +N40E030 +N40E031 +N40E032 +N40E033 +N40E034 +N40E035 +N40E036 +N40E037 +N40E038 +N40E039 +N40E040 +N40E041 +N40E042 +N40E043 +N40E044 +N40E045 +N40E046 +N40E047 +N40E048 +N40E049 +N40E050 +N40E052 +N40E053 +N40E054 +N40E055 +N40E056 +N40E057 +N40E058 +N40E059 +N40E060 +N40E061 +N40E062 +N40E063 +N40E064 +N40E065 +N40E066 +N40E067 +N40E068 +N40E069 +N40E070 +N40E071 +N40E072 +N40E073 +N40E074 +N40E075 +N40E076 +N40E077 +N40E078 +N40E079 +N40E080 +N40E081 +N40E082 +N40E083 +N40E084 +N40E085 +N40E086 +N40E087 +N40E088 +N40E089 +N40E090 +N40E091 +N40E092 +N40E093 +N40E094 +N40E095 +N40E096 +N40E097 +N40E098 +N40E099 +N40E100 +N40E101 +N40E102 +N40E103 +N40E104 +N40E105 +N40E106 +N40E107 +N40E108 +N40E109 +N40E110 +N40E111 +N40E112 +N40E113 +N40E114 +N40E115 +N40E116 +N40E117 +N40E118 +N40E119 +N40E120 +N40E121 +N40E122 +N40E123 +N40E124 +N40E125 +N40E126 +N40E127 +N40E128 +N40E129 +N40E139 +N40E140 +N40E141 +N40W001 +N40W002 +N40W003 +N40W004 +N40W005 +N40W006 +N40W007 +N40W008 +N40W009 +N41E000 +N41E001 +N41E002 +N41E003 +N41E008 +N41E009 +N41E011 +N41E012 +N41E013 +N41E014 +N41E015 +N41E016 +N41E017 +N41E019 +N41E020 +N41E021 +N41E022 +N41E023 +N41E024 +N41E025 +N41E026 +N41E027 +N41E028 +N41E029 +N41E030 +N41E031 +N41E032 +N41E033 +N41E034 +N41E035 +N41E036 +N41E037 +N41E038 +N41E039 +N41E040 +N41E041 +N41E042 +N41E043 +N41E044 +N41E045 +N41E046 +N41E047 +N41E048 +N41E049 +N41E052 +N41E053 +N41E054 +N41E055 +N41E056 +N41E057 +N41E058 +N41E059 +N41E060 +N41E061 +N41E062 +N41E063 +N41E064 +N41E065 +N41E066 +N41E067 +N41E068 +N41E069 +N41E070 +N41E071 +N41E072 +N41E073 +N41E074 +N41E075 +N41E076 +N41E077 +N41E078 +N41E079 +N41E080 +N41E081 +N41E082 +N41E083 +N41E084 +N41E085 +N41E086 +N41E087 +N41E088 +N41E089 +N41E090 +N41E091 +N41E092 +N41E093 +N41E094 +N41E095 +N41E096 +N41E097 +N41E098 +N41E099 +N41E100 +N41E101 +N41E102 +N41E103 +N41E104 +N41E105 +N41E106 +N41E107 +N41E108 +N41E109 +N41E110 +N41E111 +N41E112 +N41E113 +N41E114 +N41E115 +N41E116 +N41E117 +N41E118 +N41E119 +N41E120 +N41E121 +N41E122 +N41E123 +N41E124 +N41E125 +N41E126 +N41E127 +N41E128 +N41E129 +N41E130 +N41E139 +N41E140 +N41E141 +N41E143 +N41W001 +N41W002 +N41W003 +N41W004 +N41W005 +N41W006 +N41W007 +N41W008 +N41W009 +N42E000 +N42E001 +N42E002 +N42E003 +N42E006 +N42E008 +N42E009 +N42E010 +N42E011 +N42E012 +N42E013 +N42E014 +N42E015 +N42E016 +N42E017 +N42E018 +N42E019 +N42E020 +N42E021 +N42E022 +N42E023 +N42E024 +N42E025 +N42E026 +N42E027 +N42E028 +N42E033 +N42E034 +N42E035 +N42E040 +N42E041 +N42E042 +N42E043 +N42E044 +N42E045 +N42E046 +N42E047 +N42E048 +N42E051 +N42E052 +N42E053 +N42E054 +N42E055 +N42E056 +N42E057 +N42E058 +N42E059 +N42E060 +N42E061 +N42E062 +N42E063 +N42E064 +N42E065 +N42E066 +N42E067 +N42E068 +N42E069 +N42E070 +N42E071 +N42E072 +N42E073 +N42E074 +N42E075 +N42E076 +N42E077 +N42E078 +N42E079 +N42E080 +N42E081 +N42E082 +N42E083 +N42E084 +N42E085 +N42E086 +N42E087 +N42E088 +N42E089 +N42E090 +N42E091 +N42E092 +N42E093 +N42E094 +N42E095 +N42E096 +N42E097 +N42E098 +N42E099 +N42E100 +N42E101 +N42E102 +N42E103 +N42E104 +N42E105 +N42E106 +N42E107 +N42E108 +N42E109 +N42E110 +N42E111 +N42E112 +N42E113 +N42E114 +N42E115 +N42E116 +N42E117 +N42E118 +N42E119 +N42E120 +N42E121 +N42E122 +N42E123 +N42E124 +N42E125 +N42E126 +N42E127 +N42E128 +N42E129 +N42E130 +N42E131 +N42E132 +N42E133 +N42E134 +N42E139 +N42E140 +N42E141 +N42E142 +N42E143 +N42E144 +N42E145 +N42W001 +N42W002 +N42W003 +N42W004 +N42W005 +N42W006 +N42W007 +N42W008 +N42W009 +N42W010 +N43E000 +N43E001 +N43E002 +N43E003 +N43E004 +N43E005 +N43E006 +N43E007 +N43E008 +N43E009 +N43E010 +N43E011 +N43E012 +N43E013 +N43E015 +N43E016 +N43E017 +N43E018 +N43E019 +N43E020 +N43E021 +N43E022 +N43E023 +N43E024 +N43E025 +N43E026 +N43E027 +N43E028 +N43E039 +N43E040 +N43E041 +N43E042 +N43E043 +N43E044 +N43E045 +N43E046 +N43E047 +N43E050 +N43E051 +N43E052 +N43E053 +N43E054 +N43E055 +N43E056 +N43E057 +N43E058 +N43E059 +N43E060 +N43E061 +N43E062 +N43E063 +N43E064 +N43E065 +N43E066 +N43E067 +N43E068 +N43E069 +N43E070 +N43E071 +N43E072 +N43E073 +N43E074 +N43E075 +N43E076 +N43E077 +N43E078 +N43E079 +N43E080 +N43E081 +N43E082 +N43E083 +N43E084 +N43E085 +N43E086 +N43E087 +N43E088 +N43E089 +N43E090 +N43E091 +N43E092 +N43E093 +N43E094 +N43E095 +N43E096 +N43E097 +N43E098 +N43E099 +N43E100 +N43E101 +N43E102 +N43E103 +N43E104 +N43E105 +N43E106 +N43E107 +N43E108 +N43E109 +N43E110 +N43E111 +N43E112 +N43E113 +N43E114 +N43E115 +N43E116 +N43E117 +N43E118 +N43E119 +N43E120 +N43E121 +N43E122 +N43E123 +N43E124 +N43E125 +N43E126 +N43E127 +N43E128 +N43E129 +N43E130 +N43E131 +N43E132 +N43E133 +N43E134 +N43E135 +N43E140 +N43E141 +N43E142 +N43E143 +N43E144 +N43E145 +N43E146 +N43W001 +N43W002 +N43W003 +N43W004 +N43W005 +N43W006 +N43W007 +N43W008 +N43W009 +N43W010 +N44E000 +N44E001 +N44E002 +N44E003 +N44E004 +N44E005 +N44E006 +N44E007 +N44E008 +N44E009 +N44E010 +N44E011 +N44E012 +N44E013 +N44E014 +N44E015 +N44E016 +N44E017 +N44E018 +N44E019 +N44E020 +N44E021 +N44E022 +N44E023 +N44E024 +N44E025 +N44E026 +N44E027 +N44E028 +N44E029 +N44E033 +N44E034 +N44E035 +N44E037 +N44E038 +N44E039 +N44E040 +N44E041 +N44E042 +N44E043 +N44E044 +N44E045 +N44E046 +N44E047 +N44E050 +N44E051 +N44E052 +N44E053 +N44E054 +N44E055 +N44E056 +N44E057 +N44E058 +N44E059 +N44E060 +N44E061 +N44E062 +N44E063 +N44E064 +N44E065 +N44E066 +N44E067 +N44E068 +N44E069 +N44E070 +N44E071 +N44E072 +N44E073 +N44E074 +N44E075 +N44E076 +N44E077 +N44E078 +N44E079 +N44E080 +N44E081 +N44E082 +N44E083 +N44E084 +N44E085 +N44E086 +N44E087 +N44E088 +N44E089 +N44E090 +N44E091 +N44E092 +N44E093 +N44E094 +N44E095 +N44E096 +N44E097 +N44E098 +N44E099 +N44E100 +N44E101 +N44E102 +N44E103 +N44E104 +N44E105 +N44E106 +N44E107 +N44E108 +N44E109 +N44E110 +N44E111 +N44E112 +N44E113 +N44E114 +N44E115 +N44E116 +N44E117 +N44E118 +N44E119 +N44E120 +N44E121 +N44E122 +N44E123 +N44E124 +N44E125 +N44E126 +N44E127 +N44E128 +N44E129 +N44E130 +N44E131 +N44E132 +N44E133 +N44E134 +N44E135 +N44E136 +N44E141 +N44E142 +N44E143 +N44E144 +N44E145 +N44E146 +N44E147 +N44W001 +N44W002 +N45E000 +N45E001 +N45E002 +N45E003 +N45E004 +N45E005 +N45E006 +N45E007 +N45E008 +N45E009 +N45E010 +N45E011 +N45E012 +N45E013 +N45E014 +N45E015 +N45E016 +N45E017 +N45E018 +N45E019 +N45E020 +N45E021 +N45E022 +N45E023 +N45E024 +N45E025 +N45E026 +N45E027 +N45E028 +N45E029 +N45E030 +N45E032 +N45E033 +N45E034 +N45E035 +N45E036 +N45E037 +N45E038 +N45E039 +N45E040 +N45E041 +N45E042 +N45E043 +N45E044 +N45E045 +N45E046 +N45E047 +N45E048 +N45E049 +N45E050 +N45E051 +N45E052 +N45E053 +N45E054 +N45E055 +N45E056 +N45E057 +N45E058 +N45E059 +N45E060 +N45E061 +N45E062 +N45E063 +N45E064 +N45E065 +N45E066 +N45E067 +N45E068 +N45E069 +N45E070 +N45E071 +N45E072 +N45E073 +N45E074 +N45E075 +N45E076 +N45E077 +N45E078 +N45E079 +N45E080 +N45E081 +N45E082 +N45E083 +N45E084 +N45E085 +N45E086 +N45E087 +N45E088 +N45E089 +N45E090 +N45E091 +N45E092 +N45E093 +N45E094 +N45E095 +N45E096 +N45E097 +N45E098 +N45E099 +N45E100 +N45E101 +N45E102 +N45E103 +N45E104 +N45E105 +N45E106 +N45E107 +N45E108 +N45E109 +N45E110 +N45E111 +N45E112 +N45E113 +N45E114 +N45E115 +N45E116 +N45E117 +N45E118 +N45E119 +N45E120 +N45E121 +N45E122 +N45E123 +N45E124 +N45E125 +N45E126 +N45E127 +N45E128 +N45E129 +N45E130 +N45E131 +N45E132 +N45E133 +N45E134 +N45E135 +N45E136 +N45E137 +N45E140 +N45E141 +N45E142 +N45E147 +N45E148 +N45E149 +N45E150 +N45W001 +N45W002 +N46E000 +N46E001 +N46E002 +N46E003 +N46E004 +N46E005 +N46E006 +N46E007 +N46E008 +N46E009 +N46E010 +N46E011 +N46E012 +N46E013 +N46E014 +N46E015 +N46E016 +N46E017 +N46E018 +N46E019 +N46E020 +N46E021 +N46E022 +N46E023 +N46E024 +N46E025 +N46E026 +N46E027 +N46E028 +N46E029 +N46E030 +N46E031 +N46E032 +N46E033 +N46E034 +N46E035 +N46E036 +N46E037 +N46E038 +N46E039 +N46E040 +N46E041 +N46E042 +N46E043 +N46E044 +N46E045 +N46E046 +N46E047 +N46E048 +N46E049 +N46E050 +N46E051 +N46E052 +N46E053 +N46E054 +N46E055 +N46E056 +N46E057 +N46E058 +N46E059 +N46E060 +N46E061 +N46E062 +N46E063 +N46E064 +N46E065 +N46E066 +N46E067 +N46E068 +N46E069 +N46E070 +N46E071 +N46E072 +N46E073 +N46E074 +N46E075 +N46E076 +N46E077 +N46E078 +N46E079 +N46E080 +N46E081 +N46E082 +N46E083 +N46E084 +N46E085 +N46E086 +N46E087 +N46E088 +N46E089 +N46E090 +N46E091 +N46E092 +N46E093 +N46E094 +N46E095 +N46E096 +N46E097 +N46E098 +N46E099 +N46E100 +N46E101 +N46E102 +N46E103 +N46E104 +N46E105 +N46E106 +N46E107 +N46E108 +N46E109 +N46E110 +N46E111 +N46E112 +N46E113 +N46E114 +N46E115 +N46E116 +N46E117 +N46E118 +N46E119 +N46E120 +N46E121 +N46E122 +N46E123 +N46E124 +N46E125 +N46E126 +N46E127 +N46E128 +N46E129 +N46E130 +N46E131 +N46E132 +N46E133 +N46E134 +N46E135 +N46E136 +N46E137 +N46E138 +N46E141 +N46E142 +N46E143 +N46E149 +N46E150 +N46E151 +N46E152 +N46W001 +N46W002 +N46W003 +N47E000 +N47E001 +N47E002 +N47E003 +N47E004 +N47E005 +N47E006 +N47E007 +N47E008 +N47E009 +N47E010 +N47E011 +N47E012 +N47E013 +N47E014 +N47E015 +N47E016 +N47E017 +N47E018 +N47E019 +N47E020 +N47E021 +N47E022 +N47E023 +N47E024 +N47E025 +N47E026 +N47E027 +N47E028 +N47E029 +N47E030 +N47E031 +N47E032 +N47E033 +N47E034 +N47E035 +N47E036 +N47E037 +N47E038 +N47E039 +N47E040 +N47E041 +N47E042 +N47E043 +N47E044 +N47E045 +N47E046 +N47E047 +N47E048 +N47E049 +N47E050 +N47E051 +N47E052 +N47E053 +N47E054 +N47E055 +N47E056 +N47E057 +N47E058 +N47E059 +N47E060 +N47E061 +N47E062 +N47E063 +N47E064 +N47E065 +N47E066 +N47E067 +N47E068 +N47E069 +N47E070 +N47E071 +N47E072 +N47E073 +N47E074 +N47E075 +N47E076 +N47E077 +N47E078 +N47E079 +N47E080 +N47E081 +N47E082 +N47E083 +N47E084 +N47E085 +N47E086 +N47E087 +N47E088 +N47E089 +N47E090 +N47E091 +N47E092 +N47E093 +N47E094 +N47E095 +N47E096 +N47E097 +N47E098 +N47E099 +N47E100 +N47E101 +N47E102 +N47E103 +N47E104 +N47E105 +N47E106 +N47E107 +N47E108 +N47E109 +N47E110 +N47E111 +N47E112 +N47E113 +N47E114 +N47E115 +N47E116 +N47E117 +N47E118 +N47E119 +N47E120 +N47E121 +N47E122 +N47E123 +N47E124 +N47E125 +N47E126 +N47E127 +N47E128 +N47E129 +N47E130 +N47E131 +N47E132 +N47E133 +N47E134 +N47E135 +N47E136 +N47E137 +N47E138 +N47E139 +N47E141 +N47E142 +N47E143 +N47E152 +N47E153 +N47W001 +N47W002 +N47W003 +N47W004 +N47W005 +N48E000 +N48E001 +N48E002 +N48E003 +N48E004 +N48E005 +N48E006 +N48E007 +N48E008 +N48E009 +N48E010 +N48E011 +N48E012 +N48E013 +N48E014 +N48E015 +N48E016 +N48E017 +N48E018 +N48E019 +N48E020 +N48E021 +N48E022 +N48E023 +N48E024 +N48E025 +N48E026 +N48E027 +N48E028 +N48E029 +N48E030 +N48E031 +N48E032 +N48E033 +N48E034 +N48E035 +N48E036 +N48E037 +N48E038 +N48E039 +N48E040 +N48E041 +N48E042 +N48E043 +N48E044 +N48E045 +N48E046 +N48E047 +N48E048 +N48E049 +N48E050 +N48E051 +N48E052 +N48E053 +N48E054 +N48E055 +N48E056 +N48E057 +N48E058 +N48E059 +N48E060 +N48E061 +N48E062 +N48E063 +N48E064 +N48E065 +N48E066 +N48E067 +N48E068 +N48E069 +N48E070 +N48E071 +N48E072 +N48E073 +N48E074 +N48E075 +N48E076 +N48E077 +N48E078 +N48E079 +N48E080 +N48E081 +N48E082 +N48E083 +N48E084 +N48E085 +N48E086 +N48E087 +N48E088 +N48E089 +N48E090 +N48E091 +N48E092 +N48E093 +N48E094 +N48E095 +N48E096 +N48E097 +N48E098 +N48E099 +N48E100 +N48E101 +N48E102 +N48E103 +N48E104 +N48E105 +N48E106 +N48E107 +N48E108 +N48E109 +N48E110 +N48E111 +N48E112 +N48E113 +N48E114 +N48E115 +N48E116 +N48E117 +N48E118 +N48E119 +N48E120 +N48E121 +N48E122 +N48E123 +N48E124 +N48E125 +N48E126 +N48E127 +N48E128 +N48E129 +N48E130 +N48E131 +N48E132 +N48E133 +N48E134 +N48E135 +N48E136 +N48E137 +N48E138 +N48E139 +N48E140 +N48E141 +N48E142 +N48E144 +N48E153 +N48E154 +N48W001 +N48W002 +N48W003 +N48W004 +N48W005 +N48W006 +N49E000 +N49E001 +N49E002 +N49E003 +N49E004 +N49E005 +N49E006 +N49E007 +N49E008 +N49E009 +N49E010 +N49E011 +N49E012 +N49E013 +N49E014 +N49E015 +N49E016 +N49E017 +N49E018 +N49E019 +N49E020 +N49E021 +N49E022 +N49E023 +N49E024 +N49E025 +N49E026 +N49E027 +N49E028 +N49E029 +N49E030 +N49E031 +N49E032 +N49E033 +N49E034 +N49E035 +N49E036 +N49E037 +N49E038 +N49E039 +N49E040 +N49E041 +N49E042 +N49E043 +N49E044 +N49E045 +N49E046 +N49E047 +N49E048 +N49E049 +N49E050 +N49E051 +N49E052 +N49E053 +N49E054 +N49E055 +N49E056 +N49E057 +N49E058 +N49E059 +N49E060 +N49E061 +N49E062 +N49E063 +N49E064 +N49E065 +N49E066 +N49E067 +N49E068 +N49E069 +N49E070 +N49E071 +N49E072 +N49E073 +N49E074 +N49E075 +N49E076 +N49E077 +N49E078 +N49E079 +N49E080 +N49E081 +N49E082 +N49E083 +N49E084 +N49E085 +N49E086 +N49E087 +N49E088 +N49E089 +N49E090 +N49E091 +N49E092 +N49E093 +N49E094 +N49E095 +N49E096 +N49E097 +N49E098 +N49E099 +N49E100 +N49E101 +N49E102 +N49E103 +N49E104 +N49E105 +N49E106 +N49E107 +N49E108 +N49E109 +N49E110 +N49E111 +N49E112 +N49E113 +N49E114 +N49E115 +N49E116 +N49E117 +N49E118 +N49E119 +N49E120 +N49E121 +N49E122 +N49E123 +N49E124 +N49E125 +N49E126 +N49E127 +N49E128 +N49E129 +N49E130 +N49E131 +N49E132 +N49E133 +N49E134 +N49E135 +N49E136 +N49E137 +N49E138 +N49E139 +N49E140 +N49E142 +N49E143 +N49E144 +N49E154 +N49E155 +N49W001 +N49W002 +N49W003 +N49W006 +N49W007 +N50E000 +N50E001 +N50E002 +N50E003 +N50E004 +N50E005 +N50E006 +N50E007 +N50E008 +N50E009 +N50E010 +N50E011 +N50E012 +N50E013 +N50E014 +N50E015 +N50E016 +N50E017 +N50E018 +N50E019 +N50E020 +N50E021 +N50E022 +N50E023 +N50E024 +N50E025 +N50E026 +N50E027 +N50E028 +N50E029 +N50E030 +N50E031 +N50E032 +N50E033 +N50E034 +N50E035 +N50E036 +N50E037 +N50E038 +N50E039 +N50E040 +N50E041 +N50E042 +N50E043 +N50E044 +N50E045 +N50E046 +N50E047 +N50E048 +N50E049 +N50E050 +N50E051 +N50E052 +N50E053 +N50E054 +N50E055 +N50E056 +N50E057 +N50E058 +N50E059 +N50E060 +N50E061 +N50E062 +N50E063 +N50E064 +N50E065 +N50E066 +N50E067 +N50E068 +N50E069 +N50E070 +N50E071 +N50E072 +N50E073 +N50E074 +N50E075 +N50E076 +N50E077 +N50E078 +N50E079 +N50E080 +N50E081 +N50E082 +N50E083 +N50E084 +N50E085 +N50E086 +N50E087 +N50E088 +N50E089 +N50E090 +N50E091 +N50E092 +N50E093 +N50E094 +N50E095 +N50E096 +N50E097 +N50E098 +N50E099 +N50E100 +N50E101 +N50E102 +N50E103 +N50E104 +N50E105 +N50E106 +N50E107 +N50E108 +N50E109 +N50E110 +N50E111 +N50E112 +N50E113 +N50E114 +N50E115 +N50E116 +N50E117 +N50E118 +N50E119 +N50E120 +N50E121 +N50E122 +N50E123 +N50E124 +N50E125 +N50E126 +N50E127 +N50E128 +N50E129 +N50E130 +N50E131 +N50E132 +N50E133 +N50E134 +N50E135 +N50E136 +N50E137 +N50E138 +N50E139 +N50E140 +N50E142 +N50E143 +N50E154 +N50E155 +N50E156 +N50W001 +N50W002 +N50W003 +N50W004 +N50W005 +N50W006 +N51E000 +N51E001 +N51E002 +N51E003 +N51E004 +N51E005 +N51E006 +N51E007 +N51E008 +N51E009 +N51E010 +N51E011 +N51E012 +N51E013 +N51E014 +N51E015 +N51E016 +N51E017 +N51E018 +N51E019 +N51E020 +N51E021 +N51E022 +N51E023 +N51E024 +N51E025 +N51E026 +N51E027 +N51E028 +N51E029 +N51E030 +N51E031 +N51E032 +N51E033 +N51E034 +N51E035 +N51E036 +N51E037 +N51E038 +N51E039 +N51E040 +N51E041 +N51E042 +N51E043 +N51E044 +N51E045 +N51E046 +N51E047 +N51E048 +N51E049 +N51E050 +N51E051 +N51E052 +N51E053 +N51E054 +N51E055 +N51E056 +N51E057 +N51E058 +N51E059 +N51E060 +N51E061 +N51E062 +N51E063 +N51E064 +N51E065 +N51E066 +N51E067 +N51E068 +N51E069 +N51E070 +N51E071 +N51E072 +N51E073 +N51E074 +N51E075 +N51E076 +N51E077 +N51E078 +N51E079 +N51E080 +N51E081 +N51E082 +N51E083 +N51E084 +N51E085 +N51E086 +N51E087 +N51E088 +N51E089 +N51E090 +N51E091 +N51E092 +N51E093 +N51E094 +N51E095 +N51E096 +N51E097 +N51E098 +N51E099 +N51E100 +N51E101 +N51E102 +N51E103 +N51E104 +N51E105 +N51E106 +N51E107 +N51E108 +N51E109 +N51E110 +N51E111 +N51E112 +N51E113 +N51E114 +N51E115 +N51E116 +N51E117 +N51E118 +N51E119 +N51E120 +N51E121 +N51E122 +N51E123 +N51E124 +N51E125 +N51E126 +N51E127 +N51E128 +N51E129 +N51E130 +N51E131 +N51E132 +N51E133 +N51E134 +N51E135 +N51E136 +N51E137 +N51E138 +N51E139 +N51E140 +N51E141 +N51E142 +N51E143 +N51E156 +N51E157 +N51E158 +N51W001 +N51W002 +N51W003 +N51W004 +N51W005 +N51W006 +N51W008 +N51W009 +N51W010 +N51W011 +N52E000 +N52E001 +N52E004 +N52E005 +N52E006 +N52E007 +N52E008 +N52E009 +N52E010 +N52E011 +N52E012 +N52E013 +N52E014 +N52E015 +N52E016 +N52E017 +N52E018 +N52E019 +N52E020 +N52E021 +N52E022 +N52E023 +N52E024 +N52E025 +N52E026 +N52E027 +N52E028 +N52E029 +N52E030 +N52E031 +N52E032 +N52E033 +N52E034 +N52E035 +N52E036 +N52E037 +N52E038 +N52E039 +N52E040 +N52E041 +N52E042 +N52E043 +N52E044 +N52E045 +N52E046 +N52E047 +N52E048 +N52E049 +N52E050 +N52E051 +N52E052 +N52E053 +N52E054 +N52E055 +N52E056 +N52E057 +N52E058 +N52E059 +N52E060 +N52E061 +N52E062 +N52E063 +N52E064 +N52E065 +N52E066 +N52E067 +N52E068 +N52E069 +N52E070 +N52E071 +N52E072 +N52E073 +N52E074 +N52E075 +N52E076 +N52E077 +N52E078 +N52E079 +N52E080 +N52E081 +N52E082 +N52E083 +N52E084 +N52E085 +N52E086 +N52E087 +N52E088 +N52E089 +N52E090 +N52E091 +N52E092 +N52E093 +N52E094 +N52E095 +N52E096 +N52E097 +N52E098 +N52E099 +N52E100 +N52E101 +N52E102 +N52E103 +N52E104 +N52E105 +N52E106 +N52E107 +N52E108 +N52E109 +N52E110 +N52E111 +N52E112 +N52E113 +N52E114 +N52E115 +N52E116 +N52E117 +N52E118 +N52E119 +N52E120 +N52E121 +N52E122 +N52E123 +N52E124 +N52E125 +N52E126 +N52E127 +N52E128 +N52E129 +N52E130 +N52E131 +N52E132 +N52E133 +N52E134 +N52E135 +N52E136 +N52E137 +N52E138 +N52E139 +N52E140 +N52E141 +N52E142 +N52E143 +N52E156 +N52E157 +N52E158 +N52W001 +N52W002 +N52W003 +N52W004 +N52W005 +N52W006 +N52W007 +N52W008 +N52W009 +N52W010 +N52W011 +N53E000 +N53E004 +N53E005 +N53E006 +N53E007 +N53E008 +N53E009 +N53E010 +N53E011 +N53E012 +N53E013 +N53E014 +N53E015 +N53E016 +N53E017 +N53E018 +N53E019 +N53E020 +N53E021 +N53E022 +N53E023 +N53E024 +N53E025 +N53E026 +N53E027 +N53E028 +N53E029 +N53E030 +N53E031 +N53E032 +N53E033 +N53E034 +N53E035 +N53E036 +N53E037 +N53E038 +N53E039 +N53E040 +N53E041 +N53E042 +N53E043 +N53E044 +N53E045 +N53E046 +N53E047 +N53E048 +N53E049 +N53E050 +N53E051 +N53E052 +N53E053 +N53E054 +N53E055 +N53E056 +N53E057 +N53E058 +N53E059 +N53E060 +N53E061 +N53E062 +N53E063 +N53E064 +N53E065 +N53E066 +N53E067 +N53E068 +N53E069 +N53E070 +N53E071 +N53E072 +N53E073 +N53E074 +N53E075 +N53E076 +N53E077 +N53E078 +N53E079 +N53E080 +N53E081 +N53E082 +N53E083 +N53E084 +N53E085 +N53E086 +N53E087 +N53E088 +N53E089 +N53E090 +N53E091 +N53E092 +N53E093 +N53E094 +N53E095 +N53E096 +N53E097 +N53E098 +N53E099 +N53E100 +N53E101 +N53E102 +N53E103 +N53E104 +N53E105 +N53E106 +N53E107 +N53E108 +N53E109 +N53E110 +N53E111 +N53E112 +N53E113 +N53E114 +N53E115 +N53E116 +N53E117 +N53E118 +N53E119 +N53E120 +N53E121 +N53E122 +N53E123 +N53E124 +N53E125 +N53E126 +N53E127 +N53E128 +N53E129 +N53E130 +N53E131 +N53E132 +N53E133 +N53E134 +N53E135 +N53E136 +N53E137 +N53E138 +N53E139 +N53E140 +N53E141 +N53E142 +N53E143 +N53E155 +N53E156 +N53E157 +N53E158 +N53E159 +N53E160 +N53W001 +N53W002 +N53W003 +N53W004 +N53W005 +N53W006 +N53W007 +N53W008 +N53W009 +N53W010 +N53W011 +N54E007 +N54E008 +N54E009 +N54E010 +N54E011 +N54E012 +N54E013 +N54E014 +N54E015 +N54E016 +N54E017 +N54E018 +N54E019 +N54E020 +N54E021 +N54E022 +N54E023 +N54E024 +N54E025 +N54E026 +N54E027 +N54E028 +N54E029 +N54E030 +N54E031 +N54E032 +N54E033 +N54E034 +N54E035 +N54E036 +N54E037 +N54E038 +N54E039 +N54E040 +N54E041 +N54E042 +N54E043 +N54E044 +N54E045 +N54E046 +N54E047 +N54E048 +N54E049 +N54E050 +N54E051 +N54E052 +N54E053 +N54E054 +N54E055 +N54E056 +N54E057 +N54E058 +N54E059 +N54E060 +N54E061 +N54E062 +N54E063 +N54E064 +N54E065 +N54E066 +N54E067 +N54E068 +N54E069 +N54E070 +N54E071 +N54E072 +N54E073 +N54E074 +N54E075 +N54E076 +N54E077 +N54E078 +N54E079 +N54E080 +N54E081 +N54E082 +N54E083 +N54E084 +N54E085 +N54E086 +N54E087 +N54E088 +N54E089 +N54E090 +N54E091 +N54E092 +N54E093 +N54E094 +N54E095 +N54E096 +N54E097 +N54E098 +N54E099 +N54E100 +N54E101 +N54E102 +N54E103 +N54E104 +N54E105 +N54E106 +N54E107 +N54E108 +N54E109 +N54E110 +N54E111 +N54E112 +N54E113 +N54E114 +N54E115 +N54E116 +N54E117 +N54E118 +N54E119 +N54E120 +N54E121 +N54E122 +N54E123 +N54E124 +N54E125 +N54E126 +N54E127 +N54E128 +N54E129 +N54E130 +N54E131 +N54E132 +N54E133 +N54E134 +N54E135 +N54E136 +N54E137 +N54E138 +N54E139 +N54E140 +N54E142 +N54E155 +N54E156 +N54E157 +N54E158 +N54E159 +N54E160 +N54E161 +N54E162 +N54E166 +N54E167 +N54E168 +N54W001 +N54W002 +N54W003 +N54W004 +N54W005 +N54W006 +N54W007 +N54W008 +N54W009 +N54W010 +N54W011 +N55E008 +N55E009 +N55E010 +N55E011 +N55E012 +N55E013 +N55E014 +N55E015 +N55E020 +N55E021 +N55E022 +N55E023 +N55E024 +N55E025 +N55E026 +N55E027 +N55E028 +N55E029 +N55E030 +N55E031 +N55E032 +N55E033 +N55E034 +N55E035 +N55E036 +N55E037 +N55E038 +N55E039 +N55E040 +N55E041 +N55E042 +N55E043 +N55E044 +N55E045 +N55E046 +N55E047 +N55E048 +N55E049 +N55E050 +N55E051 +N55E052 +N55E053 +N55E054 +N55E055 +N55E056 +N55E057 +N55E058 +N55E059 +N55E060 +N55E061 +N55E062 +N55E063 +N55E064 +N55E065 +N55E066 +N55E067 +N55E068 +N55E069 +N55E070 +N55E071 +N55E072 +N55E073 +N55E074 +N55E075 +N55E076 +N55E077 +N55E078 +N55E079 +N55E080 +N55E081 +N55E082 +N55E083 +N55E084 +N55E085 +N55E086 +N55E087 +N55E088 +N55E089 +N55E090 +N55E091 +N55E092 +N55E093 +N55E094 +N55E095 +N55E096 +N55E097 +N55E098 +N55E099 +N55E100 +N55E101 +N55E102 +N55E103 +N55E104 +N55E105 +N55E106 +N55E107 +N55E108 +N55E109 +N55E110 +N55E111 +N55E112 +N55E113 +N55E114 +N55E115 +N55E116 +N55E117 +N55E118 +N55E119 +N55E120 +N55E121 +N55E122 +N55E123 +N55E124 +N55E125 +N55E126 +N55E127 +N55E128 +N55E129 +N55E130 +N55E131 +N55E132 +N55E133 +N55E134 +N55E135 +N55E136 +N55E137 +N55E138 +N55E155 +N55E156 +N55E157 +N55E158 +N55E159 +N55E160 +N55E161 +N55E162 +N55E165 +N55E166 +N55W002 +N55W003 +N55W004 +N55W005 +N55W006 +N55W007 +N55W008 +N55W009 +N56E008 +N56E009 +N56E010 +N56E011 +N56E012 +N56E013 +N56E014 +N56E015 +N56E016 +N56E018 +N56E020 +N56E021 +N56E022 +N56E023 +N56E024 +N56E025 +N56E026 +N56E027 +N56E028 +N56E029 +N56E030 +N56E031 +N56E032 +N56E033 +N56E034 +N56E035 +N56E036 +N56E037 +N56E038 +N56E039 +N56E040 +N56E041 +N56E042 +N56E043 +N56E044 +N56E045 +N56E046 +N56E047 +N56E048 +N56E049 +N56E050 +N56E051 +N56E052 +N56E053 +N56E054 +N56E055 +N56E056 +N56E057 +N56E058 +N56E059 +N56E060 +N56E061 +N56E062 +N56E063 +N56E064 +N56E065 +N56E066 +N56E067 +N56E068 +N56E069 +N56E070 +N56E071 +N56E072 +N56E073 +N56E074 +N56E075 +N56E076 +N56E077 +N56E078 +N56E079 +N56E080 +N56E081 +N56E082 +N56E083 +N56E084 +N56E085 +N56E086 +N56E087 +N56E088 +N56E089 +N56E090 +N56E091 +N56E092 +N56E093 +N56E094 +N56E095 +N56E096 +N56E097 +N56E098 +N56E099 +N56E100 +N56E101 +N56E102 +N56E103 +N56E104 +N56E105 +N56E106 +N56E107 +N56E108 +N56E109 +N56E110 +N56E111 +N56E112 +N56E113 +N56E114 +N56E115 +N56E116 +N56E117 +N56E118 +N56E119 +N56E120 +N56E121 +N56E122 +N56E123 +N56E124 +N56E125 +N56E126 +N56E127 +N56E128 +N56E129 +N56E130 +N56E131 +N56E132 +N56E133 +N56E134 +N56E135 +N56E136 +N56E137 +N56E138 +N56E143 +N56E155 +N56E156 +N56E157 +N56E158 +N56E159 +N56E160 +N56E161 +N56E162 +N56E163 +N56W003 +N56W004 +N56W005 +N56W006 +N56W007 +N56W008 +N57E006 +N57E007 +N57E008 +N57E009 +N57E010 +N57E011 +N57E012 +N57E013 +N57E014 +N57E015 +N57E016 +N57E017 +N57E018 +N57E019 +N57E021 +N57E022 +N57E023 +N57E024 +N57E025 +N57E026 +N57E027 +N57E028 +N57E029 +N57E030 +N57E031 +N57E032 +N57E033 +N57E034 +N57E035 +N57E036 +N57E037 +N57E038 +N57E039 +N57E040 +N57E041 +N57E042 +N57E043 +N57E044 +N57E045 +N57E046 +N57E047 +N57E048 +N57E049 +N57E050 +N57E051 +N57E052 +N57E053 +N57E054 +N57E055 +N57E056 +N57E057 +N57E058 +N57E059 +N57E060 +N57E061 +N57E062 +N57E063 +N57E064 +N57E065 +N57E066 +N57E067 +N57E068 +N57E069 +N57E070 +N57E071 +N57E072 +N57E073 +N57E074 +N57E075 +N57E076 +N57E077 +N57E078 +N57E079 +N57E080 +N57E081 +N57E082 +N57E083 +N57E084 +N57E085 +N57E086 +N57E087 +N57E088 +N57E089 +N57E090 +N57E091 +N57E092 +N57E093 +N57E094 +N57E095 +N57E096 +N57E097 +N57E098 +N57E099 +N57E100 +N57E101 +N57E102 +N57E103 +N57E104 +N57E105 +N57E106 +N57E107 +N57E108 +N57E109 +N57E110 +N57E111 +N57E112 +N57E113 +N57E114 +N57E115 +N57E116 +N57E117 +N57E118 +N57E119 +N57E120 +N57E121 +N57E122 +N57E123 +N57E124 +N57E125 +N57E126 +N57E127 +N57E128 +N57E129 +N57E130 +N57E131 +N57E132 +N57E133 +N57E134 +N57E135 +N57E136 +N57E137 +N57E138 +N57E139 +N57E140 +N57E156 +N57E157 +N57E158 +N57E159 +N57E160 +N57E161 +N57E162 +N57E163 +N57W002 +N57W003 +N57W004 +N57W005 +N57W006 +N57W007 +N57W008 +N57W009 +N57W014 +N58E005 +N58E006 +N58E007 +N58E008 +N58E009 +N58E010 +N58E011 +N58E012 +N58E013 +N58E014 +N58E015 +N58E016 +N58E017 +N58E018 +N58E019 +N58E021 +N58E022 +N58E023 +N58E024 +N58E025 +N58E026 +N58E027 +N58E028 +N58E029 +N58E030 +N58E031 +N58E032 +N58E033 +N58E034 +N58E035 +N58E036 +N58E037 +N58E038 +N58E039 +N58E040 +N58E041 +N58E042 +N58E043 +N58E044 +N58E045 +N58E046 +N58E047 +N58E048 +N58E049 +N58E050 +N58E051 +N58E052 +N58E053 +N58E054 +N58E055 +N58E056 +N58E057 +N58E058 +N58E059 +N58E060 +N58E061 +N58E062 +N58E063 +N58E064 +N58E065 +N58E066 +N58E067 +N58E068 +N58E069 +N58E070 +N58E071 +N58E072 +N58E073 +N58E074 +N58E075 +N58E076 +N58E077 +N58E078 +N58E079 +N58E080 +N58E081 +N58E082 +N58E083 +N58E084 +N58E085 +N58E086 +N58E087 +N58E088 +N58E089 +N58E090 +N58E091 +N58E092 +N58E093 +N58E094 +N58E095 +N58E096 +N58E097 +N58E098 +N58E099 +N58E100 +N58E101 +N58E102 +N58E103 +N58E104 +N58E105 +N58E106 +N58E107 +N58E108 +N58E109 +N58E110 +N58E111 +N58E112 +N58E113 +N58E114 +N58E115 +N58E116 +N58E117 +N58E118 +N58E119 +N58E120 +N58E121 +N58E122 +N58E123 +N58E124 +N58E125 +N58E126 +N58E127 +N58E128 +N58E129 +N58E130 +N58E131 +N58E132 +N58E133 +N58E134 +N58E135 +N58E136 +N58E137 +N58E138 +N58E139 +N58E140 +N58E141 +N58E142 +N58E150 +N58E151 +N58E152 +N58E157 +N58E158 +N58E159 +N58E160 +N58E161 +N58E162 +N58E163 +N58E164 +N58W003 +N58W004 +N58W005 +N58W006 +N58W007 +N58W008 +N59E004 +N59E005 +N59E006 +N59E007 +N59E008 +N59E009 +N59E010 +N59E011 +N59E012 +N59E013 +N59E014 +N59E015 +N59E016 +N59E017 +N59E018 +N59E019 +N59E020 +N59E021 +N59E022 +N59E023 +N59E024 +N59E025 +N59E026 +N59E027 +N59E028 +N59E029 +N59E030 +N59E031 +N59E032 +N59E033 +N59E034 +N59E035 +N59E036 +N59E037 +N59E038 +N59E039 +N59E040 +N59E041 +N59E042 +N59E043 +N59E044 +N59E045 +N59E046 +N59E047 +N59E048 +N59E049 +N59E050 +N59E051 +N59E052 +N59E053 +N59E054 +N59E055 +N59E056 +N59E057 +N59E058 +N59E059 +N59E060 +N59E061 +N59E062 +N59E063 +N59E064 +N59E065 +N59E066 +N59E067 +N59E068 +N59E069 +N59E070 +N59E071 +N59E072 +N59E073 +N59E074 +N59E075 +N59E076 +N59E077 +N59E078 +N59E079 +N59E080 +N59E081 +N59E082 +N59E083 +N59E084 +N59E085 +N59E086 +N59E087 +N59E088 +N59E089 +N59E090 +N59E091 +N59E092 +N59E093 +N59E094 +N59E095 +N59E096 +N59E097 +N59E098 +N59E099 +N59E100 +N59E101 +N59E102 +N59E103 +N59E104 +N59E105 +N59E106 +N59E107 +N59E108 +N59E109 +N59E110 +N59E111 +N59E112 +N59E113 +N59E114 +N59E115 +N59E116 +N59E117 +N59E118 +N59E119 +N59E120 +N59E121 +N59E122 +N59E123 +N59E124 +N59E125 +N59E126 +N59E127 +N59E128 +N59E129 +N59E130 +N59E131 +N59E132 +N59E133 +N59E134 +N59E135 +N59E136 +N59E137 +N59E138 +N59E139 +N59E140 +N59E141 +N59E142 +N59E143 +N59E144 +N59E145 +N59E146 +N59E147 +N59E148 +N59E149 +N59E150 +N59E151 +N59E152 +N59E153 +N59E154 +N59E155 +N59E159 +N59E160 +N59E161 +N59E162 +N59E163 +N59E164 +N59E165 +N59E166 +N59W002 +N59W003 +N59W004 +N59W005 +N59W006 +N59W007 +N60E004 +N60E005 +N60E006 +N60E007 +N60E008 +N60E009 +N60E010 +N60E011 +N60E012 +N60E013 +N60E014 +N60E015 +N60E016 +N60E017 +N60E018 +N60E019 +N60E020 +N60E021 +N60E022 +N60E023 +N60E024 +N60E025 +N60E026 +N60E027 +N60E028 +N60E029 +N60E030 +N60E031 +N60E032 +N60E033 +N60E034 +N60E035 +N60E036 +N60E037 +N60E038 +N60E039 +N60E040 +N60E041 +N60E042 +N60E043 +N60E044 +N60E045 +N60E046 +N60E047 +N60E048 +N60E049 +N60E050 +N60E051 +N60E052 +N60E053 +N60E054 +N60E055 +N60E056 +N60E057 +N60E058 +N60E059 +N60E060 +N60E061 +N60E062 +N60E063 +N60E064 +N60E065 +N60E066 +N60E067 +N60E068 +N60E069 +N60E070 +N60E071 +N60E072 +N60E073 +N60E074 +N60E075 +N60E076 +N60E077 +N60E078 +N60E079 +N60E080 +N60E081 +N60E082 +N60E083 +N60E084 +N60E085 +N60E086 +N60E087 +N60E088 +N60E089 +N60E090 +N60E091 +N60E092 +N60E093 +N60E094 +N60E095 +N60E096 +N60E097 +N60E098 +N60E099 +N60E100 +N60E101 +N60E102 +N60E103 +N60E104 +N60E105 +N60E106 +N60E107 +N60E108 +N60E109 +N60E110 +N60E111 +N60E112 +N60E113 +N60E114 +N60E115 +N60E116 +N60E117 +N60E118 +N60E119 +N60E120 +N60E121 +N60E122 +N60E123 +N60E124 +N60E125 +N60E126 +N60E127 +N60E128 +N60E129 +N60E130 +N60E131 +N60E132 +N60E133 +N60E134 +N60E135 +N60E136 +N60E137 +N60E138 +N60E139 +N60E140 +N60E141 +N60E142 +N60E143 +N60E144 +N60E145 +N60E146 +N60E147 +N60E148 +N60E149 +N60E150 +N60E151 +N60E152 +N60E153 +N60E154 +N60E155 +N60E156 +N60E159 +N60E160 +N60E161 +N60E162 +N60E163 +N60E164 +N60E165 +N60E166 +N60E167 +N60E168 +N60E169 +N60E170 +N60E171 +N60E172 +N60W001 +N60W002 +N60W003 +S01E073 +S01E098 +S01E099 +S01E100 +S01E101 +S01E102 +S01E103 +S01E104 +S01E105 +S01E109 +S01E110 +S01E111 +S01E112 +S01E113 +S01E114 +S01E115 +S01E116 +S01E117 +S01E119 +S01E120 +S01E121 +S01E122 +S01E123 +S01E127 +S01E128 +S01E129 +S01E130 +S01E131 +S01E132 +S01E133 +S01E134 +S01E135 +S01E136 +S01E145 +S01E166 +S01E169 +S01E174 +S01W161 +S02E098 +S02E099 +S02E100 +S02E101 +S02E102 +S02E103 +S02E104 +S02E105 +S02E106 +S02E108 +S02E109 +S02E110 +S02E111 +S02E112 +S02E113 +S02E114 +S02E115 +S02E116 +S02E117 +S02E119 +S02E120 +S02E121 +S02E122 +S02E123 +S02E124 +S02E125 +S02E126 +S02E127 +S02E128 +S02E129 +S02E130 +S02E131 +S02E132 +S02E133 +S02E134 +S02E135 +S02E136 +S02E137 +S02E138 +S02E139 +S02E142 +S02E143 +S02E144 +S02E145 +S02E146 +S02E147 +S02E148 +S02E149 +S02E150 +S02E174 +S02E175 +S02E176 +S03E099 +S03E100 +S03E101 +S03E102 +S03E103 +S03E104 +S03E105 +S03E106 +S03E107 +S03E108 +S03E110 +S03E111 +S03E112 +S03E113 +S03E114 +S03E115 +S03E116 +S03E117 +S03E118 +S03E119 +S03E120 +S03E121 +S03E122 +S03E123 +S03E124 +S03E125 +S03E126 +S03E127 +S03E128 +S03E129 +S03E130 +S03E131 +S03E132 +S03E133 +S03E134 +S03E135 +S03E136 +S03E137 +S03E138 +S03E139 +S03E140 +S03E141 +S03E142 +S03E145 +S03E146 +S03E147 +S03E148 +S03E149 +S03E150 +S03E151 +S03E152 +S03E175 +S03E176 +S03W172 +S04E100 +S04E101 +S04E102 +S04E103 +S04E104 +S04E105 +S04E106 +S04E107 +S04E108 +S04E110 +S04E111 +S04E112 +S04E113 +S04E114 +S04E115 +S04E116 +S04E117 +S04E118 +S04E119 +S04E120 +S04E121 +S04E122 +S04E123 +S04E125 +S04E126 +S04E127 +S04E128 +S04E129 +S04E130 +S04E131 +S04E132 +S04E133 +S04E134 +S04E135 +S04E136 +S04E137 +S04E138 +S04E139 +S04E140 +S04E141 +S04E142 +S04E143 +S04E144 +S04E150 +S04E151 +S04E152 +S04E153 +S04E154 +S04W155 +S04W171 +S04W172 +S04W175 +S05E101 +S05E102 +S05E103 +S05E104 +S05E105 +S05E114 +S05E115 +S05E116 +S05E119 +S05E120 +S05E121 +S05E122 +S05E123 +S05E129 +S05E130 +S05E131 +S05E132 +S05E133 +S05E134 +S05E135 +S05E136 +S05E137 +S05E138 +S05E139 +S05E140 +S05E141 +S05E142 +S05E143 +S05E144 +S05E145 +S05E146 +S05E149 +S05E150 +S05E151 +S05E152 +S05E153 +S05E154 +S05E155 +S05E156 +S05E157 +S05E159 +S05W155 +S05W172 +S05W173 +S05W175 +S06E071 +S06E072 +S06E102 +S06E103 +S06E104 +S06E105 +S06E106 +S06E107 +S06E108 +S06E110 +S06E112 +S06E114 +S06E117 +S06E118 +S06E119 +S06E120 +S06E121 +S06E122 +S06E123 +S06E124 +S06E127 +S06E130 +S06E131 +S06E132 +S06E133 +S06E134 +S06E137 +S06E138 +S06E139 +S06E140 +S06E141 +S06E142 +S06E143 +S06E144 +S06E145 +S06E146 +S06E147 +S06E148 +S06E149 +S06E150 +S06E151 +S06E152 +S06E154 +S06E155 +S06E159 +S06E176 +S06W156 +S07E071 +S07E105 +S07E106 +S07E107 +S07E108 +S07E109 +S07E110 +S07E111 +S07E112 +S07E113 +S07E114 +S07E115 +S07E116 +S07E118 +S07E119 +S07E120 +S07E121 +S07E122 +S07E124 +S07E126 +S07E129 +S07E130 +S07E131 +S07E132 +S07E134 +S07E138 +S07E139 +S07E140 +S07E141 +S07E142 +S07E143 +S07E144 +S07E145 +S07E146 +S07E147 +S07E148 +S07E149 +S07E150 +S07E151 +S07E154 +S07E155 +S07E156 +S07E157 +S07E176 +S07E177 +S08E072 +S08E105 +S08E106 +S08E107 +S08E108 +S08E109 +S08E110 +S08E111 +S08E112 +S08E113 +S08E114 +S08E115 +S08E117 +S08E118 +S08E120 +S08E121 +S08E122 +S08E123 +S08E125 +S08E126 +S08E127 +S08E128 +S08E129 +S08E130 +S08E131 +S08E134 +S08E137 +S08E138 +S08E139 +S08E140 +S08E141 +S08E142 +S08E143 +S08E144 +S08E145 +S08E146 +S08E147 +S08E155 +S08E156 +S08E157 +S08E158 +S08E159 +S08E160 +S08E177 +S08E178 +S08W141 +S09E110 +S09E111 +S09E112 +S09E113 +S09E114 +S09E115 +S09E116 +S09E117 +S09E118 +S09E119 +S09E120 +S09E121 +S09E122 +S09E123 +S09E124 +S09E125 +S09E126 +S09E127 +S09E128 +S09E129 +S09E130 +S09E131 +S09E137 +S09E138 +S09E139 +S09E140 +S09E141 +S09E142 +S09E143 +S09E145 +S09E146 +S09E147 +S09E148 +S09E149 +S09E150 +S09E151 +S09E152 +S09E156 +S09E157 +S09E158 +S09E159 +S09E160 +S09E161 +S09E178 +S09E179 +S09W140 +S09W141 +S09W158 +S09W159 +S09W173 +S10E116 +S10E117 +S10E118 +S10E119 +S10E120 +S10E123 +S10E124 +S10E125 +S10E126 +S10E140 +S10E141 +S10E142 +S10E143 +S10E144 +S10E146 +S10E147 +S10E148 +S10E149 +S10E150 +S10E151 +S10E152 +S10E153 +S10E158 +S10E159 +S10E160 +S10E161 +S10E167 +S10E179 +S10W139 +S10W140 +S10W141 +S10W151 +S10W158 +S10W159 +S10W162 +S10W172 +S11E105 +S12E096 +S13E096 +N16W170 +N18W156 +N19W155 +N19W156 +N19W157 +N20W156 +N20W157 +N20W158 +N21W157 +N21W158 +N21W159 +N21W160 +N21W161 +N22W160 +N22W161 +N23W162 +N23W165 +N23W167 +N24W168 +N25W168 +N25W172 +N26W174 +N27W176 +N28W178 +N28W179 +S08W015 +S16W006 +S17W006 +S21W029 +S21W030 +S29E167 +S30E167 +S30W178 +S31W179 +S32W179 +S35E172 +S35E173 +S36E173 +S36E174 +S36E175 +S37E173 +S37E174 +S37E175 +S37E176 +S38E077 +S38E174 +S38E175 +S38E176 +S38E177 +S38E178 +S38W013 +S39E077 +S39E174 +S39E175 +S39E176 +S39E177 +S39E178 +S40E173 +S40E174 +S40E175 +S40E176 +S40E177 +S40E178 +S41E172 +S41E173 +S41E174 +S41E175 +S41E176 +S41W010 +S41W011 +S42E171 +S42E172 +S42E173 +S42E174 +S42E175 +S42E176 +S43E170 +S43E171 +S43E172 +S43E173 +S43E174 +S44E168 +S44E169 +S44E170 +S44E171 +S44E172 +S44E173 +S44W176 +S44W177 +S45E167 +S45E168 +S45E169 +S45E170 +S45E171 +S45W176 +S45W177 +S46E050 +S46E166 +S46E167 +S46E168 +S46E169 +S46E170 +S46E171 +S47E037 +S47E038 +S47E050 +S47E051 +S47E052 +S47E166 +S47E167 +S47E168 +S47E169 +S47E170 +S48E167 +S48E168 +S48E179 +S49E068 +S49E069 +S49E166 +S50E068 +S50E069 +S50E070 +S50E178 +S51E068 +S51E165 +S51E166 +S53E073 +S53E168 +S53E169 +S54E072 +S54E073 +S54W038 +S54W039 +S55E003 +S55E158 +S55W036 +S55W037 +S55W038 +S55W039 +S56E158 +S56W035 +N10W110 +N15W062 +N15W064 +N15W079 +N15W080 +N15W083 +N15W084 +N15W085 +N15W086 +N15W087 +N15W088 +N15W089 +N15W090 +N15W091 +N15W092 +N15W093 +N15W094 +N15W096 +N15W097 +N15W098 +N16W062 +N16W063 +N16W086 +N16W087 +N16W088 +N16W089 +N16W090 +N16W091 +N16W092 +N16W093 +N16W094 +N16W095 +N16W096 +N16W097 +N16W098 +N16W099 +N16W100 +N16W101 +N17W062 +N17W063 +N17W064 +N17W065 +N17W066 +N17W067 +N17W068 +N17W072 +N17W076 +N17W077 +N17W078 +N17W084 +N17W088 +N17W089 +N17W090 +N17W091 +N17W092 +N17W093 +N17W094 +N17W095 +N17W096 +N17W097 +N17W098 +N17W099 +N17W100 +N17W101 +N17W102 +N17W103 +N18W063 +N18W064 +N18W065 +N18W066 +N18W067 +N18W068 +N18W069 +N18W070 +N18W071 +N18W072 +N18W073 +N18W074 +N18W075 +N18W076 +N18W077 +N18W078 +N18W079 +N18W088 +N18W089 +N18W090 +N18W091 +N18W092 +N18W093 +N18W094 +N18W095 +N18W096 +N18W097 +N18W098 +N18W099 +N18W100 +N18W101 +N18W102 +N18W103 +N18W104 +N18W105 +N18W111 +N18W112 +N18W115 +N19W069 +N19W070 +N19W071 +N19W072 +N19W073 +N19W074 +N19W075 +N19W076 +N19W077 +N19W078 +N19W080 +N19W081 +N19W082 +N19W088 +N19W089 +N19W090 +N19W091 +N19W092 +N19W096 +N19W097 +N19W098 +N19W099 +N19W100 +N19W101 +N19W102 +N19W103 +N19W104 +N19W105 +N19W106 +N19W111 +N20W073 +N20W074 +N20W075 +N20W076 +N20W077 +N20W078 +N20W079 +N20W080 +N20W087 +N20W088 +N20W089 +N20W090 +N20W091 +N20W092 +N20W093 +N20W097 +N20W098 +N20W099 +N20W100 +N20W101 +N20W102 +N20W103 +N20W104 +N20W105 +N20W106 +N21W072 +N21W073 +N21W074 +N21W076 +N21W077 +N21W078 +N21W079 +N21W080 +N21W081 +N21W082 +N21W083 +N21W084 +N21W085 +N21W087 +N21W088 +N21W089 +N21W090 +N21W091 +N21W098 +N21W099 +N21W100 +N21W101 +N21W102 +N21W103 +N21W104 +N21W105 +N21W106 +N21W107 +N22W073 +N22W074 +N22W075 +N22W076 +N22W078 +N22W079 +N22W080 +N22W081 +N22W082 +N22W083 +N22W084 +N22W085 +N22W090 +N22W092 +N22W098 +N22W099 +N22W100 +N22W101 +N22W102 +N22W103 +N22W104 +N22W105 +N22W106 +N22W107 +N22W110 +N22W111 +N23W074 +N23W075 +N23W076 +N23W077 +N23W078 +N23W080 +N23W081 +N23W082 +N23W083 +N23W084 +N23W098 +N23W099 +N23W100 +N23W101 +N23W102 +N23W103 +N23W104 +N23W105 +N23W106 +N23W107 +N23W108 +N23W110 +N23W111 +N24W075 +N24W076 +N24W077 +N24W078 +N24W079 +N24W080 +N24W081 +N24W082 +N24W083 +N24W098 +N24W099 +N24W100 +N24W101 +N24W102 +N24W103 +N24W104 +N24W105 +N24W106 +N24W107 +N24W108 +N24W109 +N24W110 +N24W111 +N24W112 +N24W113 +N24W116 +N25W077 +N25W078 +N25W079 +N25W080 +N25W081 +N25W082 +N25W098 +N25W099 +N25W100 +N25W101 +N25W102 +N25W103 +N25W104 +N25W105 +N25W106 +N25W107 +N25W108 +N25W109 +N25W110 +N25W111 +N25W112 +N25W113 +N26W077 +N26W078 +N26W079 +N26W080 +N26W081 +N26W082 +N26W083 +N26W098 +N26W099 +N26W100 +N26W101 +N26W102 +N26W103 +N26W104 +N26W105 +N26W106 +N26W107 +N26W108 +N26W109 +N26W110 +N26W112 +N26W113 +N26W114 +N26W115 +N27W078 +N27W079 +N27W081 +N27W082 +N27W083 +N27W097 +N27W098 +N27W099 +N27W100 +N27W101 +N27W102 +N27W103 +N27W104 +N27W105 +N27W106 +N27W107 +N27W108 +N27W109 +N27W110 +N27W111 +N27W112 +N27W113 +N27W114 +N27W115 +N27W116 +N28W081 +N28W082 +N28W083 +N28W090 +N28W096 +N28W097 +N28W098 +N28W099 +N28W100 +N28W101 +N28W102 +N28W103 +N28W104 +N28W105 +N28W106 +N28W107 +N28W108 +N28W109 +N28W110 +N28W111 +N28W112 +N28W113 +N28W114 +N28W115 +N28W116 +N28W119 +N29W081 +N29W082 +N29W083 +N29W084 +N29W085 +N29W086 +N29W089 +N29W090 +N29W091 +N29W092 +N29W093 +N29W094 +N29W095 +N29W096 +N29W097 +N29W098 +N29W099 +N29W100 +N29W101 +N29W102 +N29W103 +N29W104 +N29W105 +N29W106 +N29W107 +N29W108 +N29W109 +N29W110 +N29W111 +N29W112 +N29W113 +N29W114 +N29W115 +N29W116 +N29W119 +N30W082 +N30W083 +N30W084 +N30W085 +N30W086 +N30W087 +N30W088 +N30W089 +N30W090 +N30W091 +N30W092 +N30W093 +N30W094 +N30W095 +N30W096 +N30W097 +N30W098 +N30W099 +N30W100 +N30W101 +N30W102 +N30W103 +N30W104 +N30W105 +N30W106 +N30W107 +N30W108 +N30W109 +N30W110 +N30W111 +N30W112 +N30W113 +N30W114 +N30W115 +N30W116 +N30W117 +N31W081 +N31W082 +N31W083 +N31W084 +N31W085 +N31W086 +N31W087 +N31W088 +N31W089 +N31W090 +N31W091 +N31W092 +N31W093 +N31W094 +N31W095 +N31W096 +N31W097 +N31W098 +N31W099 +N31W100 +N31W101 +N31W102 +N31W103 +N31W104 +N31W105 +N31W106 +N31W107 +N31W108 +N31W109 +N31W110 +N31W111 +N31W112 +N31W113 +N31W114 +N31W115 +N31W116 +N31W117 +N32W065 +N32W080 +N32W081 +N32W082 +N32W083 +N32W084 +N32W085 +N32W086 +N32W087 +N32W088 +N32W089 +N32W090 +N32W091 +N32W092 +N32W093 +N32W094 +N32W095 +N32W096 +N32W097 +N32W098 +N32W099 +N32W100 +N32W101 +N32W102 +N32W103 +N32W104 +N32W105 +N32W106 +N32W107 +N32W108 +N32W109 +N32W110 +N32W111 +N32W112 +N32W113 +N32W114 +N32W115 +N32W116 +N32W117 +N32W118 +N32W119 +N33W078 +N33W079 +N33W080 +N33W081 +N33W082 +N33W083 +N33W084 +N33W085 +N33W086 +N33W087 +N33W088 +N33W089 +N33W090 +N33W091 +N33W092 +N33W093 +N33W094 +N33W095 +N33W096 +N33W097 +N33W098 +N33W099 +N33W100 +N33W101 +N33W102 +N33W103 +N33W104 +N33W105 +N33W106 +N33W107 +N33W108 +N33W109 +N33W110 +N33W111 +N33W112 +N33W113 +N33W114 +N33W115 +N33W116 +N33W117 +N33W118 +N33W119 +N33W120 +N33W121 +N34W077 +N34W078 +N34W079 +N34W080 +N34W081 +N34W082 +N34W083 +N34W084 +N34W085 +N34W086 +N34W087 +N34W088 +N34W089 +N34W090 +N34W091 +N34W092 +N34W093 +N34W094 +N34W095 +N34W096 +N34W097 +N34W098 +N34W099 +N34W100 +N34W101 +N34W102 +N34W103 +N34W104 +N34W105 +N34W106 +N34W107 +N34W108 +N34W109 +N34W110 +N34W111 +N34W112 +N34W113 +N34W114 +N34W115 +N34W116 +N34W117 +N34W118 +N34W119 +N34W120 +N34W121 +N35W076 +N35W077 +N35W078 +N35W079 +N35W080 +N35W081 +N35W082 +N35W083 +N35W084 +N35W085 +N35W086 +N35W087 +N35W088 +N35W089 +N35W090 +N35W091 +N35W092 +N35W093 +N35W094 +N35W095 +N35W096 +N35W097 +N35W098 +N35W099 +N35W100 +N35W101 +N35W102 +N35W103 +N35W104 +N35W105 +N35W106 +N35W107 +N35W108 +N35W109 +N35W110 +N35W111 +N35W112 +N35W113 +N35W114 +N35W115 +N35W116 +N35W117 +N35W118 +N35W119 +N35W120 +N35W121 +N35W122 +N36W076 +N36W077 +N36W078 +N36W079 +N36W080 +N36W081 +N36W082 +N36W083 +N36W084 +N36W085 +N36W086 +N36W087 +N36W088 +N36W089 +N36W090 +N36W091 +N36W092 +N36W093 +N36W094 +N36W095 +N36W096 +N36W097 +N36W098 +N36W099 +N36W100 +N36W101 +N36W102 +N36W103 +N36W104 +N36W105 +N36W106 +N36W107 +N36W108 +N36W109 +N36W110 +N36W111 +N36W112 +N36W113 +N36W114 +N36W115 +N36W116 +N36W117 +N36W118 +N36W119 +N36W120 +N36W121 +N36W122 +N36W123 +N37W076 +N37W077 +N37W078 +N37W079 +N37W080 +N37W081 +N37W082 +N37W083 +N37W084 +N37W085 +N37W086 +N37W087 +N37W088 +N37W089 +N37W090 +N37W091 +N37W092 +N37W093 +N37W094 +N37W095 +N37W096 +N37W097 +N37W098 +N37W099 +N37W100 +N37W101 +N37W102 +N37W103 +N37W104 +N37W105 +N37W106 +N37W107 +N37W108 +N37W109 +N37W110 +N37W111 +N37W112 +N37W113 +N37W114 +N37W115 +N37W116 +N37W117 +N37W118 +N37W119 +N37W120 +N37W121 +N37W122 +N37W123 +N37W124 +N38W075 +N38W076 +N38W077 +N38W078 +N38W079 +N38W080 +N38W081 +N38W082 +N38W083 +N38W084 +N38W085 +N38W086 +N38W087 +N38W088 +N38W089 +N38W090 +N38W091 +N38W092 +N38W093 +N38W094 +N38W095 +N38W096 +N38W097 +N38W098 +N38W099 +N38W100 +N38W101 +N38W102 +N38W103 +N38W104 +N38W105 +N38W106 +N38W107 +N38W108 +N38W109 +N38W110 +N38W111 +N38W112 +N38W113 +N38W114 +N38W115 +N38W116 +N38W117 +N38W118 +N38W119 +N38W120 +N38W121 +N38W122 +N38W123 +N38W124 +N39W075 +N39W076 +N39W077 +N39W078 +N39W079 +N39W080 +N39W081 +N39W082 +N39W083 +N39W084 +N39W085 +N39W086 +N39W087 +N39W088 +N39W089 +N39W090 +N39W091 +N39W092 +N39W093 +N39W094 +N39W095 +N39W096 +N39W097 +N39W098 +N39W099 +N39W100 +N39W101 +N39W102 +N39W103 +N39W104 +N39W105 +N39W106 +N39W107 +N39W108 +N39W109 +N39W110 +N39W111 +N39W112 +N39W113 +N39W114 +N39W115 +N39W116 +N39W117 +N39W118 +N39W119 +N39W120 +N39W121 +N39W122 +N39W123 +N39W124 +N39W125 +N40W073 +N40W074 +N40W075 +N40W076 +N40W077 +N40W078 +N40W079 +N40W080 +N40W081 +N40W082 +N40W083 +N40W084 +N40W085 +N40W086 +N40W087 +N40W088 +N40W089 +N40W090 +N40W091 +N40W092 +N40W093 +N40W094 +N40W095 +N40W096 +N40W097 +N40W098 +N40W099 +N40W100 +N40W101 +N40W102 +N40W103 +N40W104 +N40W105 +N40W106 +N40W107 +N40W108 +N40W109 +N40W110 +N40W111 +N40W112 +N40W113 +N40W114 +N40W115 +N40W116 +N40W117 +N40W118 +N40W119 +N40W120 +N40W121 +N40W122 +N40W123 +N40W124 +N40W125 +N41W070 +N41W071 +N41W072 +N41W073 +N41W074 +N41W075 +N41W076 +N41W077 +N41W078 +N41W079 +N41W080 +N41W081 +N41W082 +N41W083 +N41W084 +N41W085 +N41W086 +N41W087 +N41W088 +N41W089 +N41W090 +N41W091 +N41W092 +N41W093 +N41W094 +N41W095 +N41W096 +N41W097 +N41W098 +N41W099 +N41W100 +N41W101 +N41W102 +N41W103 +N41W104 +N41W105 +N41W106 +N41W107 +N41W108 +N41W109 +N41W110 +N41W111 +N41W112 +N41W113 +N41W114 +N41W115 +N41W116 +N41W117 +N41W118 +N41W119 +N41W120 +N41W121 +N41W122 +N41W123 +N41W124 +N41W125 +N42W071 +N42W072 +N42W073 +N42W074 +N42W075 +N42W076 +N42W077 +N42W078 +N42W079 +N42W080 +N42W081 +N42W082 +N42W083 +N42W084 +N42W085 +N42W086 +N42W087 +N42W088 +N42W089 +N42W090 +N42W091 +N42W092 +N42W093 +N42W094 +N42W095 +N42W096 +N42W097 +N42W098 +N42W099 +N42W100 +N42W101 +N42W102 +N42W103 +N42W104 +N42W105 +N42W106 +N42W107 +N42W108 +N42W109 +N42W110 +N42W111 +N42W112 +N42W113 +N42W114 +N42W115 +N42W116 +N42W117 +N42W118 +N42W119 +N42W120 +N42W121 +N42W122 +N42W123 +N42W124 +N42W125 +N43W060 +N43W061 +N43W065 +N43W066 +N43W067 +N43W069 +N43W070 +N43W071 +N43W072 +N43W073 +N43W074 +N43W075 +N43W076 +N43W077 +N43W078 +N43W079 +N43W080 +N43W081 +N43W082 +N43W083 +N43W084 +N43W085 +N43W086 +N43W087 +N43W088 +N43W089 +N43W090 +N43W091 +N43W092 +N43W093 +N43W094 +N43W095 +N43W096 +N43W097 +N43W098 +N43W099 +N43W100 +N43W101 +N43W102 +N43W103 +N43W104 +N43W105 +N43W106 +N43W107 +N43W108 +N43W109 +N43W110 +N43W111 +N43W112 +N43W113 +N43W114 +N43W115 +N43W116 +N43W117 +N43W118 +N43W119 +N43W120 +N43W121 +N43W122 +N43W123 +N43W124 +N43W125 +N44W060 +N44W062 +N44W063 +N44W064 +N44W065 +N44W066 +N44W067 +N44W068 +N44W069 +N44W070 +N44W071 +N44W072 +N44W073 +N44W074 +N44W075 +N44W076 +N44W077 +N44W078 +N44W079 +N44W080 +N44W081 +N44W082 +N44W083 +N44W084 +N44W085 +N44W086 +N44W087 +N44W088 +N44W089 +N44W090 +N44W091 +N44W092 +N44W093 +N44W094 +N44W095 +N44W096 +N44W097 +N44W098 +N44W099 +N44W100 +N44W101 +N44W102 +N44W103 +N44W104 +N44W105 +N44W106 +N44W107 +N44W108 +N44W109 +N44W110 +N44W111 +N44W112 +N44W113 +N44W114 +N44W115 +N44W116 +N44W117 +N44W118 +N44W119 +N44W120 +N44W121 +N44W122 +N44W123 +N44W124 +N44W125 +N45W060 +N45W061 +N45W062 +N45W063 +N45W064 +N45W065 +N45W066 +N45W067 +N45W068 +N45W069 +N45W070 +N45W071 +N45W072 +N45W073 +N45W074 +N45W075 +N45W076 +N45W077 +N45W078 +N45W079 +N45W080 +N45W081 +N45W082 +N45W083 +N45W084 +N45W085 +N45W086 +N45W087 +N45W088 +N45W089 +N45W090 +N45W091 +N45W092 +N45W093 +N45W094 +N45W095 +N45W096 +N45W097 +N45W098 +N45W099 +N45W100 +N45W101 +N45W102 +N45W103 +N45W104 +N45W105 +N45W106 +N45W107 +N45W108 +N45W109 +N45W110 +N45W111 +N45W112 +N45W113 +N45W114 +N45W115 +N45W116 +N45W117 +N45W118 +N45W119 +N45W120 +N45W121 +N45W122 +N45W123 +N45W124 +N45W125 +N46W053 +N46W054 +N46W055 +N46W056 +N46W057 +N46W060 +N46W061 +N46W062 +N46W063 +N46W064 +N46W065 +N46W066 +N46W067 +N46W068 +N46W069 +N46W070 +N46W071 +N46W072 +N46W073 +N46W074 +N46W075 +N46W076 +N46W077 +N46W078 +N46W079 +N46W080 +N46W081 +N46W082 +N46W083 +N46W084 +N46W085 +N46W086 +N46W087 +N46W088 +N46W089 +N46W090 +N46W091 +N46W092 +N46W093 +N46W094 +N46W095 +N46W096 +N46W097 +N46W098 +N46W099 +N46W100 +N46W101 +N46W102 +N46W103 +N46W104 +N46W105 +N46W106 +N46W107 +N46W108 +N46W109 +N46W110 +N46W111 +N46W112 +N46W113 +N46W114 +N46W115 +N46W116 +N46W117 +N46W118 +N46W119 +N46W120 +N46W121 +N46W122 +N46W123 +N46W124 +N46W125 +N47W053 +N47W054 +N47W055 +N47W056 +N47W057 +N47W058 +N47W059 +N47W060 +N47W061 +N47W062 +N47W063 +N47W064 +N47W065 +N47W066 +N47W067 +N47W068 +N47W069 +N47W070 +N47W071 +N47W072 +N47W073 +N47W074 +N47W075 +N47W076 +N47W077 +N47W078 +N47W079 +N47W080 +N47W081 +N47W082 +N47W083 +N47W084 +N47W085 +N47W086 +N47W088 +N47W089 +N47W090 +N47W091 +N47W092 +N47W093 +N47W094 +N47W095 +N47W096 +N47W097 +N47W098 +N47W099 +N47W100 +N47W101 +N47W102 +N47W103 +N47W104 +N47W105 +N47W106 +N47W107 +N47W108 +N47W109 +N47W110 +N47W111 +N47W112 +N47W113 +N47W114 +N47W115 +N47W116 +N47W117 +N47W118 +N47W119 +N47W120 +N47W121 +N47W122 +N47W123 +N47W124 +N47W125 +N48W053 +N48W054 +N48W055 +N48W056 +N48W057 +N48W058 +N48W059 +N48W060 +N48W065 +N48W066 +N48W067 +N48W068 +N48W069 +N48W070 +N48W071 +N48W072 +N48W073 +N48W074 +N48W075 +N48W076 +N48W077 +N48W078 +N48W079 +N48W080 +N48W081 +N48W082 +N48W083 +N48W084 +N48W085 +N48W086 +N48W087 +N48W088 +N48W089 +N48W090 +N48W091 +N48W092 +N48W093 +N48W094 +N48W095 +N48W096 +N48W097 +N48W098 +N48W099 +N48W100 +N48W101 +N48W102 +N48W103 +N48W104 +N48W105 +N48W106 +N48W107 +N48W108 +N48W109 +N48W110 +N48W111 +N48W112 +N48W113 +N48W114 +N48W115 +N48W116 +N48W117 +N48W118 +N48W119 +N48W120 +N48W121 +N48W122 +N48W123 +N48W124 +N48W125 +N48W126 +N49W054 +N49W055 +N49W056 +N49W057 +N49W058 +N49W059 +N49W062 +N49W063 +N49W064 +N49W065 +N49W066 +N49W067 +N49W068 +N49W069 +N49W070 +N49W071 +N49W072 +N49W073 +N49W074 +N49W075 +N49W076 +N49W077 +N49W078 +N49W079 +N49W080 +N49W081 +N49W082 +N49W083 +N49W084 +N49W085 +N49W086 +N49W087 +N49W088 +N49W089 +N49W090 +N49W091 +N49W092 +N49W093 +N49W094 +N49W095 +N49W096 +N49W097 +N49W098 +N49W099 +N49W100 +N49W101 +N49W102 +N49W103 +N49W104 +N49W105 +N49W106 +N49W107 +N49W108 +N49W109 +N49W110 +N49W111 +N49W112 +N49W113 +N49W114 +N49W115 +N49W116 +N49W117 +N49W118 +N49W119 +N49W120 +N49W121 +N49W122 +N49W123 +N49W124 +N49W125 +N49W126 +N49W127 +N49W128 +N50W056 +N50W057 +N50W058 +N50W059 +N50W060 +N50W061 +N50W062 +N50W063 +N50W064 +N50W065 +N50W066 +N50W067 +N50W068 +N50W069 +N50W070 +N50W071 +N50W072 +N50W073 +N50W074 +N50W075 +N50W076 +N50W077 +N50W078 +N50W079 +N50W080 +N50W081 +N50W082 +N50W083 +N50W084 +N50W085 +N50W086 +N50W087 +N50W088 +N50W089 +N50W090 +N50W091 +N50W092 +N50W093 +N50W094 +N50W095 +N50W096 +N50W097 +N50W098 +N50W099 +N50W100 +N50W101 +N50W102 +N50W103 +N50W104 +N50W105 +N50W106 +N50W107 +N50W108 +N50W109 +N50W110 +N50W111 +N50W112 +N50W113 +N50W114 +N50W115 +N50W116 +N50W117 +N50W118 +N50W119 +N50W120 +N50W121 +N50W122 +N50W123 +N50W124 +N50W125 +N50W126 +N50W127 +N50W128 +N50W129 +N50W130 +N51E177 +N51E178 +N51E179 +N51W056 +N51W057 +N51W058 +N51W059 +N51W060 +N51W061 +N51W062 +N51W063 +N51W064 +N51W065 +N51W066 +N51W067 +N51W068 +N51W069 +N51W070 +N51W071 +N51W072 +N51W073 +N51W074 +N51W075 +N51W076 +N51W077 +N51W078 +N51W079 +N51W080 +N51W081 +N51W082 +N51W083 +N51W084 +N51W085 +N51W086 +N51W087 +N51W088 +N51W089 +N51W090 +N51W091 +N51W092 +N51W093 +N51W094 +N51W095 +N51W096 +N51W097 +N51W098 +N51W099 +N51W100 +N51W101 +N51W102 +N51W103 +N51W104 +N51W105 +N51W106 +N51W107 +N51W108 +N51W109 +N51W110 +N51W111 +N51W112 +N51W113 +N51W114 +N51W115 +N51W116 +N51W117 +N51W118 +N51W119 +N51W120 +N51W121 +N51W122 +N51W123 +N51W124 +N51W125 +N51W126 +N51W127 +N51W128 +N51W129 +N51W131 +N51W132 +N51W176 +N51W177 +N51W178 +N51W179 +N51W180 +N52E172 +N52E173 +N52E174 +N52E175 +N52E177 +N52E178 +N52E179 +N52W056 +N52W057 +N52W058 +N52W059 +N52W060 +N52W061 +N52W062 +N52W063 +N52W064 +N52W065 +N52W066 +N52W067 +N52W068 +N52W069 +N52W070 +N52W071 +N52W072 +N52W073 +N52W074 +N52W075 +N52W076 +N52W077 +N52W078 +N52W079 +N52W080 +N52W081 +N52W082 +N52W083 +N52W084 +N52W085 +N52W086 +N52W087 +N52W088 +N52W089 +N52W090 +N52W091 +N52W092 +N52W093 +N52W094 +N52W095 +N52W096 +N52W097 +N52W098 +N52W099 +N52W100 +N52W101 +N52W102 +N52W103 +N52W104 +N52W105 +N52W106 +N52W107 +N52W108 +N52W109 +N52W110 +N52W111 +N52W112 +N52W113 +N52W114 +N52W115 +N52W116 +N52W117 +N52W118 +N52W119 +N52W120 +N52W121 +N52W122 +N52W123 +N52W124 +N52W125 +N52W126 +N52W127 +N52W128 +N52W129 +N52W130 +N52W131 +N52W132 +N52W133 +N52W169 +N52W170 +N52W171 +N52W172 +N52W173 +N52W174 +N52W175 +N52W176 +N52W177 +N53E172 +N53W056 +N53W057 +N53W058 +N53W059 +N53W060 +N53W061 +N53W062 +N53W063 +N53W064 +N53W065 +N53W066 +N53W067 +N53W068 +N53W069 +N53W070 +N53W071 +N53W072 +N53W073 +N53W074 +N53W075 +N53W076 +N53W077 +N53W078 +N53W079 +N53W080 +N53W081 +N53W082 +N53W083 +N53W084 +N53W085 +N53W086 +N53W087 +N53W088 +N53W089 +N53W090 +N53W091 +N53W092 +N53W093 +N53W094 +N53W095 +N53W096 +N53W097 +N53W098 +N53W099 +N53W100 +N53W101 +N53W102 +N53W103 +N53W104 +N53W105 +N53W106 +N53W107 +N53W108 +N53W109 +N53W110 +N53W111 +N53W112 +N53W113 +N53W114 +N53W115 +N53W116 +N53W117 +N53W118 +N53W119 +N53W120 +N53W121 +N53W122 +N53W123 +N53W124 +N53W125 +N53W126 +N53W127 +N53W128 +N53W129 +N53W130 +N53W131 +N53W132 +N53W133 +N53W134 +N53W167 +N53W168 +N53W169 +N53W170 +N54W057 +N54W058 +N54W059 +N54W060 +N54W061 +N54W062 +N54W063 +N54W064 +N54W065 +N54W066 +N54W067 +N54W068 +N54W069 +N54W070 +N54W071 +N54W072 +N54W073 +N54W074 +N54W075 +N54W076 +N54W077 +N54W078 +N54W079 +N54W080 +N54W081 +N54W082 +N54W083 +N54W084 +N54W085 +N54W086 +N54W087 +N54W088 +N54W089 +N54W090 +N54W091 +N54W092 +N54W093 +N54W094 +N54W095 +N54W096 +N54W097 +N54W098 +N54W099 +N54W100 +N54W101 +N54W102 +N54W103 +N54W104 +N54W105 +N54W106 +N54W107 +N54W108 +N54W109 +N54W110 +N54W111 +N54W112 +N54W113 +N54W114 +N54W115 +N54W116 +N54W117 +N54W118 +N54W119 +N54W120 +N54W121 +N54W122 +N54W123 +N54W124 +N54W125 +N54W126 +N54W127 +N54W128 +N54W129 +N54W130 +N54W131 +N54W132 +N54W133 +N54W134 +N54W160 +N54W161 +N54W162 +N54W163 +N54W164 +N54W165 +N54W166 +N54W167 +N55W059hgt.zip +N55W060hgt.zip +N55W061hgt.zip +N55W062hgt.zip +N55W063hgt.zip +N55W064hgt.zip +N55W065hgt.zip +N55W066hgt.zip +N55W067hgt.zip +N55W068hgt.zip +N55W069hgt.zip +N55W070hgt.zip +N55W071hgt.zip +N55W072hgt.zip +N55W073hgt.zip +N55W074hgt.zip +N55W075hgt.zip +N55W076hgt.zip +N55W077hgt.zip +N55W078hgt.zip +N55W079hgt.zip +N55W080hgt.zip +N55W081hgt.zip +N55W083hgt.zip +N55W084hgt.zip +N55W085hgt.zip +N55W086hgt.zip +N55W087hgt.zip +N55W088hgt.zip +N55W089hgt.zip +N55W090hgt.zip +N55W091hgt.zip +N55W092hgt.zip +N55W093hgt.zip +N55W094hgt.zip +N55W095hgt.zip +N55W096hgt.zip +N55W097hgt.zip +N55W098hgt.zip +N55W099hgt.zip +N55W100hgt.zip +N55W101hgt.zip +N55W102hgt.zip +N55W103hgt.zip +N55W104hgt.zip +N55W105hgt.zip +N55W106hgt.zip +N55W107hgt.zip +N55W108hgt.zip +N55W109hgt.zip +N55W110hgt.zip +N55W111hgt.zip +N55W112hgt.zip +N55W113hgt.zip +N55W114hgt.zip +N55W115hgt.zip +N55W116hgt.zip +N55W117hgt.zip +N55W118hgt.zip +N55W119hgt.zip +N55W120hgt.zip +N55W121hgt.zip +N55W122hgt.zip +N55W123hgt.zip +N55W124hgt.zip +N55W125hgt.zip +N55W126hgt.zip +N55W127hgt.zip +N55W128hgt.zip +N55W129hgt.zip +N55W130hgt.zip +N55W131hgt.zip +N55W132hgt.zip +N55W133hgt.zip +N55W134hgt.zip +N55W135hgt.zip +N55W156hgt.zip +N55W157hgt.zip +N55W159hgt.zip +N55W160hgt.zip +N55W161hgt.zip +N55W162hgt.zip +N55W163hgt.zip +N55W164hgt.zip +N56W061hgt.zip +N56W062hgt.zip +N56W063hgt.zip +N56W064hgt.zip +N56W065hgt.zip +N56W066hgt.zip +N56W067hgt.zip +N56W068hgt.zip +N56W069hgt.zip +N56W070hgt.zip +N56W071hgt.zip +N56W072hgt.zip +N56W073hgt.zip +N56W074hgt.zip +N56W075hgt.zip +N56W076hgt.zip +N56W077hgt.zip +N56W078hgt.zip +N56W079hgt.zip +N56W080hgt.zip +N56W081hgt.zip +N56W088hgt.zip +N56W089hgt.zip +N56W090hgt.zip +N56W091hgt.zip +N56W092hgt.zip +N56W093hgt.zip +N56W094hgt.zip +N56W095hgt.zip +N56W096hgt.zip +N56W097hgt.zip +N56W098hgt.zip +N56W099hgt.zip +N56W100hgt.zip +N56W101hgt.zip +N56W102hgt.zip +N56W103hgt.zip +N56W104hgt.zip +N56W105hgt.zip +N56W106hgt.zip +N56W107hgt.zip +N56W108hgt.zip +N56W109hgt.zip +N56W110hgt.zip +N56W111hgt.zip +N56W112hgt.zip +N56W113hgt.zip +N56W114hgt.zip +N56W115hgt.zip +N56W116hgt.zip +N56W117hgt.zip +N56W118hgt.zip +N56W119hgt.zip +N56W120hgt.zip +N56W121hgt.zip +N56W122hgt.zip +N56W123hgt.zip +N56W124hgt.zip +N56W125hgt.zip +N56W126hgt.zip +N56W127hgt.zip +N56W128hgt.zip +N56W129hgt.zip +N56W130hgt.zip +N56W131hgt.zip +N56W132hgt.zip +N56W133hgt.zip +N56W134hgt.zip +N56W135hgt.zip +N56W136hgt.zip +N56W154hgt.zip +N56W155hgt.zip +N56W157hgt.zip +N56W158hgt.zip +N56W159hgt.zip +N56W160hgt.zip +N56W161hgt.zip +N56W162hgt.zip +N56W170hgt.zip +N57W062hgt.zip +N57W063hgt.zip +N57W064hgt.zip +N57W065hgt.zip +N57W066hgt.zip +N57W067hgt.zip +N57W068hgt.zip +N57W069hgt.zip +N57W070hgt.zip +N57W071hgt.zip +N57W072hgt.zip +N57W073hgt.zip +N57W074hgt.zip +N57W075hgt.zip +N57W076hgt.zip +N57W077hgt.zip +N57W078hgt.zip +N57W079hgt.zip +N57W080hgt.zip +N57W090hgt.zip +N57W091hgt.zip +N57W092hgt.zip +N57W093hgt.zip +N57W094hgt.zip +N57W095hgt.zip +N57W096hgt.zip +N57W097hgt.zip +N57W098hgt.zip +N57W099hgt.zip +N57W100hgt.zip +N57W101hgt.zip +N57W102hgt.zip +N57W103hgt.zip +N57W104hgt.zip +N57W105hgt.zip +N57W106hgt.zip +N57W107hgt.zip +N57W108hgt.zip +N57W109hgt.zip +N57W110hgt.zip +N57W111hgt.zip +N57W112hgt.zip +N57W113hgt.zip +N57W114hgt.zip +N57W115hgt.zip +N57W116hgt.zip +N57W117hgt.zip +N57W118hgt.zip +N57W119hgt.zip +N57W120hgt.zip +N57W121hgt.zip +N57W122hgt.zip +N57W123hgt.zip +N57W124hgt.zip +N57W125hgt.zip +N57W126hgt.zip +N57W127hgt.zip +N57W128hgt.zip +N57W129hgt.zip +N57W130hgt.zip +N57W131hgt.zip +N57W132hgt.zip +N57W133hgt.zip +N57W134hgt.zip +N57W135hgt.zip +N57W136hgt.zip +N57W137hgt.zip +N57W153hgt.zip +N57W154hgt.zip +N57W155hgt.zip +N57W156hgt.zip +N57W157hgt.zip +N57W158hgt.zip +N57W159hgt.zip +N57W170hgt.zip +N57W171hgt.zip +N58W063hgt.zip +N58W064hgt.zip +N58W065hgt.zip +N58W066hgt.zip +N58W067hgt.zip +N58W068hgt.zip +N58W069hgt.zip +N58W070hgt.zip +N58W071hgt.zip +N58W072hgt.zip +N58W073hgt.zip +N58W074hgt.zip +N58W075hgt.zip +N58W076hgt.zip +N58W077hgt.zip +N58W078hgt.zip +N58W079hgt.zip +N58W080hgt.zip +N58W081hgt.zip +N58W093hgt.zip +N58W094hgt.zip +N58W095hgt.zip +N58W096hgt.zip +N58W097hgt.zip +N58W098hgt.zip +N58W099hgt.zip +N58W100hgt.zip +N58W101hgt.zip +N58W102hgt.zip +N58W103hgt.zip +N58W104hgt.zip +N58W105hgt.zip +N58W106hgt.zip +N58W107hgt.zip +N58W108hgt.zip +N58W109hgt.zip +N58W110hgt.zip +N58W111hgt.zip +N58W112hgt.zip +N58W113hgt.zip +N58W114hgt.zip +N58W115hgt.zip +N58W116hgt.zip +N58W117hgt.zip +N58W118hgt.zip +N58W119hgt.zip +N58W120hgt.zip +N58W121hgt.zip +N58W122hgt.zip +N58W123hgt.zip +N58W124hgt.zip +N58W125hgt.zip +N58W126hgt.zip +N58W127hgt.zip +N58W128hgt.zip +N58W129hgt.zip +N58W130hgt.zip +N58W131hgt.zip +N58W132hgt.zip +N58W133hgt.zip +N58W134hgt.zip +N58W135hgt.zip +N58W136hgt.zip +N58W137hgt.zip +N58W138hgt.zip +N58W139hgt.zip +N58W152hgt.zip +N58W153hgt.zip +N58W154hgt.zip +N58W155hgt.zip +N58W156hgt.zip +N58W157hgt.zip +N58W158hgt.zip +N58W159hgt.zip +N58W160hgt.zip +N58W161hgt.zip +N58W162hgt.zip +N58W163hgt.zip +N59W044hgt.zip +N59W045hgt.zip +N59W046hgt.zip +N59W064hgt.zip +N59W065hgt.zip +N59W066hgt.zip +N59W067hgt.zip +N59W069hgt.zip +N59W070hgt.zip +N59W071hgt.zip +N59W072hgt.zip +N59W073hgt.zip +N59W074hgt.zip +N59W075hgt.zip +N59W076hgt.zip +N59W077hgt.zip +N59W078hgt.zip +N59W079hgt.zip +N59W080hgt.zip +N59W081hgt.zip +N59W095hgt.zip +N59W096hgt.zip +N59W097hgt.zip +N59W098hgt.zip +N59W099hgt.zip +N59W100hgt.zip +N59W101hgt.zip +N59W102hgt.zip +N59W103hgt.zip +N59W104hgt.zip +N59W105hgt.zip +N59W106hgt.zip +N59W107hgt.zip +N59W108hgt.zip +N59W109hgt.zip +N59W110hgt.zip +N59W111hgt.zip +N59W112hgt.zip +N59W113hgt.zip +N59W114hgt.zip +N59W115hgt.zip +N59W116hgt.zip +N59W117hgt.zip +N59W118hgt.zip +N59W119hgt.zip +N59W120hgt.zip +N59W121hgt.zip +N59W122hgt.zip +N59W123hgt.zip +N59W124hgt.zip +N59W125hgt.zip +N59W126hgt.zip +N59W127hgt.zip +N59W128hgt.zip +N59W129hgt.zip +N59W130hgt.zip +N59W131hgt.zip +N59W132hgt.zip +N59W133hgt.zip +N59W134hgt.zip +N59W135hgt.zip +N59W136hgt.zip +N59W137hgt.zip +N59W138hgt.zip +N59W139hgt.zip +N59W140hgt.zip +N59W141hgt.zip +N59W142hgt.zip +N59W144hgt.zip +N59W145hgt.zip +N59W147hgt.zip +N59W148hgt.zip +N59W149hgt.zip +N59W150hgt.zip +N59W151hgt.zip +N59W152hgt.zip +N59W153hgt.zip +N59W154hgt.zip +N59W155hgt.zip +N59W156hgt.zip +N59W157hgt.zip +N59W158hgt.zip +N59W159hgt.zip +N59W160hgt.zip +N59W161hgt.zip +N59W162hgt.zip +N59W163hgt.zip +N59W164hgt.zip +N59W165hgt.zip +N60W043hgt.zip +N60W044hgt.zip +N60W045hgt.zip +N60W046hgt.zip +N60W047hgt.zip +N60W048hgt.zip +N60W049hgt.zip +N60W064hgt.zip +N60W065hgt.zip +N60W066hgt.zip +N60W068hgt.zip +N60W069hgt.zip +N60W070hgt.zip +N60W071hgt.zip +N60W072hgt.zip +N60W073hgt.zip +N60W074hgt.zip +N60W075hgt.zip +N60W076hgt.zip +N60W077hgt.zip +N60W078hgt.zip +N60W079hgt.zip +N60W095hgt.zip +N60W096hgt.zip +N60W097hgt.zip +N60W098hgt.zip +N60W099hgt.zip +N60W100hgt.zip +N60W101hgt.zip +N60W102hgt.zip +N60W103hgt.zip +N60W104hgt.zip +N60W105hgt.zip +N60W106hgt.zip +N60W107hgt.zip +N60W108hgt.zip +N60W109hgt.zip +N60W110hgt.zip +N60W111hgt.zip +N60W112hgt.zip +N60W113hgt.zip +N60W114hgt.zip +N60W115hgt.zip +N60W116hgt.zip +N60W117hgt.zip +N60W118hgt.zip +N60W119hgt.zip +N60W120hgt.zip +N60W121hgt.zip +N60W122hgt.zip +N60W123hgt.zip +N60W124hgt.zip +N60W125hgt.zip +N60W126hgt.zip +N60W127hgt.zip +N60W128hgt.zip +N60W129hgt.zip +N60W130hgt.zip +N60W131hgt.zip +N60W132hgt.zip +N60W133hgt.zip +N60W134hgt.zip +N60W135hgt.zip +N60W136hgt.zip +N60W137hgt.zip +N60W138hgt.zip +N60W139hgt.zip +N60W140hgt.zip +N60W141hgt.zip +N60W142hgt.zip +N60W143hgt.zip +N60W144hgt.zip +N60W145hgt.zip +N60W146hgt.zip +N60W147hgt.zip +N60W148hgt.zip +N60W149hgt.zip +N60W150hgt.zip +N60W151hgt.zip +N60W152hgt.zip +N60W153hgt.zip +N60W154hgt.zip +N60W155hgt.zip +N60W156hgt.zip +N60W157hgt.zip +N60W158hgt.zip +N60W159hgt.zip +N60W160hgt.zip +N60W161hgt.zip +N60W162hgt.zip +N60W163hgt.zip +N60W164hgt.zip +N60W165hgt.zip +N60W166hgt.zip +N60W167hgt.zip +N60W168hgt.zip +N60W173hgt.zip +N60W174hgt.zip +N00W050 +N00W051 +N00W052 +N00W053 +N00W054 +N00W055 +N00W056 +N00W057 +N00W058 +N00W059 +N00W060 +N00W061 +N00W062 +N00W063 +N00W064 +N00W065 +N00W066 +N00W067 +N00W068 +N00W069 +N00W070 +N00W071 +N00W072 +N00W073 +N00W074 +N00W075 +N00W076 +N00W077 +N00W078 +N00W079 +N00W080 +N00W081 +N00W090 +N00W091 +N00W092 +N01W050 +N01W051 +N01W052 +N01W053 +N01W054 +N01W055 +N01W056 +N01W057 +N01W058 +N01W059 +N01W060 +N01W061 +N01W062 +N01W063 +N01W064 +N01W065 +N01W066 +N01W067 +N01W068 +N01W069 +N01W070 +N01W071 +N01W072 +N01W073 +N01W074 +N01W075 +N01W076 +N01W077 +N01W078 +N01W079 +N01W080 +N01W092 +N02W051 +N02W052 +N02W053 +N02W054 +N02W055 +N02W056 +N02W057 +N02W058 +N02W059 +N02W060 +N02W061 +N02W062 +N02W063 +N02W064 +N02W065 +N02W066 +N02W067 +N02W068 +N02W069 +N02W070 +N02W071 +N02W072 +N02W073 +N02W074 +N02W075 +N02W076 +N02W077 +N02W078 +N02W079 +N03W051 +N03W052 +N03W053 +N03W054 +N03W055 +N03W056 +N03W057 +N03W058 +N03W059 +N03W060 +N03W061 +N03W062 +N03W063 +N03W064 +N03W065 +N03W066 +N03W067 +N03W068 +N03W069 +N03W070 +N03W071 +N03W072 +N03W073 +N03W074 +N03W075 +N03W076 +N03W077 +N03W078 +N03W079 +N03W082 +N04W052 +N04W053 +N04W054 +N04W055 +N04W056 +N04W057 +N04W058 +N04W059 +N04W060 +N04W061 +N04W062 +N04W063 +N04W064 +N04W065 +N04W066 +N04W067 +N04W068 +N04W069 +N04W070 +N04W071 +N04W072 +N04W073 +N04W074 +N04W075 +N04W076 +N04W077 +N04W078 +N04W082 +N05W053 +N05W054 +N05W055 +N05W056 +N05W057 +N05W058 +N05W059 +N05W060 +N05W061 +N05W062 +N05W063 +N05W064 +N05W065 +N05W066 +N05W067 +N05W068 +N05W069 +N05W070 +N05W071 +N05W072 +N05W073 +N05W074 +N05W075 +N05W076 +N05W077 +N05W078 +N05W088 +N06W056 +N06W057 +N06W058 +N06W059 +N06W060 +N06W061 +N06W062 +N06W063 +N06W064 +N06W065 +N06W066 +N06W067 +N06W068 +N06W069 +N06W070 +N06W071 +N06W072 +N06W073 +N06W074 +N06W075 +N06W076 +N06W077 +N06W078 +N07W059 +N07W060 +N07W061 +N07W062 +N07W063 +N07W064 +N07W065 +N07W066 +N07W067 +N07W068 +N07W069 +N07W070 +N07W071 +N07W072 +N07W073 +N07W074 +N07W075 +N07W076 +N07W077 +N07W078 +N07W079 +N07W080 +N07W081 +N07W082 +N07W083 +N08W060 +N08W061 +N08W062 +N08W063 +N08W064 +N08W065 +N08W066 +N08W067 +N08W068 +N08W069 +N08W070 +N08W071 +N08W072 +N08W073 +N08W074 +N08W075 +N08W076 +N08W077 +N08W078 +N08W079 +N08W080 +N08W081 +N08W082 +N08W083 +N08W084 +N09W061 +N09W062 +N09W063 +N09W064 +N09W065 +N09W066 +N09W067 +N09W068 +N09W069 +N09W070 +N09W071 +N09W072 +N09W073 +N09W074 +N09W075 +N09W076 +N09W077 +N09W078 +N09W079 +N09W080 +N09W081 +N09W082 +N09W083 +N09W084 +N09W085 +N09W086 +N10W061 +N10W062 +N10W063 +N10W064 +N10W065 +N10W066 +N10W067 +N10W068 +N10W069 +N10W070 +N10W071 +N10W072 +N10W073 +N10W074 +N10W075 +N10W076 +N10W084 +N10W085 +N10W086 +N11W061 +N11W062 +N11W064 +N11W065 +N11W067 +N11W068 +N11W069 +N11W070 +N11W071 +N11W072 +N11W073 +N11W074 +N11W075 +N11W084 +N11W085 +N11W086 +N11W087 +N12W062 +N12W069 +N12W070 +N12W071 +N12W072 +N12W073 +N12W082 +N12W083 +N12W084 +N12W085 +N12W086 +N12W087 +N12W088 +N13W060 +N13W061 +N13W062 +N13W081 +N13W082 +N13W084 +N13W085 +N13W086 +N13W087 +N13W088 +N13W089 +N13W090 +N13W091 +N13W092 +N14W061 +N14W062 +N14W081 +N14W083 +N14W084 +N14W085 +N14W086 +N14W087 +N14W088 +N14W089 +N14W090 +N14W091 +N14W092 +N14W093 +S01W047 +S01W048 +S01W049 +S01W050 +S01W051 +S01W052 +S01W053 +S01W054 +S01W055 +S01W056 +S01W057 +S01W058 +S01W059 +S01W060 +S01W061 +S01W062 +S01W063 +S01W064 +S01W065 +S01W066 +S01W067 +S01W068 +S01W069 +S01W070 +S01W071 +S01W072 +S01W073 +S01W074 +S01W075 +S01W076 +S01W077 +S01W078 +S01W079 +S01W080 +S01W081 +S01W090 +S01W091 +S01W092 +S02W045 +S02W046 +S02W047 +S02W048 +S02W049 +S02W050 +S02W051 +S02W052 +S02W053 +S02W054 +S02W055 +S02W056 +S02W057 +S02W058 +S02W059 +S02W060 +S02W061 +S02W062 +S02W063 +S02W064 +S02W065 +S02W066 +S02W067 +S02W068 +S02W069 +S02W070 +S02W071 +S02W072 +S02W073 +S02W074 +S02W075 +S02W076 +S02W077 +S02W078 +S02W079 +S02W080 +S02W081 +S02W082 +S02W090 +S02W091 +S02W092 +S03W040 +S03W041 +S03W042 +S03W043 +S03W044 +S03W045 +S03W046 +S03W047 +S03W048 +S03W049 +S03W050 +S03W051 +S03W052 +S03W053 +S03W054 +S03W055 +S03W056 +S03W057 +S03W058 +S03W059 +S03W060 +S03W061 +S03W062 +S03W063 +S03W064 +S03W065 +S03W066 +S03W067 +S03W068 +S03W069 +S03W070 +S03W071 +S03W072 +S03W073 +S03W074 +S03W075 +S03W076 +S03W077 +S03W078 +S03W079 +S03W080 +S03W081 +S03W082 +S04W033 +S04W034 +S04W039 +S04W040 +S04W041 +S04W042 +S04W043 +S04W044 +S04W045 +S04W046 +S04W047 +S04W048 +S04W049 +S04W050 +S04W051 +S04W052 +S04W053 +S04W054 +S04W055 +S04W056 +S04W057 +S04W058 +S04W059 +S04W060 +S04W061 +S04W062 +S04W063 +S04W064 +S04W065 +S04W066 +S04W067 +S04W068 +S04W069 +S04W070 +S04W071 +S04W072 +S04W073 +S04W074 +S04W075 +S04W076 +S04W077 +S04W078 +S04W079 +S04W080 +S04W081 +S05W037 +S05W038 +S05W039 +S05W040 +S05W041 +S05W042 +S05W043 +S05W044 +S05W045 +S05W046 +S05W047 +S05W048 +S05W049 +S05W050 +S05W051 +S05W052 +S05W053 +S05W054 +S05W055 +S05W056 +S05W057 +S05W058 +S05W059 +S05W060 +S05W061 +S05W062 +S05W063 +S05W064 +S05W065 +S05W066 +S05W067 +S05W068 +S05W069 +S05W070 +S05W071 +S05W072 +S05W073 +S05W074 +S05W075 +S05W076 +S05W077 +S05W078 +S05W079 +S05W080 +S05W081 +S05W082 +S06W036 +S06W037 +S06W038 +S06W039 +S06W040 +S06W041 +S06W042 +S06W043 +S06W044 +S06W045 +S06W046 +S06W047 +S06W048 +S06W049 +S06W050 +S06W051 +S06W052 +S06W053 +S06W054 +S06W055 +S06W056 +S06W057 +S06W058 +S06W059 +S06W060 +S06W061 +S06W062 +S06W063 +S06W064 +S06W065 +S06W066 +S06W067 +S06W068 +S06W069 +S06W070 +S06W071 +S06W072 +S06W073 +S06W074 +S06W075 +S06W076 +S06W077 +S06W078 +S06W079 +S06W080 +S06W081 +S06W082 +S07W035 +S07W036 +S07W037 +S07W038 +S07W039 +S07W040 +S07W041 +S07W042 +S07W043 +S07W044 +S07W045 +S07W046 +S07W047 +S07W048 +S07W049 +S07W050 +S07W051 +S07W052 +S07W053 +S07W054 +S07W055 +S07W056 +S07W057 +S07W058 +S07W059 +S07W060 +S07W061 +S07W062 +S07W063 +S07W064 +S07W065 +S07W066 +S07W067 +S07W068 +S07W069 +S07W070 +S07W071 +S07W072 +S07W073 +S07W074 +S07W075 +S07W076 +S07W077 +S07W078 +S07W079 +S07W080 +S07W081 +S07W082 +S08W035 +S08W036 +S08W037 +S08W038 +S08W039 +S08W040 +S08W041 +S08W042 +S08W043 +S08W044 +S08W045 +S08W046 +S08W047 +S08W048 +S08W049 +S08W050 +S08W051 +S08W052 +S08W053 +S08W054 +S08W055 +S08W056 +S08W057 +S08W058 +S08W059 +S08W060 +S08W061 +S08W062 +S08W063 +S08W064 +S08W065 +S08W066 +S08W067 +S08W068 +S08W069 +S08W070 +S08W071 +S08W072 +S08W073 +S08W074 +S08W075 +S08W076 +S08W077 +S08W078 +S08W079 +S08W080 +S09W035 +S09W036 +S09W037 +S09W038 +S09W039 +S09W040 +S09W041 +S09W042 +S09W043 +S09W044 +S09W045 +S09W046 +S09W047 +S09W048 +S09W049 +S09W050 +S09W051 +S09W052 +S09W053 +S09W054 +S09W055 +S09W056 +S09W057 +S09W058 +S09W059 +S09W060 +S09W061 +S09W062 +S09W063 +S09W064 +S09W065 +S09W066 +S09W067 +S09W068 +S09W069 +S09W070 +S09W071 +S09W072 +S09W073 +S09W074 +S09W075 +S09W076 +S09W077 +S09W078 +S09W079 +S09W080 +S10W036 +S10W037 +S10W038 +S10W039 +S10W040 +S10W041 +S10W042 +S10W043 +S10W044 +S10W045 +S10W046 +S10W047 +S10W048 +S10W049 +S10W050 +S10W051 +S10W052 +S10W053 +S10W054 +S10W055 +S10W056 +S10W057 +S10W058 +S10W059 +S10W060 +S10W061 +S10W062 +S10W063 +S10W064 +S10W065 +S10W066 +S10W067 +S10W068 +S10W069 +S10W070 +S10W071 +S10W072 +S10W073 +S10W074 +S10W075 +S10W076 +S10W077 +S10W078 +S10W079 +S11W037 +S11W038 +S11W039 +S11W040 +S11W041 +S11W042 +S11W043 +S11W044 +S11W045 +S11W046 +S11W047 +S11W048 +S11W049 +S11W050 +S11W051 +S11W052 +S11W053 +S11W054 +S11W055 +S11W056 +S11W057 +S11W058 +S11W059 +S11W060 +S11W061 +S11W062 +S11W063 +S11W064 +S11W065 +S11W066 +S11W067 +S11W068 +S11W069 +S11W070 +S11W071 +S11W072 +S11W073 +S11W074 +S11W075 +S11W076 +S11W077 +S11W078 +S11W079 +S12W038 +S12W039 +S12W040 +S12W041 +S12W042 +S12W043 +S12W044 +S12W045 +S12W046 +S12W047 +S12W048 +S12W049 +S12W050 +S12W051 +S12W052 +S12W053 +S12W054 +S12W055 +S12W056 +S12W057 +S12W058 +S12W059 +S12W060 +S12W061 +S12W062 +S12W063 +S12W064 +S12W065 +S12W066 +S12W067 +S12W068 +S12W069 +S12W070 +S12W071 +S12W072 +S12W073 +S12W074 +S12W075 +S12W076 +S12W077 +S12W078 +S13W038 +S13W039 +S13W040 +S13W041 +S13W042 +S13W043 +S13W044 +S13W045 +S13W046 +S13W047 +S13W048 +S13W049 +S13W050 +S13W051 +S13W052 +S13W053 +S13W054 +S13W055 +S13W056 +S13W057 +S13W058 +S13W059 +S13W060 +S13W061 +S13W062 +S13W063 +S13W064 +S13W065 +S13W066 +S13W067 +S13W068 +S13W069 +S13W070 +S13W071 +S13W072 +S13W073 +S13W074 +S13W075 +S13W076 +S13W077 +S13W078 +S14W039 +S14W040 +S14W041 +S14W042 +S14W043 +S14W044 +S14W045 +S14W046 +S14W047 +S14W048 +S14W049 +S14W050 +S14W051 +S14W052 +S14W053 +S14W054 +S14W055 +S14W056 +S14W057 +S14W058 +S14W059 +S14W060 +S14W061 +S14W062 +S14W063 +S14W064 +S14W065 +S14W066 +S14W067 +S14W068 +S14W069 +S14W070 +S14W071 +S14W072 +S14W073 +S14W074 +S14W075 +S14W076 +S14W077 +S15W039 +S15W040 +S15W041 +S15W042 +S15W043 +S15W044 +S15W045 +S15W046 +S15W047 +S15W048 +S15W049 +S15W050 +S15W051 +S15W052 +S15W053 +S15W054 +S15W055 +S15W056 +S15W057 +S15W058 +S15W059 +S15W060 +S15W061 +S15W062 +S15W063 +S15W064 +S15W065 +S15W066 +S15W067 +S15W068 +S15W069 +S15W070 +S15W071 +S15W072 +S15W073 +S15W074 +S15W075 +S15W076 +S15W077 +S16W039 +S16W040 +S16W041 +S16W042 +S16W043 +S16W044 +S16W045 +S16W046 +S16W047 +S16W048 +S16W049 +S16W050 +S16W051 +S16W052 +S16W053 +S16W054 +S16W055 +S16W056 +S16W057 +S16W058 +S16W059 +S16W060 +S16W061 +S16W062 +S16W063 +S16W064 +S16W065 +S16W066 +S16W067 +S16W068 +S16W069 +S16W070 +S16W071 +S16W072 +S16W073 +S16W074 +S16W075 +S16W076 +S17W039 +S17W040 +S17W041 +S17W042 +S17W043 +S17W044 +S17W045 +S17W046 +S17W047 +S17W048 +S17W049 +S17W050 +S17W051 +S17W052 +S17W053 +S17W054 +S17W055 +S17W056 +S17W057 +S17W058 +S17W059 +S17W060 +S17W061 +S17W062 +S17W063 +S17W064 +S17W065 +S17W066 +S17W067 +S17W068 +S17W069 +S17W070 +S17W071 +S17W072 +S17W073 +S17W074 +S17W075 +S18W039 +S18W040 +S18W041 +S18W042 +S18W043 +S18W044 +S18W045 +S18W046 +S18W047 +S18W048 +S18W049 +S18W050 +S18W051 +S18W052 +S18W053 +S18W054 +S18W055 +S18W056 +S18W057 +S18W058 +S18W059 +S18W060 +S18W061 +S18W062 +S18W063 +S18W064 +S18W065 +S18W066 +S18W067 +S18W068 +S18W069 +S18W070 +S18W071 +S18W072 +S18W073 +S19W040 +S19W041 +S19W042 +S19W043 +S19W044 +S19W045 +S19W046 +S19W047 +S19W048 +S19W049 +S19W050 +S19W051 +S19W052 +S19W053 +S19W054 +S19W055 +S19W056 +S19W057 +S19W058 +S19W059 +S19W060 +S19W061 +S19W062 +S19W063 +S19W064 +S19W065 +S19W066 +S19W067 +S19W068 +S19W069 +S19W070 +S19W071 +S20W040 +S20W041 +S20W042 +S20W043 +S20W044 +S20W045 +S20W046 +S20W047 +S20W048 +S20W049 +S20W050 +S20W051 +S20W052 +S20W053 +S20W054 +S20W055 +S20W056 +S20W057 +S20W058 +S20W059 +S20W060 +S20W061 +S20W062 +S20W063 +S20W064 +S20W065 +S20W066 +S20W067 +S20W068 +S20W069 +S20W070 +S20W071 +S21W041 +S21W042 +S21W043 +S21W044 +S21W045 +S21W046 +S21W047 +S21W048 +S21W049 +S21W050 +S21W051 +S21W052 +S21W053 +S21W054 +S21W055 +S21W056 +S21W057 +S21W058 +S21W059 +S21W060 +S21W061 +S21W062 +S21W063 +S21W064 +S21W065 +S21W066 +S21W067 +S21W068 +S21W069 +S21W070 +S21W071 +S22W041 +S22W042 +S22W043 +S22W044 +S22W045 +S22W046 +S22W047 +S22W048 +S22W049 +S22W050 +S22W051 +S22W052 +S22W053 +S22W054 +S22W055 +S22W056 +S22W057 +S22W058 +S22W059 +S22W060 +S22W061 +S22W062 +S22W063 +S22W064 +S22W065 +S22W066 +S22W067 +S22W068 +S22W069 +S22W070 +S22W071 +S23W041 +S23W042 +S23W043 +S23W044 +S23W045 +S23W046 +S23W047 +S23W048 +S23W049 +S23W050 +S23W051 +S23W052 +S23W053 +S23W054 +S23W055 +S23W056 +S23W057 +S23W058 +S23W059 +S23W060 +S23W061 +S23W062 +S23W063 +S23W064 +S23W065 +S23W066 +S23W067 +S23W068 +S23W069 +S23W070 +S23W071 +S24W042 +S24W043 +S24W044 +S24W045 +S24W046 +S24W047 +S24W048 +S24W049 +S24W050 +S24W051 +S24W052 +S24W053 +S24W054 +S24W055 +S24W056 +S24W057 +S24W058 +S24W059 +S24W060 +S24W061 +S24W062 +S24W063 +S24W064 +S24W065 +S24W066 +S24W067 +S24W068 +S24W069 +S24W070 +S24W071 +S25W046 +S25W047 +S25W048 +S25W049 +S25W050 +S25W051 +S25W052 +S25W053 +S25W054 +S25W055 +S25W056 +S25W057 +S25W058 +S25W059 +S25W060 +S25W061 +S25W062 +S25W063 +S25W064 +S25W065 +S25W066 +S25W067 +S25W068 +S25W069 +S25W070 +S25W071 +S26W048 +S26W049 +S26W050 +S26W051 +S26W052 +S26W053 +S26W054 +S26W055 +S26W056 +S26W057 +S26W058 +S26W059 +S26W060 +S26W061 +S26W062 +S26W063 +S26W064 +S26W065 +S26W066 +S26W067 +S26W068 +S26W069 +S26W070 +S26W071 +S27W049 +S27W050 +S27W051 +S27W052 +S27W053 +S27W054 +S27W055 +S27W056 +S27W057 +S27W058 +S27W059 +S27W060 +S27W061 +S27W062 +S27W063 +S27W064 +S27W065 +S27W066 +S27W067 +S27W068 +S27W069 +S27W070 +S27W071 +S27W080 +S27W081 +S28W049 +S28W050 +S28W051 +S28W052 +S28W053 +S28W054 +S28W055 +S28W056 +S28W057 +S28W058 +S28W059 +S28W060 +S28W061 +S28W062 +S28W063 +S28W064 +S28W065 +S28W066 +S28W067 +S28W068 +S28W069 +S28W070 +S28W071 +S28W072 +S29W049 +S29W050 +S29W051 +S29W052 +S29W053 +S29W054 +S29W055 +S29W056 +S29W057 +S29W058 +S29W059 +S29W060 +S29W061 +S29W062 +S29W063 +S29W064 +S29W065 +S29W066 +S29W067 +S29W068 +S29W069 +S29W070 +S29W071 +S29W072 +S30W050 +S30W051 +S30W052 +S30W053 +S30W054 +S30W055 +S30W056 +S30W057 +S30W058 +S30W059 +S30W060 +S30W061 +S30W062 +S30W063 +S30W064 +S30W065 +S30W066 +S30W067 +S30W068 +S30W069 +S30W070 +S30W071 +S30W072 +S31W051 +S31W052 +S31W053 +S31W054 +S31W055 +S31W056 +S31W057 +S31W058 +S31W059 +S31W060 +S31W061 +S31W062 +S31W063 +S31W064 +S31W065 +S31W066 +S31W067 +S31W068 +S31W069 +S31W070 +S31W071 +S31W072 +S32W051 +S32W052 +S32W053 +S32W054 +S32W055 +S32W056 +S32W057 +S32W058 +S32W059 +S32W060 +S32W061 +S32W062 +S32W063 +S32W064 +S32W065 +S32W066 +S32W067 +S32W068 +S32W069 +S32W070 +S32W071 +S32W072 +S33W052 +S33W053 +S33W054 +S33W055 +S33W056 +S33W057 +S33W058 +S33W059 +S33W060 +S33W061 +S33W062 +S33W063 +S33W064 +S33W065 +S33W066 +S33W067 +S33W068 +S33W069 +S33W070 +S33W071 +S33W072 +S34W053 +S34W054 +S34W055 +S34W056 +S34W057 +S34W058 +S34W059 +S34W060 +S34W061 +S34W062 +S34W063 +S34W064 +S34W065 +S34W066 +S34W067 +S34W068 +S34W069 +S34W070 +S34W071 +S34W072 +S34W079 +S34W081 +S35W054 +S35W055 +S35W056 +S35W057 +S35W058 +S35W059 +S35W060 +S35W061 +S35W062 +S35W063 +S35W064 +S35W065 +S35W066 +S35W067 +S35W068 +S35W069 +S35W070 +S35W071 +S35W072 +S35W073 +S36W058 +S36W059 +S36W060 +S36W061 +S36W062 +S36W063 +S36W064 +S36W065 +S36W066 +S36W067 +S36W068 +S36W069 +S36W070 +S36W071 +S36W072 +S36W073 +S37W057 +S37W058 +S37W059 +S37W060 +S37W061 +S37W062 +S37W063 +S37W064 +S37W065 +S37W066 +S37W067 +S37W068 +S37W069 +S37W070 +S37W071 +S37W072 +S37W073 +S37W074 +S38W057 +S38W058 +S38W059 +S38W060 +S38W061 +S38W062 +S38W063 +S38W064 +S38W065 +S38W066 +S38W067 +S38W068 +S38W069 +S38W070 +S38W071 +S38W072 +S38W073 +S38W074 +S39W058 +S39W059 +S39W060 +S39W061 +S39W062 +S39W063 +S39W064 +S39W065 +S39W066 +S39W067 +S39W068 +S39W069 +S39W070 +S39W071 +S39W072 +S39W073 +S39W074 +S40W062 +S40W063 +S40W064 +S40W065 +S40W066 +S40W067 +S40W068 +S40W069 +S40W070 +S40W071 +S40W072 +S40W073 +S40W074 +S41W063 +S41W064 +S41W065 +S41W066 +S41W067 +S41W068 +S41W069 +S41W070 +S41W071 +S41W072 +S41W073 +S41W074 +S42W063 +S42W064 +S42W065 +S42W066 +S42W067 +S42W068 +S42W069 +S42W070 +S42W071 +S42W072 +S42W073 +S42W074 +S42W075 +S43W064 +S43W065 +S43W066 +S43W067 +S43W068 +S43W069 +S43W070 +S43W071 +S43W072 +S43W073 +S43W074 +S43W075 +S44W065 +S44W066 +S44W067 +S44W068 +S44W069 +S44W070 +S44W071 +S44W072 +S44W073 +S44W074 +S44W075 +S45W066 +S45W067 +S45W068 +S45W069 +S45W070 +S45W071 +S45W072 +S45W073 +S45W074 +S45W075 +S45W076 +S46W066 +S46W067 +S46W068 +S46W069 +S46W070 +S46W071 +S46W072 +S46W073 +S46W074 +S46W075 +S46W076 +S47W067 +S47W068 +S47W069 +S47W070 +S47W071 +S47W072 +S47W073 +S47W074 +S47W075 +S47W076 +S48W066 +S48W067 +S48W068 +S48W069 +S48W070 +S48W071 +S48W072 +S48W073 +S48W074 +S48W075 +S48W076 +S49W066 +S49W067 +S49W068 +S49W069 +S49W070 +S49W071 +S49W072 +S49W073 +S49W074 +S49W075 +S49W076 +S50W068 +S50W069 +S50W070 +S50W071 +S50W072 +S50W073 +S50W074 +S50W075 +S50W076 +S51W062 +S51W068 +S51W069 +S51W070 +S51W071 +S51W072 +S51W073 +S51W074 +S51W075 +S51W076 +S52W058 +S52W059 +S52W060 +S52W061 +S52W062 +S52W069 +S52W070 +S52W071 +S52W072 +S52W073 +S52W074 +S52W075 +S52W076 +S53W059 +S53W060 +S53W061 +S53W062 +S53W069 +S53W070 +S53W071 +S53W072 +S53W073 +S53W074 +S53W075 +S53W076 +S54W068 +S54W069 +S54W070 +S54W071 +S54W072 +S54W073 +S54W074 +S54W075 +S55W064 +S55W065 +S55W066 +S55W067 +S55W068 +S55W069 +S55W070 +S55W071 +S55W072 +S55W073 +S55W074 +S56W067 +S56W068 +S56W069 +S56W070 +S56W071 +S56W072 diff --git a/components/isceobj/Alos2Proc/swbd_tiles.txt b/components/isceobj/Alos2Proc/swbd_tiles.txt new file mode 100644 index 0000000..268bebb --- /dev/null +++ b/components/isceobj/Alos2Proc/swbd_tiles.txt @@ -0,0 +1,12229 @@ +N05E000 +N06E000 +N07E000 +N08E000 +N09E000 +N10E000 +N11E000 +N12E000 +N13E000 +N14E000 +N15E000 +N16E000 +N34E000 +N35E000 +N36E000 +N38E000 +N39E000 +N40E000 +N41E000 +N42E000 +N43E000 +N44E000 +N45E000 +N46E000 +N47E000 +N48E000 +N49E000 +N50E000 +N51E000 +N52E000 +N53E000 +N05E001 +N06E001 +N07E001 +N09E001 +N11E001 +N12E001 +N13E001 +N14E001 +N15E001 +N16E001 +N35E001 +N36E001 +N38E001 +N39E001 +N41E001 +N42E001 +N43E001 +N44E001 +N45E001 +N46E001 +N47E001 +N48E001 +N49E001 +N50E001 +N51E001 +N52E001 +N06E002 +N07E002 +N08E002 +N09E002 +N12E002 +N13E002 +N14E002 +N15E002 +N30E002 +N35E002 +N36E002 +N39E002 +N41E002 +N42E002 +N43E002 +N44E002 +N45E002 +N46E002 +N47E002 +N48E002 +N49E002 +N50E002 +N51E002 +N06E003 +N07E003 +N08E003 +N09E003 +N11E003 +N12E003 +N13E003 +N14E003 +N34E003 +N36E003 +N39E003 +N40E003 +N41E003 +N42E003 +N43E003 +N44E003 +N45E003 +N46E003 +N47E003 +N48E003 +N49E003 +N50E003 +N51E003 +S55E003 +N05E004 +N06E004 +N07E004 +N08E004 +N09E004 +N10E004 +N11E004 +N12E004 +N13E004 +N14E004 +N35E004 +N36E004 +N39E004 +N40E004 +N43E004 +N44E004 +N45E004 +N46E004 +N47E004 +N48E004 +N49E004 +N50E004 +N51E004 +N52E004 +N53E004 +N59E004 +N04E005 +N05E005 +N06E005 +N07E005 +N08E005 +N09E005 +N10E005 +N11E005 +N12E005 +N13E005 +N14E005 +N15E005 +N31E005 +N33E005 +N34E005 +N35E005 +N36E005 +N43E005 +N44E005 +N45E005 +N46E005 +N47E005 +N48E005 +N49E005 +N50E005 +N51E005 +N52E005 +N53E005 +N58E005 +N59E005 +S02E005 +N00E006 +N04E006 +N05E006 +N06E006 +N07E006 +N08E006 +N09E006 +N10E006 +N11E006 +N12E006 +N13E006 +N14E006 +N33E006 +N34E006 +N35E006 +N36E006 +N37E006 +N42E006 +N43E006 +N44E006 +N45E006 +N46E006 +N47E006 +N48E006 +N49E006 +N50E006 +N51E006 +N52E006 +N53E006 +N57E006 +N58E006 +N59E006 +S01E006 +N01E007 +N04E007 +N05E007 +N06E007 +N07E007 +N08E007 +N09E007 +N10E007 +N11E007 +N12E007 +N13E007 +N35E007 +N36E007 +N37E007 +N43E007 +N44E007 +N45E007 +N46E007 +N47E007 +N48E007 +N49E007 +N50E007 +N51E007 +N52E007 +N53E007 +N54E007 +N57E007 +N58E007 +N59E007 +N03E008 +N04E008 +N05E008 +N06E008 +N07E008 +N08E008 +N09E008 +N10E008 +N11E008 +N12E008 +N13E008 +N33E008 +N34E008 +N36E008 +N37E008 +N38E008 +N39E008 +N40E008 +N41E008 +N42E008 +N43E008 +N44E008 +N45E008 +N46E008 +N47E008 +N48E008 +N49E008 +N50E008 +N51E008 +N52E008 +N53E008 +N54E008 +N55E008 +N56E008 +N57E008 +N58E008 +N59E008 +S01E008 +S02E008 +N00E009 +N01E009 +N02E009 +N03E009 +N04E009 +N05E009 +N06E009 +N07E009 +N08E009 +N09E009 +N10E009 +N11E009 +N12E009 +N13E009 +N33E009 +N34E009 +N35E009 +N36E009 +N37E009 +N38E009 +N39E009 +N40E009 +N41E009 +N42E009 +N43E009 +N44E009 +N45E009 +N46E009 +N47E009 +N48E009 +N49E009 +N50E009 +N51E009 +N52E009 +N53E009 +N54E009 +N55E009 +N56E009 +N57E009 +N58E009 +N59E009 +S01E009 +S02E009 +S03E009 +N00E010 +N02E010 +N03E010 +N04E010 +N05E010 +N06E010 +N07E010 +N08E010 +N09E010 +N10E010 +N11E010 +N12E010 +N13E010 +N33E010 +N34E010 +N35E010 +N36E010 +N37E010 +N42E010 +N43E010 +N44E010 +N45E010 +N46E010 +N47E010 +N48E010 +N49E010 +N50E010 +N51E010 +N52E010 +N53E010 +N54E010 +N55E010 +N56E010 +N57E010 +N58E010 +N59E010 +S01E010 +S02E010 +S03E010 +S04E010 +N00E011 +N02E011 +N03E011 +N04E011 +N05E011 +N06E011 +N09E011 +N10E011 +N12E011 +N32E011 +N33E011 +N34E011 +N35E011 +N36E011 +N37E011 +N41E011 +N42E011 +N43E011 +N44E011 +N45E011 +N46E011 +N47E011 +N48E011 +N49E011 +N50E011 +N51E011 +N52E011 +N53E011 +N54E011 +N55E011 +N56E011 +N57E011 +N58E011 +N59E011 +S01E011 +S02E011 +S03E011 +S04E011 +S05E011 +S06E011 +S16E011 +S17E011 +S18E011 +S19E011 +N00E012 +N01E012 +N04E012 +N05E012 +N06E012 +N09E012 +N10E012 +N12E012 +N13E012 +N32E012 +N35E012 +N36E012 +N37E012 +N38E012 +N40E012 +N41E012 +N42E012 +N43E012 +N44E012 +N45E012 +N46E012 +N47E012 +N48E012 +N49E012 +N50E012 +N51E012 +N52E012 +N53E012 +N54E012 +N55E012 +N56E012 +N57E012 +N58E012 +N59E012 +S01E012 +S02E012 +S04E012 +S05E012 +S06E012 +S07E012 +S08E012 +S10E012 +S13E012 +S14E012 +S15E012 +S16E012 +S19E012 +S20E012 +N00E013 +N01E013 +N02E013 +N04E013 +N05E013 +N06E013 +N07E013 +N08E013 +N09E013 +N10E013 +N11E013 +N12E013 +N13E013 +N32E013 +N37E013 +N38E013 +N40E013 +N41E013 +N42E013 +N43E013 +N44E013 +N45E013 +N46E013 +N47E013 +N48E013 +N49E013 +N50E013 +N51E013 +N52E013 +N53E013 +N54E013 +N55E013 +N56E013 +N57E013 +N58E013 +N59E013 +S01E013 +S02E013 +S05E013 +S06E013 +S07E013 +S08E013 +S09E013 +S10E013 +S11E013 +S12E013 +S13E013 +S14E013 +S15E013 +S16E013 +S20E013 +S21E013 +S22E013 +N02E014 +N07E014 +N08E014 +N09E014 +N10E014 +N12E014 +N13E014 +N27E014 +N32E014 +N35E014 +N36E014 +N37E014 +N38E014 +N40E014 +N41E014 +N42E014 +N44E014 +N45E014 +N46E014 +N47E014 +N48E014 +N49E014 +N50E014 +N51E014 +N52E014 +N53E014 +N54E014 +N55E014 +N56E014 +N57E014 +N58E014 +N59E014 +S01E014 +S02E014 +S03E014 +S05E014 +S06E014 +S07E014 +S08E014 +S09E014 +S10E014 +S11E014 +S12E014 +S14E014 +S15E014 +S17E014 +S18E014 +S22E014 +S23E014 +S24E014 +S25E014 +S26E014 +S27E014 +N01E015 +N02E015 +N03E015 +N04E015 +N07E015 +N08E015 +N09E015 +N10E015 +N11E015 +N12E015 +N13E015 +N14E015 +N31E015 +N32E015 +N36E015 +N37E015 +N38E015 +N39E015 +N40E015 +N41E015 +N42E015 +N43E015 +N44E015 +N45E015 +N46E015 +N47E015 +N48E015 +N49E015 +N50E015 +N51E015 +N52E015 +N53E015 +N54E015 +N55E015 +N56E015 +N57E015 +N58E015 +N59E015 +S01E015 +S02E015 +S03E015 +S04E015 +S05E015 +S08E015 +S09E015 +S10E015 +S11E015 +S12E015 +S13E015 +S14E015 +S15E015 +S17E015 +S18E015 +S19E015 +S20E015 +S21E015 +S22E015 +S27E015 +S28E015 +S29E015 +N00E016 +N01E016 +N02E016 +N03E016 +N04E016 +N06E016 +N07E016 +N08E016 +N09E016 +N10E016 +N31E016 +N37E016 +N38E016 +N39E016 +N40E016 +N41E016 +N42E016 +N43E016 +N44E016 +N45E016 +N46E016 +N47E016 +N48E016 +N49E016 +N50E016 +N51E016 +N52E016 +N53E016 +N54E016 +N56E016 +N57E016 +N58E016 +N59E016 +S01E016 +S02E016 +S03E016 +S04E016 +S05E016 +S06E016 +S07E016 +S08E016 +S10E016 +S11E016 +S13E016 +S14E016 +S15E016 +S16E016 +S18E016 +S19E016 +S21E016 +S22E016 +S23E016 +S24E016 +S29E016 +S30E016 +N00E017 +N01E017 +N04E017 +N05E017 +N06E017 +N07E017 +N08E017 +N09E017 +N10E017 +N12E017 +N29E017 +N30E017 +N31E017 +N38E017 +N39E017 +N40E017 +N41E017 +N42E017 +N43E017 +N44E017 +N45E017 +N46E017 +N47E017 +N48E017 +N49E017 +N50E017 +N51E017 +N52E017 +N53E017 +N54E017 +N57E017 +N58E017 +N59E017 +S01E017 +S02E017 +S03E017 +S04E017 +S05E017 +S06E017 +S07E017 +S08E017 +S09E017 +S11E017 +S12E017 +S13E017 +S14E017 +S15E017 +S16E017 +S19E017 +S21E017 +S22E017 +S23E017 +S24E017 +S25E017 +S27E017 +S28E017 +S29E017 +S30E017 +S31E017 +S32E017 +S33E017 +S34E017 +N00E018 +N01E018 +N02E018 +N03E018 +N04E018 +N07E018 +N08E018 +N09E018 +N13E018 +N28E018 +N30E018 +N39E018 +N40E018 +N42E018 +N43E018 +N44E018 +N45E018 +N46E018 +N47E018 +N48E018 +N49E018 +N50E018 +N51E018 +N52E018 +N53E018 +N54E018 +N56E018 +N57E018 +N58E018 +N59E018 +S01E018 +S02E018 +S03E018 +S04E018 +S05E018 +S06E018 +S10E018 +S13E018 +S14E018 +S16E018 +S20E018 +S21E018 +S22E018 +S23E018 +S26E018 +S27E018 +S28E018 +S29E018 +S30E018 +S32E018 +S33E018 +S34E018 +S35E018 +N00E019 +N01E019 +N02E019 +N04E019 +N05E019 +N08E019 +N10E019 +N11E019 +N28E019 +N29E019 +N30E019 +N31E019 +N32E019 +N39E019 +N40E019 +N41E019 +N42E019 +N43E019 +N44E019 +N45E019 +N46E019 +N47E019 +N48E019 +N49E019 +N50E019 +N51E019 +N52E019 +N53E019 +N54E019 +N57E019 +N58E019 +N59E019 +S01E019 +S02E019 +S03E019 +S04E019 +S05E019 +S06E019 +S07E019 +S08E019 +S10E019 +S12E019 +S13E019 +S14E019 +S15E019 +S16E019 +S18E019 +S27E019 +S28E019 +S29E019 +S30E019 +S31E019 +S33E019 +S34E019 +S35E019 +N00E020 +N01E020 +N02E020 +N03E020 +N04E020 +N09E020 +N11E020 +N13E020 +N18E020 +N19E020 +N30E020 +N31E020 +N32E020 +N37E020 +N38E020 +N39E020 +N40E020 +N41E020 +N42E020 +N43E020 +N44E020 +N45E020 +N46E020 +N47E020 +N48E020 +N49E020 +N50E020 +N51E020 +N52E020 +N53E020 +N54E020 +N55E020 +N56E020 +N59E020 +S01E020 +S04E020 +S05E020 +S06E020 +S07E020 +S09E020 +S12E020 +S13E020 +S14E020 +S18E020 +S19E020 +S20E020 +S24E020 +S25E020 +S26E020 +S27E020 +S28E020 +S30E020 +S31E020 +S32E020 +S33E020 +S34E020 +S35E020 +N00E021 +N01E021 +N02E021 +N04E021 +N05E021 +N06E021 +N12E021 +N28E021 +N32E021 +N36E021 +N37E021 +N38E021 +N39E021 +N40E021 +N41E021 +N42E021 +N43E021 +N44E021 +N45E021 +N46E021 +N47E021 +N48E021 +N49E021 +N50E021 +N51E021 +N52E021 +N53E021 +N54E021 +N55E021 +N56E021 +N57E021 +N58E021 +N59E021 +S01E021 +S02E021 +S03E021 +S04E021 +S05E021 +S06E021 +S07E021 +S08E021 +S09E021 +S12E021 +S13E021 +S14E021 +S17E021 +S18E021 +S19E021 +S24E021 +S25E021 +S28E021 +S29E021 +S30E021 +S31E021 +S32E021 +S33E021 +S34E021 +S35E021 +N01E022 +N02E022 +N03E022 +N04E022 +N05E022 +N06E022 +N10E022 +N11E022 +N13E022 +N14E022 +N32E022 +N36E022 +N37E022 +N38E022 +N39E022 +N40E022 +N41E022 +N42E022 +N43E022 +N44E022 +N45E022 +N46E022 +N47E022 +N48E022 +N49E022 +N50E022 +N51E022 +N52E022 +N53E022 +N54E022 +N55E022 +N56E022 +N57E022 +N58E022 +N59E022 +S01E022 +S02E022 +S04E022 +S05E022 +S06E022 +S07E022 +S08E022 +S11E022 +S12E022 +S13E022 +S14E022 +S15E022 +S16E022 +S17E022 +S19E022 +S20E022 +S21E022 +S23E022 +S24E022 +S25E022 +S28E022 +S29E022 +S30E022 +S31E022 +S32E022 +S33E022 +S34E022 +S35E022 +N01E023 +N02E023 +N03E023 +N04E023 +N05E023 +N09E023 +N11E023 +N32E023 +N34E023 +N35E023 +N36E023 +N37E023 +N38E023 +N39E023 +N40E023 +N41E023 +N42E023 +N43E023 +N44E023 +N45E023 +N46E023 +N47E023 +N48E023 +N49E023 +N50E023 +N51E023 +N52E023 +N53E023 +N54E023 +N55E023 +N56E023 +N57E023 +N58E023 +N59E023 +S01E023 +S02E023 +S05E023 +S06E023 +S07E023 +S10E023 +S11E023 +S12E023 +S14E023 +S15E023 +S16E023 +S17E023 +S18E023 +S19E023 +S20E023 +S22E023 +S24E023 +S25E023 +S27E023 +S28E023 +S29E023 +S30E023 +S31E023 +S32E023 +S33E023 +S34E023 +S35E023 +N00E024 +N01E024 +N03E024 +N04E024 +N05E024 +N12E024 +N29E024 +N31E024 +N32E024 +N34E024 +N35E024 +N36E024 +N37E024 +N38E024 +N39E024 +N40E024 +N41E024 +N42E024 +N43E024 +N44E024 +N45E024 +N46E024 +N48E024 +N49E024 +N50E024 +N51E024 +N52E024 +N53E024 +N54E024 +N55E024 +N56E024 +N57E024 +N58E024 +N59E024 +S01E024 +S02E024 +S03E024 +S04E024 +S05E024 +S06E024 +S07E024 +S08E024 +S09E024 +S10E024 +S12E024 +S18E024 +S21E024 +S22E024 +S24E024 +S25E024 +S26E024 +S27E024 +S28E024 +S29E024 +S30E024 +S31E024 +S32E024 +S33E024 +S34E024 +S35E024 +N00E025 +N01E025 +N03E025 +N04E025 +N06E025 +N13E025 +N29E025 +N31E025 +N34E025 +N35E025 +N36E025 +N37E025 +N38E025 +N39E025 +N40E025 +N41E025 +N42E025 +N43E025 +N44E025 +N45E025 +N46E025 +N47E025 +N48E025 +N49E025 +N50E025 +N51E025 +N52E025 +N53E025 +N54E025 +N55E025 +N56E025 +N57E025 +N58E025 +N59E025 +S01E025 +S02E025 +S03E025 +S04E025 +S05E025 +S06E025 +S07E025 +S08E025 +S09E025 +S10E025 +S11E025 +S12E025 +S13E025 +S15E025 +S16E025 +S18E025 +S19E025 +S20E025 +S21E025 +S22E025 +S24E025 +S25E025 +S26E025 +S27E025 +S28E025 +S29E025 +S30E025 +S31E025 +S32E025 +S33E025 +S34E025 +S35E025 +N01E026 +N03E026 +N04E026 +N08E026 +N28E026 +N29E026 +N31E026 +N34E026 +N35E026 +N36E026 +N37E026 +N38E026 +N39E026 +N40E026 +N41E026 +N42E026 +N43E026 +N44E026 +N45E026 +N46E026 +N47E026 +N48E026 +N49E026 +N50E026 +N51E026 +N52E026 +N53E026 +N54E026 +N55E026 +N56E026 +N57E026 +N58E026 +N59E026 +S02E026 +S03E026 +S04E026 +S05E026 +S06E026 +S07E026 +S08E026 +S09E026 +S10E026 +S11E026 +S12E026 +S13E026 +S15E026 +S16E026 +S17E026 +S18E026 +S19E026 +S21E026 +S22E026 +S23E026 +S24E026 +S25E026 +S26E026 +S27E026 +S28E026 +S29E026 +S30E026 +S31E026 +S32E026 +S33E026 +S34E026 +N00E027 +N01E027 +N02E027 +N03E027 +N08E027 +N09E027 +N14E027 +N31E027 +N35E027 +N36E027 +N37E027 +N38E027 +N39E027 +N40E027 +N41E027 +N42E027 +N43E027 +N44E027 +N45E027 +N46E027 +N47E027 +N48E027 +N49E027 +N50E027 +N51E027 +N52E027 +N53E027 +N54E027 +N55E027 +N56E027 +N57E027 +N58E027 +N59E027 +S02E027 +S03E027 +S06E027 +S07E027 +S08E027 +S09E027 +S10E027 +S11E027 +S12E027 +S13E027 +S14E027 +S15E027 +S16E027 +S17E027 +S18E027 +S19E027 +S20E027 +S21E027 +S22E027 +S23E027 +S24E027 +S25E027 +S26E027 +S27E027 +S28E027 +S29E027 +S30E027 +S31E027 +S32E027 +S33E027 +S34E027 +N00E028 +N01E028 +N03E028 +N07E028 +N08E028 +N09E028 +N30E028 +N31E028 +N36E028 +N37E028 +N38E028 +N39E028 +N40E028 +N41E028 +N42E028 +N43E028 +N44E028 +N45E028 +N46E028 +N47E028 +N48E028 +N49E028 +N50E028 +N51E028 +N52E028 +N53E028 +N54E028 +N55E028 +N56E028 +N57E028 +N58E028 +N59E028 +S02E028 +S03E028 +S04E028 +S06E028 +S08E028 +S09E028 +S10E028 +S11E028 +S12E028 +S13E028 +S14E028 +S15E028 +S16E028 +S17E028 +S18E028 +S19E028 +S20E028 +S21E028 +S22E028 +S23E028 +S24E028 +S25E028 +S26E028 +S27E028 +S28E028 +S29E028 +S30E028 +S31E028 +S32E028 +S33E028 +N03E029 +N07E029 +N08E029 +N09E029 +N10E029 +N11E029 +N30E029 +N31E029 +N36E029 +N37E029 +N38E029 +N39E029 +N40E029 +N41E029 +N44E029 +N45E029 +N46E029 +N47E029 +N48E029 +N49E029 +N50E029 +N51E029 +N52E029 +N53E029 +N54E029 +N55E029 +N56E029 +N57E029 +N58E029 +N59E029 +S01E029 +S02E029 +S03E029 +S04E029 +S05E029 +S06E029 +S07E029 +S08E029 +S09E029 +S10E029 +S11E029 +S12E029 +S13E029 +S14E029 +S15E029 +S16E029 +S17E029 +S18E029 +S19E029 +S20E029 +S21E029 +S22E029 +S23E029 +S24E029 +S25E029 +S26E029 +S27E029 +S28E029 +S29E029 +S30E029 +S31E029 +S32E029 +S33E029 +N00E030 +N01E030 +N06E030 +N07E030 +N08E030 +N09E030 +N10E030 +N12E030 +N13E030 +N18E030 +N19E030 +N20E030 +N21E030 +N23E030 +N27E030 +N28E030 +N29E030 +N30E030 +N31E030 +N36E030 +N37E030 +N38E030 +N39E030 +N40E030 +N41E030 +N45E030 +N46E030 +N47E030 +N48E030 +N49E030 +N50E030 +N51E030 +N52E030 +N53E030 +N54E030 +N55E030 +N56E030 +N57E030 +N58E030 +N59E030 +S01E030 +S02E030 +S03E030 +S04E030 +S05E030 +S06E030 +S07E030 +S08E030 +S09E030 +S10E030 +S11E030 +S12E030 +S13E030 +S14E030 +S15E030 +S16E030 +S17E030 +S18E030 +S19E030 +S20E030 +S21E030 +S22E030 +S23E030 +S24E030 +S25E030 +S26E030 +S27E030 +S28E030 +S29E030 +S30E030 +S31E030 +S32E030 +N00E031 +N01E031 +N02E031 +N03E031 +N04E031 +N05E031 +N06E031 +N07E031 +N09E031 +N17E031 +N18E031 +N21E031 +N22E031 +N23E031 +N26E031 +N27E031 +N28E031 +N29E031 +N30E031 +N31E031 +N36E031 +N37E031 +N38E031 +N40E031 +N41E031 +N46E031 +N47E031 +N48E031 +N49E031 +N50E031 +N51E031 +N52E031 +N53E031 +N54E031 +N55E031 +N56E031 +N57E031 +N58E031 +N59E031 +S01E031 +S02E031 +S03E031 +S05E031 +S06E031 +S07E031 +S08E031 +S09E031 +S11E031 +S12E031 +S13E031 +S14E031 +S15E031 +S16E031 +S17E031 +S18E031 +S19E031 +S20E031 +S21E031 +S22E031 +S23E031 +S24E031 +S25E031 +S26E031 +S27E031 +S28E031 +S29E031 +S30E031 +N00E032 +N01E032 +N02E032 +N03E032 +N08E032 +N09E032 +N10E032 +N11E032 +N12E032 +N13E032 +N14E032 +N15E032 +N16E032 +N18E032 +N19E032 +N22E032 +N23E032 +N24E032 +N25E032 +N26E032 +N28E032 +N29E032 +N30E032 +N31E032 +N34E032 +N35E032 +N36E032 +N37E032 +N38E032 +N39E032 +N40E032 +N41E032 +N45E032 +N46E032 +N47E032 +N48E032 +N49E032 +N50E032 +N51E032 +N52E032 +N53E032 +N54E032 +N55E032 +N56E032 +N57E032 +N58E032 +N59E032 +S01E032 +S02E032 +S03E032 +S04E032 +S05E032 +S06E032 +S08E032 +S09E032 +S10E032 +S11E032 +S12E032 +S13E032 +S14E032 +S15E032 +S16E032 +S17E032 +S18E032 +S19E032 +S20E032 +S21E032 +S22E032 +S23E032 +S24E032 +S25E032 +S26E032 +S27E032 +S28E032 +S29E032 +N00E033 +N01E033 +N02E033 +N03E033 +N06E033 +N07E033 +N08E033 +N09E033 +N12E033 +N13E033 +N14E033 +N15E033 +N16E033 +N17E033 +N18E033 +N19E033 +N22E033 +N23E033 +N26E033 +N27E033 +N28E033 +N29E033 +N31E033 +N34E033 +N35E033 +N36E033 +N37E033 +N38E033 +N39E033 +N40E033 +N41E033 +N42E033 +N44E033 +N45E033 +N46E033 +N47E033 +N48E033 +N49E033 +N50E033 +N51E033 +N52E033 +N53E033 +N54E033 +N55E033 +N56E033 +N57E033 +N58E033 +N59E033 +S01E033 +S02E033 +S03E033 +S04E033 +S05E033 +S06E033 +S08E033 +S09E033 +S10E033 +S11E033 +S12E033 +S13E033 +S14E033 +S15E033 +S16E033 +S17E033 +S19E033 +S20E033 +S22E033 +S23E033 +S24E033 +S25E033 +S26E033 +N00E034 +N01E034 +N04E034 +N06E034 +N07E034 +N08E034 +N11E034 +N12E034 +N13E034 +N24E034 +N25E034 +N26E034 +N27E034 +N28E034 +N29E034 +N31E034 +N32E034 +N34E034 +N35E034 +N36E034 +N37E034 +N38E034 +N39E034 +N40E034 +N41E034 +N42E034 +N44E034 +N45E034 +N46E034 +N47E034 +N48E034 +N49E034 +N50E034 +N51E034 +N52E034 +N53E034 +N54E034 +N55E034 +N56E034 +N57E034 +N58E034 +N59E034 +S01E034 +S02E034 +S03E034 +S04E034 +S05E034 +S06E034 +S08E034 +S09E034 +S10E034 +S11E034 +S12E034 +S13E034 +S14E034 +S15E034 +S16E034 +S17E034 +S18E034 +S19E034 +S20E034 +S21E034 +S22E034 +S24E034 +S25E034 +S26E034 +N00E035 +N01E035 +N03E035 +N04E035 +N07E035 +N09E035 +N10E035 +N11E035 +N14E035 +N22E035 +N23E035 +N24E035 +N26E035 +N27E035 +N28E035 +N29E035 +N30E035 +N31E035 +N32E035 +N33E035 +N34E035 +N35E035 +N36E035 +N37E035 +N38E035 +N39E035 +N40E035 +N41E035 +N42E035 +N44E035 +N45E035 +N46E035 +N47E035 +N48E035 +N49E035 +N50E035 +N51E035 +N52E035 +N53E035 +N54E035 +N55E035 +N56E035 +N57E035 +N58E035 +N59E035 +S01E035 +S03E035 +S04E035 +S05E035 +S06E035 +S07E035 +S08E035 +S09E035 +S10E035 +S12E035 +S14E035 +S15E035 +S16E035 +S17E035 +S18E035 +S19E035 +S20E035 +S21E035 +S22E035 +S23E035 +S24E035 +S25E035 +N00E036 +N02E036 +N03E036 +N04E036 +N05E036 +N06E036 +N07E036 +N10E036 +N11E036 +N21E036 +N22E036 +N23E036 +N25E036 +N26E036 +N28E036 +N29E036 +N32E036 +N33E036 +N34E036 +N35E036 +N36E036 +N37E036 +N40E036 +N41E036 +N45E036 +N46E036 +N47E036 +N48E036 +N49E036 +N50E036 +N51E036 +N52E036 +N53E036 +N54E036 +N55E036 +N56E036 +N57E036 +N58E036 +N59E036 +S01E036 +S02E036 +S03E036 +S04E036 +S06E036 +S07E036 +S08E036 +S09E036 +S10E036 +S11E036 +S12E036 +S13E036 +S17E036 +S18E036 +S19E036 +N00E037 +N02E037 +N05E037 +N06E037 +N08E037 +N09E037 +N10E037 +N11E037 +N12E037 +N18E037 +N19E037 +N20E037 +N21E037 +N24E037 +N25E037 +N33E037 +N35E037 +N36E037 +N37E037 +N38E037 +N39E037 +N40E037 +N41E037 +N44E037 +N45E037 +N46E037 +N47E037 +N48E037 +N49E037 +N50E037 +N51E037 +N52E037 +N53E037 +N54E037 +N55E037 +N56E037 +N57E037 +N58E037 +N59E037 +S01E037 +S02E037 +S03E037 +S04E037 +S06E037 +S07E037 +S08E037 +S09E037 +S10E037 +S12E037 +S13E037 +S15E037 +S17E037 +S18E037 +S19E037 +S47E037 +N03E038 +N04E038 +N05E038 +N06E038 +N07E038 +N08E038 +N09E038 +N10E038 +N15E038 +N17E038 +N18E038 +N19E038 +N21E038 +N22E038 +N23E038 +N24E038 +N33E038 +N34E038 +N35E038 +N36E038 +N37E038 +N38E038 +N39E038 +N40E038 +N41E038 +N44E038 +N45E038 +N46E038 +N47E038 +N48E038 +N49E038 +N50E038 +N51E038 +N52E038 +N53E038 +N54E038 +N55E038 +N56E038 +N57E038 +N58E038 +N59E038 +S01E038 +S04E038 +S05E038 +S06E038 +S07E038 +S08E038 +S09E038 +S12E038 +S13E038 +S14E038 +S15E038 +S17E038 +S18E038 +S47E038 +N07E039 +N08E039 +N10E039 +N11E039 +N12E039 +N13E039 +N14E039 +N15E039 +N16E039 +N17E039 +N19E039 +N20E039 +N21E039 +N22E039 +N29E039 +N32E039 +N33E039 +N35E039 +N36E039 +N37E039 +N38E039 +N40E039 +N41E039 +N43E039 +N44E039 +N45E039 +N46E039 +N47E039 +N48E039 +N49E039 +N50E039 +N51E039 +N52E039 +N53E039 +N54E039 +N55E039 +N56E039 +N57E039 +N58E039 +N59E039 +S01E039 +S04E039 +S05E039 +S06E039 +S07E039 +S08E039 +S09E039 +S10E039 +S11E039 +S12E039 +S14E039 +S15E039 +S16E039 +S17E039 +S18E039 +N04E040 +N08E040 +N09E040 +N10E040 +N11E040 +N13E040 +N14E040 +N15E040 +N16E040 +N18E040 +N19E040 +N20E040 +N32E040 +N34E040 +N35E040 +N36E040 +N37E040 +N38E040 +N39E040 +N40E040 +N41E040 +N42E040 +N43E040 +N44E040 +N45E040 +N46E040 +N47E040 +N48E040 +N49E040 +N50E040 +N51E040 +N52E040 +N53E040 +N54E040 +N55E040 +N56E040 +N57E040 +N58E040 +N59E040 +S02E040 +S03E040 +S04E040 +S11E040 +S12E040 +S13E040 +S14E040 +S15E040 +S16E040 +S17E040 +S23E040 +N04E041 +N06E041 +N09E041 +N11E041 +N13E041 +N14E041 +N15E041 +N16E041 +N17E041 +N18E041 +N19E041 +N20E041 +N34E041 +N35E041 +N36E041 +N37E041 +N38E041 +N39E041 +N40E041 +N41E041 +N42E041 +N43E041 +N44E041 +N45E041 +N46E041 +N47E041 +N48E041 +N49E041 +N50E041 +N51E041 +N52E041 +N53E041 +N54E041 +N55E041 +N56E041 +N57E041 +N58E041 +N59E041 +S01E041 +S02E041 +S03E041 +N00E042 +N01E042 +N09E042 +N11E042 +N12E042 +N13E042 +N14E042 +N15E042 +N16E042 +N17E042 +N18E042 +N19E042 +N31E042 +N33E042 +N34E042 +N35E042 +N36E042 +N37E042 +N38E042 +N39E042 +N40E042 +N42E042 +N43E042 +N44E042 +N45E042 +N46E042 +N47E042 +N48E042 +N49E042 +N50E042 +N51E042 +N52E042 +N53E042 +N54E042 +N55E042 +N56E042 +N57E042 +N58E042 +N59E042 +S01E042 +S02E042 +S18E042 +N00E043 +N01E043 +N10E043 +N11E043 +N12E043 +N13E043 +N14E043 +N17E043 +N23E043 +N29E043 +N32E043 +N33E043 +N34E043 +N35E043 +N36E043 +N38E043 +N39E043 +N40E043 +N41E043 +N42E043 +N43E043 +N44E043 +N45E043 +N46E043 +N47E043 +N48E043 +N49E043 +N50E043 +N51E043 +N52E043 +N53E043 +N54E043 +N55E043 +N56E043 +N57E043 +N58E043 +N59E043 +S12E043 +S13E043 +S17E043 +S18E043 +S19E043 +S21E043 +S22E043 +S23E043 +S24E043 +S25E043 +N01E044 +N10E044 +N12E044 +N31E044 +N32E044 +N33E044 +N34E044 +N35E044 +N36E044 +N38E044 +N39E044 +N40E044 +N41E044 +N42E044 +N43E044 +N44E044 +N45E044 +N46E044 +N47E044 +N48E044 +N49E044 +N50E044 +N51E044 +N52E044 +N53E044 +N54E044 +N55E044 +N56E044 +N57E044 +N58E044 +N59E044 +S13E044 +S17E044 +S18E044 +S19E044 +S20E044 +S21E044 +S22E044 +S23E044 +S24E044 +S25E044 +S26E044 +N01E045 +N02E045 +N10E045 +N12E045 +N13E045 +N15E045 +N31E045 +N32E045 +N33E045 +N34E045 +N35E045 +N36E045 +N37E045 +N38E045 +N39E045 +N40E045 +N41E045 +N42E045 +N43E045 +N44E045 +N45E045 +N46E045 +N47E045 +N48E045 +N49E045 +N50E045 +N51E045 +N52E045 +N53E045 +N54E045 +N55E045 +N56E045 +N57E045 +N58E045 +N59E045 +S13E045 +S14E045 +S16E045 +S17E045 +S18E045 +S19E045 +S20E045 +S21E045 +S22E045 +S23E045 +S24E045 +S26E045 +N02E046 +N03E046 +N10E046 +N13E046 +N24E046 +N30E046 +N31E046 +N32E046 +N33E046 +N35E046 +N36E046 +N37E046 +N39E046 +N40E046 +N41E046 +N42E046 +N43E046 +N44E046 +N45E046 +N46E046 +N47E046 +N48E046 +N49E046 +N50E046 +N51E046 +N52E046 +N53E046 +N54E046 +N55E046 +N56E046 +N57E046 +S10E046 +S16E046 +S17E046 +S18E046 +S19E046 +S20E046 +S21E046 +S22E046 +S23E046 +S24E046 +S25E046 +S26E046 +N03E047 +N04E047 +N10E047 +N11E047 +N13E047 +N14E047 +N28E047 +N29E047 +N30E047 +N31E047 +N32E047 +N35E047 +N38E047 +N39E047 +N40E047 +N41E047 +N42E047 +N43E047 +N44E047 +N45E047 +N46E047 +N47E047 +N48E047 +N49E047 +N50E047 +N51E047 +N52E047 +N53E047 +N54E047 +N55E047 +N56E047 +N57E047 +N58E047 +S10E047 +S11E047 +S12E047 +S14E047 +S15E047 +S16E047 +S17E047 +S18E047 +S19E047 +S20E047 +S21E047 +S22E047 +S23E047 +S24E047 +S25E047 +S26E047 +N04E048 +N05E048 +N06E048 +N11E048 +N13E048 +N14E048 +N27E048 +N28E048 +N29E048 +N30E048 +N31E048 +N32E048 +N37E048 +N38E048 +N39E048 +N40E048 +N41E048 +N42E048 +N45E048 +N46E048 +N47E048 +N48E048 +N49E048 +N50E048 +N51E048 +N52E048 +N53E048 +N54E048 +N55E048 +N56E048 +N57E048 +N58E048 +N59E048 +S13E048 +S14E048 +S15E048 +S16E048 +S17E048 +S18E048 +S19E048 +S20E048 +S21E048 +S22E048 +S23E048 +N06E049 +N07E049 +N08E049 +N11E049 +N14E049 +N25E049 +N26E049 +N27E049 +N29E049 +N30E049 +N31E049 +N32E049 +N33E049 +N36E049 +N37E049 +N38E049 +N39E049 +N40E049 +N41E049 +N45E049 +N46E049 +N47E049 +N48E049 +N49E049 +N50E049 +N51E049 +N52E049 +N53E049 +N54E049 +N55E049 +N56E049 +N57E049 +N58E049 +N59E049 +S12E049 +S13E049 +S14E049 +S15E049 +S16E049 +S17E049 +S18E049 +S19E049 +S20E049 +N08E050 +N09E050 +N10E050 +N11E050 +N14E050 +N15E050 +N24E050 +N25E050 +N26E050 +N27E050 +N28E050 +N29E050 +N30E050 +N31E050 +N32E050 +N34E050 +N35E050 +N36E050 +N37E050 +N40E050 +N43E050 +N44E050 +N45E050 +N46E050 +N47E050 +N48E050 +N49E050 +N50E050 +N51E050 +N52E050 +N53E050 +N54E050 +N55E050 +N56E050 +N57E050 +N58E050 +N59E050 +S10E050 +S14E050 +S15E050 +S16E050 +S17E050 +S46E050 +S47E050 +N10E051 +N11E051 +N15E051 +N23E051 +N24E051 +N25E051 +N26E051 +N27E051 +N28E051 +N29E051 +N31E051 +N32E051 +N34E051 +N35E051 +N36E051 +N42E051 +N43E051 +N44E051 +N45E051 +N46E051 +N47E051 +N48E051 +N49E051 +N50E051 +N51E051 +N52E051 +N53E051 +N54E051 +N55E051 +N56E051 +N57E051 +N58E051 +N59E051 +S10E051 +S11E051 +S47E051 +N12E052 +N15E052 +N16E052 +N23E052 +N24E052 +N25E052 +N27E052 +N29E052 +N30E052 +N32E052 +N33E052 +N34E052 +N35E052 +N36E052 +N39E052 +N40E052 +N41E052 +N42E052 +N43E052 +N44E052 +N45E052 +N46E052 +N47E052 +N48E052 +N49E052 +N50E052 +N51E052 +N52E052 +N53E052 +N54E052 +N55E052 +N56E052 +N57E052 +N58E052 +N59E052 +S07E052 +S08E052 +S47E052 +N12E053 +N16E053 +N24E053 +N26E053 +N27E053 +N29E053 +N32E053 +N34E053 +N36E053 +N37E053 +N38E053 +N39E053 +N40E053 +N41E053 +N42E053 +N43E053 +N44E053 +N45E053 +N46E053 +N47E053 +N48E053 +N49E053 +N50E053 +N51E053 +N52E053 +N53E053 +N54E053 +N55E053 +N56E053 +N57E053 +N58E053 +N59E053 +S05E053 +S06E053 +S07E053 +N12E054 +N16E054 +N17E054 +N24E054 +N25E054 +N26E054 +N29E054 +N30E054 +N34E054 +N36E054 +N37E054 +N38E054 +N39E054 +N40E054 +N41E054 +N44E054 +N45E054 +N46E054 +N47E054 +N48E054 +N49E054 +N50E054 +N51E054 +N52E054 +N53E054 +N54E054 +N55E054 +N56E054 +N57E054 +N58E054 +N59E054 +S16E054 +N16E055 +N17E055 +N24E055 +N25E055 +N26E055 +N27E055 +N29E055 +N30E055 +N31E055 +N34E055 +N35E055 +N37E055 +N39E055 +N40E055 +N41E055 +N43E055 +N44E055 +N45E055 +N46E055 +N47E055 +N48E055 +N49E055 +N50E055 +N51E055 +N52E055 +N53E055 +N54E055 +N55E055 +N56E055 +N57E055 +N58E055 +N59E055 +S04E055 +S05E055 +S06E055 +S21E055 +S22E055 +N17E056 +N18E056 +N24E056 +N25E056 +N26E056 +N27E056 +N30E056 +N35E056 +N36E056 +N38E056 +N39E056 +N41E056 +N42E056 +N44E056 +N45E056 +N46E056 +N47E056 +N48E056 +N49E056 +N50E056 +N51E056 +N52E056 +N53E056 +N54E056 +N55E056 +N56E056 +N57E056 +N58E056 +N59E056 +S08E056 +S11E056 +N18E057 +N19E057 +N20E057 +N23E057 +N24E057 +N25E057 +N26E057 +N27E057 +N28E057 +N38E057 +N40E057 +N41E057 +N42E057 +N44E057 +N45E057 +N46E057 +N47E057 +N48E057 +N49E057 +N50E057 +N51E057 +N52E057 +N53E057 +N54E057 +N55E057 +N56E057 +N57E057 +N58E057 +N59E057 +S20E057 +S21E057 +N20E058 +N21E058 +N23E058 +N25E058 +N27E058 +N28E058 +N33E058 +N34E058 +N37E058 +N38E058 +N40E058 +N41E058 +N42E058 +N43E058 +N44E058 +N45E058 +N46E058 +N47E058 +N48E058 +N49E058 +N50E058 +N51E058 +N52E058 +N53E058 +N54E058 +N55E058 +N56E058 +N57E058 +N58E058 +N59E058 +N21E059 +N22E059 +N23E059 +N25E059 +N26E059 +N32E059 +N35E059 +N36E059 +N37E059 +N38E059 +N39E059 +N40E059 +N41E059 +N42E059 +N43E059 +N44E059 +N45E059 +N46E059 +N47E059 +N48E059 +N50E059 +N51E059 +N52E059 +N53E059 +N54E059 +N55E059 +N56E059 +N57E059 +N58E059 +N59E059 +S17E059 +N25E060 +N34E060 +N36E060 +N38E060 +N41E060 +N42E060 +N43E060 +N44E060 +N45E060 +N46E060 +N47E060 +N48E060 +N49E060 +N50E060 +N51E060 +N52E060 +N53E060 +N54E060 +N55E060 +N56E060 +N57E060 +N58E060 +N59E060 +N25E061 +N26E061 +N27E061 +N29E061 +N30E061 +N31E061 +N34E061 +N35E061 +N37E061 +N38E061 +N40E061 +N41E061 +N42E061 +N43E061 +N44E061 +N45E061 +N46E061 +N48E061 +N49E061 +N50E061 +N51E061 +N52E061 +N53E061 +N54E061 +N55E061 +N56E061 +N57E061 +N58E061 +N59E061 +N25E062 +N26E062 +N29E062 +N30E062 +N36E062 +N37E062 +N38E062 +N39E062 +N40E062 +N41E062 +N43E062 +N44E062 +N45E062 +N46E062 +N47E062 +N48E062 +N49E062 +N50E062 +N51E062 +N52E062 +N53E062 +N54E062 +N55E062 +N56E062 +N57E062 +N58E062 +N59E062 +N25E063 +N37E063 +N38E063 +N39E063 +N40E063 +N41E063 +N42E063 +N44E063 +N45E063 +N46E063 +N47E063 +N48E063 +N49E063 +N50E063 +N51E063 +N52E063 +N53E063 +N54E063 +N55E063 +N56E063 +N57E063 +N58E063 +N59E063 +S20E063 +N25E064 +N34E064 +N35E064 +N37E064 +N38E064 +N39E064 +N40E064 +N41E064 +N44E064 +N45E064 +N46E064 +N47E064 +N48E064 +N49E064 +N50E064 +N51E064 +N52E064 +N53E064 +N54E064 +N55E064 +N56E064 +N57E064 +N58E064 +N59E064 +N25E065 +N32E065 +N35E065 +N36E065 +N37E065 +N38E065 +N39E065 +N40E065 +N41E065 +N44E065 +N45E065 +N46E065 +N47E065 +N48E065 +N49E065 +N50E065 +N51E065 +N52E065 +N53E065 +N54E065 +N55E065 +N56E065 +N57E065 +N58E065 +N59E065 +N24E066 +N25E066 +N34E066 +N35E066 +N37E066 +N38E066 +N39E066 +N40E066 +N41E066 +N43E066 +N44E066 +N45E066 +N46E066 +N47E066 +N48E066 +N49E066 +N50E066 +N51E066 +N52E066 +N53E066 +N54E066 +N55E066 +N56E066 +N57E066 +N58E066 +N59E066 +N23E067 +N24E067 +N25E067 +N26E067 +N27E067 +N29E067 +N30E067 +N34E067 +N36E067 +N37E067 +N38E067 +N39E067 +N40E067 +N41E067 +N42E067 +N43E067 +N44E067 +N45E067 +N46E067 +N47E067 +N48E067 +N49E067 +N50E067 +N51E067 +N52E067 +N53E067 +N54E067 +N55E067 +N56E067 +N57E067 +N58E067 +N59E067 +N22E068 +N23E068 +N24E068 +N25E068 +N26E068 +N27E068 +N28E068 +N33E068 +N34E068 +N35E068 +N36E068 +N37E068 +N38E068 +N39E068 +N40E068 +N41E068 +N42E068 +N43E068 +N44E068 +N45E068 +N46E068 +N47E068 +N48E068 +N49E068 +N50E068 +N51E068 +N52E068 +N53E068 +N54E068 +N55E068 +N56E068 +N57E068 +N58E068 +N59E068 +S49E068 +S50E068 +S51E068 +N21E069 +N22E069 +N23E069 +N24E069 +N25E069 +N26E069 +N27E069 +N28E069 +N29E069 +N34E069 +N35E069 +N37E069 +N38E069 +N39E069 +N40E069 +N41E069 +N42E069 +N43E069 +N44E069 +N45E069 +N46E069 +N47E069 +N48E069 +N49E069 +N50E069 +N51E069 +N52E069 +N53E069 +N54E069 +N55E069 +N56E069 +N57E069 +N58E069 +N59E069 +S49E069 +S50E069 +N20E070 +N21E070 +N22E070 +N23E070 +N24E070 +N27E070 +N28E070 +N29E070 +N30E070 +N31E070 +N33E070 +N34E070 +N35E070 +N36E070 +N38E070 +N39E070 +N40E070 +N41E070 +N42E070 +N43E070 +N44E070 +N45E070 +N46E070 +N47E070 +N48E070 +N49E070 +N50E070 +N51E070 +N52E070 +N53E070 +N54E070 +N55E070 +N56E070 +N57E070 +N58E070 +N59E070 +S50E070 +N20E071 +N21E071 +N22E071 +N23E071 +N24E071 +N25E071 +N26E071 +N27E071 +N29E071 +N30E071 +N31E071 +N32E071 +N33E071 +N34E071 +N35E071 +N36E071 +N37E071 +N38E071 +N39E071 +N40E071 +N41E071 +N42E071 +N43E071 +N44E071 +N45E071 +N46E071 +N47E071 +N48E071 +N49E071 +N50E071 +N51E071 +N52E071 +N53E071 +N54E071 +N55E071 +N56E071 +N57E071 +N58E071 +N59E071 +S06E071 +S07E071 +N00E072 +N02E072 +N03E072 +N04E072 +N05E072 +N06E072 +N07E072 +N10E072 +N11E072 +N18E072 +N19E072 +N20E072 +N21E072 +N22E072 +N23E072 +N24E072 +N25E072 +N26E072 +N27E072 +N28E072 +N29E072 +N30E072 +N31E072 +N32E072 +N33E072 +N34E072 +N35E072 +N36E072 +N37E072 +N38E072 +N39E072 +N40E072 +N41E072 +N42E072 +N43E072 +N44E072 +N46E072 +N47E072 +N48E072 +N49E072 +N50E072 +N51E072 +N52E072 +N53E072 +N54E072 +N55E072 +N56E072 +N57E072 +N58E072 +N59E072 +S06E072 +S08E072 +S54E072 +N00E073 +N01E073 +N02E073 +N03E073 +N04E073 +N05E073 +N06E073 +N07E073 +N08E073 +N10E073 +N11E073 +N15E073 +N16E073 +N17E073 +N18E073 +N19E073 +N20E073 +N21E073 +N22E073 +N23E073 +N24E073 +N25E073 +N26E073 +N27E073 +N28E073 +N29E073 +N30E073 +N31E073 +N32E073 +N33E073 +N35E073 +N36E073 +N37E073 +N38E073 +N39E073 +N40E073 +N41E073 +N42E073 +N43E073 +N45E073 +N46E073 +N47E073 +N48E073 +N49E073 +N50E073 +N51E073 +N52E073 +N53E073 +N54E073 +N55E073 +N56E073 +N57E073 +N58E073 +N59E073 +S01E073 +S53E073 +S54E073 +N12E074 +N13E074 +N14E074 +N15E074 +N16E074 +N17E074 +N18E074 +N19E074 +N20E074 +N21E074 +N22E074 +N23E074 +N24E074 +N25E074 +N26E074 +N27E074 +N29E074 +N30E074 +N31E074 +N32E074 +N33E074 +N34E074 +N35E074 +N36E074 +N37E074 +N38E074 +N39E074 +N40E074 +N41E074 +N42E074 +N43E074 +N44E074 +N45E074 +N46E074 +N47E074 +N48E074 +N49E074 +N50E074 +N51E074 +N52E074 +N53E074 +N54E074 +N55E074 +N56E074 +N57E074 +N58E074 +N59E074 +N10E075 +N11E075 +N12E075 +N13E075 +N14E075 +N15E075 +N16E075 +N17E075 +N18E075 +N19E075 +N20E075 +N21E075 +N22E075 +N23E075 +N24E075 +N25E075 +N26E075 +N27E075 +N29E075 +N30E075 +N31E075 +N32E075 +N33E075 +N34E075 +N35E075 +N36E075 +N38E075 +N39E075 +N40E075 +N41E075 +N42E075 +N43E075 +N44E075 +N45E075 +N46E075 +N47E075 +N48E075 +N49E075 +N50E075 +N51E075 +N52E075 +N53E075 +N54E075 +N55E075 +N56E075 +N58E075 +N59E075 +N08E076 +N09E076 +N10E076 +N11E076 +N12E076 +N13E076 +N14E076 +N15E076 +N16E076 +N17E076 +N18E076 +N19E076 +N20E076 +N21E076 +N22E076 +N23E076 +N24E076 +N25E076 +N26E076 +N27E076 +N28E076 +N29E076 +N30E076 +N31E076 +N32E076 +N33E076 +N34E076 +N35E076 +N38E076 +N39E076 +N40E076 +N41E076 +N42E076 +N43E076 +N44E076 +N45E076 +N46E076 +N47E076 +N48E076 +N49E076 +N50E076 +N51E076 +N52E076 +N53E076 +N54E076 +N55E076 +N56E076 +N57E076 +N58E076 +N59E076 +N08E077 +N09E077 +N10E077 +N11E077 +N12E077 +N13E077 +N14E077 +N15E077 +N16E077 +N17E077 +N18E077 +N19E077 +N20E077 +N21E077 +N22E077 +N23E077 +N24E077 +N25E077 +N26E077 +N27E077 +N28E077 +N29E077 +N30E077 +N31E077 +N32E077 +N33E077 +N34E077 +N35E077 +N37E077 +N38E077 +N39E077 +N40E077 +N41E077 +N42E077 +N43E077 +N44E077 +N45E077 +N46E077 +N48E077 +N49E077 +N50E077 +N51E077 +N52E077 +N53E077 +N54E077 +N55E077 +N56E077 +N57E077 +N58E077 +N59E077 +S38E077 +S39E077 +N08E078 +N09E078 +N10E078 +N11E078 +N12E078 +N13E078 +N14E078 +N15E078 +N16E078 +N17E078 +N18E078 +N19E078 +N20E078 +N21E078 +N22E078 +N23E078 +N24E078 +N25E078 +N26E078 +N27E078 +N28E078 +N29E078 +N30E078 +N32E078 +N33E078 +N34E078 +N35E078 +N36E078 +N37E078 +N39E078 +N40E078 +N41E078 +N42E078 +N43E078 +N44E078 +N45E078 +N46E078 +N48E078 +N49E078 +N50E078 +N51E078 +N52E078 +N53E078 +N54E078 +N55E078 +N56E078 +N57E078 +N58E078 +N59E078 +N06E079 +N07E079 +N08E079 +N09E079 +N10E079 +N11E079 +N12E079 +N13E079 +N14E079 +N15E079 +N16E079 +N17E079 +N18E079 +N19E079 +N20E079 +N21E079 +N22E079 +N23E079 +N24E079 +N25E079 +N26E079 +N27E079 +N28E079 +N29E079 +N31E079 +N32E079 +N33E079 +N34E079 +N35E079 +N37E079 +N39E079 +N40E079 +N42E079 +N43E079 +N44E079 +N45E079 +N46E079 +N47E079 +N48E079 +N49E079 +N50E079 +N51E079 +N52E079 +N53E079 +N54E079 +N55E079 +N56E079 +N57E079 +N58E079 +N59E079 +N05E080 +N06E080 +N07E080 +N08E080 +N09E080 +N12E080 +N13E080 +N14E080 +N15E080 +N16E080 +N17E080 +N18E080 +N19E080 +N20E080 +N21E080 +N22E080 +N23E080 +N24E080 +N25E080 +N26E080 +N27E080 +N28E080 +N29E080 +N30E080 +N31E080 +N32E080 +N33E080 +N34E080 +N35E080 +N37E080 +N40E080 +N41E080 +N42E080 +N43E080 +N44E080 +N45E080 +N46E080 +N47E080 +N48E080 +N49E080 +N50E080 +N51E080 +N52E080 +N53E080 +N54E080 +N55E080 +N56E080 +N57E080 +N58E080 +N59E080 +N06E081 +N07E081 +N08E081 +N15E081 +N16E081 +N17E081 +N18E081 +N19E081 +N20E081 +N21E081 +N22E081 +N23E081 +N24E081 +N25E081 +N26E081 +N27E081 +N28E081 +N30E081 +N31E081 +N32E081 +N33E081 +N34E081 +N35E081 +N36E081 +N37E081 +N38E081 +N40E081 +N41E081 +N43E081 +N44E081 +N45E081 +N46E081 +N47E081 +N48E081 +N49E081 +N50E081 +N51E081 +N52E081 +N53E081 +N54E081 +N55E081 +N56E081 +N57E081 +N58E081 +N59E081 +N16E082 +N17E082 +N18E082 +N19E082 +N20E082 +N21E082 +N22E082 +N23E082 +N24E082 +N25E082 +N26E082 +N27E082 +N28E082 +N29E082 +N30E082 +N31E082 +N32E082 +N33E082 +N34E082 +N35E082 +N36E082 +N37E082 +N40E082 +N41E082 +N42E082 +N43E082 +N44E082 +N45E082 +N46E082 +N48E082 +N49E082 +N50E082 +N51E082 +N52E082 +N53E082 +N54E082 +N55E082 +N56E082 +N57E082 +N58E082 +N59E082 +N17E083 +N18E083 +N19E083 +N20E083 +N21E083 +N22E083 +N23E083 +N24E083 +N25E083 +N26E083 +N27E083 +N28E083 +N29E083 +N30E083 +N31E083 +N32E083 +N33E083 +N34E083 +N35E083 +N36E083 +N37E083 +N40E083 +N41E083 +N42E083 +N43E083 +N44E083 +N45E083 +N46E083 +N47E083 +N48E083 +N49E083 +N50E083 +N51E083 +N52E083 +N53E083 +N54E083 +N55E083 +N56E083 +N57E083 +N58E083 +N59E083 +N18E084 +N19E084 +N20E084 +N21E084 +N22E084 +N23E084 +N24E084 +N25E084 +N26E084 +N27E084 +N28E084 +N29E084 +N30E084 +N31E084 +N32E084 +N33E084 +N34E084 +N35E084 +N36E084 +N41E084 +N42E084 +N43E084 +N44E084 +N45E084 +N46E084 +N47E084 +N48E084 +N49E084 +N50E084 +N51E084 +N52E084 +N53E084 +N54E084 +N55E084 +N56E084 +N57E084 +N58E084 +N59E084 +N19E085 +N20E085 +N21E085 +N22E085 +N23E085 +N24E085 +N25E085 +N26E085 +N27E085 +N28E085 +N29E085 +N30E085 +N31E085 +N32E085 +N33E085 +N34E085 +N35E085 +N36E085 +N38E085 +N40E085 +N41E085 +N42E085 +N43E085 +N44E085 +N45E085 +N46E085 +N47E085 +N48E085 +N49E085 +N50E085 +N51E085 +N52E085 +N53E085 +N54E085 +N55E085 +N56E085 +N57E085 +N58E085 +N59E085 +N19E086 +N20E086 +N21E086 +N22E086 +N23E086 +N24E086 +N25E086 +N26E086 +N27E086 +N28E086 +N29E086 +N30E086 +N31E086 +N32E086 +N33E086 +N34E086 +N35E086 +N36E086 +N37E086 +N38E086 +N40E086 +N41E086 +N42E086 +N43E086 +N44E086 +N45E086 +N46E086 +N47E086 +N48E086 +N49E086 +N51E086 +N52E086 +N53E086 +N54E086 +N55E086 +N56E086 +N57E086 +N58E086 +N59E086 +N20E087 +N21E087 +N22E087 +N23E087 +N24E087 +N25E087 +N26E087 +N27E087 +N28E087 +N29E087 +N30E087 +N31E087 +N32E087 +N33E087 +N34E087 +N35E087 +N36E087 +N39E087 +N40E087 +N41E087 +N42E087 +N43E087 +N44E087 +N46E087 +N47E087 +N48E087 +N49E087 +N50E087 +N51E087 +N52E087 +N53E087 +N54E087 +N55E087 +N56E087 +N57E087 +N58E087 +N59E087 +N21E088 +N22E088 +N23E088 +N24E088 +N25E088 +N26E088 +N27E088 +N28E088 +N29E088 +N30E088 +N31E088 +N32E088 +N33E088 +N34E088 +N35E088 +N36E088 +N37E088 +N39E088 +N43E088 +N44E088 +N46E088 +N47E088 +N48E088 +N49E088 +N50E088 +N51E088 +N52E088 +N53E088 +N54E088 +N55E088 +N57E088 +N58E088 +N59E088 +N21E089 +N22E089 +N23E089 +N24E089 +N25E089 +N26E089 +N27E089 +N28E089 +N29E089 +N30E089 +N31E089 +N32E089 +N33E089 +N34E089 +N35E089 +N36E089 +N37E089 +N38E089 +N42E089 +N43E089 +N44E089 +N46E089 +N47E089 +N48E089 +N49E089 +N50E089 +N51E089 +N52E089 +N53E089 +N54E089 +N55E089 +N56E089 +N57E089 +N58E089 +N59E089 +N21E090 +N22E090 +N23E090 +N24E090 +N25E090 +N26E090 +N27E090 +N28E090 +N29E090 +N30E090 +N31E090 +N32E090 +N33E090 +N34E090 +N35E090 +N36E090 +N37E090 +N38E090 +N43E090 +N46E090 +N47E090 +N48E090 +N49E090 +N50E090 +N51E090 +N52E090 +N53E090 +N54E090 +N55E090 +N56E090 +N57E090 +N58E090 +N59E090 +N21E091 +N22E091 +N23E091 +N24E091 +N25E091 +N26E091 +N27E091 +N28E091 +N29E091 +N30E091 +N31E091 +N32E091 +N33E091 +N34E091 +N35E091 +N36E091 +N37E091 +N38E091 +N41E091 +N42E091 +N43E091 +N44E091 +N46E091 +N47E091 +N48E091 +N49E091 +N50E091 +N51E091 +N52E091 +N53E091 +N54E091 +N55E091 +N57E091 +N58E091 +N59E091 +N08E092 +N09E092 +N10E092 +N11E092 +N12E092 +N13E092 +N19E092 +N20E092 +N21E092 +N22E092 +N23E092 +N24E092 +N25E092 +N26E092 +N27E092 +N28E092 +N29E092 +N30E092 +N31E092 +N32E092 +N33E092 +N34E092 +N35E092 +N36E092 +N37E092 +N38E092 +N42E092 +N43E092 +N45E092 +N46E092 +N47E092 +N48E092 +N49E092 +N50E092 +N51E092 +N52E092 +N53E092 +N54E092 +N55E092 +N56E092 +N58E092 +N59E092 +N06E093 +N07E093 +N08E093 +N11E093 +N12E093 +N13E093 +N14E093 +N18E093 +N19E093 +N20E093 +N21E093 +N23E093 +N24E093 +N26E093 +N27E093 +N28E093 +N29E093 +N30E093 +N31E093 +N32E093 +N33E093 +N34E093 +N35E093 +N36E093 +N37E093 +N38E093 +N40E093 +N41E093 +N42E093 +N43E093 +N46E093 +N47E093 +N48E093 +N49E093 +N50E093 +N51E093 +N52E093 +N53E093 +N54E093 +N55E093 +N56E093 +N57E093 +N58E093 +N59E093 +N05E094 +N13E094 +N15E094 +N16E094 +N17E094 +N18E094 +N19E094 +N20E094 +N21E094 +N22E094 +N23E094 +N24E094 +N25E094 +N26E094 +N27E094 +N28E094 +N29E094 +N30E094 +N31E094 +N32E094 +N33E094 +N34E094 +N35E094 +N36E094 +N37E094 +N38E094 +N39E094 +N40E094 +N42E094 +N43E094 +N44E094 +N45E094 +N46E094 +N47E094 +N48E094 +N49E094 +N50E094 +N51E094 +N52E094 +N53E094 +N54E094 +N55E094 +N56E094 +N57E094 +N58E094 +N02E095 +N03E095 +N04E095 +N05E095 +N06E095 +N15E095 +N16E095 +N17E095 +N18E095 +N19E095 +N20E095 +N21E095 +N22E095 +N23E095 +N24E095 +N25E095 +N26E095 +N27E095 +N28E095 +N29E095 +N30E095 +N31E095 +N33E095 +N34E095 +N35E095 +N36E095 +N37E095 +N38E095 +N39E095 +N40E095 +N45E095 +N46E095 +N47E095 +N48E095 +N49E095 +N50E095 +N51E095 +N52E095 +N53E095 +N54E095 +N55E095 +N56E095 +N57E095 +N58E095 +N02E096 +N03E096 +N04E096 +N05E096 +N16E096 +N17E096 +N18E096 +N19E096 +N20E096 +N21E096 +N22E096 +N23E096 +N24E096 +N25E096 +N26E096 +N27E096 +N28E096 +N29E096 +N30E096 +N31E096 +N32E096 +N33E096 +N34E096 +N35E096 +N36E096 +N37E096 +N38E096 +N40E096 +N44E096 +N46E096 +N48E096 +N49E096 +N50E096 +N51E096 +N52E096 +N53E096 +N54E096 +N56E096 +N57E096 +N58E096 +N59E096 +S12E096 +S13E096 +N00E097 +N01E097 +N02E097 +N03E097 +N04E097 +N05E097 +N08E097 +N09E097 +N10E097 +N11E097 +N12E097 +N13E097 +N14E097 +N15E097 +N16E097 +N17E097 +N18E097 +N19E097 +N20E097 +N21E097 +N22E097 +N23E097 +N24E097 +N25E097 +N26E097 +N27E097 +N28E097 +N29E097 +N30E097 +N32E097 +N33E097 +N34E097 +N35E097 +N36E097 +N37E097 +N38E097 +N40E097 +N45E097 +N46E097 +N47E097 +N48E097 +N49E097 +N50E097 +N51E097 +N52E097 +N53E097 +N54E097 +N55E097 +N56E097 +N57E097 +N58E097 +N59E097 +N00E098 +N01E098 +N02E098 +N03E098 +N04E098 +N07E098 +N08E098 +N09E098 +N10E098 +N11E098 +N12E098 +N13E098 +N14E098 +N15E098 +N16E098 +N17E098 +N18E098 +N19E098 +N20E098 +N21E098 +N22E098 +N23E098 +N24E098 +N25E098 +N26E098 +N28E098 +N29E098 +N32E098 +N34E098 +N35E098 +N36E098 +N37E098 +N38E098 +N39E098 +N40E098 +N44E098 +N45E098 +N46E098 +N47E098 +N48E098 +N49E098 +N50E098 +N51E098 +N52E098 +N53E098 +N54E098 +N55E098 +N56E098 +N57E098 +N58E098 +S01E098 +S02E098 +N00E099 +N01E099 +N02E099 +N03E099 +N06E099 +N07E099 +N08E099 +N09E099 +N10E099 +N11E099 +N12E099 +N13E099 +N14E099 +N15E099 +N16E099 +N17E099 +N18E099 +N19E099 +N20E099 +N21E099 +N22E099 +N23E099 +N24E099 +N25E099 +N26E099 +N27E099 +N28E099 +N29E099 +N30E099 +N31E099 +N32E099 +N33E099 +N34E099 +N35E099 +N36E099 +N37E099 +N38E099 +N39E099 +N40E099 +N44E099 +N45E099 +N46E099 +N47E099 +N48E099 +N49E099 +N50E099 +N51E099 +N52E099 +N53E099 +N54E099 +N55E099 +N56E099 +N57E099 +N58E099 +N59E099 +S01E099 +S02E099 +S03E099 +N00E100 +N01E100 +N02E100 +N03E100 +N04E100 +N05E100 +N06E100 +N07E100 +N08E100 +N09E100 +N12E100 +N13E100 +N14E100 +N15E100 +N16E100 +N17E100 +N18E100 +N19E100 +N20E100 +N21E100 +N22E100 +N23E100 +N24E100 +N25E100 +N26E100 +N27E100 +N28E100 +N29E100 +N31E100 +N33E100 +N35E100 +N36E100 +N37E100 +N38E100 +N39E100 +N40E100 +N41E100 +N42E100 +N45E100 +N46E100 +N47E100 +N48E100 +N49E100 +N50E100 +N51E100 +N52E100 +N53E100 +N54E100 +N55E100 +N57E100 +N58E100 +N59E100 +S01E100 +S02E100 +S03E100 +S04E100 +N00E101 +N01E101 +N02E101 +N03E101 +N04E101 +N05E101 +N06E101 +N12E101 +N13E101 +N14E101 +N15E101 +N16E101 +N17E101 +N18E101 +N19E101 +N20E101 +N21E101 +N22E101 +N23E101 +N24E101 +N25E101 +N26E101 +N27E101 +N28E101 +N29E101 +N30E101 +N31E101 +N32E101 +N33E101 +N34E101 +N35E101 +N36E101 +N37E101 +N38E101 +N39E101 +N41E101 +N42E101 +N45E101 +N46E101 +N47E101 +N48E101 +N49E101 +N50E101 +N51E101 +N52E101 +N53E101 +N54E101 +N55E101 +N56E101 +N57E101 +N58E101 +S01E101 +S02E101 +S03E101 +S04E101 +S05E101 +N00E102 +N01E102 +N02E102 +N03E102 +N04E102 +N05E102 +N06E102 +N09E102 +N10E102 +N11E102 +N12E102 +N13E102 +N14E102 +N15E102 +N16E102 +N17E102 +N18E102 +N19E102 +N20E102 +N21E102 +N23E102 +N24E102 +N25E102 +N26E102 +N27E102 +N28E102 +N30E102 +N31E102 +N32E102 +N33E102 +N34E102 +N35E102 +N36E102 +N37E102 +N38E102 +N39E102 +N40E102 +N45E102 +N46E102 +N47E102 +N48E102 +N49E102 +N50E102 +N51E102 +N52E102 +N53E102 +N54E102 +N55E102 +N56E102 +N57E102 +N58E102 +N59E102 +S01E102 +S02E102 +S03E102 +S04E102 +S05E102 +S06E102 +N00E103 +N01E103 +N02E103 +N03E103 +N04E103 +N05E103 +N09E103 +N10E103 +N11E103 +N12E103 +N13E103 +N14E103 +N15E103 +N16E103 +N17E103 +N18E103 +N21E103 +N22E103 +N23E103 +N24E103 +N25E103 +N26E103 +N27E103 +N28E103 +N29E103 +N30E103 +N31E103 +N32E103 +N33E103 +N35E103 +N36E103 +N37E103 +N40E103 +N44E103 +N45E103 +N46E103 +N47E103 +N49E103 +N50E103 +N51E103 +N52E103 +N53E103 +N54E103 +N55E103 +N56E103 +N57E103 +N59E103 +S01E103 +S02E103 +S03E103 +S04E103 +S05E103 +S06E103 +N00E104 +N01E104 +N02E104 +N08E104 +N09E104 +N10E104 +N11E104 +N12E104 +N13E104 +N14E104 +N15E104 +N16E104 +N17E104 +N18E104 +N19E104 +N20E104 +N21E104 +N22E104 +N23E104 +N24E104 +N25E104 +N26E104 +N27E104 +N28E104 +N29E104 +N30E104 +N31E104 +N32E104 +N33E104 +N35E104 +N36E104 +N37E104 +N38E104 +N39E104 +N40E104 +N43E104 +N44E104 +N45E104 +N46E104 +N47E104 +N48E104 +N49E104 +N50E104 +N51E104 +N52E104 +N56E104 +N57E104 +N58E104 +N59E104 +S01E104 +S02E104 +S03E104 +S04E104 +S05E104 +S06E104 +N02E105 +N03E105 +N08E105 +N09E105 +N10E105 +N11E105 +N12E105 +N13E105 +N14E105 +N15E105 +N16E105 +N17E105 +N18E105 +N19E105 +N20E105 +N21E105 +N22E105 +N23E105 +N24E105 +N25E105 +N26E105 +N27E105 +N28E105 +N29E105 +N30E105 +N31E105 +N32E105 +N33E105 +N34E105 +N35E105 +N36E105 +N37E105 +N38E105 +N39E105 +N43E105 +N44E105 +N45E105 +N46E105 +N47E105 +N48E105 +N49E105 +N50E105 +N51E105 +N52E105 +N53E105 +N54E105 +N55E105 +N56E105 +N57E105 +N58E105 +N59E105 +S01E105 +S02E105 +S03E105 +S04E105 +S05E105 +S06E105 +S07E105 +S08E105 +S11E105 +N00E106 +N01E106 +N02E106 +N03E106 +N08E106 +N09E106 +N10E106 +N11E106 +N12E106 +N13E106 +N14E106 +N15E106 +N16E106 +N17E106 +N18E106 +N19E106 +N20E106 +N21E106 +N22E106 +N23E106 +N24E106 +N25E106 +N26E106 +N27E106 +N28E106 +N29E106 +N30E106 +N31E106 +N32E106 +N33E106 +N34E106 +N35E106 +N36E106 +N37E106 +N38E106 +N40E106 +N41E106 +N44E106 +N45E106 +N46E106 +N47E106 +N48E106 +N49E106 +N50E106 +N51E106 +N52E106 +N53E106 +N54E106 +N55E106 +N56E106 +N57E106 +N58E106 +N59E106 +S02E106 +S03E106 +S04E106 +S06E106 +S07E106 +S08E106 +N00E107 +N01E107 +N02E107 +N03E107 +N04E107 +N10E107 +N11E107 +N12E107 +N13E107 +N14E107 +N15E107 +N16E107 +N17E107 +N20E107 +N21E107 +N22E107 +N23E107 +N24E107 +N25E107 +N26E107 +N27E107 +N28E107 +N29E107 +N30E107 +N31E107 +N33E107 +N34E107 +N35E107 +N37E107 +N38E107 +N39E107 +N40E107 +N41E107 +N43E107 +N46E107 +N47E107 +N48E107 +N49E107 +N50E107 +N51E107 +N52E107 +N53E107 +N54E107 +N55E107 +N56E107 +N57E107 +N58E107 +N59E107 +S03E107 +S04E107 +S06E107 +S07E107 +S08E107 +N00E108 +N01E108 +N02E108 +N03E108 +N04E108 +N10E108 +N11E108 +N12E108 +N13E108 +N14E108 +N15E108 +N16E108 +N18E108 +N19E108 +N21E108 +N22E108 +N23E108 +N24E108 +N25E108 +N26E108 +N27E108 +N28E108 +N29E108 +N30E108 +N31E108 +N32E108 +N33E108 +N34E108 +N35E108 +N36E108 +N37E108 +N38E108 +N39E108 +N40E108 +N41E108 +N42E108 +N44E108 +N45E108 +N46E108 +N47E108 +N48E108 +N49E108 +N50E108 +N51E108 +N52E108 +N53E108 +N54E108 +N55E108 +N56E108 +N57E108 +N58E108 +N59E108 +S02E108 +S03E108 +S04E108 +S06E108 +S07E108 +S08E108 +N00E109 +N01E109 +N02E109 +N09E109 +N11E109 +N12E109 +N13E109 +N14E109 +N15E109 +N18E109 +N19E109 +N20E109 +N21E109 +N22E109 +N23E109 +N24E109 +N25E109 +N26E109 +N27E109 +N28E109 +N29E109 +N30E109 +N31E109 +N32E109 +N33E109 +N34E109 +N35E109 +N36E109 +N37E109 +N38E109 +N39E109 +N40E109 +N41E109 +N42E109 +N43E109 +N44E109 +N45E109 +N46E109 +N47E109 +N48E109 +N49E109 +N51E109 +N52E109 +N53E109 +N54E109 +N55E109 +N56E109 +N57E109 +N58E109 +N59E109 +S01E109 +S02E109 +S07E109 +S08E109 +N00E110 +N01E110 +N18E110 +N19E110 +N20E110 +N21E110 +N22E110 +N23E110 +N24E110 +N25E110 +N26E110 +N27E110 +N28E110 +N29E110 +N30E110 +N31E110 +N32E110 +N33E110 +N34E110 +N35E110 +N36E110 +N37E110 +N38E110 +N39E110 +N40E110 +N41E110 +N42E110 +N43E110 +N44E110 +N45E110 +N46E110 +N47E110 +N48E110 +N49E110 +N51E110 +N52E110 +N53E110 +N54E110 +N55E110 +N56E110 +N57E110 +N58E110 +N59E110 +S01E110 +S02E110 +S03E110 +S04E110 +S06E110 +S07E110 +S08E110 +S09E110 +N00E111 +N01E111 +N02E111 +N08E111 +N15E111 +N16E111 +N19E111 +N21E111 +N22E111 +N23E111 +N24E111 +N25E111 +N26E111 +N27E111 +N28E111 +N29E111 +N30E111 +N31E111 +N32E111 +N33E111 +N34E111 +N35E111 +N36E111 +N37E111 +N38E111 +N39E111 +N40E111 +N41E111 +N42E111 +N43E111 +N44E111 +N45E111 +N46E111 +N47E111 +N48E111 +N49E111 +N50E111 +N51E111 +N52E111 +N53E111 +N54E111 +N55E111 +N56E111 +N57E111 +N58E111 +N59E111 +S01E111 +S03E111 +S04E111 +S07E111 +S08E111 +S09E111 +N00E112 +N01E112 +N02E112 +N03E112 +N16E112 +N21E112 +N22E112 +N23E112 +N24E112 +N25E112 +N26E112 +N27E112 +N28E112 +N29E112 +N30E112 +N31E112 +N32E112 +N33E112 +N34E112 +N35E112 +N36E112 +N37E112 +N38E112 +N39E112 +N40E112 +N41E112 +N42E112 +N43E112 +N44E112 +N45E112 +N46E112 +N47E112 +N48E112 +N49E112 +N50E112 +N51E112 +N52E112 +N53E112 +N54E112 +N55E112 +N56E112 +N57E112 +N58E112 +N59E112 +S01E112 +S02E112 +S03E112 +S04E112 +S06E112 +S07E112 +S08E112 +S09E112 +S26E112 +N00E113 +N02E113 +N03E113 +N04E113 +N07E113 +N21E113 +N22E113 +N23E113 +N24E113 +N25E113 +N26E113 +N27E113 +N28E113 +N29E113 +N30E113 +N31E113 +N32E113 +N33E113 +N34E113 +N35E113 +N36E113 +N37E113 +N38E113 +N39E113 +N40E113 +N41E113 +N42E113 +N43E113 +N44E113 +N45E113 +N46E113 +N47E113 +N48E113 +N49E113 +N50E113 +N51E113 +N52E113 +N53E113 +N54E113 +N55E113 +N56E113 +N57E113 +N58E113 +N59E113 +S02E113 +S03E113 +S04E113 +S07E113 +S08E113 +S09E113 +S22E113 +S23E113 +S24E113 +S25E113 +S26E113 +S27E113 +S28E113 +S29E113 +N00E114 +N02E114 +N03E114 +N04E114 +N05E114 +N10E114 +N11E114 +N21E114 +N22E114 +N23E114 +N24E114 +N25E114 +N26E114 +N27E114 +N28E114 +N29E114 +N30E114 +N31E114 +N32E114 +N33E114 +N34E114 +N35E114 +N36E114 +N37E114 +N38E114 +N39E114 +N40E114 +N41E114 +N42E114 +N43E114 +N44E114 +N45E114 +N46E114 +N47E114 +N48E114 +N49E114 +N50E114 +N51E114 +N53E114 +N54E114 +N55E114 +N56E114 +N57E114 +N58E114 +N59E114 +S01E114 +S02E114 +S03E114 +S04E114 +S05E114 +S06E114 +S07E114 +S08E114 +S09E114 +S22E114 +S23E114 +S24E114 +S25E114 +S26E114 +S27E114 +S28E114 +S29E114 +S30E114 +S31E114 +S34E114 +S35E114 +N00E115 +N04E115 +N05E115 +N06E115 +N10E115 +N11E115 +N22E115 +N23E115 +N24E115 +N25E115 +N26E115 +N27E115 +N28E115 +N29E115 +N30E115 +N31E115 +N32E115 +N33E115 +N34E115 +N35E115 +N36E115 +N37E115 +N38E115 +N39E115 +N40E115 +N41E115 +N42E115 +N43E115 +N44E115 +N45E115 +N46E115 +N47E115 +N48E115 +N49E115 +N50E115 +N51E115 +N52E115 +N54E115 +N55E115 +N56E115 +N57E115 +N58E115 +S01E115 +S02E115 +S03E115 +S04E115 +S05E115 +S07E115 +S08E115 +S09E115 +S21E115 +S22E115 +S23E115 +S24E115 +S25E115 +S26E115 +S27E115 +S30E115 +S31E115 +S32E115 +S33E115 +S34E115 +S35E115 +N00E116 +N02E116 +N03E116 +N05E116 +N06E116 +N07E116 +N08E116 +N20E116 +N22E116 +N23E116 +N24E116 +N25E116 +N26E116 +N27E116 +N28E116 +N29E116 +N30E116 +N31E116 +N32E116 +N33E116 +N34E116 +N35E116 +N36E116 +N37E116 +N38E116 +N39E116 +N40E116 +N41E116 +N42E116 +N43E116 +N44E116 +N45E116 +N46E116 +N47E116 +N48E116 +N49E116 +N50E116 +N51E116 +N52E116 +N53E116 +N54E116 +N55E116 +N56E116 +N57E116 +N58E116 +N59E116 +S01E116 +S02E116 +S03E116 +S04E116 +S05E116 +S07E116 +S09E116 +S10E116 +S21E116 +S22E116 +S25E116 +S28E116 +S29E116 +S30E116 +S31E116 +S32E116 +S33E116 +S34E116 +S35E116 +S36E116 +N00E117 +N01E117 +N02E117 +N03E117 +N04E117 +N05E117 +N06E117 +N07E117 +N08E117 +N09E117 +N23E117 +N24E117 +N25E117 +N26E117 +N27E117 +N28E117 +N29E117 +N30E117 +N31E117 +N32E117 +N33E117 +N34E117 +N35E117 +N36E117 +N37E117 +N38E117 +N39E117 +N40E117 +N41E117 +N42E117 +N43E117 +N44E117 +N45E117 +N46E117 +N47E117 +N48E117 +N49E117 +N50E117 +N51E117 +N52E117 +N55E117 +N56E117 +N57E117 +N58E117 +N59E117 +S01E117 +S02E117 +S03E117 +S04E117 +S06E117 +S08E117 +S09E117 +S10E117 +S21E117 +S22E117 +S27E117 +S28E117 +S30E117 +S31E117 +S32E117 +S33E117 +S34E117 +S35E117 +S36E117 +N00E118 +N01E118 +N02E118 +N04E118 +N05E118 +N06E118 +N07E118 +N08E118 +N09E118 +N10E118 +N24E118 +N25E118 +N26E118 +N27E118 +N28E118 +N29E118 +N30E118 +N31E118 +N32E118 +N33E118 +N34E118 +N35E118 +N36E118 +N37E118 +N38E118 +N39E118 +N40E118 +N41E118 +N42E118 +N43E118 +N44E118 +N45E118 +N46E118 +N47E118 +N48E118 +N49E118 +N50E118 +N51E118 +N52E118 +N54E118 +N55E118 +N56E118 +N57E118 +N58E118 +N59E118 +S03E118 +S04E118 +S06E118 +S07E118 +S08E118 +S09E118 +S10E118 +S18E118 +S20E118 +S21E118 +S22E118 +S27E118 +S28E118 +S29E118 +S30E118 +S31E118 +S32E118 +S33E118 +S34E118 +S35E118 +S36E118 +N00E119 +N01E119 +N04E119 +N05E119 +N09E119 +N10E119 +N11E119 +N12E119 +N15E119 +N16E119 +N23E119 +N24E119 +N25E119 +N26E119 +N27E119 +N28E119 +N29E119 +N30E119 +N31E119 +N32E119 +N33E119 +N34E119 +N35E119 +N36E119 +N37E119 +N39E119 +N40E119 +N41E119 +N42E119 +N43E119 +N44E119 +N45E119 +N46E119 +N47E119 +N48E119 +N49E119 +N50E119 +N51E119 +N52E119 +N53E119 +N54E119 +N55E119 +N56E119 +N57E119 +N58E119 +N59E119 +S01E119 +S02E119 +S03E119 +S04E119 +S05E119 +S06E119 +S07E119 +S09E119 +S10E119 +S11E119 +S18E119 +S20E119 +S21E119 +S24E119 +S26E119 +S29E119 +S31E119 +S32E119 +S33E119 +S34E119 +S35E119 +N00E120 +N01E120 +N05E120 +N06E120 +N09E120 +N10E120 +N11E120 +N12E120 +N13E120 +N14E120 +N15E120 +N16E120 +N17E120 +N18E120 +N21E120 +N22E120 +N23E120 +N24E120 +N26E120 +N27E120 +N28E120 +N29E120 +N30E120 +N31E120 +N32E120 +N33E120 +N34E120 +N35E120 +N36E120 +N37E120 +N38E120 +N40E120 +N41E120 +N42E120 +N43E120 +N44E120 +N47E120 +N49E120 +N51E120 +N52E120 +N53E120 +N54E120 +N55E120 +N56E120 +N57E120 +N58E120 +N59E120 +S01E120 +S02E120 +S03E120 +S04E120 +S05E120 +S06E120 +S07E120 +S08E120 +S09E120 +S10E120 +S11E120 +S20E120 +S22E120 +S24E120 +S25E120 +S26E120 +S27E120 +S28E120 +S29E120 +S30E120 +S31E120 +S32E120 +S33E120 +S34E120 +S35E120 +N00E121 +N01E121 +N05E121 +N06E121 +N07E121 +N09E121 +N10E121 +N11E121 +N12E121 +N13E121 +N14E121 +N15E121 +N16E121 +N17E121 +N18E121 +N19E121 +N20E121 +N21E121 +N22E121 +N23E121 +N24E121 +N25E121 +N27E121 +N28E121 +N29E121 +N30E121 +N31E121 +N32E121 +N36E121 +N37E121 +N38E121 +N39E121 +N40E121 +N41E121 +N42E121 +N43E121 +N44E121 +N45E121 +N46E121 +N47E121 +N53E121 +N55E121 +N56E121 +N57E121 +N58E121 +N59E121 +S01E121 +S02E121 +S03E121 +S04E121 +S05E121 +S06E121 +S07E121 +S08E121 +S09E121 +S11E121 +S15E121 +S19E121 +S20E121 +S22E121 +S23E121 +S25E121 +S26E121 +S27E121 +S28E121 +S29E121 +S30E121 +S31E121 +S32E121 +S33E121 +S34E121 +S35E121 +N00E122 +N01E122 +N06E122 +N07E122 +N08E122 +N09E122 +N10E122 +N11E122 +N12E122 +N13E122 +N14E122 +N15E122 +N16E122 +N17E122 +N18E122 +N19E122 +N20E122 +N24E122 +N25E122 +N28E122 +N29E122 +N30E122 +N31E122 +N36E122 +N37E122 +N39E122 +N40E122 +N41E122 +N42E122 +N43E122 +N44E122 +N45E122 +N46E122 +N47E122 +N51E122 +N53E122 +N55E122 +N56E122 +N57E122 +N58E122 +N59E122 +S01E122 +S02E122 +S03E122 +S04E122 +S05E122 +S06E122 +S07E122 +S08E122 +S09E122 +S11E122 +S12E122 +S13E122 +S17E122 +S18E122 +S19E122 +S22E122 +S23E122 +S24E122 +S26E122 +S27E122 +S29E122 +S30E122 +S31E122 +S32E122 +S33E122 +S34E122 +S35E122 +N00E123 +N06E123 +N07E123 +N08E123 +N09E123 +N10E123 +N11E123 +N12E123 +N13E123 +N14E123 +N24E123 +N25E123 +N39E123 +N40E123 +N41E123 +N42E123 +N43E123 +N44E123 +N45E123 +N46E123 +N47E123 +N48E123 +N49E123 +N53E123 +N55E123 +N56E123 +N57E123 +N58E123 +S01E123 +S02E123 +S03E123 +S04E123 +S05E123 +S06E123 +S08E123 +S09E123 +S10E123 +S11E123 +S13E123 +S15E123 +S16E123 +S17E123 +S18E123 +S19E123 +S22E123 +S23E123 +S24E123 +S27E123 +S28E123 +S32E123 +S33E123 +S34E123 +S35E123 +N00E124 +N01E124 +N05E124 +N06E124 +N07E124 +N08E124 +N09E124 +N10E124 +N11E124 +N12E124 +N13E124 +N14E124 +N24E124 +N25E124 +N37E124 +N38E124 +N39E124 +N40E124 +N41E124 +N42E124 +N43E124 +N44E124 +N45E124 +N46E124 +N47E124 +N48E124 +N49E124 +N53E124 +N55E124 +N56E124 +N57E124 +N58E124 +S02E124 +S03E124 +S06E124 +S07E124 +S09E124 +S10E124 +S11E124 +S15E124 +S16E124 +S17E124 +S18E124 +S19E124 +S20E124 +S22E124 +S25E124 +S28E124 +S29E124 +S30E124 +S32E124 +S33E124 +S34E124 +N01E125 +N02E125 +N03E125 +N04E125 +N05E125 +N06E125 +N07E125 +N08E125 +N09E125 +N10E125 +N11E125 +N12E125 +N24E125 +N34E125 +N35E125 +N36E125 +N37E125 +N38E125 +N39E125 +N40E125 +N41E125 +N42E125 +N43E125 +N44E125 +N45E125 +N46E125 +N47E125 +N48E125 +N49E125 +N52E125 +N53E125 +N54E125 +N55E125 +N56E125 +N57E125 +N58E125 +N59E125 +S02E125 +S03E125 +S04E125 +S08E125 +S09E125 +S10E125 +S14E125 +S15E125 +S16E125 +S19E125 +S20E125 +S22E125 +S27E125 +S30E125 +S33E125 +N00E126 +N01E126 +N03E126 +N04E126 +N05E126 +N06E126 +N07E126 +N08E126 +N09E126 +N10E126 +N26E126 +N33E126 +N34E126 +N35E126 +N36E126 +N37E126 +N38E126 +N39E126 +N40E126 +N41E126 +N42E126 +N43E126 +N44E126 +N45E126 +N46E126 +N47E126 +N48E126 +N49E126 +N50E126 +N51E126 +N52E126 +N53E126 +N54E126 +N56E126 +N57E126 +N58E126 +N59E126 +S02E126 +S03E126 +S04E126 +S07E126 +S08E126 +S09E126 +S10E126 +S14E126 +S15E126 +S16E126 +S18E126 +S19E126 +S25E126 +S27E126 +S30E126 +S31E126 +S33E126 +N00E127 +N01E127 +N02E127 +N04E127 +N26E127 +N27E127 +N34E127 +N35E127 +N36E127 +N37E127 +N38E127 +N39E127 +N40E127 +N41E127 +N42E127 +N43E127 +N44E127 +N45E127 +N46E127 +N47E127 +N48E127 +N49E127 +N50E127 +N51E127 +N52E127 +N53E127 +N54E127 +N56E127 +N57E127 +N58E127 +N59E127 +S01E127 +S02E127 +S03E127 +S04E127 +S06E127 +S08E127 +S09E127 +S14E127 +S15E127 +S16E127 +S17E127 +S19E127 +S21E127 +S23E127 +S30E127 +S31E127 +S33E127 +N00E128 +N01E128 +N02E128 +N26E128 +N27E128 +N28E128 +N31E128 +N32E128 +N33E128 +N34E128 +N35E128 +N36E128 +N37E128 +N38E128 +N39E128 +N40E128 +N41E128 +N42E128 +N43E128 +N44E128 +N45E128 +N46E128 +N48E128 +N49E128 +N50E128 +N51E128 +N52E128 +N53E128 +N54E128 +N56E128 +N57E128 +N58E128 +N59E128 +S01E128 +S02E128 +S03E128 +S04E128 +S08E128 +S09E128 +S15E128 +S16E128 +S17E128 +S18E128 +S19E128 +S20E128 +S23E128 +S24E128 +S25E128 +S26E128 +S28E128 +S29E128 +S30E128 +S32E128 +S33E128 +N00E129 +N27E129 +N28E129 +N29E129 +N30E129 +N31E129 +N32E129 +N33E129 +N34E129 +N35E129 +N36E129 +N37E129 +N40E129 +N41E129 +N42E129 +N43E129 +N44E129 +N45E129 +N46E129 +N47E129 +N48E129 +N49E129 +N50E129 +N51E129 +N52E129 +N53E129 +N54E129 +N56E129 +N57E129 +N58E129 +N59E129 +S01E129 +S02E129 +S03E129 +S04E129 +S05E129 +S07E129 +S08E129 +S09E129 +S14E129 +S15E129 +S16E129 +S19E129 +S20E129 +S22E129 +S24E129 +S25E129 +S28E129 +S29E129 +S30E129 +S32E129 +N00E130 +N28E130 +N30E130 +N31E130 +N32E130 +N33E130 +N34E130 +N37E130 +N41E130 +N42E130 +N43E130 +N44E130 +N45E130 +N46E130 +N47E130 +N48E130 +N49E130 +N50E130 +N51E130 +N52E130 +N53E130 +N54E130 +N55E130 +N56E130 +N57E130 +N58E130 +S01E130 +S02E130 +S03E130 +S04E130 +S05E130 +S06E130 +S07E130 +S08E130 +S09E130 +S12E130 +S13E130 +S14E130 +S15E130 +S16E130 +S25E130 +S30E130 +S32E130 +N00E131 +N01E131 +N02E131 +N03E131 +N04E131 +N24E131 +N25E131 +N30E131 +N31E131 +N32E131 +N33E131 +N34E131 +N37E131 +N42E131 +N43E131 +N44E131 +N45E131 +N46E131 +N47E131 +N50E131 +N51E131 +N52E131 +N54E131 +N55E131 +N56E131 +N57E131 +N58E131 +N59E131 +S01E131 +S02E131 +S03E131 +S04E131 +S05E131 +S06E131 +S07E131 +S08E131 +S09E131 +S12E131 +S13E131 +S14E131 +S15E131 +S21E131 +S24E131 +S25E131 +S26E131 +S30E131 +S31E131 +S32E131 +N04E132 +N05E132 +N32E132 +N33E132 +N34E132 +N35E132 +N36E132 +N42E132 +N43E132 +N44E132 +N45E132 +N46E132 +N47E132 +N48E132 +N50E132 +N51E132 +N52E132 +N53E132 +N54E132 +N55E132 +N56E132 +N57E132 +N58E132 +N59E132 +S01E132 +S02E132 +S03E132 +S04E132 +S05E132 +S06E132 +S07E132 +S11E132 +S12E132 +S13E132 +S14E132 +S15E132 +S19E132 +S23E132 +S25E132 +S26E132 +S27E132 +S28E132 +S29E132 +S30E132 +S31E132 +S32E132 +S33E132 +N32E133 +N33E133 +N34E133 +N35E133 +N36E133 +N42E133 +N43E133 +N44E133 +N45E133 +N46E133 +N47E133 +N48E133 +N49E133 +N51E133 +N52E133 +N53E133 +N54E133 +N55E133 +N56E133 +N57E133 +N58E133 +N59E133 +S01E133 +S02E133 +S03E133 +S04E133 +S05E133 +S06E133 +S11E133 +S12E133 +S13E133 +S14E133 +S15E133 +S16E133 +S17E133 +S18E133 +S19E133 +S21E133 +S22E133 +S23E133 +S24E133 +S25E133 +S26E133 +S28E133 +S29E133 +S30E133 +S31E133 +S32E133 +S33E133 +N00E134 +N06E134 +N07E134 +N08E134 +N33E134 +N34E134 +N35E134 +N42E134 +N43E134 +N44E134 +N45E134 +N46E134 +N47E134 +N48E134 +N49E134 +N51E134 +N54E134 +N55E134 +N56E134 +N57E134 +N58E134 +N59E134 +S01E134 +S02E134 +S03E134 +S04E134 +S05E134 +S06E134 +S07E134 +S08E134 +S12E134 +S13E134 +S14E134 +S15E134 +S16E134 +S19E134 +S20E134 +S21E134 +S22E134 +S24E134 +S25E134 +S29E134 +S30E134 +S31E134 +S32E134 +S33E134 +S34E134 +S35E134 +N33E135 +N34E135 +N35E135 +N36E135 +N43E135 +N44E135 +N45E135 +N46E135 +N47E135 +N48E135 +N49E135 +N51E135 +N52E135 +N53E135 +N54E135 +N55E135 +N56E135 +N57E135 +N58E135 +N59E135 +S01E135 +S02E135 +S03E135 +S04E135 +S05E135 +S12E135 +S13E135 +S14E135 +S15E135 +S16E135 +S18E135 +S19E135 +S20E135 +S27E135 +S28E135 +S29E135 +S30E135 +S31E135 +S32E135 +S33E135 +S34E135 +S35E135 +S36E135 +N20E136 +N33E136 +N34E136 +N35E136 +N36E136 +N37E136 +N44E136 +N45E136 +N48E136 +N49E136 +N50E136 +N51E136 +N52E136 +N53E136 +N54E136 +N55E136 +N56E136 +N57E136 +N58E136 +N59E136 +S01E136 +S02E136 +S03E136 +S04E136 +S05E136 +S12E136 +S13E136 +S14E136 +S15E136 +S16E136 +S17E136 +S20E136 +S24E136 +S25E136 +S28E136 +S29E136 +S30E136 +S31E136 +S32E136 +S33E136 +S34E136 +S35E136 +S36E136 +S37E136 +N08E137 +N34E137 +N35E137 +N36E137 +N37E137 +N45E137 +N46E137 +N49E137 +N50E137 +N51E137 +N52E137 +N53E137 +N54E137 +N55E137 +N56E137 +N58E137 +N59E137 +S02E137 +S03E137 +S04E137 +S05E137 +S06E137 +S08E137 +S09E137 +S16E137 +S17E137 +S19E137 +S20E137 +S21E137 +S24E137 +S26E137 +S27E137 +S28E137 +S29E137 +S30E137 +S31E137 +S32E137 +S33E137 +S34E137 +S35E137 +S36E137 +S37E137 +N09E138 +N33E138 +N34E138 +N35E138 +N36E138 +N37E138 +N38E138 +N46E138 +N47E138 +N50E138 +N51E138 +N52E138 +N53E138 +N54E138 +N55E138 +N56E138 +N57E138 +N58E138 +N59E138 +S02E138 +S03E138 +S04E138 +S05E138 +S06E138 +S07E138 +S08E138 +S09E138 +S17E138 +S18E138 +S21E138 +S23E138 +S24E138 +S25E138 +S26E138 +S27E138 +S28E138 +S29E138 +S30E138 +S31E138 +S32E138 +S33E138 +S34E138 +S35E138 +S36E138 +N09E139 +N10E139 +N31E139 +N32E139 +N33E139 +N34E139 +N35E139 +N36E139 +N37E139 +N38E139 +N39E139 +N40E139 +N41E139 +N42E139 +N47E139 +N48E139 +N51E139 +N52E139 +N53E139 +N54E139 +N57E139 +N59E139 +S02E139 +S03E139 +S04E139 +S05E139 +S06E139 +S07E139 +S08E139 +S09E139 +S17E139 +S18E139 +S19E139 +S20E139 +S21E139 +S25E139 +S26E139 +S27E139 +S28E139 +S29E139 +S30E139 +S31E139 +S32E139 +S33E139 +S35E139 +S36E139 +S37E139 +S38E139 +N08E140 +N09E140 +N27E140 +N29E140 +N30E140 +N31E140 +N35E140 +N36E140 +N37E140 +N38E140 +N39E140 +N40E140 +N41E140 +N42E140 +N43E140 +N45E140 +N48E140 +N49E140 +N50E140 +N51E140 +N52E140 +N53E140 +N54E140 +N57E140 +N58E140 +S03E140 +S04E140 +S05E140 +S06E140 +S07E140 +S08E140 +S09E140 +S10E140 +S17E140 +S18E140 +S19E140 +S20E140 +S21E140 +S22E140 +S23E140 +S24E140 +S25E140 +S26E140 +S27E140 +S28E140 +S29E140 +S30E140 +S31E140 +S32E140 +S33E140 +S34E140 +S35E140 +S36E140 +S37E140 +S38E140 +S39E140 +N24E141 +N25E141 +N37E141 +N38E141 +N39E141 +N40E141 +N41E141 +N42E141 +N43E141 +N44E141 +N45E141 +N46E141 +N47E141 +N48E141 +N51E141 +N52E141 +N53E141 +N58E141 +N59E141 +S03E141 +S04E141 +S05E141 +S06E141 +S07E141 +S08E141 +S09E141 +S10E141 +S11E141 +S12E141 +S13E141 +S14E141 +S15E141 +S16E141 +S17E141 +S18E141 +S19E141 +S20E141 +S22E141 +S23E141 +S24E141 +S26E141 +S27E141 +S28E141 +S29E141 +S30E141 +S31E141 +S32E141 +S33E141 +S34E141 +S35E141 +S36E141 +S37E141 +S38E141 +S39E141 +N26E142 +N27E142 +N39E142 +N42E142 +N43E142 +N44E142 +N45E142 +N46E142 +N47E142 +N48E142 +N49E142 +N50E142 +N51E142 +N52E142 +N53E142 +N54E142 +N58E142 +N59E142 +S02E142 +S03E142 +S04E142 +S05E142 +S06E142 +S07E142 +S08E142 +S09E142 +S10E142 +S11E142 +S12E142 +S13E142 +S14E142 +S15E142 +S16E142 +S17E142 +S18E142 +S19E142 +S21E142 +S23E142 +S24E142 +S28E142 +S29E142 +S30E142 +S31E142 +S32E142 +S33E142 +S34E142 +S35E142 +S36E142 +S37E142 +S38E142 +S39E142 +N06E143 +N07E143 +N41E143 +N42E143 +N43E143 +N44E143 +N46E143 +N47E143 +N49E143 +N50E143 +N51E143 +N52E143 +N53E143 +N56E143 +N59E143 +S02E143 +S04E143 +S05E143 +S06E143 +S07E143 +S08E143 +S09E143 +S10E143 +S11E143 +S12E143 +S13E143 +S14E143 +S15E143 +S16E143 +S17E143 +S19E143 +S21E143 +S22E143 +S23E143 +S26E143 +S27E143 +S28E143 +S29E143 +S30E143 +S31E143 +S32E143 +S33E143 +S35E143 +S36E143 +S37E143 +S38E143 +S39E143 +S40E143 +S41E143 +N07E144 +N08E144 +N13E144 +N20E144 +N42E144 +N43E144 +N44E144 +N48E144 +N49E144 +N59E144 +S02E144 +S04E144 +S05E144 +S06E144 +S07E144 +S08E144 +S10E144 +S12E144 +S14E144 +S15E144 +S16E144 +S17E144 +S18E144 +S19E144 +S20E144 +S21E144 +S22E144 +S23E144 +S26E144 +S27E144 +S28E144 +S29E144 +S30E144 +S31E144 +S32E144 +S33E144 +S34E144 +S35E144 +S36E144 +S37E144 +S38E144 +S39E144 +S40E144 +S41E144 +S42E144 +N07E145 +N09E145 +N14E145 +N15E145 +N16E145 +N17E145 +N18E145 +N19E145 +N20E145 +N42E145 +N43E145 +N44E145 +N59E145 +S01E145 +S02E145 +S03E145 +S05E145 +S06E145 +S07E145 +S08E145 +S09E145 +S15E145 +S16E145 +S17E145 +S18E145 +S19E145 +S20E145 +S21E145 +S22E145 +S23E145 +S24E145 +S28E145 +S29E145 +S30E145 +S31E145 +S32E145 +S34E145 +S35E145 +S36E145 +S37E145 +S38E145 +S39E145 +S41E145 +S42E145 +S43E145 +S44E145 +N07E146 +N08E146 +N16E146 +N43E146 +N44E146 +N59E146 +S02E146 +S03E146 +S05E146 +S06E146 +S07E146 +S08E146 +S09E146 +S10E146 +S17E146 +S18E146 +S19E146 +S20E146 +S21E146 +S22E146 +S27E146 +S28E146 +S29E146 +S30E146 +S31E146 +S34E146 +S35E146 +S36E146 +S37E146 +S38E146 +S39E146 +S40E146 +S41E146 +S42E146 +S43E146 +S44E146 +N07E147 +N08E147 +N44E147 +N45E147 +N59E147 +S02E147 +S03E147 +S06E147 +S07E147 +S08E147 +S09E147 +S10E147 +S11E147 +S20E147 +S21E147 +S22E147 +S23E147 +S24E147 +S25E147 +S27E147 +S28E147 +S29E147 +S30E147 +S31E147 +S32E147 +S33E147 +S34E147 +S35E147 +S36E147 +S37E147 +S38E147 +S39E147 +S40E147 +S41E147 +S42E147 +S43E147 +S44E147 +N45E148 +N59E148 +S02E148 +S03E148 +S06E148 +S07E148 +S09E148 +S10E148 +S11E148 +S18E148 +S20E148 +S21E148 +S22E148 +S23E148 +S24E148 +S25E148 +S26E148 +S27E148 +S28E148 +S29E148 +S30E148 +S31E148 +S32E148 +S33E148 +S34E148 +S35E148 +S36E148 +S37E148 +S38E148 +S40E148 +S41E148 +S42E148 +S43E148 +S44E148 +N06E149 +N07E149 +N08E149 +N45E149 +N46E149 +N59E149 +S02E149 +S03E149 +S05E149 +S06E149 +S07E149 +S09E149 +S10E149 +S11E149 +S17E149 +S21E149 +S22E149 +S23E149 +S24E149 +S25E149 +S26E149 +S27E149 +S28E149 +S29E149 +S30E149 +S31E149 +S32E149 +S33E149 +S34E149 +S35E149 +S36E149 +S37E149 +S38E149 +N08E150 +N45E150 +N46E150 +N58E150 +N59E150 +S02E150 +S03E150 +S04E150 +S05E150 +S06E150 +S07E150 +S09E150 +S10E150 +S11E150 +S17E150 +S21E150 +S22E150 +S23E150 +S24E150 +S25E150 +S26E150 +S27E150 +S28E150 +S29E150 +S30E150 +S31E150 +S32E150 +S33E150 +S34E150 +S35E150 +S36E150 +S37E150 +S38E150 +N06E151 +N07E151 +N08E151 +N46E151 +N58E151 +N59E151 +S03E151 +S04E151 +S05E151 +S06E151 +S07E151 +S09E151 +S10E151 +S11E151 +S12E151 +S22E151 +S24E151 +S25E151 +S26E151 +S27E151 +S28E151 +S29E151 +S30E151 +S31E151 +S32E151 +S33E151 +S34E151 +S35E151 +N06E152 +N07E152 +N08E152 +N46E152 +N47E152 +N58E152 +N59E152 +S03E152 +S04E152 +S05E152 +S06E152 +S09E152 +S10E152 +S11E152 +S12E152 +S22E152 +S23E152 +S24E152 +S25E152 +S26E152 +S27E152 +S28E152 +S29E152 +S30E152 +S31E152 +S32E152 +S33E152 +N05E153 +N24E153 +N47E153 +N48E153 +N59E153 +S04E153 +S05E153 +S10E153 +S11E153 +S12E153 +S22E153 +S25E153 +S26E153 +S27E153 +S28E153 +S29E153 +S30E153 +S31E153 +S32E153 +N01E154 +N03E154 +N08E154 +N48E154 +N49E154 +N50E154 +N59E154 +S04E154 +S05E154 +S06E154 +S07E154 +S12E154 +S21E154 +S22E154 +N07E155 +N49E155 +N50E155 +N53E155 +N54E155 +N55E155 +N56E155 +N59E155 +S05E155 +S06E155 +S07E155 +S08E155 +S18E155 +S22E155 +S23E155 +S24E155 +N50E156 +N51E156 +N52E156 +N53E156 +N54E156 +N55E156 +N56E156 +N57E156 +S05E156 +S07E156 +S08E156 +S09E156 +N05E157 +N06E157 +N07E157 +N51E157 +N52E157 +N53E157 +N54E157 +N55E157 +N56E157 +N57E157 +N58E157 +S05E157 +S07E157 +S08E157 +S09E157 +N06E158 +N07E158 +N51E158 +N52E158 +N53E158 +N54E158 +N55E158 +N56E158 +N57E158 +N58E158 +S08E158 +S09E158 +S10E158 +S20E158 +S22E158 +S55E158 +S56E158 +N06E159 +N53E159 +N54E159 +N55E159 +N56E159 +N57E159 +N58E159 +N59E159 +S05E159 +S06E159 +S08E159 +S09E159 +S10E159 +S12E159 +S32E159 +N06E160 +N09E160 +N53E160 +N54E160 +N55E160 +N56E160 +N57E160 +N58E160 +N59E160 +S08E160 +S09E160 +S10E160 +S12E160 +N54E161 +N55E161 +N56E161 +N57E161 +N58E161 +N59E161 +S09E161 +S10E161 +S11E161 +N05E162 +N11E162 +N54E162 +N55E162 +N56E162 +N57E162 +N58E162 +N59E162 +S11E162 +S19E162 +N05E163 +N56E163 +N57E163 +N58E163 +N59E163 +S19E163 +S20E163 +S21E163 +N58E164 +N59E164 +S21E164 +S22E164 +N08E165 +N09E165 +N10E165 +N11E165 +N55E165 +N59E165 +S11E165 +S21E165 +S22E165 +S23E165 +S51E165 +N08E166 +N09E166 +N10E166 +N11E166 +N19E166 +N54E166 +N55E166 +N59E166 +S01E166 +S11E166 +S12E166 +S14E166 +S15E166 +S16E166 +S21E166 +S22E166 +S23E166 +S46E166 +S47E166 +S49E166 +S51E166 +N08E167 +N09E167 +N11E167 +N54E167 +S10E167 +S14E167 +S15E167 +S16E167 +S17E167 +S21E167 +S22E167 +S23E167 +S29E167 +S30E167 +S45E167 +S46E167 +S47E167 +S48E167 +N04E168 +N05E168 +N07E168 +N08E168 +N10E168 +N14E168 +N54E168 +S13E168 +S15E168 +S16E168 +S17E168 +S18E168 +S19E168 +S22E168 +S23E168 +S44E168 +S45E168 +S46E168 +S47E168 +S48E168 +S53E168 +N05E169 +N06E169 +N09E169 +N10E169 +N11E169 +N14E169 +S01E169 +S12E169 +S19E169 +S20E169 +S21E169 +S44E169 +S45E169 +S46E169 +S47E169 +S53E169 +N08E170 +N09E170 +N10E170 +N12E170 +S12E170 +S20E170 +S43E170 +S44E170 +S45E170 +S46E170 +S47E170 +N06E171 +N07E171 +N08E171 +S23E171 +S42E171 +S43E171 +S44E171 +S45E171 +S46E171 +N00E172 +N01E172 +N03E172 +N05E172 +N06E172 +N52E172 +N53E172 +S23E172 +S35E172 +S41E172 +S42E172 +S43E172 +S44E172 +N00E173 +N01E173 +N02E173 +N03E173 +N52E173 +S35E173 +S36E173 +S37E173 +S40E173 +S41E173 +S42E173 +S43E173 +S44E173 +N52E174 +S01E174 +S02E174 +S36E174 +S37E174 +S38E174 +S39E174 +S40E174 +S41E174 +S42E174 +S43E174 +N52E175 +S02E175 +S03E175 +S36E175 +S37E175 +S38E175 +S39E175 +S40E175 +S41E175 +S42E175 +S02E176 +S03E176 +S06E176 +S07E176 +S13E176 +S18E176 +S37E176 +S38E176 +S39E176 +S40E176 +S41E176 +S42E176 +N51E177 +N52E177 +S07E177 +S08E177 +S13E177 +S17E177 +S18E177 +S19E177 +S20E177 +S38E177 +S39E177 +S40E177 +N51E178 +N52E178 +S08E178 +S09E178 +S17E178 +S18E178 +S19E178 +S20E178 +S38E178 +S39E178 +S40E178 +S50E178 +N51E179 +N52E179 +S09E179 +S10E179 +S11E179 +S17E179 +S18E179 +S19E179 +S20E179 +S48E179 +N05W001 +N06W001 +N07W001 +N08W001 +N09W001 +N10W001 +N11W001 +N12W001 +N13W001 +N14W001 +N15W001 +N16W001 +N17W001 +N33W001 +N34W001 +N35W001 +N37W001 +N38W001 +N39W001 +N40W001 +N41W001 +N42W001 +N43W001 +N44W001 +N45W001 +N46W001 +N47W001 +N48W001 +N49W001 +N50W001 +N51W001 +N52W001 +N53W001 +N54W001 +N04W002 +N05W002 +N06W002 +N08W002 +N09W002 +N10W002 +N11W002 +N12W002 +N13W002 +N14W002 +N15W002 +N16W002 +N17W002 +N32W002 +N33W002 +N34W002 +N35W002 +N36W002 +N37W002 +N38W002 +N39W002 +N40W002 +N41W002 +N42W002 +N43W002 +N44W002 +N45W002 +N46W002 +N47W002 +N48W002 +N49W002 +N50W002 +N51W002 +N52W002 +N53W002 +N54W002 +N55W002 +N57W002 +N59W002 +N04W003 +N05W003 +N08W003 +N09W003 +N10W003 +N11W003 +N12W003 +N13W003 +N15W003 +N16W003 +N31W003 +N32W003 +N34W003 +N35W003 +N36W003 +N37W003 +N38W003 +N39W003 +N40W003 +N41W003 +N42W003 +N43W003 +N46W003 +N47W003 +N48W003 +N49W003 +N50W003 +N51W003 +N52W003 +N53W003 +N54W003 +N55W003 +N56W003 +N57W003 +N58W003 +N59W003 +N05W004 +N06W004 +N07W004 +N10W004 +N11W004 +N12W004 +N13W004 +N14W004 +N15W004 +N16W004 +N35W004 +N36W004 +N37W004 +N38W004 +N39W004 +N40W004 +N41W004 +N42W004 +N43W004 +N47W004 +N48W004 +N50W004 +N51W004 +N52W004 +N53W004 +N54W004 +N55W004 +N56W004 +N57W004 +N58W004 +N59W004 +N05W005 +N06W005 +N07W005 +N08W005 +N10W005 +N11W005 +N12W005 +N13W005 +N14W005 +N15W005 +N31W005 +N32W005 +N33W005 +N34W005 +N35W005 +N36W005 +N37W005 +N38W005 +N39W005 +N40W005 +N41W005 +N42W005 +N43W005 +N47W005 +N48W005 +N50W005 +N51W005 +N52W005 +N53W005 +N54W005 +N55W005 +N56W005 +N57W005 +N58W005 +N59W005 +N04W006 +N05W006 +N06W006 +N07W006 +N08W006 +N09W006 +N10W006 +N11W006 +N12W006 +N13W006 +N14W006 +N31W006 +N32W006 +N33W006 +N34W006 +N35W006 +N36W006 +N37W006 +N38W006 +N39W006 +N40W006 +N41W006 +N42W006 +N43W006 +N48W006 +N49W006 +N50W006 +N51W006 +N52W006 +N53W006 +N54W006 +N55W006 +N56W006 +N57W006 +N58W006 +N59W006 +S16W006 +S17W006 +N04W007 +N05W007 +N06W007 +N07W007 +N08W007 +N09W007 +N10W007 +N12W007 +N13W007 +N14W007 +N30W007 +N31W007 +N32W007 +N33W007 +N34W007 +N35W007 +N36W007 +N37W007 +N38W007 +N39W007 +N40W007 +N41W007 +N42W007 +N43W007 +N49W007 +N52W007 +N53W007 +N54W007 +N55W007 +N56W007 +N57W007 +N58W007 +N59W007 +N04W008 +N05W008 +N06W008 +N07W008 +N08W008 +N12W008 +N13W008 +N15W008 +N30W008 +N31W008 +N32W008 +N33W008 +N36W008 +N37W008 +N38W008 +N39W008 +N40W008 +N41W008 +N42W008 +N43W008 +N51W008 +N52W008 +N53W008 +N54W008 +N55W008 +N56W008 +N57W008 +N58W008 +N04W009 +N07W009 +N11W009 +N12W009 +N13W009 +N30W009 +N31W009 +N32W009 +N33W009 +N36W009 +N37W009 +N38W009 +N39W009 +N40W009 +N41W009 +N42W009 +N43W009 +N51W009 +N52W009 +N53W009 +N54W009 +N55W009 +N57W009 +N04W010 +N05W010 +N06W010 +N07W010 +N09W010 +N10W010 +N11W010 +N13W010 +N29W010 +N30W010 +N31W010 +N32W010 +N38W010 +N39W010 +N42W010 +N43W010 +N51W010 +N52W010 +N53W010 +N54W010 +S41W010 +N05W011 +N06W011 +N07W011 +N08W011 +N10W011 +N11W011 +N12W011 +N13W011 +N14W011 +N15W011 +N28W011 +N29W011 +N51W011 +N52W011 +N53W011 +N54W011 +S41W011 +N06W012 +N07W012 +N08W012 +N09W012 +N11W012 +N13W012 +N14W012 +N15W012 +N28W012 +N07W013 +N08W013 +N09W013 +N10W013 +N11W013 +N13W013 +N14W013 +N15W013 +N16W013 +N17W013 +N18W013 +N27W013 +N28W013 +S38W013 +N07W014 +N08W014 +N09W014 +N10W014 +N11W014 +N12W014 +N13W014 +N15W014 +N16W014 +N17W014 +N26W014 +N27W014 +N28W014 +N29W014 +N57W014 +N09W015 +N10W015 +N11W015 +N12W015 +N13W015 +N16W015 +N17W015 +N24W015 +N25W015 +N26W015 +N28W015 +S08W015 +N10W016 +N11W016 +N12W016 +N13W016 +N14W016 +N15W016 +N16W016 +N23W016 +N24W016 +N27W016 +N28W016 +N30W016 +N11W017 +N12W017 +N13W017 +N14W017 +N15W017 +N16W017 +N17W017 +N18W017 +N19W017 +N20W017 +N21W017 +N22W017 +N23W017 +N27W017 +N28W017 +N30W017 +N32W017 +N33W017 +N14W018 +N15W018 +N20W018 +N21W018 +N27W018 +N28W018 +N32W018 +N27W019 +N28W019 +N15W023 +N16W023 +N14W024 +N15W024 +N14W025 +N15W025 +N16W025 +N17W025 +N37W025 +N16W026 +N17W026 +N36W026 +N37W026 +N38W028 +N39W028 +N38W029 +N39W029 +S21W029 +S21W030 +N39W032 +S04W033 +S04W034 +S07W035 +S08W035 +S09W035 +S56W035 +S06W036 +S07W036 +S08W036 +S09W036 +S10W036 +S55W036 +S05W037 +S06W037 +S07W037 +S08W037 +S09W037 +S10W037 +S11W037 +S55W037 +S05W038 +S06W038 +S07W038 +S08W038 +S09W038 +S10W038 +S11W038 +S12W038 +S13W038 +S54W038 +S55W038 +S04W039 +S05W039 +S06W039 +S07W039 +S08W039 +S09W039 +S10W039 +S11W039 +S12W039 +S13W039 +S14W039 +S15W039 +S16W039 +S17W039 +S18W039 +S54W039 +S55W039 +S03W040 +S04W040 +S05W040 +S06W040 +S07W040 +S08W040 +S09W040 +S10W040 +S11W040 +S12W040 +S13W040 +S14W040 +S15W040 +S16W040 +S17W040 +S18W040 +S19W040 +S20W040 +S03W041 +S04W041 +S05W041 +S06W041 +S07W041 +S08W041 +S09W041 +S10W041 +S11W041 +S12W041 +S13W041 +S14W041 +S15W041 +S16W041 +S17W041 +S18W041 +S19W041 +S20W041 +S21W041 +S22W041 +S23W041 +S03W042 +S04W042 +S05W042 +S06W042 +S07W042 +S08W042 +S09W042 +S10W042 +S11W042 +S12W042 +S13W042 +S14W042 +S15W042 +S16W042 +S17W042 +S18W042 +S19W042 +S20W042 +S21W042 +S22W042 +S23W042 +S24W042 +S03W043 +S04W043 +S05W043 +S06W043 +S07W043 +S08W043 +S09W043 +S10W043 +S11W043 +S12W043 +S13W043 +S14W043 +S15W043 +S16W043 +S17W043 +S18W043 +S19W043 +S20W043 +S21W043 +S22W043 +S23W043 +S24W043 +N59W044 +S03W044 +S04W044 +S05W044 +S06W044 +S07W044 +S08W044 +S09W044 +S10W044 +S11W044 +S12W044 +S13W044 +S14W044 +S15W044 +S16W044 +S17W044 +S18W044 +S19W044 +S20W044 +S21W044 +S22W044 +S23W044 +S24W044 +N59W045 +S02W045 +S03W045 +S04W045 +S05W045 +S06W045 +S07W045 +S08W045 +S09W045 +S10W045 +S11W045 +S12W045 +S13W045 +S14W045 +S15W045 +S16W045 +S17W045 +S18W045 +S19W045 +S20W045 +S21W045 +S22W045 +S23W045 +S24W045 +N59W046 +S02W046 +S03W046 +S04W046 +S05W046 +S06W046 +S08W046 +S10W046 +S11W046 +S12W046 +S13W046 +S14W046 +S15W046 +S16W046 +S17W046 +S18W046 +S19W046 +S20W046 +S21W046 +S22W046 +S23W046 +S24W046 +S25W046 +S01W047 +S02W047 +S03W047 +S04W047 +S05W047 +S06W047 +S07W047 +S08W047 +S11W047 +S12W047 +S13W047 +S14W047 +S15W047 +S16W047 +S17W047 +S18W047 +S19W047 +S20W047 +S21W047 +S22W047 +S23W047 +S24W047 +S25W047 +S01W048 +S02W048 +S03W048 +S04W048 +S05W048 +S06W048 +S07W048 +S08W048 +S09W048 +S10W048 +S11W048 +S12W048 +S13W048 +S14W048 +S15W048 +S16W048 +S17W048 +S18W048 +S19W048 +S20W048 +S21W048 +S22W048 +S23W048 +S24W048 +S25W048 +S26W048 +S01W049 +S02W049 +S03W049 +S04W049 +S05W049 +S06W049 +S07W049 +S08W049 +S09W049 +S10W049 +S11W049 +S12W049 +S13W049 +S14W049 +S15W049 +S16W049 +S17W049 +S18W049 +S19W049 +S20W049 +S21W049 +S22W049 +S23W049 +S24W049 +S25W049 +S26W049 +S27W049 +S28W049 +S29W049 +N00W050 +N01W050 +S01W050 +S02W050 +S03W050 +S04W050 +S05W050 +S06W050 +S07W050 +S08W050 +S09W050 +S10W050 +S11W050 +S12W050 +S13W050 +S14W050 +S15W050 +S16W050 +S17W050 +S18W050 +S19W050 +S20W050 +S21W050 +S22W050 +S23W050 +S24W050 +S25W050 +S26W050 +S27W050 +S28W050 +S29W050 +S30W050 +N00W051 +N01W051 +N02W051 +N03W051 +S01W051 +S02W051 +S03W051 +S04W051 +S06W051 +S07W051 +S08W051 +S09W051 +S10W051 +S11W051 +S12W051 +S13W051 +S14W051 +S15W051 +S16W051 +S17W051 +S18W051 +S19W051 +S20W051 +S21W051 +S22W051 +S23W051 +S24W051 +S25W051 +S26W051 +S27W051 +S28W051 +S29W051 +S30W051 +S31W051 +S32W051 +N00W052 +N01W052 +N02W052 +N03W052 +N04W052 +S01W052 +S02W052 +S03W052 +S04W052 +S05W052 +S07W052 +S08W052 +S09W052 +S10W052 +S11W052 +S12W052 +S13W052 +S14W052 +S15W052 +S16W052 +S17W052 +S18W052 +S20W052 +S21W052 +S22W052 +S23W052 +S24W052 +S25W052 +S26W052 +S27W052 +S28W052 +S29W052 +S30W052 +S31W052 +S32W052 +S33W052 +N00W053 +N01W053 +N02W053 +N03W053 +N04W053 +N05W053 +N46W053 +N47W053 +N48W053 +S01W053 +S02W053 +S03W053 +S04W053 +S05W053 +S06W053 +S07W053 +S08W053 +S09W053 +S10W053 +S11W053 +S12W053 +S13W053 +S14W053 +S15W053 +S16W053 +S18W053 +S19W053 +S20W053 +S21W053 +S22W053 +S23W053 +S24W053 +S25W053 +S26W053 +S27W053 +S28W053 +S29W053 +S30W053 +S31W053 +S32W053 +S33W053 +S34W053 +N00W054 +N01W054 +N03W054 +N04W054 +N05W054 +N46W054 +N47W054 +N48W054 +N49W054 +S01W054 +S02W054 +S03W054 +S04W054 +S05W054 +S07W054 +S08W054 +S09W054 +S10W054 +S11W054 +S12W054 +S13W054 +S14W054 +S15W054 +S16W054 +S17W054 +S18W054 +S19W054 +S20W054 +S21W054 +S22W054 +S23W054 +S24W054 +S25W054 +S26W054 +S27W054 +S28W054 +S29W054 +S30W054 +S31W054 +S32W054 +S33W054 +S34W054 +S35W054 +N00W055 +N01W055 +N03W055 +N04W055 +N05W055 +N46W055 +N47W055 +N48W055 +N49W055 +S02W055 +S03W055 +S04W055 +S05W055 +S06W055 +S07W055 +S08W055 +S10W055 +S11W055 +S12W055 +S13W055 +S14W055 +S15W055 +S16W055 +S17W055 +S18W055 +S19W055 +S20W055 +S21W055 +S22W055 +S23W055 +S24W055 +S25W055 +S26W055 +S27W055 +S28W055 +S29W055 +S30W055 +S31W055 +S32W055 +S33W055 +S34W055 +S35W055 +N00W056 +N02W056 +N03W056 +N04W056 +N05W056 +N06W056 +N46W056 +N47W056 +N48W056 +N49W056 +N50W056 +N51W056 +N52W056 +N53W056 +S02W056 +S03W056 +S04W056 +S05W056 +S06W056 +S07W056 +S08W056 +S10W056 +S11W056 +S12W056 +S13W056 +S14W056 +S15W056 +S16W056 +S17W056 +S18W056 +S19W056 +S20W056 +S21W056 +S22W056 +S23W056 +S25W056 +S26W056 +S27W056 +S28W056 +S29W056 +S30W056 +S31W056 +S32W056 +S33W056 +S34W056 +S35W056 +N00W057 +N04W057 +N05W057 +N06W057 +N46W057 +N47W057 +N48W057 +N49W057 +N50W057 +N51W057 +N52W057 +N53W057 +N54W057 +S01W057 +S02W057 +S03W057 +S04W057 +S05W057 +S06W057 +S07W057 +S10W057 +S11W057 +S12W057 +S13W057 +S14W057 +S15W057 +S16W057 +S17W057 +S18W057 +S19W057 +S20W057 +S21W057 +S22W057 +S23W057 +S24W057 +S25W057 +S26W057 +S27W057 +S28W057 +S29W057 +S30W057 +S31W057 +S32W057 +S33W057 +S34W057 +S35W057 +S37W057 +S38W057 +N00W058 +N01W058 +N02W058 +N03W058 +N04W058 +N05W058 +N06W058 +N47W058 +N48W058 +N49W058 +N50W058 +N51W058 +N52W058 +N53W058 +N54W058 +S01W058 +S02W058 +S03W058 +S04W058 +S05W058 +S06W058 +S07W058 +S08W058 +S09W058 +S10W058 +S11W058 +S12W058 +S13W058 +S14W058 +S15W058 +S16W058 +S17W058 +S18W058 +S19W058 +S20W058 +S21W058 +S22W058 +S23W058 +S24W058 +S25W058 +S26W058 +S27W058 +S28W058 +S29W058 +S30W058 +S31W058 +S32W058 +S33W058 +S34W058 +S35W058 +S36W058 +S37W058 +S38W058 +S39W058 +S52W058 +N00W059 +N02W059 +N03W059 +N04W059 +N05W059 +N06W059 +N07W059 +N47W059 +N48W059 +N49W059 +N50W059 +N51W059 +N52W059 +N53W059 +N54W059 +N55W059 +S01W059 +S02W059 +S03W059 +S04W059 +S05W059 +S06W059 +S07W059 +S08W059 +S09W059 +S10W059 +S11W059 +S12W059 +S13W059 +S14W059 +S15W059 +S16W059 +S17W059 +S18W059 +S19W059 +S20W059 +S21W059 +S22W059 +S23W059 +S24W059 +S25W059 +S26W059 +S27W059 +S28W059 +S29W059 +S30W059 +S31W059 +S32W059 +S33W059 +S34W059 +S35W059 +S36W059 +S37W059 +S38W059 +S39W059 +S52W059 +S53W059 +N00W060 +N02W060 +N03W060 +N05W060 +N06W060 +N07W060 +N08W060 +N13W060 +N43W060 +N44W060 +N45W060 +N46W060 +N47W060 +N48W060 +N50W060 +N51W060 +N52W060 +N53W060 +N54W060 +N55W060 +S01W060 +S02W060 +S03W060 +S04W060 +S05W060 +S06W060 +S07W060 +S09W060 +S10W060 +S11W060 +S12W060 +S13W060 +S14W060 +S15W060 +S16W060 +S17W060 +S19W060 +S21W060 +S22W060 +S23W060 +S24W060 +S25W060 +S26W060 +S27W060 +S28W060 +S29W060 +S30W060 +S31W060 +S32W060 +S33W060 +S34W060 +S35W060 +S36W060 +S37W060 +S38W060 +S39W060 +S52W060 +S53W060 +N00W061 +N01W061 +N02W061 +N03W061 +N05W061 +N06W061 +N07W061 +N08W061 +N09W061 +N10W061 +N11W061 +N13W061 +N14W061 +N43W061 +N45W061 +N46W061 +N47W061 +N50W061 +N51W061 +N52W061 +N53W061 +N54W061 +N55W061 +N56W061 +S01W061 +S02W061 +S03W061 +S04W061 +S05W061 +S06W061 +S07W061 +S08W061 +S09W061 +S10W061 +S11W061 +S12W061 +S13W061 +S14W061 +S16W061 +S17W061 +S18W061 +S20W061 +S24W061 +S25W061 +S26W061 +S27W061 +S28W061 +S29W061 +S30W061 +S31W061 +S32W061 +S33W061 +S34W061 +S35W061 +S36W061 +S37W061 +S38W061 +S39W061 +S52W061 +S53W061 +N00W062 +N01W062 +N02W062 +N03W062 +N04W062 +N05W062 +N06W062 +N07W062 +N08W062 +N09W062 +N10W062 +N11W062 +N12W062 +N13W062 +N14W062 +N15W062 +N16W062 +N17W062 +N44W062 +N45W062 +N46W062 +N47W062 +N49W062 +N50W062 +N51W062 +N52W062 +N53W062 +N54W062 +N55W062 +N56W062 +N57W062 +S01W062 +S02W062 +S03W062 +S04W062 +S05W062 +S06W062 +S07W062 +S08W062 +S09W062 +S10W062 +S11W062 +S12W062 +S13W062 +S14W062 +S15W062 +S16W062 +S17W062 +S18W062 +S22W062 +S23W062 +S24W062 +S25W062 +S26W062 +S27W062 +S28W062 +S29W062 +S30W062 +S31W062 +S32W062 +S33W062 +S34W062 +S35W062 +S36W062 +S37W062 +S38W062 +S39W062 +S40W062 +S51W062 +S52W062 +S53W062 +N00W063 +N01W063 +N03W063 +N04W063 +N05W063 +N06W063 +N07W063 +N08W063 +N09W063 +N10W063 +N16W063 +N17W063 +N18W063 +N44W063 +N45W063 +N46W063 +N47W063 +N49W063 +N50W063 +N51W063 +N52W063 +N53W063 +N54W063 +N55W063 +N56W063 +N57W063 +N58W063 +S01W063 +S02W063 +S03W063 +S04W063 +S05W063 +S06W063 +S07W063 +S08W063 +S09W063 +S10W063 +S11W063 +S12W063 +S13W063 +S14W063 +S15W063 +S16W063 +S17W063 +S18W063 +S19W063 +S20W063 +S22W063 +S23W063 +S24W063 +S25W063 +S27W063 +S28W063 +S29W063 +S30W063 +S31W063 +S32W063 +S33W063 +S34W063 +S35W063 +S36W063 +S37W063 +S38W063 +S39W063 +S40W063 +S41W063 +S42W063 +N00W064 +N01W064 +N03W064 +N05W064 +N06W064 +N07W064 +N08W064 +N09W064 +N10W064 +N11W064 +N15W064 +N17W064 +N18W064 +N44W064 +N45W064 +N46W064 +N47W064 +N49W064 +N50W064 +N51W064 +N52W064 +N53W064 +N54W064 +N55W064 +N56W064 +N57W064 +N58W064 +N59W064 +S01W064 +S02W064 +S03W064 +S04W064 +S05W064 +S06W064 +S07W064 +S08W064 +S09W064 +S10W064 +S13W064 +S14W064 +S15W064 +S16W064 +S17W064 +S18W064 +S19W064 +S20W064 +S21W064 +S22W064 +S23W064 +S24W064 +S25W064 +S26W064 +S27W064 +S28W064 +S29W064 +S30W064 +S31W064 +S32W064 +S33W064 +S34W064 +S35W064 +S36W064 +S37W064 +S38W064 +S39W064 +S40W064 +S41W064 +S42W064 +S43W064 +S55W064 +N04W065 +N05W065 +N06W065 +N07W065 +N08W065 +N09W065 +N10W065 +N11W065 +N17W065 +N18W065 +N32W065 +N43W065 +N44W065 +N45W065 +N46W065 +N47W065 +N48W065 +N49W065 +N50W065 +N51W065 +N52W065 +N53W065 +N54W065 +N55W065 +N56W065 +N57W065 +N58W065 +N59W065 +S01W065 +S02W065 +S03W065 +S04W065 +S05W065 +S06W065 +S07W065 +S08W065 +S09W065 +S10W065 +S12W065 +S13W065 +S14W065 +S15W065 +S16W065 +S17W065 +S18W065 +S19W065 +S21W065 +S22W065 +S23W065 +S24W065 +S25W065 +S26W065 +S27W065 +S28W065 +S29W065 +S30W065 +S31W065 +S32W065 +S33W065 +S34W065 +S35W065 +S36W065 +S37W065 +S38W065 +S39W065 +S40W065 +S41W065 +S42W065 +S43W065 +S44W065 +S55W065 +N01W066 +N02W066 +N03W066 +N04W066 +N05W066 +N07W066 +N08W066 +N09W066 +N10W066 +N17W066 +N18W066 +N43W066 +N44W066 +N45W066 +N46W066 +N47W066 +N48W066 +N49W066 +N50W066 +N51W066 +N52W066 +N53W066 +N54W066 +N55W066 +N56W066 +N57W066 +N58W066 +N59W066 +S01W066 +S02W066 +S03W066 +S04W066 +S05W066 +S06W066 +S07W066 +S08W066 +S09W066 +S10W066 +S11W066 +S12W066 +S13W066 +S14W066 +S15W066 +S16W066 +S17W066 +S18W066 +S19W066 +S20W066 +S21W066 +S22W066 +S23W066 +S24W066 +S25W066 +S26W066 +S27W066 +S28W066 +S29W066 +S30W066 +S31W066 +S32W066 +S33W066 +S34W066 +S35W066 +S36W066 +S37W066 +S38W066 +S39W066 +S40W066 +S41W066 +S42W066 +S43W066 +S44W066 +S45W066 +S46W066 +S48W066 +S49W066 +S55W066 +N00W067 +N01W067 +N02W067 +N03W067 +N04W067 +N05W067 +N06W067 +N07W067 +N08W067 +N09W067 +N10W067 +N11W067 +N17W067 +N18W067 +N43W067 +N44W067 +N45W067 +N46W067 +N47W067 +N48W067 +N49W067 +N50W067 +N51W067 +N52W067 +N53W067 +N54W067 +N55W067 +N56W067 +N57W067 +N58W067 +N59W067 +S01W067 +S02W067 +S03W067 +S04W067 +S05W067 +S06W067 +S07W067 +S08W067 +S09W067 +S10W067 +S11W067 +S12W067 +S13W067 +S14W067 +S15W067 +S16W067 +S17W067 +S18W067 +S19W067 +S20W067 +S21W067 +S22W067 +S23W067 +S24W067 +S25W067 +S26W067 +S27W067 +S28W067 +S30W067 +S31W067 +S32W067 +S33W067 +S34W067 +S35W067 +S36W067 +S37W067 +S38W067 +S39W067 +S40W067 +S41W067 +S42W067 +S43W067 +S44W067 +S45W067 +S46W067 +S47W067 +S48W067 +S49W067 +S55W067 +S56W067 +N00W068 +N01W068 +N02W068 +N03W068 +N04W068 +N05W068 +N06W068 +N07W068 +N08W068 +N09W068 +N10W068 +N11W068 +N17W068 +N18W068 +N44W068 +N45W068 +N46W068 +N47W068 +N48W068 +N49W068 +N50W068 +N51W068 +N52W068 +N53W068 +N54W068 +N55W068 +N56W068 +N57W068 +N58W068 +S01W068 +S02W068 +S03W068 +S04W068 +S05W068 +S06W068 +S07W068 +S08W068 +S09W068 +S10W068 +S11W068 +S12W068 +S13W068 +S14W068 +S15W068 +S16W068 +S17W068 +S18W068 +S19W068 +S20W068 +S21W068 +S22W068 +S23W068 +S24W068 +S25W068 +S26W068 +S27W068 +S28W068 +S29W068 +S31W068 +S33W068 +S34W068 +S35W068 +S36W068 +S37W068 +S38W068 +S39W068 +S40W068 +S41W068 +S42W068 +S43W068 +S44W068 +S45W068 +S46W068 +S47W068 +S48W068 +S49W068 +S50W068 +S51W068 +S54W068 +S55W068 +S56W068 +N00W069 +N01W069 +N02W069 +N03W069 +N04W069 +N05W069 +N06W069 +N07W069 +N08W069 +N09W069 +N10W069 +N11W069 +N12W069 +N18W069 +N19W069 +N43W069 +N44W069 +N45W069 +N46W069 +N47W069 +N48W069 +N49W069 +N50W069 +N51W069 +N52W069 +N53W069 +N54W069 +N55W069 +N56W069 +N57W069 +N58W069 +N59W069 +S01W069 +S02W069 +S03W069 +S04W069 +S05W069 +S06W069 +S07W069 +S08W069 +S09W069 +S10W069 +S11W069 +S12W069 +S13W069 +S14W069 +S16W069 +S17W069 +S18W069 +S19W069 +S20W069 +S21W069 +S22W069 +S23W069 +S24W069 +S25W069 +S26W069 +S27W069 +S28W069 +S29W069 +S30W069 +S31W069 +S32W069 +S33W069 +S34W069 +S35W069 +S36W069 +S37W069 +S38W069 +S39W069 +S40W069 +S41W069 +S42W069 +S43W069 +S44W069 +S45W069 +S46W069 +S47W069 +S48W069 +S49W069 +S50W069 +S51W069 +S52W069 +S53W069 +S54W069 +S55W069 +S56W069 +N00W070 +N01W070 +N02W070 +N03W070 +N04W070 +N05W070 +N06W070 +N07W070 +N08W070 +N09W070 +N10W070 +N11W070 +N12W070 +N18W070 +N19W070 +N41W070 +N43W070 +N44W070 +N45W070 +N46W070 +N47W070 +N48W070 +N49W070 +N50W070 +N51W070 +N52W070 +N53W070 +N54W070 +N55W070 +N56W070 +N57W070 +N58W070 +N59W070 +S01W070 +S02W070 +S03W070 +S04W070 +S05W070 +S07W070 +S08W070 +S09W070 +S10W070 +S12W070 +S13W070 +S14W070 +S15W070 +S16W070 +S17W070 +S18W070 +S19W070 +S20W070 +S23W070 +S24W070 +S25W070 +S27W070 +S28W070 +S29W070 +S30W070 +S31W070 +S32W070 +S33W070 +S35W070 +S36W070 +S37W070 +S38W070 +S39W070 +S40W070 +S41W070 +S42W070 +S43W070 +S44W070 +S45W070 +S46W070 +S47W070 +S48W070 +S49W070 +S50W070 +S51W070 +S52W070 +S53W070 +S54W070 +S55W070 +S56W070 +N00W071 +N01W071 +N02W071 +N03W071 +N04W071 +N05W071 +N06W071 +N07W071 +N08W071 +N09W071 +N10W071 +N11W071 +N12W071 +N18W071 +N19W071 +N41W071 +N42W071 +N43W071 +N44W071 +N45W071 +N46W071 +N47W071 +N48W071 +N49W071 +N50W071 +N51W071 +N52W071 +N53W071 +N54W071 +N55W071 +N56W071 +N57W071 +N58W071 +N59W071 +S01W071 +S02W071 +S03W071 +S04W071 +S05W071 +S06W071 +S07W071 +S08W071 +S09W071 +S10W071 +S11W071 +S12W071 +S13W071 +S14W071 +S15W071 +S16W071 +S17W071 +S18W071 +S19W071 +S20W071 +S21W071 +S22W071 +S23W071 +S24W071 +S25W071 +S26W071 +S27W071 +S28W071 +S31W071 +S32W071 +S33W071 +S34W071 +S35W071 +S36W071 +S37W071 +S38W071 +S39W071 +S40W071 +S41W071 +S42W071 +S43W071 +S44W071 +S45W071 +S46W071 +S47W071 +S48W071 +S49W071 +S50W071 +S51W071 +S52W071 +S53W071 +S54W071 +S55W071 +S56W071 +N00W072 +N01W072 +N02W072 +N04W072 +N05W072 +N06W072 +N07W072 +N08W072 +N09W072 +N10W072 +N11W072 +N12W072 +N17W072 +N18W072 +N19W072 +N21W072 +N41W072 +N42W072 +N43W072 +N44W072 +N45W072 +N46W072 +N47W072 +N48W072 +N49W072 +N50W072 +N51W072 +N52W072 +N53W072 +N54W072 +N55W072 +N56W072 +N57W072 +N58W072 +N59W072 +S01W072 +S02W072 +S03W072 +S04W072 +S05W072 +S06W072 +S07W072 +S08W072 +S11W072 +S12W072 +S13W072 +S14W072 +S15W072 +S16W072 +S17W072 +S18W072 +S28W072 +S29W072 +S30W072 +S31W072 +S32W072 +S33W072 +S34W072 +S35W072 +S36W072 +S37W072 +S38W072 +S39W072 +S40W072 +S41W072 +S42W072 +S43W072 +S44W072 +S45W072 +S46W072 +S47W072 +S48W072 +S49W072 +S50W072 +S51W072 +S52W072 +S53W072 +S54W072 +S55W072 +S56W072 +N00W073 +N01W073 +N02W073 +N03W073 +N04W073 +N05W073 +N06W073 +N07W073 +N08W073 +N09W073 +N10W073 +N11W073 +N12W073 +N18W073 +N19W073 +N20W073 +N21W073 +N22W073 +N40W073 +N41W073 +N42W073 +N43W073 +N44W073 +N45W073 +N46W073 +N47W073 +N48W073 +N49W073 +N50W073 +N51W073 +N52W073 +N53W073 +N54W073 +N55W073 +N56W073 +N57W073 +N58W073 +N59W073 +S01W073 +S02W073 +S03W073 +S04W073 +S05W073 +S06W073 +S08W073 +S09W073 +S10W073 +S12W073 +S13W073 +S14W073 +S15W073 +S16W073 +S17W073 +S18W073 +S35W073 +S36W073 +S37W073 +S38W073 +S39W073 +S40W073 +S41W073 +S42W073 +S43W073 +S44W073 +S45W073 +S46W073 +S47W073 +S48W073 +S49W073 +S50W073 +S51W073 +S52W073 +S53W073 +S54W073 +S55W073 +N00W074 +N02W074 +N03W074 +N04W074 +N05W074 +N06W074 +N07W074 +N08W074 +N09W074 +N10W074 +N11W074 +N18W074 +N19W074 +N20W074 +N21W074 +N22W074 +N23W074 +N40W074 +N41W074 +N42W074 +N43W074 +N44W074 +N45W074 +N46W074 +N47W074 +N48W074 +N49W074 +N50W074 +N51W074 +N52W074 +N53W074 +N54W074 +N55W074 +N56W074 +N57W074 +N58W074 +N59W074 +S01W074 +S02W074 +S03W074 +S04W074 +S05W074 +S06W074 +S08W074 +S10W074 +S11W074 +S12W074 +S13W074 +S14W074 +S15W074 +S16W074 +S17W074 +S37W074 +S38W074 +S39W074 +S40W074 +S41W074 +S42W074 +S43W074 +S44W074 +S45W074 +S46W074 +S47W074 +S48W074 +S49W074 +S50W074 +S51W074 +S52W074 +S53W074 +S54W074 +S55W074 +N00W075 +N01W075 +N02W075 +N03W075 +N04W075 +N05W075 +N06W075 +N07W075 +N08W075 +N09W075 +N10W075 +N11W075 +N18W075 +N19W075 +N20W075 +N22W075 +N23W075 +N24W075 +N38W075 +N39W075 +N40W075 +N41W075 +N42W075 +N43W075 +N44W075 +N45W075 +N46W075 +N47W075 +N48W075 +N49W075 +N50W075 +N51W075 +N52W075 +N53W075 +N54W075 +N55W075 +N56W075 +N57W075 +N58W075 +N59W075 +S01W075 +S02W075 +S03W075 +S04W075 +S05W075 +S06W075 +S07W075 +S08W075 +S09W075 +S10W075 +S11W075 +S12W075 +S13W075 +S14W075 +S15W075 +S16W075 +S17W075 +S42W075 +S43W075 +S44W075 +S45W075 +S46W075 +S47W075 +S48W075 +S49W075 +S50W075 +S51W075 +S52W075 +S53W075 +S54W075 +N00W076 +N01W076 +N02W076 +N03W076 +N04W076 +N05W076 +N06W076 +N07W076 +N08W076 +N09W076 +N10W076 +N17W076 +N18W076 +N19W076 +N20W076 +N21W076 +N22W076 +N23W076 +N24W076 +N35W076 +N36W076 +N37W076 +N38W076 +N39W076 +N40W076 +N41W076 +N42W076 +N43W076 +N44W076 +N45W076 +N46W076 +N47W076 +N48W076 +N49W076 +N50W076 +N51W076 +N52W076 +N53W076 +N54W076 +N55W076 +N56W076 +N57W076 +N58W076 +N59W076 +S01W076 +S02W076 +S03W076 +S04W076 +S05W076 +S06W076 +S07W076 +S08W076 +S09W076 +S10W076 +S11W076 +S12W076 +S13W076 +S14W076 +S15W076 +S16W076 +S45W076 +S46W076 +S47W076 +S48W076 +S49W076 +S50W076 +S51W076 +S52W076 +S53W076 +N00W077 +N01W077 +N02W077 +N03W077 +N04W077 +N05W077 +N06W077 +N07W077 +N08W077 +N09W077 +N17W077 +N18W077 +N19W077 +N20W077 +N21W077 +N23W077 +N24W077 +N25W077 +N26W077 +N34W077 +N35W077 +N36W077 +N37W077 +N38W077 +N39W077 +N40W077 +N41W077 +N42W077 +N43W077 +N44W077 +N45W077 +N46W077 +N47W077 +N48W077 +N49W077 +N50W077 +N51W077 +N52W077 +N53W077 +N54W077 +N55W077 +N56W077 +N57W077 +N58W077 +N59W077 +S01W077 +S02W077 +S03W077 +S04W077 +S05W077 +S06W077 +S07W077 +S08W077 +S09W077 +S10W077 +S11W077 +S12W077 +S13W077 +S14W077 +S15W077 +N00W078 +N01W078 +N02W078 +N03W078 +N04W078 +N05W078 +N06W078 +N07W078 +N08W078 +N09W078 +N17W078 +N18W078 +N19W078 +N20W078 +N21W078 +N22W078 +N23W078 +N24W078 +N25W078 +N26W078 +N27W078 +N33W078 +N34W078 +N35W078 +N36W078 +N37W078 +N38W078 +N39W078 +N40W078 +N41W078 +N42W078 +N43W078 +N44W078 +N45W078 +N46W078 +N47W078 +N48W078 +N49W078 +N50W078 +N51W078 +N52W078 +N53W078 +N54W078 +N55W078 +N56W078 +N57W078 +N58W078 +N59W078 +S01W078 +S02W078 +S03W078 +S04W078 +S05W078 +S06W078 +S07W078 +S08W078 +S09W078 +S10W078 +S11W078 +S12W078 +S13W078 +N00W079 +N01W079 +N02W079 +N03W079 +N07W079 +N08W079 +N09W079 +N15W079 +N18W079 +N20W079 +N21W079 +N22W079 +N24W079 +N25W079 +N26W079 +N27W079 +N33W079 +N34W079 +N35W079 +N36W079 +N37W079 +N38W079 +N39W079 +N40W079 +N41W079 +N42W079 +N43W079 +N44W079 +N45W079 +N46W079 +N47W079 +N48W079 +N49W079 +N50W079 +N51W079 +N52W079 +N53W079 +N54W079 +N55W079 +N56W079 +N57W079 +N58W079 +N59W079 +S01W079 +S02W079 +S03W079 +S04W079 +S05W079 +S06W079 +S07W079 +S08W079 +S09W079 +S10W079 +S11W079 +S34W079 +N00W080 +N01W080 +N07W080 +N08W080 +N09W080 +N15W080 +N19W080 +N20W080 +N21W080 +N22W080 +N23W080 +N24W080 +N25W080 +N26W080 +N32W080 +N33W080 +N34W080 +N35W080 +N36W080 +N37W080 +N38W080 +N39W080 +N40W080 +N41W080 +N42W080 +N43W080 +N44W080 +N45W080 +N46W080 +N47W080 +N48W080 +N49W080 +N50W080 +N51W080 +N52W080 +N53W080 +N54W080 +N55W080 +N56W080 +N57W080 +N58W080 +N59W080 +S01W080 +S02W080 +S03W080 +S04W080 +S05W080 +S06W080 +S07W080 +S08W080 +S09W080 +S27W080 +N00W081 +N07W081 +N08W081 +N09W081 +N13W081 +N14W081 +N19W081 +N21W081 +N22W081 +N23W081 +N24W081 +N25W081 +N26W081 +N27W081 +N28W081 +N29W081 +N31W081 +N32W081 +N33W081 +N34W081 +N35W081 +N36W081 +N37W081 +N38W081 +N39W081 +N40W081 +N41W081 +N42W081 +N43W081 +N44W081 +N45W081 +N46W081 +N47W081 +N48W081 +N49W081 +N50W081 +N51W081 +N52W081 +N53W081 +N54W081 +N55W081 +N56W081 +N58W081 +N59W081 +S01W081 +S02W081 +S03W081 +S04W081 +S05W081 +S06W081 +S07W081 +S27W081 +S34W081 +N03W082 +N04W082 +N07W082 +N08W082 +N09W082 +N12W082 +N13W082 +N19W082 +N21W082 +N22W082 +N23W082 +N24W082 +N25W082 +N26W082 +N27W082 +N28W082 +N29W082 +N30W082 +N31W082 +N32W082 +N33W082 +N34W082 +N35W082 +N36W082 +N37W082 +N38W082 +N39W082 +N40W082 +N41W082 +N42W082 +N43W082 +N44W082 +N45W082 +N46W082 +N47W082 +N48W082 +N49W082 +N50W082 +N51W082 +N52W082 +N53W082 +N54W082 +S02W082 +S03W082 +S05W082 +S06W082 +S07W082 +N07W083 +N08W083 +N09W083 +N12W083 +N14W083 +N15W083 +N21W083 +N22W083 +N23W083 +N24W083 +N26W083 +N27W083 +N28W083 +N29W083 +N30W083 +N31W083 +N32W083 +N33W083 +N34W083 +N35W083 +N36W083 +N37W083 +N38W083 +N39W083 +N40W083 +N41W083 +N42W083 +N43W083 +N44W083 +N45W083 +N46W083 +N47W083 +N48W083 +N49W083 +N50W083 +N51W083 +N52W083 +N53W083 +N54W083 +N55W083 +N08W084 +N09W084 +N10W084 +N11W084 +N12W084 +N13W084 +N14W084 +N15W084 +N17W084 +N21W084 +N22W084 +N23W084 +N29W084 +N30W084 +N31W084 +N32W084 +N33W084 +N34W084 +N35W084 +N36W084 +N37W084 +N38W084 +N39W084 +N40W084 +N41W084 +N42W084 +N43W084 +N44W084 +N45W084 +N46W084 +N47W084 +N48W084 +N49W084 +N50W084 +N51W084 +N52W084 +N53W084 +N54W084 +N55W084 +N09W085 +N10W085 +N11W085 +N12W085 +N13W085 +N14W085 +N15W085 +N21W085 +N22W085 +N29W085 +N30W085 +N31W085 +N32W085 +N33W085 +N34W085 +N35W085 +N36W085 +N37W085 +N38W085 +N39W085 +N40W085 +N41W085 +N42W085 +N43W085 +N44W085 +N45W085 +N46W085 +N47W085 +N48W085 +N49W085 +N50W085 +N51W085 +N52W085 +N53W085 +N54W085 +N55W085 +N09W086 +N10W086 +N11W086 +N12W086 +N13W086 +N14W086 +N15W086 +N16W086 +N29W086 +N30W086 +N31W086 +N32W086 +N33W086 +N34W086 +N35W086 +N36W086 +N37W086 +N38W086 +N39W086 +N40W086 +N41W086 +N42W086 +N43W086 +N44W086 +N45W086 +N46W086 +N47W086 +N48W086 +N49W086 +N50W086 +N51W086 +N52W086 +N53W086 +N54W086 +N55W086 +N11W087 +N12W087 +N13W087 +N14W087 +N15W087 +N16W087 +N20W087 +N21W087 +N30W087 +N31W087 +N32W087 +N33W087 +N34W087 +N35W087 +N36W087 +N37W087 +N38W087 +N39W087 +N40W087 +N41W087 +N42W087 +N43W087 +N44W087 +N45W087 +N46W087 +N48W087 +N49W087 +N50W087 +N51W087 +N52W087 +N53W087 +N54W087 +N55W087 +N05W088 +N12W088 +N13W088 +N14W088 +N15W088 +N16W088 +N17W088 +N18W088 +N19W088 +N20W088 +N21W088 +N30W088 +N31W088 +N32W088 +N33W088 +N34W088 +N35W088 +N36W088 +N37W088 +N38W088 +N39W088 +N40W088 +N41W088 +N42W088 +N43W088 +N44W088 +N45W088 +N46W088 +N47W088 +N48W088 +N49W088 +N50W088 +N51W088 +N52W088 +N53W088 +N54W088 +N55W088 +N56W088 +N13W089 +N14W089 +N15W089 +N16W089 +N17W089 +N18W089 +N19W089 +N21W089 +N29W089 +N30W089 +N31W089 +N32W089 +N33W089 +N34W089 +N35W089 +N36W089 +N37W089 +N38W089 +N39W089 +N40W089 +N41W089 +N42W089 +N43W089 +N44W089 +N45W089 +N46W089 +N47W089 +N48W089 +N49W089 +N50W089 +N51W089 +N52W089 +N53W089 +N54W089 +N55W089 +N56W089 +N00W090 +N13W090 +N14W090 +N15W090 +N16W090 +N17W090 +N18W090 +N19W090 +N20W090 +N21W090 +N22W090 +N28W090 +N29W090 +N30W090 +N31W090 +N32W090 +N33W090 +N34W090 +N35W090 +N36W090 +N37W090 +N38W090 +N39W090 +N40W090 +N41W090 +N42W090 +N43W090 +N44W090 +N45W090 +N46W090 +N47W090 +N48W090 +N49W090 +N50W090 +N51W090 +N52W090 +N53W090 +N54W090 +N55W090 +N56W090 +N57W090 +S01W090 +S02W090 +N00W091 +N13W091 +N14W091 +N15W091 +N16W091 +N17W091 +N18W091 +N19W091 +N20W091 +N21W091 +N29W091 +N30W091 +N31W091 +N32W091 +N33W091 +N34W091 +N35W091 +N36W091 +N37W091 +N38W091 +N39W091 +N40W091 +N41W091 +N42W091 +N43W091 +N44W091 +N45W091 +N46W091 +N47W091 +N48W091 +N49W091 +N50W091 +N51W091 +N52W091 +N53W091 +N54W091 +N55W091 +N56W091 +N57W091 +S01W091 +S02W091 +N00W092 +N01W092 +N13W092 +N14W092 +N15W092 +N16W092 +N17W092 +N18W092 +N19W092 +N20W092 +N22W092 +N29W092 +N30W092 +N31W092 +N32W092 +N33W092 +N34W092 +N35W092 +N36W092 +N37W092 +N38W092 +N39W092 +N40W092 +N41W092 +N42W092 +N43W092 +N44W092 +N45W092 +N46W092 +N47W092 +N48W092 +N49W092 +N50W092 +N51W092 +N52W092 +N53W092 +N54W092 +N55W092 +N56W092 +N57W092 +S01W092 +S02W092 +N14W093 +N15W093 +N16W093 +N17W093 +N18W093 +N20W093 +N29W093 +N30W093 +N31W093 +N32W093 +N33W093 +N34W093 +N35W093 +N36W093 +N37W093 +N38W093 +N39W093 +N40W093 +N41W093 +N42W093 +N43W093 +N44W093 +N45W093 +N46W093 +N47W093 +N48W093 +N49W093 +N50W093 +N51W093 +N52W093 +N53W093 +N54W093 +N55W093 +N56W093 +N57W093 +N58W093 +N15W094 +N16W094 +N17W094 +N18W094 +N29W094 +N30W094 +N31W094 +N32W094 +N33W094 +N34W094 +N35W094 +N36W094 +N37W094 +N38W094 +N39W094 +N40W094 +N41W094 +N42W094 +N43W094 +N44W094 +N45W094 +N46W094 +N47W094 +N48W094 +N49W094 +N50W094 +N51W094 +N52W094 +N53W094 +N54W094 +N55W094 +N56W094 +N57W094 +N58W094 +N16W095 +N17W095 +N18W095 +N29W095 +N30W095 +N31W095 +N32W095 +N33W095 +N34W095 +N35W095 +N36W095 +N37W095 +N38W095 +N39W095 +N40W095 +N41W095 +N42W095 +N43W095 +N44W095 +N45W095 +N46W095 +N47W095 +N48W095 +N49W095 +N50W095 +N51W095 +N52W095 +N53W095 +N54W095 +N55W095 +N56W095 +N57W095 +N58W095 +N59W095 +N15W096 +N16W096 +N17W096 +N18W096 +N19W096 +N28W096 +N29W096 +N30W096 +N31W096 +N32W096 +N33W096 +N34W096 +N35W096 +N36W096 +N37W096 +N38W096 +N39W096 +N40W096 +N41W096 +N42W096 +N43W096 +N44W096 +N45W096 +N46W096 +N47W096 +N48W096 +N49W096 +N50W096 +N51W096 +N52W096 +N53W096 +N54W096 +N55W096 +N56W096 +N57W096 +N58W096 +N59W096 +N15W097 +N16W097 +N17W097 +N18W097 +N19W097 +N20W097 +N27W097 +N28W097 +N29W097 +N30W097 +N31W097 +N32W097 +N33W097 +N34W097 +N35W097 +N36W097 +N37W097 +N38W097 +N39W097 +N40W097 +N41W097 +N42W097 +N43W097 +N44W097 +N45W097 +N46W097 +N47W097 +N48W097 +N49W097 +N50W097 +N51W097 +N52W097 +N53W097 +N54W097 +N55W097 +N56W097 +N57W097 +N58W097 +N59W097 +N15W098 +N16W098 +N17W098 +N18W098 +N19W098 +N20W098 +N21W098 +N22W098 +N23W098 +N24W098 +N25W098 +N26W098 +N27W098 +N28W098 +N29W098 +N30W098 +N31W098 +N32W098 +N33W098 +N34W098 +N35W098 +N36W098 +N37W098 +N38W098 +N39W098 +N40W098 +N41W098 +N42W098 +N43W098 +N44W098 +N45W098 +N46W098 +N47W098 +N48W098 +N49W098 +N50W098 +N51W098 +N52W098 +N53W098 +N54W098 +N55W098 +N56W098 +N57W098 +N58W098 +N59W098 +N16W099 +N17W099 +N18W099 +N19W099 +N20W099 +N21W099 +N22W099 +N23W099 +N24W099 +N25W099 +N26W099 +N27W099 +N28W099 +N29W099 +N30W099 +N31W099 +N32W099 +N33W099 +N34W099 +N35W099 +N36W099 +N37W099 +N38W099 +N39W099 +N40W099 +N41W099 +N42W099 +N43W099 +N44W099 +N45W099 +N46W099 +N47W099 +N48W099 +N49W099 +N50W099 +N51W099 +N52W099 +N53W099 +N54W099 +N55W099 +N56W099 +N57W099 +N58W099 +N59W099 +N16W100 +N17W100 +N18W100 +N19W100 +N20W100 +N21W100 +N22W100 +N23W100 +N24W100 +N25W100 +N26W100 +N27W100 +N28W100 +N29W100 +N30W100 +N31W100 +N32W100 +N33W100 +N34W100 +N35W100 +N36W100 +N37W100 +N38W100 +N39W100 +N40W100 +N41W100 +N42W100 +N43W100 +N44W100 +N45W100 +N46W100 +N47W100 +N48W100 +N49W100 +N50W100 +N51W100 +N52W100 +N53W100 +N54W100 +N55W100 +N56W100 +N57W100 +N58W100 +N59W100 +N16W101 +N17W101 +N18W101 +N19W101 +N20W101 +N21W101 +N22W101 +N23W101 +N24W101 +N25W101 +N26W101 +N27W101 +N28W101 +N29W101 +N31W101 +N32W101 +N33W101 +N34W101 +N35W101 +N36W101 +N37W101 +N38W101 +N39W101 +N40W101 +N41W101 +N42W101 +N43W101 +N44W101 +N45W101 +N46W101 +N47W101 +N48W101 +N49W101 +N50W101 +N51W101 +N52W101 +N53W101 +N54W101 +N55W101 +N56W101 +N57W101 +N58W101 +N59W101 +N17W102 +N18W102 +N19W102 +N20W102 +N21W102 +N22W102 +N23W102 +N24W102 +N25W102 +N26W102 +N27W102 +N29W102 +N31W102 +N32W102 +N33W102 +N34W102 +N35W102 +N36W102 +N37W102 +N39W102 +N40W102 +N41W102 +N42W102 +N43W102 +N44W102 +N45W102 +N46W102 +N47W102 +N48W102 +N49W102 +N50W102 +N51W102 +N52W102 +N53W102 +N54W102 +N55W102 +N56W102 +N57W102 +N58W102 +N59W102 +N17W103 +N18W103 +N19W103 +N20W103 +N21W103 +N22W103 +N23W103 +N24W103 +N25W103 +N26W103 +N27W103 +N28W103 +N31W103 +N32W103 +N33W103 +N34W103 +N35W103 +N36W103 +N37W103 +N38W103 +N39W103 +N40W103 +N41W103 +N42W103 +N43W103 +N44W103 +N45W103 +N46W103 +N47W103 +N48W103 +N49W103 +N50W103 +N51W103 +N52W103 +N53W103 +N54W103 +N55W103 +N56W103 +N57W103 +N58W103 +N59W103 +N18W104 +N19W104 +N20W104 +N21W104 +N22W104 +N23W104 +N24W104 +N25W104 +N26W104 +N27W104 +N28W104 +N29W104 +N30W104 +N31W104 +N32W104 +N33W104 +N34W104 +N35W104 +N36W104 +N38W104 +N39W104 +N40W104 +N41W104 +N42W104 +N43W104 +N44W104 +N45W104 +N46W104 +N47W104 +N48W104 +N49W104 +N50W104 +N51W104 +N52W104 +N53W104 +N54W104 +N55W104 +N56W104 +N57W104 +N58W104 +N59W104 +N18W105 +N19W105 +N20W105 +N21W105 +N22W105 +N23W105 +N24W105 +N25W105 +N26W105 +N27W105 +N28W105 +N29W105 +N31W105 +N32W105 +N33W105 +N34W105 +N35W105 +N36W105 +N37W105 +N38W105 +N39W105 +N40W105 +N41W105 +N42W105 +N43W105 +N44W105 +N45W105 +N46W105 +N47W105 +N48W105 +N49W105 +N50W105 +N51W105 +N52W105 +N53W105 +N54W105 +N55W105 +N56W105 +N57W105 +N58W105 +N59W105 +N19W106 +N20W106 +N21W106 +N22W106 +N23W106 +N24W106 +N25W106 +N26W106 +N27W106 +N28W106 +N29W106 +N31W106 +N32W106 +N33W106 +N34W106 +N35W106 +N36W106 +N37W106 +N38W106 +N39W106 +N40W106 +N41W106 +N42W106 +N43W106 +N44W106 +N45W106 +N46W106 +N47W106 +N48W106 +N49W106 +N50W106 +N51W106 +N52W106 +N53W106 +N54W106 +N55W106 +N56W106 +N57W106 +N58W106 +N59W106 +S27W106 +N21W107 +N22W107 +N23W107 +N24W107 +N26W107 +N28W107 +N29W107 +N30W107 +N31W107 +N32W107 +N33W107 +N34W107 +N35W107 +N36W107 +N37W107 +N38W107 +N39W107 +N40W107 +N41W107 +N42W107 +N43W107 +N44W107 +N45W107 +N46W107 +N47W107 +N48W107 +N49W107 +N50W107 +N51W107 +N52W107 +N53W107 +N54W107 +N55W107 +N56W107 +N57W107 +N58W107 +N59W107 +N23W108 +N24W108 +N25W108 +N26W108 +N27W108 +N28W108 +N29W108 +N30W108 +N31W108 +N32W108 +N33W108 +N34W108 +N35W108 +N36W108 +N37W108 +N38W108 +N39W108 +N40W108 +N41W108 +N42W108 +N44W108 +N45W108 +N46W108 +N47W108 +N48W108 +N49W108 +N50W108 +N51W108 +N52W108 +N53W108 +N54W108 +N55W108 +N56W108 +N57W108 +N58W108 +N59W108 +N24W109 +N25W109 +N26W109 +N27W109 +N29W109 +N30W109 +N31W109 +N32W109 +N33W109 +N34W109 +N35W109 +N36W109 +N37W109 +N38W109 +N39W109 +N40W109 +N41W109 +N42W109 +N43W109 +N44W109 +N45W109 +N46W109 +N47W109 +N48W109 +N49W109 +N50W109 +N51W109 +N52W109 +N53W109 +N54W109 +N55W109 +N56W109 +N57W109 +N58W109 +N59W109 +N10W110 +N22W110 +N23W110 +N24W110 +N25W110 +N26W110 +N27W110 +N28W110 +N29W110 +N30W110 +N31W110 +N32W110 +N33W110 +N34W110 +N35W110 +N36W110 +N37W110 +N38W110 +N39W110 +N40W110 +N41W110 +N42W110 +N43W110 +N44W110 +N45W110 +N46W110 +N47W110 +N48W110 +N49W110 +N50W110 +N51W110 +N52W110 +N53W110 +N54W110 +N55W110 +N56W110 +N57W110 +N58W110 +N59W110 +S28W110 +N18W111 +N19W111 +N22W111 +N23W111 +N24W111 +N25W111 +N27W111 +N28W111 +N29W111 +N30W111 +N31W111 +N32W111 +N33W111 +N34W111 +N35W111 +N36W111 +N37W111 +N39W111 +N40W111 +N41W111 +N42W111 +N43W111 +N44W111 +N45W111 +N46W111 +N47W111 +N48W111 +N49W111 +N50W111 +N51W111 +N52W111 +N53W111 +N54W111 +N55W111 +N56W111 +N57W111 +N58W111 +N59W111 +N18W112 +N24W112 +N25W112 +N26W112 +N27W112 +N28W112 +N29W112 +N30W112 +N31W112 +N32W112 +N33W112 +N34W112 +N35W112 +N36W112 +N37W112 +N38W112 +N39W112 +N40W112 +N41W112 +N42W112 +N43W112 +N44W112 +N45W112 +N46W112 +N47W112 +N48W112 +N49W112 +N50W112 +N51W112 +N52W112 +N53W112 +N54W112 +N55W112 +N56W112 +N57W112 +N58W112 +N59W112 +N24W113 +N25W113 +N26W113 +N27W113 +N28W113 +N29W113 +N30W113 +N31W113 +N32W113 +N33W113 +N34W113 +N35W113 +N37W113 +N38W113 +N39W113 +N40W113 +N41W113 +N42W113 +N43W113 +N44W113 +N45W113 +N46W113 +N47W113 +N48W113 +N49W113 +N50W113 +N51W113 +N52W113 +N53W113 +N54W113 +N55W113 +N56W113 +N57W113 +N58W113 +N59W113 +N26W114 +N27W114 +N28W114 +N29W114 +N30W114 +N31W114 +N33W114 +N34W114 +N35W114 +N36W114 +N37W114 +N39W114 +N40W114 +N41W114 +N42W114 +N43W114 +N44W114 +N45W114 +N46W114 +N47W114 +N48W114 +N49W114 +N50W114 +N51W114 +N52W114 +N53W114 +N54W114 +N55W114 +N56W114 +N57W114 +N58W114 +N59W114 +N18W115 +N26W115 +N27W115 +N28W115 +N29W115 +N30W115 +N31W115 +N32W115 +N33W115 +N34W115 +N35W115 +N36W115 +N38W115 +N39W115 +N40W115 +N41W115 +N42W115 +N43W115 +N44W115 +N45W115 +N46W115 +N47W115 +N48W115 +N49W115 +N50W115 +N51W115 +N52W115 +N53W115 +N54W115 +N55W115 +N56W115 +N57W115 +N58W115 +N59W115 +N24W116 +N27W116 +N28W116 +N29W116 +N30W116 +N31W116 +N32W116 +N33W116 +N34W116 +N36W116 +N37W116 +N38W116 +N39W116 +N40W116 +N41W116 +N42W116 +N43W116 +N44W116 +N45W116 +N46W116 +N47W116 +N48W116 +N49W116 +N50W116 +N51W116 +N52W116 +N53W116 +N54W116 +N55W116 +N56W116 +N57W116 +N58W116 +N59W116 +N30W117 +N31W117 +N32W117 +N33W117 +N34W117 +N36W117 +N38W117 +N39W117 +N40W117 +N41W117 +N42W117 +N43W117 +N44W117 +N45W117 +N46W117 +N47W117 +N48W117 +N49W117 +N50W117 +N51W117 +N52W117 +N53W117 +N54W117 +N55W117 +N56W117 +N57W117 +N58W117 +N59W117 +N32W118 +N33W118 +N34W118 +N35W118 +N36W118 +N37W118 +N38W118 +N39W118 +N40W118 +N41W118 +N42W118 +N43W118 +N44W118 +N45W118 +N46W118 +N47W118 +N48W118 +N49W118 +N50W118 +N51W118 +N52W118 +N53W118 +N54W118 +N55W118 +N56W118 +N57W118 +N58W118 +N59W118 +N28W119 +N29W119 +N32W119 +N33W119 +N34W119 +N35W119 +N36W119 +N37W119 +N38W119 +N39W119 +N40W119 +N41W119 +N42W119 +N43W119 +N44W119 +N45W119 +N46W119 +N47W119 +N48W119 +N49W119 +N50W119 +N51W119 +N52W119 +N53W119 +N54W119 +N55W119 +N56W119 +N57W119 +N58W119 +N59W119 +N33W120 +N34W120 +N35W120 +N36W120 +N37W120 +N38W120 +N39W120 +N40W120 +N41W120 +N42W120 +N43W120 +N44W120 +N45W120 +N46W120 +N47W120 +N48W120 +N49W120 +N50W120 +N51W120 +N52W120 +N53W120 +N54W120 +N55W120 +N56W120 +N57W120 +N58W120 +N59W120 +N33W121 +N34W121 +N35W121 +N36W121 +N37W121 +N38W121 +N39W121 +N40W121 +N41W121 +N42W121 +N43W121 +N44W121 +N45W121 +N46W121 +N47W121 +N48W121 +N49W121 +N50W121 +N51W121 +N52W121 +N53W121 +N54W121 +N55W121 +N56W121 +N57W121 +N58W121 +N59W121 +N35W122 +N36W122 +N37W122 +N38W122 +N39W122 +N40W122 +N41W122 +N42W122 +N43W122 +N44W122 +N45W122 +N46W122 +N47W122 +N48W122 +N49W122 +N50W122 +N51W122 +N52W122 +N53W122 +N54W122 +N55W122 +N56W122 +N57W122 +N58W122 +N59W122 +N36W123 +N37W123 +N38W123 +N39W123 +N40W123 +N41W123 +N42W123 +N43W123 +N44W123 +N45W123 +N46W123 +N47W123 +N48W123 +N49W123 +N50W123 +N51W123 +N52W123 +N53W123 +N54W123 +N55W123 +N56W123 +N57W123 +N58W123 +N59W123 +N37W124 +N38W124 +N39W124 +N40W124 +N41W124 +N42W124 +N43W124 +N44W124 +N45W124 +N46W124 +N47W124 +N48W124 +N49W124 +N50W124 +N51W124 +N52W124 +N53W124 +N54W124 +N55W124 +N56W124 +N57W124 +N58W124 +N59W124 +N39W125 +N40W125 +N41W125 +N42W125 +N43W125 +N44W125 +N45W125 +N46W125 +N47W125 +N48W125 +N49W125 +N50W125 +N51W125 +N52W125 +N53W125 +N54W125 +N55W125 +N56W125 +N57W125 +N58W125 +N59W125 +S25W125 +N48W126 +N49W126 +N50W126 +N51W126 +N52W126 +N53W126 +N54W126 +N55W126 +N56W126 +N57W126 +N58W126 +N59W126 +N49W127 +N50W127 +N51W127 +N52W127 +N53W127 +N54W127 +N55W127 +N56W127 +N57W127 +N58W127 +N59W127 +N49W128 +N50W128 +N51W128 +N52W128 +N53W128 +N54W128 +N55W128 +N56W128 +N57W128 +N58W128 +N59W128 +N50W129 +N51W129 +N52W129 +N53W129 +N54W129 +N55W129 +N56W129 +N57W129 +N58W129 +N59W129 +S25W129 +N50W130 +N52W130 +N53W130 +N54W130 +N55W130 +N56W130 +N57W130 +N58W130 +N59W130 +N51W131 +N52W131 +N53W131 +N54W131 +N55W131 +N56W131 +N57W131 +N58W131 +N59W131 +S24W131 +S26W131 +N51W132 +N52W132 +N53W132 +N54W132 +N55W132 +N56W132 +N57W132 +N58W132 +N59W132 +N52W133 +N53W133 +N54W133 +N55W133 +N56W133 +N57W133 +N58W133 +N59W133 +N53W134 +N54W134 +N55W134 +N56W134 +N57W134 +N58W134 +N59W134 +N55W135 +N56W135 +N57W135 +N58W135 +N59W135 +S23W135 +S24W135 +N56W136 +N57W136 +N58W136 +N59W136 +S22W136 +S24W136 +N57W137 +N58W137 +N59W137 +S19W137 +S22W137 +S23W137 +N58W138 +N59W138 +S19W138 +S24W138 +N58W139 +N59W139 +S10W139 +S15W139 +S18W139 +S19W139 +S20W139 +S21W139 +S22W139 +S23W139 +N59W140 +S09W140 +S10W140 +S11W140 +S19W140 +S20W140 +S21W140 +S22W140 +N59W141 +S08W141 +S09W141 +S10W141 +S16W141 +S17W141 +S18W141 +S19W141 +S20W141 +S22W141 +N59W142 +S15W142 +S17W142 +S18W142 +S19W142 +S20W142 +S16W143 +S17W143 +S18W143 +S19W143 +N59W144 +S17W144 +S18W144 +S21W144 +S28W144 +N59W145 +S15W145 +S16W145 +S17W145 +S18W145 +S20W145 +S28W145 +S15W146 +S16W146 +S17W146 +S18W146 +S20W146 +N59W147 +S15W147 +S16W147 +S17W147 +N59W148 +S15W148 +S16W148 +S24W148 +N59W149 +S15W149 +S16W149 +S18W149 +N59W150 +S17W150 +S18W150 +S24W150 +N59W151 +S10W151 +S11W151 +S17W151 +S18W151 +N58W152 +N59W152 +S12W152 +S17W152 +S23W152 +N57W153 +N58W153 +N59W153 +S17W153 +S23W153 +N56W154 +N57W154 +N58W154 +N59W154 +S17W154 +N19W155 +N56W155 +N57W155 +N58W155 +N59W155 +S04W155 +S05W155 +S16W155 +S17W155 +S22W155 +N18W156 +N19W156 +N20W156 +N55W156 +N57W156 +N58W156 +N59W156 +S06W156 +N19W157 +N20W157 +N21W157 +N55W157 +N56W157 +N57W157 +N58W157 +N59W157 +N01W158 +N02W158 +N20W158 +N21W158 +N56W158 +N57W158 +N58W158 +N59W158 +S09W158 +S10W158 +S20W158 +S21W158 +S22W158 +N21W159 +N55W159 +N56W159 +N57W159 +N58W159 +N59W159 +S09W159 +S10W159 +S20W159 +S21W159 +N03W160 +N21W160 +N22W160 +N54W160 +N55W160 +N56W160 +N58W160 +N59W160 +S19W160 +S22W160 +N04W161 +N21W161 +N22W161 +N54W161 +N55W161 +N56W161 +N58W161 +N59W161 +S01W161 +S11W161 +N23W162 +N54W162 +N55W162 +N56W162 +N58W162 +N59W162 +S10W162 +S11W162 +N05W163 +N06W163 +N54W163 +N55W163 +N58W163 +N59W163 +N54W164 +N55W164 +N59W164 +S14W164 +S19W164 +N23W165 +N54W165 +N59W165 +N54W166 +S11W166 +S12W166 +N23W167 +N53W167 +N54W167 +N24W168 +N25W168 +N53W168 +N52W169 +N53W169 +S15W169 +N16W170 +N52W170 +N53W170 +N56W170 +N57W170 +S15W170 +S19W170 +S20W170 +N52W171 +N57W171 +S04W171 +S15W171 +N25W172 +N52W172 +S03W172 +S04W172 +S05W172 +S10W172 +S12W172 +S14W172 +S15W172 +N52W173 +S05W173 +S09W173 +S14W173 +N26W174 +N52W174 +S16W174 +S19W174 +N52W175 +S04W175 +S05W175 +S19W175 +S20W175 +S21W175 +S22W175 +N27W176 +N51W176 +N52W176 +S16W176 +S20W176 +S21W176 +S22W176 +S44W176 +S45W176 +N00W177 +N51W177 +N52W177 +S14W177 +S23W177 +S44W177 +S45W177 +N28W178 +N51W178 +S15W178 +S30W178 +N28W179 +N51W179 +S15W179 +S18W179 +S19W179 +S20W179 +S21W179 +S22W179 +S31W179 +S32W179 +N51W180 +S16W180 +S17W180 +S18W180 +S19W180 +S20W180 diff --git a/components/isceobj/Alos2burstProc/Alos2burstProc.py b/components/isceobj/Alos2burstProc/Alos2burstProc.py new file mode 100644 index 0000000..fe1a875 --- /dev/null +++ b/components/isceobj/Alos2burstProc/Alos2burstProc.py @@ -0,0 +1,1109 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +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_DATE = Component.Parameter('masterDate', + public_name='master date', + default=None, + type=str, + mandatory=True, + doc='master acquistion date') + +SLAVE_DATE = Component.Parameter('slaveDate', + public_name='slave date', + default=None, + type=str, + mandatory=True, + doc='slave acquistion date') + +MODE_COMBINATION = Component.Parameter('modeCombination', + public_name='mode combination', + default=None, + type=int, + mandatory=True, + doc='mode combination') + +MASTER_FRAMES = Component.Parameter('masterFrames', + public_name = 'master frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'master frames to process') + +SLAVE_FRAMES = Component.Parameter('slaveFrames', + public_name = 'slave frames', + default = None, + type=str, + container=list, + mandatory=False, + doc = 'slave frames to process') + +STARTING_SWATH = Component.Parameter('startingSwath', + public_name='starting swath', + default=1, + type=int, + mandatory=False, + doc="starting swath to process") + +ENDING_SWATH = Component.Parameter('endingSwath', + public_name='ending swath', + default=5, + type=int, + mandatory=False, + doc="ending swath to process") + +BURST_UNSYNCHRONIZED_TIME = Component.Parameter('burstUnsynchronizedTime', + public_name = 'burst unsynchronized time', + default = None, + type = float, + mandatory = False, + doc = 'burst unsynchronized time in second') + +BURST_SYNCHRONIZATION = Component.Parameter('burstSynchronization', + public_name = 'burst synchronization', + default = None, + type = float, + mandatory = False, + doc = 'average burst synchronization of all swaths and frames in percentage') + +RANGE_RESIDUAL_OFFSET_CC = Component.Parameter('rangeResidualOffsetCc', + public_name = 'range residual offset estimated by cross correlation', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'range residual offset estimated by cross correlation') + +AZIMUTH_RESIDUAL_OFFSET_CC = Component.Parameter('azimuthResidualOffsetCc', + public_name = 'azimuth residual offset estimated by cross correlation', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'azimuth residual offset estimated by cross correlation') + +RANGE_RESIDUAL_OFFSET_SD = Component.Parameter('rangeResidualOffsetSd', + public_name = 'range residual offset estimated by spectral diversity', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'range residual offset estimated by spectral diversity') + +AZIMUTH_RESIDUAL_OFFSET_SD = Component.Parameter('azimuthResidualOffsetSd', + public_name = 'azimuth residual offset estimated by spectral diversity', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'azimuth residual offset estimated by spectral diversity') + +SWATH_RANGE_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('swathRangeOffsetGeometricalMaster', + public_name = 'swath range offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from geometry master') + +SWATH_AZIMUTH_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('swathAzimuthOffsetGeometricalMaster', + public_name = 'swath azimuth offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from geometry master') + +SWATH_RANGE_OFFSET_MATCHING_MASTER = Component.Parameter('swathRangeOffsetMatchingMaster', + public_name = 'swath range offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from matching master') + +SWATH_AZIMUTH_OFFSET_MATCHING_MASTER = Component.Parameter('swathAzimuthOffsetMatchingMaster', + public_name = 'swath azimuth offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from matching master') + +SWATH_RANGE_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('swathRangeOffsetGeometricalSlave', + public_name = 'swath range offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from geometry slave') + +SWATH_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('swathAzimuthOffsetGeometricalSlave', + public_name = 'swath azimuth offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from geometry slave') + +SWATH_RANGE_OFFSET_MATCHING_SLAVE = Component.Parameter('swathRangeOffsetMatchingSlave', + public_name = 'swath range offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath range offset from matching slave') + +SWATH_AZIMUTH_OFFSET_MATCHING_SLAVE = Component.Parameter('swathAzimuthOffsetMatchingSlave', + public_name = 'swath azimuth offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'swath azimuth offset from matching slave') + + + +FRAME_RANGE_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('frameRangeOffsetGeometricalMaster', + public_name = 'frame range offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from geometry master') + +FRAME_AZIMUTH_OFFSET_GEOMETRICAL_MASTER = Component.Parameter('frameAzimuthOffsetGeometricalMaster', + public_name = 'frame azimuth offset from geometry master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from geometry master') + +FRAME_RANGE_OFFSET_MATCHING_MASTER = Component.Parameter('frameRangeOffsetMatchingMaster', + public_name = 'frame range offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from matching master') + +FRAME_AZIMUTH_OFFSET_MATCHING_MASTER = Component.Parameter('frameAzimuthOffsetMatchingMaster', + public_name = 'frame azimuth offset from matching master', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from matching master') + +FRAME_RANGE_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('frameRangeOffsetGeometricalSlave', + public_name = 'frame range offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from geometry slave') + +FRAME_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE = Component.Parameter('frameAzimuthOffsetGeometricalSlave', + public_name = 'frame azimuth offset from geometry slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from geometry slave') + +FRAME_RANGE_OFFSET_MATCHING_SLAVE = Component.Parameter('frameRangeOffsetMatchingSlave', + public_name = 'frame range offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame range offset from matching slave') + +FRAME_AZIMUTH_OFFSET_MATCHING_SLAVE = Component.Parameter('frameAzimuthOffsetMatchingSlave', + public_name = 'frame azimuth offset from matching slave', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'frame azimuth offset from matching slave') + +NUMBER_RANGE_LOOKS1 = Component.Parameter('numberRangeLooks1', + public_name='number of range looks 1', + default=None, + type=int, + mandatory=False, + doc="number of range looks when forming interferogram") + +NUMBER_AZIMUTH_LOOKS1 = Component.Parameter('numberAzimuthLooks1', + public_name='number of azimuth looks 1', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when forming interferogram") + +NUMBER_RANGE_LOOKS2 = Component.Parameter('numberRangeLooks2', + public_name='number of range looks 2', + default=None, + type=int, + mandatory=False, + doc="number of range looks for further multiple looking") + +NUMBER_AZIMUTH_LOOKS2 = Component.Parameter('numberAzimuthLooks2', + public_name='number of azimuth looks 2', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for further multiple looking") + +NUMBER_RANGE_LOOKS_SIM = Component.Parameter('numberRangeLooksSim', + public_name='number of range looks sim', + default=None, + type=int, + mandatory=False, + doc="number of range looks when simulating radar image") + +NUMBER_AZIMUTH_LOOKS_SIM = Component.Parameter('numberAzimuthLooksSim', + public_name='number of azimuth looks sim', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks when simulating radar image") + +NUMBER_RANGE_LOOKS_ION = Component.Parameter('numberRangeLooksIon', + public_name='number of range looks ion', + default=None, + type=int, + mandatory=False, + doc="number of range looks for ionospheric correction") + +NUMBER_AZIMUTH_LOOKS_ION = Component.Parameter('numberAzimuthLooksIon', + public_name='number of azimuth looks ion', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for ionospheric correction") + +NUMBER_RANGE_LOOKS_SD = Component.Parameter('numberRangeLooksSd', + public_name='number of range looks sd', + default=None, + type=int, + mandatory=False, + doc="number of range looks for spectral diversity") + +NUMBER_AZIMUTH_LOOKS_SD = Component.Parameter('numberAzimuthLooksSd', + public_name='number of azimuth looks sd', + default=None, + type=int, + mandatory=False, + doc="number of azimuth looks for spectral diversity") + +SUBBAND_RADAR_WAVLENGTH = Component.Parameter('subbandRadarWavelength', + public_name='lower and upper radar wavelength for ionosphere correction', + default=None, + type=float, + mandatory=False, + container = list, + doc="lower and upper radar wavelength for ionosphere correction") + +RADAR_DEM_AFFINE_TRANSFORM = Component.Parameter('radarDemAffineTransform', + public_name = 'radar dem affine transform parameters', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'radar dem affine transform parameters') + +MASTER_SLC = Component.Parameter('masterSlc', + public_name='master slc', + default=None, + type=str, + mandatory=False, + doc='master slc file') + +SLAVE_SLC = Component.Parameter('slaveSlc', + public_name='slave slc', + default=None, + type=str, + mandatory=False, + doc='slave slc file') + +MASTER_BURST_PREFIX = Component.Parameter('masterBurstPrefix', + public_name='master burst prefix', + default=None, + type=str, + mandatory=False, + doc='master burst prefix') + +SLAVE_BURST_PREFIX = Component.Parameter('slaveBurstPrefix', + public_name='slave burst prefix', + default=None, + type=str, + mandatory=False, + doc='slave burst prefix') + +MASTER_MAGNITUDE = Component.Parameter('masterMagnitude', + public_name='master magnitude', + default=None, + type=str, + mandatory=False, + doc='master magnitude file') + +SLAVE_MAGNITUDE = Component.Parameter('slaveMagnitude', + public_name='slave magnitude', + default=None, + type=str, + mandatory=False, + doc='slave magnitude file') + +MASTER_SWATH_OFFSET = Component.Parameter('masterSwathOffset', + public_name='master swath offset', + default=None, + type=str, + mandatory=False, + doc='master swath offset file') + +SLAVE_SWATH_OFFSET = Component.Parameter('slaveSwathOffset', + public_name='slave swath offset', + default=None, + type=str, + mandatory=False, + doc='slave swath offset file') + +MASTER_FRAME_OFFSET = Component.Parameter('masterFrameOffset', + public_name='master frame offset', + default=None, + type=str, + mandatory=False, + doc='master frame offset file') + +SLAVE_FRAME_OFFSET = Component.Parameter('slaveFrameOffset', + public_name='slave frame offset', + default=None, + type=str, + mandatory=False, + doc='slave frame offset file') + +MASTER_FRAME_PARAMETER = Component.Parameter('masterFrameParameter', + public_name='master frame parameter', + default=None, + type=str, + mandatory=False, + doc='master frame parameter file') + +SLAVE_FRAME_PARAMETER = Component.Parameter('slaveFrameParameter', + public_name='slave frame parameter', + default=None, + type=str, + mandatory=False, + doc='slave frame parameter file') + +MASTER_TRACK_PARAMETER = Component.Parameter('masterTrackParameter', + public_name='master track parameter', + default=None, + type=str, + mandatory=False, + doc='master track parameter file') + +SLAVE_TRACK_PARAMETER = Component.Parameter('slaveTrackParameter', + public_name='slave track parameter', + default=None, + type=str, + mandatory=False, + doc='slave track parameter file') + +DEM = Component.Parameter('dem', + public_name='dem for coregistration', + default=None, + type=str, + mandatory=False, + doc='dem for coregistration file') + +DEM_GEO = Component.Parameter('demGeo', + public_name='dem for geocoding', + default=None, + type=str, + mandatory=False, + doc='dem for geocoding file') + +WBD = Component.Parameter('wbd', + public_name='water body', + default=None, + type=str, + mandatory=False, + doc='water body file') + +WBD_OUT = Component.Parameter('wbdOut', + public_name='output water body', + default=None, + type=str, + mandatory=False, + doc='output water body file') + +INTERFEROGRAM = Component.Parameter('interferogram', + public_name='interferogram', + default=None, + type=str, + mandatory=False, + doc='interferogram file') + +AMPLITUDE = Component.Parameter('amplitude', + public_name='amplitude', + default=None, + type=str, + mandatory=False, + doc='amplitude file') + +DIFFERENTIAL_INTERFEROGRAM = Component.Parameter('differentialInterferogram', + public_name='differential interferogram', + default=None, + type=str, + mandatory=False, + doc='differential interferogram file') + +MULTILOOK_DIFFERENTIAL_INTERFEROGRAM = Component.Parameter('multilookDifferentialInterferogram', + public_name='multilook differential interferogram', + default=None, + type=str, + mandatory=False, + doc='multilook differential interferogram file') + +MULTILOOK_DIFFERENTIAL_INTERFEROGRAM_ORIGINAL = Component.Parameter('multilookDifferentialInterferogramOriginal', + public_name='original multilook differential interferogram', + default=None, + type=str, + mandatory=False, + doc='original multilook differential interferogram file') + +MULTILOOK_AMPLITUDE = Component.Parameter('multilookAmplitude', + public_name='multilook amplitude', + default=None, + type=str, + mandatory=False, + doc='multilook amplitude file') + +MULTILOOK_COHERENCE = Component.Parameter('multilookCoherence', + public_name='multilook coherence', + default=None, + type=str, + mandatory=False, + doc='multilook coherence file') + +MULTILOOK_PHSIG = Component.Parameter('multilookPhsig', + public_name='multilook phase sigma', + default=None, + type=str, + mandatory=False, + doc='multilook phase sigma file') + +FILTERED_INTERFEROGRAM = Component.Parameter('filteredInterferogram', + public_name='filtered interferogram', + default=None, + type=str, + mandatory=False, + doc='filtered interferogram file') + +UNWRAPPED_INTERFEROGRAM = Component.Parameter('unwrappedInterferogram', + public_name='unwrapped interferogram', + default=None, + type=str, + mandatory=False, + doc='unwrapped interferogram file') + +UNWRAPPED_MASKED_INTERFEROGRAM = Component.Parameter('unwrappedMaskedInterferogram', + public_name='unwrapped masked interferogram', + default=None, + type=str, + mandatory=False, + doc='unwrapped masked interferogram file') + +LATITUDE = Component.Parameter('latitude', + public_name='latitude', + default=None, + type=str, + mandatory=False, + doc='latitude file') + +LONGITUDE = Component.Parameter('longitude', + public_name='longitude', + default=None, + type=str, + mandatory=False, + doc='longitude file') + +HEIGHT = Component.Parameter('height', + public_name='height', + default=None, + type=str, + mandatory=False, + doc='height file') + +LOS = Component.Parameter('los', + public_name='los', + default=None, + type=str, + mandatory=False, + doc='los file') + +SIM = Component.Parameter('sim', + public_name='sim', + default=None, + type=str, + mandatory=False, + doc='sim file') + +MSK = Component.Parameter('msk', + public_name='msk', + default=None, + type=str, + mandatory=False, + doc='msk file') + +RANGE_OFFSET = Component.Parameter('rangeOffset', + public_name='range offset', + default=None, + type=str, + mandatory=False, + doc='range offset file') + +AZIMUTH_OFFSET = Component.Parameter('azimuthOffset', + public_name='azimuth offset', + default=None, + type=str, + mandatory=False, + doc='azimuth offset file') + + +MULTILOOK_LOS = Component.Parameter('multilookLos', + public_name='multilook los', + default=None, + type=str, + mandatory=False, + doc='multilook los file') + +MULTILOOK_MSK = Component.Parameter('multilookMsk', + public_name='multilook msk', + default=None, + type=str, + mandatory=False, + doc='multilook msk file') + +MULTILOOK_WBD_OUT = Component.Parameter('multilookWbdOut', + public_name='multilook wbdOut', + default=None, + type=str, + mandatory=False, + doc='multilook output water body file') + +MULTILOOK_LATITUDE = Component.Parameter('multilookLatitude', + public_name='multilook latitude', + default=None, + type=str, + mandatory=False, + doc='multilook latitude file') + +MULTILOOK_LONGITUDE = Component.Parameter('multilookLongitude', + public_name='multilook longitude', + default=None, + type=str, + mandatory=False, + doc='multilook longitude file') + +MULTILOOK_HEIGHT = Component.Parameter('multilookHeight', + public_name='multilook height', + default=None, + type=str, + mandatory=False, + doc='multilook height file') + +MULTILOOK_ION = Component.Parameter('multilookIon', + public_name='multilook ionospheric phase', + default=None, + type=str, + mandatory=False, + doc='multilook ionospheric phase file') + +RECT_RANGE_OFFSET = Component.Parameter('rectRangeOffset', + public_name='rectified range offset', + default=None, + type=str, + mandatory=False, + doc='rectified range offset file') + +GEO_INTERFEROGRAM = Component.Parameter('geoInterferogram', + public_name='geocoded interferogram', + default=None, + type=str, + mandatory=False, + doc='geocoded interferogram file') + +GEO_MASKED_INTERFEROGRAM = Component.Parameter('geoMaskedInterferogram', + public_name='geocoded masked interferogram', + default=None, + type=str, + mandatory=False, + doc='geocoded masked interferogram file') + +GEO_COHERENCE = Component.Parameter('geoCoherence', + public_name='geocoded coherence', + default=None, + type=str, + mandatory=False, + container = list, + doc='geocoded coherence file') + +GEO_LOS = Component.Parameter('geoLos', + public_name='geocoded los', + default=None, + type=str, + mandatory=False, + doc='geocoded los file') + +GEO_ION = Component.Parameter('geoIon', + public_name='geocoded ionospheric phase', + default=None, + type=str, + mandatory=False, + doc='geocoded ionospheric phase file') +################################################################### + +#spectral diversity +INTERFEROGRAM_SD = Component.Parameter('interferogramSd', + public_name='spectral diversity interferograms', + default=None, + type=str, + mandatory=False, + container = list, + doc='spectral diversity interferogram files') + +MULTILOOK_INTERFEROGRAM_SD = Component.Parameter('multilookInterferogramSd', + public_name='multilook spectral diversity interferograms', + default=None, + type=str, + mandatory=False, + container = list, + doc='multilook spectral diversity interferogram files') + +MULTILOOK_COHERENCE_SD = Component.Parameter('multilookCoherenceSd', + public_name='multilook coherence for spectral diversity', + default=None, + type=str, + mandatory=False, + doc='multilook coherence for spectral diversity file') + +FILTERED_INTERFEROGRAM_SD = Component.Parameter('filteredInterferogramSd', + public_name='filtered spectral diversity interferograms', + default=None, + type=str, + mandatory=False, + container = list, + doc='filtered spectral diversity interferogram files') + +UNWRAPPED_INTERFEROGRAM_SD = Component.Parameter('unwrappedInterferogramSd', + public_name='unwrapped spectral diversity interferograms', + default=None, + type=str, + mandatory=False, + container = list, + doc='unwrapped spectral diversity interferogram files') + +UNWRAPPED_MASKED_INTERFEROGRAM_SD = Component.Parameter('unwrappedMaskedInterferogramSd', + public_name='unwrapped masked spectral diversity interferograms', + default=None, + type=str, + mandatory=False, + container = list, + doc='unwrapped masked spectral diversity interferogram files') + +AZIMUTH_DEFORMATION_SD = Component.Parameter('azimuthDeformationSd', + public_name='azimuth deformation', + default=None, + type=str, + mandatory=False, + container = list, + doc='azimuth deformation files') + +MASKED_AZIMUTH_DEFORMATION_SD = Component.Parameter('maskedAzimuthDeformationSd', + public_name='masked azimuth deformation', + default=None, + type=str, + mandatory=False, + container = list, + doc='masked azimuth deformation files') + +MULTILOOK_WBD_OUT_SD = Component.Parameter('multilookWbdOutSd', + public_name='multilook wbdOut for SD', + default=None, + type=str, + mandatory=False, + doc='multilook output water body for SD file') + +MULTILOOK_LATITUDE_SD = Component.Parameter('multilookLatitudeSd', + public_name='multilook latitude for SD', + default=None, + type=str, + mandatory=False, + doc='multilook latitude for SD file') + +MULTILOOK_LONGITUDE_SD = Component.Parameter('multilookLongitudeSd', + public_name='multilook longitude for SD', + default=None, + type=str, + mandatory=False, + doc='multilook longitude for SD file') + +GEO_COHERENCE_SD = Component.Parameter('geoCoherenceSd', + public_name='geocoded coherence for spectral diversity', + default=None, + type=str, + mandatory=False, + container = list, + doc='geocoded coherence for spectral diversity file') + +GEO_AZIMUTH_DEFORMATION_SD = Component.Parameter('geoAzimuthDeformationSd', + public_name='geocoded azimuth deformation', + default=None, + type=str, + mandatory=False, + container = list, + doc='geocoded azimuth deformation files') + +GEO_MASKED_AZIMUTH_DEFORMATION_SD = Component.Parameter('geoMaskedAzimuthDeformationSd', + public_name='geocoded masked azimuth deformation', + default=None, + type=str, + mandatory=False, + container = list, + doc='geocoded masked azimuth deformation files') + +################################################################### +class Alos2burstProc(Component): + """ + This class holds the properties, along with methods (setters and getters) + to modify and return their values. + """ + + parameter_list = (MASTER_DATE, + SLAVE_DATE, + MODE_COMBINATION, + MASTER_FRAMES, + SLAVE_FRAMES, + STARTING_SWATH, + ENDING_SWATH, + BURST_UNSYNCHRONIZED_TIME, + BURST_SYNCHRONIZATION, + RANGE_RESIDUAL_OFFSET_CC, + AZIMUTH_RESIDUAL_OFFSET_CC, + RANGE_RESIDUAL_OFFSET_SD, + AZIMUTH_RESIDUAL_OFFSET_SD, + SWATH_RANGE_OFFSET_GEOMETRICAL_MASTER, + SWATH_AZIMUTH_OFFSET_GEOMETRICAL_MASTER, + SWATH_RANGE_OFFSET_MATCHING_MASTER, + SWATH_AZIMUTH_OFFSET_MATCHING_MASTER, + SWATH_RANGE_OFFSET_GEOMETRICAL_SLAVE, + SWATH_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE, + SWATH_RANGE_OFFSET_MATCHING_SLAVE, + SWATH_AZIMUTH_OFFSET_MATCHING_SLAVE, + FRAME_RANGE_OFFSET_GEOMETRICAL_MASTER, + FRAME_AZIMUTH_OFFSET_GEOMETRICAL_MASTER, + FRAME_RANGE_OFFSET_MATCHING_MASTER, + FRAME_AZIMUTH_OFFSET_MATCHING_MASTER, + FRAME_RANGE_OFFSET_GEOMETRICAL_SLAVE, + FRAME_AZIMUTH_OFFSET_GEOMETRICAL_SLAVE, + FRAME_RANGE_OFFSET_MATCHING_SLAVE, + FRAME_AZIMUTH_OFFSET_MATCHING_SLAVE, + NUMBER_RANGE_LOOKS1, + NUMBER_AZIMUTH_LOOKS1, + NUMBER_RANGE_LOOKS2, + NUMBER_AZIMUTH_LOOKS2, + NUMBER_RANGE_LOOKS_SIM, + NUMBER_AZIMUTH_LOOKS_SIM, + NUMBER_RANGE_LOOKS_ION, + NUMBER_AZIMUTH_LOOKS_ION, + NUMBER_RANGE_LOOKS_SD, + NUMBER_AZIMUTH_LOOKS_SD, + SUBBAND_RADAR_WAVLENGTH, + RADAR_DEM_AFFINE_TRANSFORM, + MASTER_SLC, + SLAVE_SLC, + MASTER_BURST_PREFIX, + SLAVE_BURST_PREFIX, + MASTER_MAGNITUDE, + SLAVE_MAGNITUDE, + MASTER_SWATH_OFFSET, + SLAVE_SWATH_OFFSET, + MASTER_FRAME_OFFSET, + SLAVE_FRAME_OFFSET, + MASTER_FRAME_PARAMETER, + SLAVE_FRAME_PARAMETER, + MASTER_TRACK_PARAMETER, + SLAVE_TRACK_PARAMETER, + DEM, + DEM_GEO, + WBD, + WBD_OUT, + INTERFEROGRAM, + AMPLITUDE, + DIFFERENTIAL_INTERFEROGRAM, + MULTILOOK_DIFFERENTIAL_INTERFEROGRAM, + MULTILOOK_DIFFERENTIAL_INTERFEROGRAM_ORIGINAL, + MULTILOOK_AMPLITUDE, + MULTILOOK_COHERENCE, + MULTILOOK_PHSIG, + FILTERED_INTERFEROGRAM, + UNWRAPPED_INTERFEROGRAM, + UNWRAPPED_MASKED_INTERFEROGRAM, + LATITUDE, + LONGITUDE, + HEIGHT, + LOS, + SIM, + MSK, + RANGE_OFFSET, + AZIMUTH_OFFSET, + MULTILOOK_LOS, + MULTILOOK_MSK, + MULTILOOK_WBD_OUT, + MULTILOOK_LATITUDE, + MULTILOOK_LONGITUDE, + MULTILOOK_HEIGHT, + MULTILOOK_ION, + RECT_RANGE_OFFSET, + GEO_INTERFEROGRAM, + GEO_MASKED_INTERFEROGRAM, + GEO_COHERENCE, + GEO_LOS, + GEO_ION, + #spectral diversity + INTERFEROGRAM_SD, + MULTILOOK_INTERFEROGRAM_SD, + MULTILOOK_COHERENCE_SD, + FILTERED_INTERFEROGRAM_SD, + UNWRAPPED_INTERFEROGRAM_SD, + UNWRAPPED_MASKED_INTERFEROGRAM_SD, + AZIMUTH_DEFORMATION_SD, + MASKED_AZIMUTH_DEFORMATION_SD, + MULTILOOK_WBD_OUT_SD, + MULTILOOK_LATITUDE_SD, + MULTILOOK_LONGITUDE_SD, + GEO_COHERENCE_SD, + GEO_AZIMUTH_DEFORMATION_SD, + GEO_MASKED_AZIMUTH_DEFORMATION_SD) + + facility_list = () + + + family='alos2burstcontext' + + def __init__(self, name='', procDoc=None): + #self.updatePrivate() + + super().__init__(family=self.__class__.family, name=name) + self.procDoc = procDoc + return None + + def setFilename(self, masterDate, slaveDate, nrlks1, nalks1, nrlks2, nalks2): + + # if masterDate == None: + # masterDate = self.masterDate + # if slaveDate == None: + # slaveDate = self.slaveDate + # if nrlks1 == None: + # nrlks1 = self.numberRangeLooks1 + # if nalks1 == None: + # nalks1 = self.numberAzimuthLooks1 + # if nrlks2 == None: + # nrlks2 = self.numberRangeLooks2 + # if nalks2 == None: + # nalks2 = self.numberAzimuthLooks2 + + ms = masterDate + '-' + slaveDate + ml1 = '_{}rlks_{}alks'.format(nrlks1, nalks1) + ml2 = '_{}rlks_{}alks'.format(nrlks1*nrlks2, nalks1*nalks2) + + self.masterSlc = masterDate + '.slc' + self.slaveSlc = slaveDate + '.slc' + self.masterBurstPrefix = masterDate + self.slaveBurstPrefix = slaveDate + self.masterMagnitude = masterDate + '.mag' + self.slaveMagnitude = slaveDate + '.mag' + self.masterSwathOffset = 'swath_offset_' + masterDate + '.txt' + self.slaveSwathOffset = 'swath_offset_' + slaveDate + '.txt' + self.masterFrameOffset = 'frame_offset_' + masterDate + '.txt' + self.slaveFrameOffset = 'frame_offset_' + slaveDate + '.txt' + self.masterFrameParameter = masterDate + '.frame.xml' + self.slaveFrameParameter = slaveDate + '.frame.xml' + self.masterTrackParameter = masterDate + '.track.xml' + self.slaveTrackParameter = slaveDate + '.track.xml' + #self.dem = + #self.demGeo = + #self.wbd = + self.interferogram = ms + ml1 + '.int' + self.amplitude = ms + ml1 + '.amp' + self.differentialInterferogram = 'diff_' + ms + ml1 + '.int' + self.multilookDifferentialInterferogram = 'diff_' + ms + ml2 + '.int' + self.multilookDifferentialInterferogramOriginal = 'diff_' + ms + ml2 + '_ori.int' + self.multilookAmplitude = ms + ml2 + '.amp' + self.multilookCoherence = ms + ml2 + '.cor' + self.multilookPhsig = ms + ml2 + '.phsig' + self.filteredInterferogram = 'filt_' + ms + ml2 + '.int' + self.unwrappedInterferogram = 'filt_' + ms + ml2 + '.unw' + self.unwrappedMaskedInterferogram = 'filt_' + ms + ml2 + '_msk.unw' + self.latitude = ms + ml1 + '.lat' + self.longitude = ms + ml1 + '.lon' + self.height = ms + ml1 + '.hgt' + self.los = ms + ml1 + '.los' + self.sim = ms + ml1 + '.sim' + self.msk = ms + ml1 + '.msk' + self.wbdOut = ms + ml1 + '.wbd' + self.rangeOffset = ms + ml1 + '_rg.off' + self.azimuthOffset = ms + ml1 + '_az.off' + self.multilookLos = ms + ml2 + '.los' + self.multilookWbdOut = ms + ml2 + '.wbd' + self.multilookMsk = ms + ml2 + '.msk' + self.multilookLatitude = ms + ml2 + '.lat' + self.multilookLongitude = ms + ml2 + '.lon' + self.multilookHeight = ms + ml2 + '.hgt' + self.multilookIon = ms + ml2 + '.ion' + self.rectRangeOffset = ms + ml1 + '_rg_rect.off' + self.geoInterferogram = 'filt_' + ms + ml2 + '.unw.geo' + self.geoMaskedInterferogram = 'filt_' + ms + ml2 + '_msk.unw.geo' + self.geoCoherence = ms + ml2 + '.cor.geo' + self.geoLos = ms + ml2 + '.los.geo' + self.geoIon = ms + ml2 + '.ion.geo' + + + def setFilenameSd(self, masterDate, slaveDate, nrlks1, nalks1, nrlks_sd, nalks_sd, nsd=3): + #spectral diversity + # if masterDate == None: + # masterDate = self.masterDate + # if slaveDate == None: + # slaveDate = self.slaveDate + # if nrlks1 == None: + # nrlks1 = self.numberRangeLooks1 + # if nalks1 == None: + # nalks1 = self.numberAzimuthLooks1 + # if nrlks_sd == None: + # nrlks_sd = self.numberRangeLooksSd + # if nalks_sd == None: + # nalks_sd = self.numberAzimuthLooksSd + + ms = masterDate + '-' + slaveDate + ml1 = '_{}rlks_{}alks'.format(nrlks1, nalks1) + ml2sd = '_{}rlks_{}alks'.format(nrlks1*nrlks_sd, nalks1*nalks_sd) + self.interferogramSd = ['sd_{}_'.format(i+1) + ms + ml1 + '.int' for i in range(nsd)] + self.multilookInterferogramSd = ['sd_{}_'.format(i+1) + ms + ml2sd + '.int' for i in range(nsd)] + self.multilookCoherenceSd = ['filt_{}_'.format(i+1) + ms + ml2sd + '.cor' for i in range(nsd)] + self.filteredInterferogramSd = ['filt_{}_'.format(i+1) + ms + ml2sd + '.int' for i in range(nsd)] + self.unwrappedInterferogramSd = ['filt_{}_'.format(i+1) + ms + ml2sd + '.unw' for i in range(nsd)] + self.unwrappedMaskedInterferogramSd = ['filt_{}_'.format(i+1) + ms + ml2sd + '_msk.unw' for i in range(nsd)] + self.azimuthDeformationSd = ['azd_{}_'.format(i+1) + ms + ml2sd + '.unw' for i in range(nsd)] + self.azimuthDeformationSd.append('azd_' + ms + ml2sd + '.unw') + self.maskedAzimuthDeformationSd = ['azd_{}_'.format(i+1) + ms + ml2sd + '_msk.unw' for i in range(nsd)] + self.maskedAzimuthDeformationSd.append('azd_' + ms + ml2sd + '_msk.unw') + self.multilookWbdOutSd = ms + ml2sd + '.wbd' + self.multilookLatitudeSd = ms + ml2sd + '.lat' + self.multilookLongitudeSd = ms + ml2sd + '.lon' + self.geoCoherenceSd = ['filt_{}_'.format(i+1) + ms + ml2sd + '.cor.geo' for i in range(nsd)] + self.geoAzimuthDeformationSd = ['azd_{}_'.format(i+1) + ms + ml2sd + '.unw.geo' for i in range(nsd)] + self.geoAzimuthDeformationSd.append('azd_' + ms + ml2sd + '.unw.geo') + self.geoMaskedAzimuthDeformationSd = ['azd_{}_'.format(i+1) + ms + ml2sd + '_msk.unw.geo' for i in range(nsd)] + self.geoMaskedAzimuthDeformationSd.append('azd_' + ms + ml2sd + '_msk.unw.geo') + + + 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 loadTrack(self, master=True): + ''' + Load the track using Product Manager. + ''' + if master: + track = self.loadProduct(self.masterTrackParameter) + else: + track = self.loadProduct(self.slaveTrackParameter) + + track.frames = [] + for i, frameNumber in enumerate(self.masterFrames): + os.chdir('f{}_{}'.format(i+1, frameNumber)) + if master: + track.frames.append(self.loadProduct(self.masterFrameParameter)) + else: + track.frames.append(self.loadProduct(self.slaveFrameParameter)) + os.chdir('../') + + return track + + + def saveTrack(self, track, master=True): + ''' + Save the track to XML files using Product Manager. + ''' + if master: + self.saveProduct(track, self.masterTrackParameter) + else: + self.saveProduct(track, self.slaveTrackParameter) + + for i, frameNumber in enumerate(self.masterFrames): + os.chdir('f{}_{}'.format(i+1, frameNumber)) + if master: + self.saveProduct(track.frames[i], self.masterFrameParameter) + else: + self.saveProduct(track.frames[i], self.slaveFrameParameter) + os.chdir('../') + + return None + + + 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 + diff --git a/components/isceobj/Alos2burstProc/Factories.py b/components/isceobj/Alos2burstProc/Factories.py new file mode 100644 index 0000000..0e9aeb7 --- /dev/null +++ b/components/isceobj/Alos2burstProc/Factories.py @@ -0,0 +1,114 @@ +# +# Author: Piyush Agram +# Copyright 2016 +# + +# Path to the _RunWrapper factories +_PATH = "isceobj.Alos2burstProc." + +## A factory to make _RunWrapper factories +def _factory(name, other_name=None, path=_PATH): + """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() == 'downsample_snaphu': + from .run_downsample_unwrapper import 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") +createExtractBurst = _factory("runExtractBurst") +createDownloadDem = _factory("runDownloadDem", path = "isceobj.Alos2Proc.") +createCoregGeom = _factory("runCoregGeom") +createCoregCc = _factory("runCoregCc") +createCoregSd = _factory("runCoregSd") +createSwathOffset = _factory("runSwathOffset") +createSwathMosaic = _factory("runSwathMosaic") +createFrameOffset = _factory("runFrameOffset") +createFrameMosaic = _factory("runFrameMosaic") +createRdr2Geo = _factory("runRdr2Geo", path = "isceobj.Alos2Proc.") +createGeo2Rdr = _factory("runGeo2Rdr", path = "isceobj.Alos2Proc.") +createRdrDemOffset = _factory("runRdrDemOffset", path = "isceobj.Alos2Proc.") +createRectRangeOffset = _factory("runRectRangeOffset", path = "isceobj.Alos2Proc.") +createDiffInterferogram = _factory("runDiffInterferogram", path = "isceobj.Alos2Proc.") +createLook = _factory("runLook", path = "isceobj.Alos2Proc.") +createCoherence = _factory("runCoherence", path = "isceobj.Alos2Proc.") +createIonSubband = _factory("runIonSubband") +createIonUwrap = _factory("runIonUwrap", path = "isceobj.Alos2Proc.") +createIonFilt = _factory("runIonFilt", path = "isceobj.Alos2Proc.") +createFilt = _factory("runFilt", path = "isceobj.Alos2Proc.") +createUnwrapSnaphu = _factory("runUnwrapSnaphu", path = "isceobj.Alos2Proc.") +createGeocode = _factory("runGeocode", path = "isceobj.Alos2Proc.") + +createLookSd = _factory("runLookSd") +createFiltSd = _factory("runFiltSd") +createUnwrapSnaphuSd = _factory("runUnwrapSnaphuSd") +createGeocodeSd = _factory("runGeocodeSd") + + +# steps imported from: Alos2Proc +# ############################################################## +# there is only problem with (at start of script): +# logger = logging.getLogger('isce.alos2insar.runDownloadDem') +# but it looks like OK. + + + + diff --git a/components/isceobj/Alos2burstProc/SConscript b/components/isceobj/Alos2burstProc/SConscript new file mode 100644 index 0000000..7c7055c --- /dev/null +++ b/components/isceobj/Alos2burstProc/SConscript @@ -0,0 +1,45 @@ +#! /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 = 'Alos2burstProc' + +install = os.path.join(envisceobj['PRJ_SCONS_INSTALL'],package,project) + +listFiles = ['__init__.py', 'Factories.py', 'Alos2burstProc.py', 'runPreprocessor.py', 'runExtractBurst.py', 'runCoregGeom.py', 'runCoregCc.py', 'runCoregSd.py', 'runSwathOffset.py', 'runSwathMosaic.py', 'runFrameOffset.py', 'runFrameMosaic.py', 'runIonSubband.py', 'runLookSd.py', 'runFiltSd.py', 'runUnwrapSnaphuSd.py', 'runGeocodeSd.py'] +envisceobj.Install(install,listFiles) +envisceobj.Alias('install',install) diff --git a/components/isceobj/Alos2burstProc/__init__.py b/components/isceobj/Alos2burstProc/__init__.py new file mode 100644 index 0000000..1ed27cf --- /dev/null +++ b/components/isceobj/Alos2burstProc/__init__.py @@ -0,0 +1,22 @@ +# +# Author: Piyush Agram +# Copyright 2016 +# + +from .Alos2burstProc import * +from .Factories import * + +def getFactoriesInfo(): + return {'Alos2burstProc': + {'args': + { + 'procDoc':{'value':None,'type':'Catalog','optional':True} + }, + 'factory':'createAlos2burstProc' + } + + } + +def createAlos2burstProc(name=None, procDoc= None): + from .Alos2burstProc import Alos2burstProc + return Alos2burstProc(name = name,procDoc = procDoc) diff --git a/components/isceobj/Alos2burstProc/readme.txt b/components/isceobj/Alos2burstProc/readme.txt new file mode 100644 index 0000000..19ee0e9 --- /dev/null +++ b/components/isceobj/Alos2burstProc/readme.txt @@ -0,0 +1,13 @@ +order of Doppler and azimuth FM rate polynomials +############################################################## +while Doppler and azimuth FM rate polynomials support 3rd order, try to use smaller order, +because (range sample number)^3 can be very large. There may be float point error that is too +large? + + + + + + + + diff --git a/components/isceobj/Alos2burstProc/runCoregCc.py b/components/isceobj/Alos2burstProc/runCoregCc.py new file mode 100644 index 0000000..87251eb --- /dev/null +++ b/components/isceobj/Alos2burstProc/runCoregCc.py @@ -0,0 +1,306 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import copy +import shutil +import logging +import numpy as np + +import isceobj +from mroipac.ampcor.Ampcor import Ampcor +from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsetsRoipac +from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset +from isceobj.Alos2Proc.Alos2ProcPublic import resampleBursts +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstAmplitude +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstInterferogram +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2burstinsar.runCoregCc') + +def runCoregCc(self): + '''coregister bursts by cross correlation + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + #demFile = os.path.abspath(self._insar.dem) + #wbdFile = os.path.abspath(self._insar.wbd) +############################################################################### + self._insar.rangeResidualOffsetCc = [[] for i in range(len(masterTrack.frames))] + self._insar.azimuthResidualOffsetCc = [[] for i in range(len(masterTrack.frames))] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('processing frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + ################################################## + # estimate cross-correlation offsets + ################################################## + #compute number of offsets to use + wbdImg = isceobj.createImage() + wbdImg.load(self._insar.wbdOut+'.xml') + width = wbdImg.width + length = wbdImg.length + + #initial number of offsets to use + numberOfOffsets = 800 + + #compute land ratio to further determine the number of offsets to use + if self.useWbdForNumberOffsets: + wbd=np.memmap(self._insar.wbdOut, dtype='byte', mode='r', shape=(length, width)) + landRatio = np.sum(wbd==0) / length / width + del wbd + if (landRatio <= 0.00125): + print('\n\nWARNING: land area too small for estimating offsets between master and slave magnitudes at frame {}, swath {}'.format(frameNumber, swathNumber)) + print('set offsets to zero\n\n') + self._insar.rangeResidualOffsetCc[i].append(0.0) + self._insar.azimuthResidualOffsetCc[i].append(0.0) + catalog.addItem('warning message', 'land area too small for estimating offsets between master and slave magnitudes at frame {}, swath {}'.format(frameNumber, swathNumber), 'runCoregCc') + continue + #total number of offsets to use + numberOfOffsets /= landRatio + + #allocate number of offsets in range/azimuth according to image width/length + #number of offsets to use in range/azimuth + numberOfOffsetsRange = int(np.sqrt(numberOfOffsets * width / length)) + numberOfOffsetsAzimuth = int(length / width * np.sqrt(numberOfOffsets * width / length)) + + #this should be better? + numberOfOffsetsRange = int(np.sqrt(numberOfOffsets)) + numberOfOffsetsAzimuth = int(np.sqrt(numberOfOffsets)) + + if numberOfOffsetsRange > int(width/2): + numberOfOffsetsRange = int(width/2) + if numberOfOffsetsAzimuth > int(length/2): + numberOfOffsetsAzimuth = int(length/2) + + if numberOfOffsetsRange < 10: + numberOfOffsetsRange = 10 + if numberOfOffsetsAzimuth < 10: + numberOfOffsetsAzimuth = 10 + + #user's settings + if self.numberRangeOffsets != None: + numberOfOffsetsRange = self.numberRangeOffsets[i][j] + if self.numberAzimuthOffsets != None: + numberOfOffsetsAzimuth = self.numberAzimuthOffsets[i][j] + + catalog.addItem('number of range offsets at frame {}, swath {}'.format(frameNumber, swathNumber), '{}'.format(numberOfOffsetsRange), 'runCoregCc') + catalog.addItem('number of azimuth offsets at frame {}, swath {}'.format(frameNumber, swathNumber), '{}'.format(numberOfOffsetsAzimuth), 'runCoregCc') + + #need to cp to current directory to make it (gdal) work + if not os.path.isfile(self._insar.masterMagnitude): + os.symlink(os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude), self._insar.masterMagnitude) + #shutil.copy2() can overwrite + shutil.copy2(os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude+'.vrt'), self._insar.masterMagnitude+'.vrt') + shutil.copy2(os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude+'.xml'), self._insar.masterMagnitude+'.xml') + + if not os.path.isfile(self._insar.slaveMagnitude): + os.symlink(os.path.join(self._insar.slaveBurstPrefix + '_1_coreg_geom', self._insar.slaveMagnitude), self._insar.slaveMagnitude) + #shutil.copy2() can overwrite + shutil.copy2(os.path.join(self._insar.slaveBurstPrefix + '_1_coreg_geom', self._insar.slaveMagnitude+'.vrt'), self._insar.slaveMagnitude+'.vrt') + shutil.copy2(os.path.join(self._insar.slaveBurstPrefix + '_1_coreg_geom', self._insar.slaveMagnitude+'.xml'), self._insar.slaveMagnitude+'.xml') + + #matching + ampcor = Ampcor(name='insarapp_slcs_ampcor') + ampcor.configure() + + mMag = isceobj.createImage() + mMag.load(self._insar.masterMagnitude+'.xml') + mMag.setAccessMode('read') + mMag.createImage() + + sMag = isceobj.createImage() + sMag.load(self._insar.slaveMagnitude+'.xml') + sMag.setAccessMode('read') + sMag.createImage() + + ampcor.setImageDataType1('real') + ampcor.setImageDataType2('real') + + ampcor.setMasterSlcImage(mMag) + ampcor.setSlaveSlcImage(sMag) + + #MATCH REGION + rgoff = 0 + azoff = 0 + #it seems that we cannot use 0, haven't look into the problem + if rgoff == 0: + rgoff = 1 + if azoff == 0: + azoff = 1 + firstSample = 1 + if rgoff < 0: + firstSample = int(35 - rgoff) + firstLine = 1 + if azoff < 0: + firstLine = int(35 - azoff) + ampcor.setAcrossGrossOffset(rgoff) + ampcor.setDownGrossOffset(azoff) + ampcor.setFirstSampleAcross(firstSample) + ampcor.setLastSampleAcross(mMag.width) + ampcor.setNumberLocationAcross(numberOfOffsetsRange) + ampcor.setFirstSampleDown(firstLine) + ampcor.setLastSampleDown(mMag.length) + ampcor.setNumberLocationDown(numberOfOffsetsAzimuth) + + #MATCH PARAMETERS + ampcor.setWindowSizeWidth(64) + ampcor.setWindowSizeHeight(64) + #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1 + ampcor.setSearchWindowSizeWidth(8) + ampcor.setSearchWindowSizeHeight(8) + + #REST OF THE STUFF + ampcor.setAcrossLooks(1) + ampcor.setDownLooks(1) + ampcor.setOversamplingFactor(64) + ampcor.setZoomWindowSize(16) + #1. The following not set + #Matching Scale for Sample/Line Directions (-) = 1. 1. + #should add the following in Ampcor.py? + #if not set, in this case, Ampcor.py'value is also 1. 1. + #ampcor.setScaleFactorX(1.) + #ampcor.setScaleFactorY(1.) + + #MATCH THRESHOLDS AND DEBUG DATA + #2. The following not set + #in roi_pac the value is set to 0 1 + #in isce the value is set to 0.001 1000.0 + #SNR and Covariance Thresholds (-) = {s1} {s2} + #should add the following in Ampcor? + #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC + #ampcor.setThresholdSNR(0) + #ampcor.setThresholdCov(1) + ampcor.setDebugFlag(False) + ampcor.setDisplayFlag(False) + + #in summary, only two things not set which are indicated by 'The following not set' above. + + #run ampcor + ampcor.ampcor() + offsets = ampcor.getOffsetField() + refinedOffsets = cullOffsetsRoipac(offsets, numThreshold=50) + + #finalize image, and re-create it + #otherwise the file pointer is still at the end of the image + mMag.finalizeImage() + sMag.finalizeImage() + + #clear up + os.remove(self._insar.masterMagnitude) + os.remove(self._insar.masterMagnitude+'.vrt') + os.remove(self._insar.masterMagnitude+'.xml') + os.remove(self._insar.slaveMagnitude) + os.remove(self._insar.slaveMagnitude+'.vrt') + os.remove(self._insar.slaveMagnitude+'.xml') + + #compute average offsets to use in resampling + if refinedOffsets == None: + rangeOffset = 0 + azimuthOffset = 0 + self._insar.rangeResidualOffsetCc[i].append(rangeOffset) + self._insar.azimuthResidualOffsetCc[i].append(azimuthOffset) + print('\n\nWARNING: too few offsets left in matching master and slave magnitudes at frame {}, swath {}'.format(frameNumber, swathNumber)) + print('set offsets to zero\n\n') + catalog.addItem('warning message', 'too few offsets left in matching master and slave magnitudes at frame {}, swath {}'.format(frameNumber, swathNumber), 'runCoregCc') + else: + rangeOffset, azimuthOffset = meanOffset(refinedOffsets) + #for range offset, need to compute from a polynomial + #see components/isceobj/Location/Offset.py and components/isceobj/Util/Library/python/Poly2D.py for definations + (azimuthPoly, rangePoly) = refinedOffsets.getFitPolynomials(rangeOrder=2,azimuthOrder=2) + #make a deep copy, otherwise it also changes original coefficient list of rangePoly, which affects following rangePoly(*, *) computation + polyCoeff = copy.deepcopy(rangePoly.getCoeffs()) + rgIndex = (np.arange(width)-rangePoly.getMeanRange())/rangePoly.getNormRange() + azIndex = (np.arange(length)-rangePoly.getMeanAzimuth())/rangePoly.getNormAzimuth() + rangeOffset = polyCoeff[0][0] + polyCoeff[0][1]*rgIndex[None,:] + polyCoeff[0][2]*rgIndex[None,:]**2 + \ + (polyCoeff[1][0] + polyCoeff[1][1]*rgIndex[None,:]) * azIndex[:, None] + \ + polyCoeff[2][0] * azIndex[:, None]**2 + polyCoeff.append([rangePoly.getMeanRange(), rangePoly.getNormRange(), rangePoly.getMeanAzimuth(), rangePoly.getNormAzimuth()]) + self._insar.rangeResidualOffsetCc[i].append(polyCoeff) + self._insar.azimuthResidualOffsetCc[i].append(azimuthOffset) + + catalog.addItem('range residual offset at {} {} at frame {}, swath {}'.format(0, 0, frameNumber, swathNumber), + '{}'.format(rangePoly(0, 0)), 'runCoregCc') + catalog.addItem('range residual offset at {} {} at frame {}, swath {}'.format(0, width-1, frameNumber, swathNumber), + '{}'.format(rangePoly(0, width-1)), 'runCoregCc') + catalog.addItem('range residual offset at {} {} at frame {}, swath {}'.format(length-1, 0, frameNumber, swathNumber), + '{}'.format(rangePoly(length-1, 0)), 'runCoregCc') + catalog.addItem('range residual offset at {} {} at frame {}, swath {}'.format(length-1,width-1, frameNumber, swathNumber), + '{}'.format(rangePoly(length-1,width-1)), 'runCoregCc') + catalog.addItem('azimuth residual offset at frame {}, swath {}'.format(frameNumber, swathNumber), + '{}'.format(azimuthOffset), 'runCoregCc') + + DEBUG=False + if DEBUG: + print('+++++++++++++++++++++++++++++') + print(rangeOffset[0,0], rangePoly(0, 0)) + print(rangeOffset[0,width-1], rangePoly(0, width-1)) + print(rangeOffset[length-1,0], rangePoly(length-1, 0)) + print(rangeOffset[length-1,width-1], rangePoly(length-1,width-1)) + print(rangeOffset[int((length-1)/2),int((width-1)/2)], rangePoly(int((length-1)/2),int((width-1)/2))) + print('+++++++++++++++++++++++++++++') + + + ################################################## + # resample bursts + ################################################## + slaveBurstResampledDir = self._insar.slaveBurstPrefix + '_2_coreg_cc' + #interferogramDir = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + '_coreg_geom' + interferogramDir = 'burst_interf_2_coreg_cc' + interferogramPrefix = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + resampleBursts(masterSwath, slaveSwath, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, slaveBurstResampledDir, interferogramDir, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, self._insar.slaveBurstPrefix, interferogramPrefix, + self._insar.rangeOffset, self._insar.azimuthOffset, rangeOffsetResidual=rangeOffset, azimuthOffsetResidual=azimuthOffset) + + + ################################################## + # mosaic burst amplitudes and interferograms + ################################################## + os.chdir(slaveBurstResampledDir) + mosaicBurstAmplitude(masterSwath, self._insar.slaveBurstPrefix, self._insar.slaveMagnitude, numberOfLooksThreshold=4) + os.chdir('../') + + os.chdir(interferogramDir) + mosaicBurstInterferogram(masterSwath, interferogramPrefix, self._insar.interferogram, numberOfLooksThreshold=4) + os.chdir('../') + + + ################################################## + # final amplitude and interferogram + ################################################## + amp = np.zeros((masterSwath.numberOfLines, 2*masterSwath.numberOfSamples), dtype=np.float32) + amp[0:, 1:masterSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(slaveBurstResampledDir, self._insar.slaveMagnitude), \ + dtype=np.float32).reshape(masterSwath.numberOfLines, masterSwath.numberOfSamples) + amp[0:, 0:masterSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude), \ + dtype=np.float32).reshape(masterSwath.numberOfLines, masterSwath.numberOfSamples) + amp.astype(np.float32).tofile(self._insar.amplitude) + create_xml(self._insar.amplitude, masterSwath.numberOfSamples, masterSwath.numberOfLines, 'amp') + + os.rename(os.path.join(interferogramDir, self._insar.interferogram), self._insar.interferogram) + os.rename(os.path.join(interferogramDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + os.rename(os.path.join(interferogramDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + + os.chdir('../') + os.chdir('../') + +############################################################################### + catalog.printToLog(logger, "runCoregCc") + self._insar.procDoc.addAllFromCatalog(catalog) + + + diff --git a/components/isceobj/Alos2burstProc/runCoregGeom.py b/components/isceobj/Alos2burstProc/runCoregGeom.py new file mode 100644 index 0000000..48a545b --- /dev/null +++ b/components/isceobj/Alos2burstProc/runCoregGeom.py @@ -0,0 +1,142 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.runRdr2Geo import topoCPU +from isceobj.Alos2Proc.runRdr2Geo import topoGPU +from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrCPU +from isceobj.Alos2Proc.runGeo2Rdr import geo2RdrGPU +from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar +from isceobj.Alos2Proc.Alos2ProcPublic import resampleBursts +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstAmplitude +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstInterferogram + +logger = logging.getLogger('isce.alos2burstinsar.runCoregGeom') + +def runCoregGeom(self): + '''compute geometric offset + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + demFile = os.path.abspath(self._insar.dem) + wbdFile = os.path.abspath(self._insar.wbd) +############################################################################### + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('processing frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + + ################################################## + # compute geometric offsets + ################################################## + #set up track parameters just for computing offsets + #ALL track parameters are listed here + #master + #masterTrack.passDirection = + #masterTrack.pointingDirection = + #masterTrack.operationMode = + #masterTrack.radarWavelength = + masterTrack.numberOfSamples = masterSwath.numberOfSamples + masterTrack.numberOfLines = masterSwath.numberOfLines + masterTrack.startingRange = masterSwath.startingRange + #masterTrack.rangeSamplingRate = + masterTrack.rangePixelSize = masterSwath.rangePixelSize + masterTrack.sensingStart = masterSwath.sensingStart + #masterTrack.prf = + #masterTrack.azimuthPixelSize = + masterTrack.azimuthLineInterval = masterSwath.azimuthLineInterval + #masterTrack.dopplerVsPixel = + #masterTrack.frames = + #masterTrack.orbit = + + #slave + slaveTrack.numberOfSamples = slaveSwath.numberOfSamples + slaveTrack.numberOfLines = slaveSwath.numberOfLines + slaveTrack.startingRange = slaveSwath.startingRange + slaveTrack.rangePixelSize = slaveSwath.rangePixelSize + slaveTrack.sensingStart = slaveSwath.sensingStart + slaveTrack.azimuthLineInterval = slaveSwath.azimuthLineInterval + + if self.useGPU and self._insar.hasGPU(): + topoGPU(masterTrack, 1, 1, demFile, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.los) + geo2RdrGPU(slaveTrack, 1, 1, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.rangeOffset, self._insar.azimuthOffset) + else: + topoCPU(masterTrack, 1, 1, demFile, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.los) + geo2RdrCPU(slaveTrack, 1, 1, + self._insar.latitude, self._insar.longitude, self._insar.height, self._insar.rangeOffset, self._insar.azimuthOffset) + + waterBodyRadar(self._insar.latitude, self._insar.longitude, wbdFile, self._insar.wbdOut) + + #clear up, leaving only range/azimuth offsets + os.remove(self._insar.latitude) + os.remove(self._insar.latitude+'.vrt') + os.remove(self._insar.latitude+'.xml') + os.remove(self._insar.longitude) + os.remove(self._insar.longitude+'.vrt') + os.remove(self._insar.longitude+'.xml') + os.remove(self._insar.height) + os.remove(self._insar.height+'.vrt') + os.remove(self._insar.height+'.xml') + os.remove(self._insar.los) + os.remove(self._insar.los+'.vrt') + os.remove(self._insar.los+'.xml') + + + ################################################## + # resample bursts + ################################################## + slaveBurstResampledDir = self._insar.slaveBurstPrefix + '_1_coreg_geom' + #interferogramDir = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + '_coreg_geom' + interferogramDir = 'burst_interf_1_coreg_geom' + interferogramPrefix = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + resampleBursts(masterSwath, slaveSwath, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, slaveBurstResampledDir, interferogramDir, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, self._insar.slaveBurstPrefix, interferogramPrefix, + self._insar.rangeOffset, self._insar.azimuthOffset, rangeOffsetResidual=0, azimuthOffsetResidual=0) + + + ################################################## + # mosaic burst amplitudes and interferograms + ################################################## + os.chdir(slaveBurstResampledDir) + mosaicBurstAmplitude(masterSwath, self._insar.slaveBurstPrefix, self._insar.slaveMagnitude, numberOfLooksThreshold=4) + os.chdir('../') + + #the interferogram is not good enough, do not mosaic + mosaic=False + if mosaic: + os.chdir(interferogramDir) + mosaicBurstInterferogram(masterSwath, interferogramPrefix, self._insar.interferogram, numberOfLooksThreshold=4) + os.chdir('../') + + + os.chdir('../') + os.chdir('../') + +############################################################################### + catalog.printToLog(logger, "runCoregGeom") + self._insar.procDoc.addAllFromCatalog(catalog) + + + diff --git a/components/isceobj/Alos2burstProc/runCoregSd.py b/components/isceobj/Alos2burstProc/runCoregSd.py new file mode 100644 index 0000000..b0e9911 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runCoregSd.py @@ -0,0 +1,236 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import resampleBursts +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstAmplitude +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstInterferogram + +logger = logging.getLogger('isce.alos2burstinsar.runCoregSd') + +def runCoregSd(self): + '''coregister bursts by spectral diversity + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + #demFile = os.path.abspath(self._insar.dem) + #wbdFile = os.path.abspath(self._insar.wbd) +############################################################################### + #self._insar.rangeResidualOffsetSd = [[] for i in range(len(masterTrack.frames))] + self._insar.azimuthResidualOffsetSd = [[] for i in range(len(masterTrack.frames))] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('processing frame {}, swath {}'.format(frameNumber, swathNumber)) + + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + ################################################## + # spectral diversity or mai + ################################################## + sdDir = 'spectral_diversity' + if not os.path.exists(sdDir): + os.makedirs(sdDir) + os.chdir(sdDir) + + interferogramDir = 'burst_interf_2_coreg_cc' + interferogramPrefix = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + offsetSd = spectralDiversity(masterSwath, os.path.join('../', interferogramDir), interferogramPrefix, self._insar.interferogramSd, + numberLooksScanSAR=4, numberRangeLooks=28, numberAzimuthLooks=8, coherenceThreshold=0.85, + keep=True, filt=True, filtWinSizeRange=5, filtWinSizeAzimuth=5) + #here use the number of looks for sd as filtWinSizeRange and filtWinSizeAzimuth to get the best filtering result? + + os.chdir('../') + + self._insar.azimuthResidualOffsetSd[i].append(offsetSd) + catalog.addItem('azimuth residual offset at frame {}, swath {}'.format(frameNumber, swathNumber), '{}'.format(offsetSd), 'runCoregSd') + + + #this small residual azimuth offset has small impact, it's not worth the time to resample slave bursts again. + formInterferogram=False + if formInterferogram: + ################################################## + # resample bursts + ################################################## + slaveBurstResampledDir = self._insar.slaveBurstPrefix + '_3_coreg_sd' + #interferogramDir = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + '_coreg_geom' + interferogramDir = 'burst_interf_3_coreg_sd' + interferogramPrefix = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + resampleBursts(masterSwath, slaveSwath, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, slaveBurstResampledDir, interferogramDir, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, self._insar.slaveBurstPrefix, interferogramPrefix, + self._insar.rangeOffset, self._insar.azimuthOffset, rangeOffsetResidual=self._insar.rangeResidualOffsetCc[i][j], azimuthOffsetResidual=self._insar.azimuthResidualOffsetCc[i][j]+offsetSd) + + + ################################################## + # mosaic burst amplitudes and interferograms + ################################################## + os.chdir(slaveBurstResampledDir) + mosaicBurstAmplitude(masterSwath, self._insar.slaveBurstPrefix, self._insar.slaveMagnitude, numberOfLooksThreshold=4) + os.chdir('../') + + os.chdir(interferogramDir) + mosaicBurstInterferogram(masterSwath, interferogramPrefix, self._insar.interferogram, numberOfLooksThreshold=4) + os.chdir('../') + + + os.chdir('../') + os.chdir('../') + +############################################################################### + catalog.printToLog(logger, "runCoregSd") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def spectralDiversity(masterSwath, interferogramDir, interferogramPrefix, outputList, numberLooksScanSAR=None, numberRangeLooks=20, numberAzimuthLooks=10, coherenceThreshold=0.85, keep=False, filt=False, filtWinSizeRange=5, filtWinSizeAzimuth=5): + ''' + numberLooksScanSAR: number of looks of the ScanSAR system + numberRangeLooks: number of range looks to take + numberAzimuthLooks: number of azimuth looks to take + keep: whether keep intermediate files + ''' + import os + import numpy as np + from isceobj.Alos2Proc.Alos2ProcPublic import create_multi_index + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + from isceobj.Alos2Proc.Alos2ProcPublic import multilook + from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1 + + width = masterSwath.numberOfSamples + length = masterSwath.numberOfLines + lengthBurst = masterSwath.burstSlcNumberOfLines + nBurst = masterSwath.numberOfBursts + azsi = masterSwath.azimuthLineInterval + tc = masterSwath.burstCycleLength / masterSwath.prf + + bursts = [os.path.join(interferogramDir, interferogramPrefix+'_%02d.int'%(i+1)) for i in range(masterSwath.numberOfBursts)] + + #################################################### + #input parameters + rgl = numberRangeLooks + azl = numberAzimuthLooks + cor_th = coherenceThreshold + nls0 = lengthBurst / (masterSwath.burstSlcFirstLineOffsets[nBurst-1] / (nBurst-1.0)) + print('number of looks of the ScanSAR system: {}'.format(nls0)) + if numberLooksScanSAR != None: + nls = numberLooksScanSAR + else: + nls = int(nls0) + print('number of looks to be used: {}'.format(nls)) + #################################################### + + #read burst interferograms + inf = np.zeros((length, width, nls), dtype=np.complex64) + cnt = np.zeros((length, width), dtype=np.int8) + for i in range(nBurst): + if (i+1)%5 == 0 or (i+1) == nBurst: + print('reading burst %02d' % (i+1)) + + burst = np.fromfile(bursts[i], dtype=np.complex64).reshape(lengthBurst, width) + + #subset for the burst + cntBurst = cnt[0+masterSwath.burstSlcFirstLineOffsets[i]:lengthBurst+masterSwath.burstSlcFirstLineOffsets[i], :] + infBurst = inf[0+masterSwath.burstSlcFirstLineOffsets[i]:lengthBurst+masterSwath.burstSlcFirstLineOffsets[i], :, :] + + #set number of non-zero pixels + cntBurst[np.nonzero(burst)] += 1 + + #get index + index1 = np.nonzero(np.logical_and(burst!=0, cntBurst<=nls)) + index2 = index1 + (cntBurst[index1]-1,) + + #set values + infBurst[index2] = burst[index1] + + #number of looks for each sample + if keep: + nlFile = 'number_of_looks.nl' + cnt.astype(np.int8).tofile(nlFile) + create_xml(nlFile, width, length, 'byte') + + if filt: + import scipy.signal as ss + filterKernel = np.ones((filtWinSizeAzimuth,filtWinSizeRange), dtype=np.float64) + for i in range(nls): + print('filtering look {}'.format(i+1)) + flag = (inf[:,:,i]!=0) + #scale = ss.fftconvolve(flag, filterKernel, mode='same') + #inf[:,:,i] = flag*ss.fftconvolve(inf[:,:,i], filterKernel, mode='same') / (scale + (scale==0)) + #this should be faster? + scale = ss.convolve2d(flag, filterKernel, mode='same') + inf[:,:,i] = flag*ss.convolve2d(inf[:,:,i], filterKernel, mode='same') / (scale + (scale==0)) + + #width and length after multilooking + widthm = int(width/rgl) + lengthm = int(length/azl) + #use the convention that ka > 0 + ka = -np.polyval(masterSwath.azimuthFmrateVsPixel[::-1], create_multi_index(width, rgl)) + + #get spectral diversity inteferogram + offset_sd=[] + for i in range(1, nls): + print('ouput spectral diversity inteferogram %d' % i) + #original spectral diversity inteferogram + sd = inf[:,:,0] * np.conj(inf[:,:,i]) + + #replace original amplitude with its square root + index = np.nonzero(sd!=0) + sd[index] /= np.sqrt(np.absolute(sd[index])) + + sdFile = outputList[i-1] + sd.astype(np.complex64).tofile(sdFile) + create_xml(sdFile, width, length, 'int') + + #multi look + sdm = multilook(sd, azl, rgl) + cor = cal_coherence_1(sdm) + + #convert phase to offset + offset = np.angle(sdm)/(2.0 * np.pi * ka * tc * i)[None,:] / azsi + + #compute offset using good samples + point_index = np.nonzero(np.logical_and(cor>=cor_th, np.angle(sdm)!=0)) + npoint = round(np.size(point_index)/2) + if npoint < 20: + print('WARNING: too few good samples for spectral diversity at look {}: {}'.format(i, npoint)) + offset_sd.append(0) + else: + offset_sd.append( np.sum(offset[point_index]*cor[point_index])/np.sum(cor[point_index]) ) + + if keep: + sdmFile = 'sd_%d_%drlks_%dalks.int' % (i, rgl, azl) + sdm.astype(np.complex64).tofile(sdmFile) + create_xml(sdmFile, widthm, lengthm, 'int') + corFile = 'sd_%d_%drlks_%dalks.cor' % (i, rgl, azl) + cor.astype(np.float32).tofile(corFile) + create_xml(corFile, widthm, lengthm, 'float') + offsetFile = 'sd_%d_%drlks_%dalks.off' % (i, rgl, azl) + offset.astype(np.float32).tofile(offsetFile) + create_xml(offsetFile, widthm, lengthm, 'float') + + offset_mean = np.sum(np.array(offset_sd) * np.arange(1, nls)) / np.sum(np.arange(1, nls)) + + return offset_mean + + + + + + + + diff --git a/components/isceobj/Alos2burstProc/runExtractBurst.py b/components/isceobj/Alos2burstProc/runExtractBurst.py new file mode 100644 index 0000000..1ec8de3 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runExtractBurst.py @@ -0,0 +1,136 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +#import subprocess +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml +from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstAmplitude +from contrib.alos2proc.alos2proc import extract_burst + +logger = logging.getLogger('isce.alos2burstinsar.runExtractBurst') + +def runExtractBurst(self): + '''extract bursts. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + #demFile = os.path.abspath(self._insar.dem) + #wbdFile = os.path.abspath(self._insar.wbd) +############################################################################### + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + os.chdir(swathDir) + + print('extracting bursts frame {}, swath {}'.format(frameNumber, swathNumber)) + + az_ratio1 = 20.0 + for k in range(2): + if k==0: + #master + swath = masterTrack.frames[i].swaths[j] + unsynLines = self._insar.burstUnsynchronizedTime * swath.prf + extractDir = self._insar.masterBurstPrefix + burstPrefix = self._insar.masterBurstPrefix + fullApertureSlc = self._insar.masterSlc + magnitude = self._insar.masterMagnitude + else: + #slave + swath = slaveTrack.frames[i].swaths[j] + unsynLines = -self._insar.burstUnsynchronizedTime * swath.prf + extractDir = self._insar.slaveBurstPrefix + burstPrefix = self._insar.slaveBurstPrefix + fullApertureSlc = self._insar.slaveSlc + magnitude = self._insar.slaveMagnitude + + #UPDATE SWATH PARAMETERS 1 + ######################################################################################### + if self._insar.burstSynchronization <= self.burstSynchronizationThreshold: + swath.burstLength -= abs(unsynLines) + if unsynLines < 0: + swath.burstStartTime += datetime.timedelta(seconds=abs(unsynLines)/swath.prf) + ######################################################################################### + + #extract burst + if not os.path.exists(extractDir): + os.makedirs(extractDir) + os.chdir(extractDir) + if os.path.isfile(os.path.join('../', fullApertureSlc)): + os.rename(os.path.join('../', fullApertureSlc), fullApertureSlc) + os.rename(os.path.join('../', fullApertureSlc+'.vrt'), fullApertureSlc+'.vrt') + os.rename(os.path.join('../', fullApertureSlc+'.xml'), fullApertureSlc+'.xml') + + extract_burst(fullApertureSlc, burstPrefix, swath.prf, swath.prfFraction, swath.burstLength, swath.burstCycleLength-swath.burstLength, \ + (swath.burstStartTime - swath.sensingStart).total_seconds() * swath.prf, swath.azimuthFmrateVsPixel, swath.dopplerVsPixel, az_ratio1, 0.0) + + #read output parameters + with open('extract_burst.txt', 'r') as f: + lines = f.readlines() + offsetFromFirstBurst = [] + for linex in lines: + if 'total number of bursts extracted' in linex: + numberOfBursts = int(linex.split(':')[1]) + if 'output burst length' in linex: + burstSlcNumberOfLines = int(linex.split(':')[1]) + if 'line number of first line of first output burst in original SLC (1.0/prf)' in linex: + fb_ln = float(linex.split(':')[1]) + if 'bsl of first output burst' in linex: + bsl_firstburst = float(linex.split(':')[1]) + if 'offset from first burst' in linex: + offsetFromFirstBurst.append(int(linex.split(',')[0].split(':')[1])) + + #time of first line of first burst raw + firstBurstRawStartTime = swath.sensingStart + datetime.timedelta(seconds=bsl_firstburst/swath.prf) + + #time of first line of first burst slc + #original time is at the upper edge of first line, we change it to center of first line. + sensingStart = swath.sensingStart + datetime.timedelta(seconds=fb_ln/swath.prf+(az_ratio1-1.0)/2.0/swath.prf) + numberOfLines = offsetFromFirstBurst[numberOfBursts-1] + burstSlcNumberOfLines + + for ii in range(numberOfBursts): + burstFile = burstPrefix + '_%02d.slc'%(ii+1) + create_xml(burstFile, swath.numberOfSamples, burstSlcNumberOfLines, 'slc') + + #UPDATE SWATH PARAMETERS 2 + ######################################################################################### + swath.numberOfLines = numberOfLines + #this is also the time of the first line of the first burst slc + swath.sensingStart = sensingStart + swath.azimuthPixelSize = az_ratio1 * swath.azimuthPixelSize + swath.azimuthLineInterval = az_ratio1 * swath.azimuthLineInterval + + swath.numberOfBursts = numberOfBursts + swath.firstBurstRawStartTime = firstBurstRawStartTime + swath.firstBurstSlcStartTime = sensingStart + swath.burstSlcFirstLineOffsets = offsetFromFirstBurst + swath.burstSlcNumberOfSamples = swath.numberOfSamples + swath.burstSlcNumberOfLines = burstSlcNumberOfLines + ######################################################################################### + + #create a magnitude image + mosaicBurstAmplitude(swath, burstPrefix, magnitude, numberOfLooksThreshold=4) + + os.chdir('../') + os.chdir('../') + self._insar.saveProduct(masterTrack.frames[i], self._insar.masterFrameParameter) + self._insar.saveProduct(slaveTrack.frames[i], self._insar.slaveFrameParameter) + os.chdir('../') + +############################################################################### + catalog.printToLog(logger, "runExtractBurst") + self._insar.procDoc.addAllFromCatalog(catalog) + diff --git a/components/isceobj/Alos2burstProc/runFiltSd.py b/components/isceobj/Alos2burstProc/runFiltSd.py new file mode 100644 index 0000000..e19ae36 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runFiltSd.py @@ -0,0 +1,94 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import shutil +import logging +import numpy as np + +import isceobj +from mroipac.filter.Filter import Filter +from mroipac.icu.Icu import Icu +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from isceobj.Alos2Proc.Alos2ProcPublic import renameFile +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml +from contrib.alos2filter.alos2filter import psfilt1 +from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence + +logger = logging.getLogger('isce.alos2burstinsar.runFiltSd') + +def runFiltSd(self): + '''filter interferogram + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + #masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + sdDir = 'sd' + if not os.path.exists(sdDir): + os.makedirs(sdDir) + os.chdir(sdDir) + + sd = isceobj.createImage() + sd.load(self._insar.multilookInterferogramSd[0]+'.xml') + width = sd.width + length = sd.length + + ############################################################ + # STEP 1. filter interferogram + ############################################################ + for sdInterferogram, sdInterferogramFilt, sdCoherence in zip(self._insar.multilookInterferogramSd, self._insar.filteredInterferogramSd, self._insar.multilookCoherenceSd): + print('filter interferogram: {}'.format(sdInterferogram)) + #remove mangnitude + data = np.fromfile(sdInterferogram, dtype=np.complex64).reshape(length, width) + index = np.nonzero(data!=0) + data[index] /= np.absolute(data[index]) + data.astype(np.complex64).tofile('tmp.int') + + #filter + windowSize = self.filterWinsizeSd + stepSize = self.filterStepsizeSd + psfilt1('tmp.int', sdInterferogramFilt, width, self.filterStrengthSd, windowSize, stepSize) + create_xml(sdInterferogramFilt, width, length, 'int') + os.remove('tmp.int') + + #restore magnitude + data = np.fromfile(sdInterferogram, dtype=np.complex64).reshape(length, width) + dataFilt = np.fromfile(sdInterferogramFilt, dtype=np.complex64).reshape(length, width) + index = np.nonzero(dataFilt!=0) + dataFilt[index] = dataFilt[index] / np.absolute(dataFilt[index]) * np.absolute(data[index]) + dataFilt.astype(np.complex64).tofile(sdInterferogramFilt) + + # #create a coherence using an interferogram with most sparse fringes + # if sdInterferogramFilt == self._insar.filteredInterferogramSd[0]: + # print('create coherence using: {}'.format(sdInterferogramFilt)) + # cor = cal_coherence(dataFilt, win=3, edge=2) + # cor.astype(np.float32).tofile(self._insar.multilookCoherenceSd) + # create_xml(self._insar.multilookCoherenceSd, width, length, 'float') + + cor = cal_coherence(dataFilt, win=3, edge=2) + cor.astype(np.float32).tofile(sdCoherence) + create_xml(sdCoherence, width, length, 'float') + + + ############################################################ + # STEP 3. mask filtered interferogram using water body + ############################################################ + if self.waterBodyMaskStartingStepSd=='filt': + print('mask filtered interferogram using: {}'.format(self._insar.multilookWbdOutSd)) + wbd = np.fromfile(self._insar.multilookWbdOutSd, dtype=np.int8).reshape(length, width) + cor=np.memmap(self._insar.multilookCoherenceSd, dtype='float32', mode='r+', shape=(length, width)) + cor[np.nonzero(wbd==-1)]=0 + for sdInterferogramFilt in self._insar.filteredInterferogramSd: + filt=np.memmap(sdInterferogramFilt, dtype='complex64', mode='r+', shape=(length, width)) + filt[np.nonzero(wbd==-1)]=0 + + os.chdir('../') + + catalog.printToLog(logger, "runFiltSd") + self._insar.procDoc.addAllFromCatalog(catalog) + diff --git a/components/isceobj/Alos2burstProc/runFrameMosaic.py b/components/isceobj/Alos2burstProc/runFrameMosaic.py new file mode 100644 index 0000000..d3cf9fb --- /dev/null +++ b/components/isceobj/Alos2burstProc/runFrameMosaic.py @@ -0,0 +1,172 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.runFrameMosaic import frameMosaic +from isceobj.Alos2Proc.runFrameMosaic import frameMosaicParameters +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2burstinsar.runFrameMosaic') + +def runFrameMosaic(self): + '''mosaic frames + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + mosaicDir = 'insar' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + numberOfFrames = len(masterTrack.frames) + if numberOfFrames == 1: + import shutil + frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.masterFrames[0])) + if not os.path.isfile(self._insar.interferogram): + os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + #shutil.copy2() can overwrite + shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + if not os.path.isfile(self._insar.amplitude): + os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + # os.rename(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + # os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # os.rename(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + # os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + #update track parameters + ######################################################### + #mosaic size + masterTrack.numberOfSamples = masterTrack.frames[0].numberOfSamples + masterTrack.numberOfLines = masterTrack.frames[0].numberOfLines + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + masterTrack.startingRange = masterTrack.frames[0].startingRange + masterTrack.rangeSamplingRate = masterTrack.frames[0].rangeSamplingRate + masterTrack.rangePixelSize = masterTrack.frames[0].rangePixelSize + #azimuth parameters + masterTrack.sensingStart = masterTrack.frames[0].sensingStart + masterTrack.prf = masterTrack.frames[0].prf + masterTrack.azimuthPixelSize = masterTrack.frames[0].azimuthPixelSize + masterTrack.azimuthLineInterval = masterTrack.frames[0].azimuthLineInterval + + #update track parameters, slave + ######################################################### + #mosaic size + slaveTrack.numberOfSamples = slaveTrack.frames[0].numberOfSamples + slaveTrack.numberOfLines = slaveTrack.frames[0].numberOfLines + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + slaveTrack.startingRange = slaveTrack.frames[0].startingRange + slaveTrack.rangeSamplingRate = slaveTrack.frames[0].rangeSamplingRate + slaveTrack.rangePixelSize = slaveTrack.frames[0].rangePixelSize + #azimuth parameters + slaveTrack.sensingStart = slaveTrack.frames[0].sensingStart + slaveTrack.prf = slaveTrack.frames[0].prf + slaveTrack.azimuthPixelSize = slaveTrack.frames[0].azimuthPixelSize + slaveTrack.azimuthLineInterval = slaveTrack.frames[0].azimuthLineInterval + + else: + #choose offsets + if self.frameOffsetMatching: + rangeOffsets = self._insar.frameRangeOffsetMatchingMaster + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster + else: + rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + inputInterferograms.append(os.path.join('../', frameDir, 'mosaic', self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', frameDir, 'mosaic', self._insar.amplitude)) + + #note that track parameters are updated after mosaicking + #mosaic amplitudes + frameMosaic(masterTrack, inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=False, resamplingMethod=0) + #mosaic interferograms + frameMosaic(masterTrack, inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=True, phaseCompensation=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'int') + + #update slave parameters here + #do not match for slave, always use geometrical + rangeOffsets = self._insar.frameRangeOffsetGeometricalSlave + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalSlave + frameMosaicParameters(slaveTrack, rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1) + + os.chdir('../') + #save parameter file + self._insar.saveProduct(masterTrack, self._insar.masterTrackParameter) + self._insar.saveProduct(slaveTrack, self._insar.slaveTrackParameter) + + + + #mosaic spectral diversity inteferograms + mosaicDir = 'sd' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + numberOfFrames = len(masterTrack.frames) + if numberOfFrames == 1: + import shutil + frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.masterFrames[0])) + for sdFile in self._insar.interferogramSd: + if not os.path.isfile(sdFile): + os.symlink(os.path.join('../', frameDir, sdFile), sdFile) + shutil.copy2(os.path.join('../', frameDir, sdFile+'.vrt'), sdFile+'.vrt') + shutil.copy2(os.path.join('../', frameDir, sdFile+'.xml'), sdFile+'.xml') + else: + #choose offsets + if self.frameOffsetMatching: + rangeOffsets = self._insar.frameRangeOffsetMatchingMaster + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster + else: + rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster + + #list of input files + inputSd = [[], [], []] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + for k, sdFile in enumerate(self._insar.interferogramSd): + inputSd[k].append(os.path.join('../', frameDir, 'mosaic', sdFile)) + + #mosaic spectral diversity interferograms + for inputSdList, outputSdFile in zip(inputSd, self._insar.interferogramSd): + frameMosaic(masterTrack, inputSdList, outputSdFile, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=True, resamplingMethod=1) + + for sdFile in self._insar.interferogramSd: + create_xml(sdFile, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'int') + + os.chdir('../') + + + catalog.printToLog(logger, "runFrameMosaic") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2burstProc/runFrameOffset.py b/components/isceobj/Alos2burstProc/runFrameOffset.py new file mode 100644 index 0000000..983a3a2 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runFrameOffset.py @@ -0,0 +1,55 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.runFrameOffset import frameOffset + +logger = logging.getLogger('isce.alos2burstinsar.runFrameOffset') + +def runFrameOffset(self): + '''estimate frame offsets. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + mosaicDir = 'insar' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if len(masterTrack.frames) > 1: + #here we use master amplitude image mosaicked from extracted bursts. + matchingMode=1 + + #compute swath offset + offsetMaster = frameOffset(masterTrack, os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude), self._insar.masterFrameOffset, + crossCorrelation=self.frameOffsetMatching, matchingMode=matchingMode) + #only use geometrical offset for slave + offsetSlave = frameOffset(slaveTrack, os.path.join(self._insar.slaveBurstPrefix, self._insar.slaveMagnitude), self._insar.slaveFrameOffset, + crossCorrelation=False, matchingMode=matchingMode) + + self._insar.frameRangeOffsetGeometricalMaster = offsetMaster[0] + self._insar.frameAzimuthOffsetGeometricalMaster = offsetMaster[1] + self._insar.frameRangeOffsetGeometricalSlave = offsetSlave[0] + self._insar.frameAzimuthOffsetGeometricalSlave = offsetSlave[1] + if self.frameOffsetMatching: + self._insar.frameRangeOffsetMatchingMaster = offsetMaster[2] + self._insar.frameAzimuthOffsetMatchingMaster = offsetMaster[3] + #self._insar.frameRangeOffsetMatchingSlave = offsetSlave[2] + #self._insar.frameAzimuthOffsetMatchingSlave = offsetSlave[3] + + + os.chdir('../') + + catalog.printToLog(logger, "runFrameOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2burstProc/runGeocodeSd.py b/components/isceobj/Alos2burstProc/runGeocodeSd.py new file mode 100644 index 0000000..f8ef935 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runGeocodeSd.py @@ -0,0 +1,64 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging +import numpy as np + +import isceobj +from isceobj.Alos2Proc.runGeocode import geocode +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo + +logger = logging.getLogger('isce.alos2insar.runGeocodeSd') + +def runGeocodeSd(self): + '''geocode final products + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + demFile = os.path.abspath(self._insar.demGeo) + + sdDir = 'sd' + if not os.path.exists(sdDir): + os.makedirs(sdDir) + os.chdir(sdDir) + + if self.geocodeListSd == None: + geocodeList = self._insar.multilookCoherenceSd + self._insar.azimuthDeformationSd + self._insar.maskedAzimuthDeformationSd + else: + geocodeList = self.geocodeListSd + + if self.bbox == None: + bbox = getBboxGeo(masterTrack) + else: + bbox = self.bbox + catalog.addItem('geocode bounding box', bbox, 'runGeocodeSd') + + numberRangeLooks = self._insar.numberRangeLooks1 * self._insar.numberRangeLooksSd + numberAzimuthLooks = self._insar.numberAzimuthLooks1 * self._insar.numberAzimuthLooksSd + + for inputFile in geocodeList: + if self.geocodeInterpMethodSd == None: + img = isceobj.createImage() + img.load(inputFile + '.xml') + if img.dataType.upper() == 'CFLOAT': + interpMethod = 'sinc' + else: + interpMethod = 'bilinear' + else: + interpMethod = self.geocodeInterpMethodSd.lower() + + geocode(masterTrack, demFile, inputFile, bbox, numberRangeLooks, numberAzimuthLooks, interpMethod, 0, 0) + + + os.chdir('../') + + catalog.printToLog(logger, "runGeocodeSd") + self._insar.procDoc.addAllFromCatalog(catalog) + diff --git a/components/isceobj/Alos2burstProc/runIonSubband.py b/components/isceobj/Alos2burstProc/runIonSubband.py new file mode 100644 index 0000000..8cdf5aa --- /dev/null +++ b/components/isceobj/Alos2burstProc/runIonSubband.py @@ -0,0 +1,425 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import shutil +import logging + +import isceobj +from isceobj.Constants import SPEED_OF_LIGHT + +logger = logging.getLogger('isce.alos2burstinsar.runIonSubband') + +def runIonSubband(self): + '''create subband interferograms + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + if not self.doIon: + catalog.printToLog(logger, "runIonSubband") + self._insar.procDoc.addAllFromCatalog(catalog) + return + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + #using 1/3, 1/3, 1/3 band split + radarWavelength = masterTrack.radarWavelength + rangeBandwidth = masterTrack.frames[0].swaths[0].rangeBandwidth + rangeSamplingRate = masterTrack.frames[0].swaths[0].rangeSamplingRate + radarWavelengthLower = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength - rangeBandwidth / 3.0) + radarWavelengthUpper = SPEED_OF_LIGHT/(SPEED_OF_LIGHT / radarWavelength + rangeBandwidth / 3.0) + subbandRadarWavelength = [radarWavelengthLower, radarWavelengthUpper] + subbandBandWidth = [rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate] + subbandFrequencyCenter = [-rangeBandwidth / 3.0 / rangeSamplingRate, rangeBandwidth / 3.0 / rangeSamplingRate] + + subbandPrefix = ['lower', 'upper'] + + ''' + ionDir = { + ionDir['swathMosaic'] : 'mosaic', + ionDir['insar'] : 'insar', + ionDir['ion'] : 'ion', + ionDir['subband'] : ['lower', 'upper'], + ionDir['ionCal'] : 'ion_cal' + } + ''' + #define upper level directory names + ionDir = defineIonDir() + + + self._insar.subbandRadarWavelength = subbandRadarWavelength + + + ############################################################ + # STEP 1. create directories + ############################################################ + #create and enter 'ion' directory + #after finishing each step, we are in this directory + if not os.path.exists(ionDir['ion']): + os.makedirs(ionDir['ion']) + os.chdir(ionDir['ion']) + + #create insar processing directories + for k in range(2): + subbandDir = ionDir['subband'][k] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + fullDir = os.path.join(subbandDir, frameDir, swathDir) + if not os.path.exists(fullDir): + os.makedirs(fullDir) + + #create ionospheric phase directory + if not os.path.exists(ionDir['ionCal']): + os.makedirs(ionDir['ionCal']) + + + ############################################################ + # STEP 2. create subband interferograms + ############################################################ + import shutil + import numpy as np + from contrib.alos2proc.alos2proc import rg_filter + from isceobj.Alos2Proc.Alos2ProcPublic import resampleBursts + from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstAmplitude + from isceobj.Alos2Proc.Alos2ProcPublic import mosaicBurstInterferogram + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + #filter master and slave images + for burstPrefix, swath in zip([self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix], + [masterTrack.frames[i].swaths[j], slaveTrack.frames[i].swaths[j]]): + slcDir = os.path.join('../', frameDir, swathDir, burstPrefix) + slcLowerDir = os.path.join(ionDir['subband'][0], frameDir, swathDir, burstPrefix) + slcUpperDir = os.path.join(ionDir['subband'][1], frameDir, swathDir, burstPrefix) + if not os.path.exists(slcLowerDir): + os.makedirs(slcLowerDir) + if not os.path.exists(slcUpperDir): + os.makedirs(slcUpperDir) + for k in range(swath.numberOfBursts): + print('processing burst: %02d'%(k+1)) + slc = os.path.join(slcDir, burstPrefix+'_%02d.slc'%(k+1)) + slcLower = os.path.join(slcLowerDir, burstPrefix+'_%02d.slc'%(k+1)) + slcUpper = os.path.join(slcUpperDir, burstPrefix+'_%02d.slc'%(k+1)) + rg_filter(slc, 2, + [slcLower, slcUpper], + subbandBandWidth, + subbandFrequencyCenter, + 257, 2048, 0.1, 0, 0.0) + #resample + for l in range(2): + os.chdir(os.path.join(ionDir['subband'][l], frameDir, swathDir)) + #recreate xml file to remove the file path + #can also use fixImageXml.py? + for burstPrefix, swath in zip([self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix], + [masterTrack.frames[i].swaths[j], slaveTrack.frames[i].swaths[j]]): + os.chdir(burstPrefix) + for k in range(swath.numberOfBursts): + slc = burstPrefix+'_%02d.slc'%(k+1) + img = isceobj.createSlcImage() + img.load(slc + '.xml') + img.setFilename(slc) + img.extraFilename = slc + '.vrt' + img.setAccessMode('READ') + img.renderHdr() + os.chdir('../') + + ############################################# + #1. form interferogram + ############################################# + masterSwath = masterTrack.frames[i].swaths[j] + slaveSwath = slaveTrack.frames[i].swaths[j] + + #set up resampling parameters + width = masterSwath.numberOfSamples + length = masterSwath.numberOfLines + polyCoeff = self._insar.rangeResidualOffsetCc[i][j] + rgIndex = (np.arange(width)-polyCoeff[-1][0])/polyCoeff[-1][1] + azIndex = (np.arange(length)-polyCoeff[-1][2])/polyCoeff[-1][3] + rangeOffset = polyCoeff[0][0] + polyCoeff[0][1]*rgIndex[None,:] + polyCoeff[0][2]*rgIndex[None,:]**2 + \ + (polyCoeff[1][0] + polyCoeff[1][1]*rgIndex[None,:]) * azIndex[:, None] + \ + polyCoeff[2][0] * azIndex[:, None]**2 + azimuthOffset = self._insar.azimuthResidualOffsetCc[i][j] + + slaveBurstResampledDir = self._insar.slaveBurstPrefix + '_2_coreg_cc' + interferogramDir = 'burst_interf_2_coreg_cc' + interferogramPrefix = self._insar.masterBurstPrefix + '-' + self._insar.slaveBurstPrefix + resampleBursts(masterSwath, slaveSwath, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, slaveBurstResampledDir, interferogramDir, + self._insar.masterBurstPrefix, self._insar.slaveBurstPrefix, self._insar.slaveBurstPrefix, interferogramPrefix, + os.path.join('../../../../{}/{}'.format(frameDir, swathDir), self._insar.rangeOffset), + os.path.join('../../../../{}/{}'.format(frameDir, swathDir), self._insar.azimuthOffset), + rangeOffsetResidual=rangeOffset, azimuthOffsetResidual=azimuthOffset) + + os.chdir(self._insar.masterBurstPrefix) + mosaicBurstAmplitude(masterSwath, self._insar.masterBurstPrefix, self._insar.masterMagnitude, numberOfLooksThreshold=4) + os.chdir('../') + + os.chdir(slaveBurstResampledDir) + mosaicBurstAmplitude(masterSwath, self._insar.slaveBurstPrefix, self._insar.slaveMagnitude, numberOfLooksThreshold=4) + os.chdir('../') + + os.chdir(interferogramDir) + mosaicBurstInterferogram(masterSwath, interferogramPrefix, self._insar.interferogram, numberOfLooksThreshold=4) + os.chdir('../') + + + amp = np.zeros((masterSwath.numberOfLines, 2*masterSwath.numberOfSamples), dtype=np.float32) + amp[0:, 1:masterSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(slaveBurstResampledDir, self._insar.slaveMagnitude), \ + dtype=np.float32).reshape(masterSwath.numberOfLines, masterSwath.numberOfSamples) + amp[0:, 0:masterSwath.numberOfSamples*2:2] = np.fromfile(os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude), \ + dtype=np.float32).reshape(masterSwath.numberOfLines, masterSwath.numberOfSamples) + amp.astype(np.float32).tofile(self._insar.amplitude) + create_xml(self._insar.amplitude, masterSwath.numberOfSamples, masterSwath.numberOfLines, 'amp') + + os.rename(os.path.join(interferogramDir, self._insar.interferogram), self._insar.interferogram) + os.rename(os.path.join(interferogramDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + os.rename(os.path.join(interferogramDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + + ############################################# + #2. delete subband slcs + ############################################# + shutil.rmtree(self._insar.masterBurstPrefix) + shutil.rmtree(self._insar.slaveBurstPrefix) + shutil.rmtree(slaveBurstResampledDir) + shutil.rmtree(interferogramDir) + + os.chdir('../../../') + + + ############################################################ + # STEP 3. mosaic swaths + ############################################################ + from isceobj.Alos2Proc.runSwathMosaic import swathMosaic + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + for k in range(2): + os.chdir(ionDir['subband'][k]) + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = 'mosaic' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if self._insar.endingSwath-self._insar.startingSwath+1 == 1: + import shutil + swathDir = 's{}'.format(masterTrack.frames[i].swaths[0].swathNumber) + + # if not os.path.isfile(self._insar.interferogram): + # os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # if not os.path.isfile(self._insar.amplitude): + # os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + os.chdir('../') + os.chdir('../') + continue + + #choose offsets + numberOfFrames = len(masterTrack.frames) + numberOfSwaths = len(masterTrack.frames[i].swaths) + if self.swathOffsetMatching: + #no need to do this as the API support 2-d list + #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetMatchingMaster + azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster + + else: + #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster + + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude)) + + #note that frame parameters are updated after mosaicking + #mosaic amplitudes + swathMosaic(masterTrack.frames[i], inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, resamplingMethod=0) + #mosaic interferograms + swathMosaic(masterTrack.frames[i], inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=False, phaseCompensation=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'int') + + os.chdir('../') + os.chdir('../') + os.chdir('../') + + + ############################################################ + # STEP 4. mosaic frames + ############################################################ + from isceobj.Alos2Proc.runFrameMosaic import frameMosaic + from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + + for k in range(2): + os.chdir(ionDir['subband'][k]) + + mosaicDir = 'insar' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + numberOfFrames = len(masterTrack.frames) + if numberOfFrames == 1: + import shutil + frameDir = os.path.join('f1_{}/mosaic'.format(self._insar.masterFrames[0])) + # if not os.path.isfile(self._insar.interferogram): + # os.symlink(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + # #shutil.copy2() can overwrite + # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # shutil.copy2(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # if not os.path.isfile(self._insar.amplitude): + # os.symlink(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # shutil.copy2(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + os.rename(os.path.join('../', frameDir, self._insar.interferogram), self._insar.interferogram) + os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + os.rename(os.path.join('../', frameDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + os.rename(os.path.join('../', frameDir, self._insar.amplitude), self._insar.amplitude) + os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + os.rename(os.path.join('../', frameDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + else: + #choose offsets + if self.frameOffsetMatching: + rangeOffsets = self._insar.frameRangeOffsetMatchingMaster + azimuthOffsets = self._insar.frameAzimuthOffsetMatchingMaster + else: + rangeOffsets = self._insar.frameRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.frameAzimuthOffsetGeometricalMaster + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + inputInterferograms.append(os.path.join('../', frameDir, 'mosaic', self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', frameDir, 'mosaic', self._insar.amplitude)) + + #note that track parameters are updated after mosaicking + #mosaic amplitudes + frameMosaic(masterTrack, inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=False, resamplingMethod=0) + #mosaic interferograms + frameMosaic(masterTrack, inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, + updateTrack=False, phaseCompensation=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.numberOfSamples, masterTrack.numberOfLines, 'int') + + os.chdir('../') + os.chdir('../') + + + ############################################################ + # STEP 5. clear frame processing files + ############################################################ + import shutil + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + + for k in range(2): + os.chdir(ionDir['subband'][k]) + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + shutil.rmtree(frameDir) + #cmd = 'rm -rf {}'.format(frameDir) + #runCmd(cmd) + os.chdir('../') + + + ############################################################ + # STEP 6. create differential interferograms + ############################################################ + import numpy as np + from isceobj.Alos2Proc.Alos2ProcPublic import runCmd + + for k in range(2): + os.chdir(ionDir['subband'][k]) + + insarDir = ionDir['insar'] + if not os.path.exists(insarDir): + os.makedirs(insarDir) + os.chdir(insarDir) + + rangePixelSize = self._insar.numberRangeLooks1 * masterTrack.rangePixelSize + radarWavelength = subbandRadarWavelength[k] + rectRangeOffset = os.path.join('../../../', insarDir, self._insar.rectRangeOffset) + + cmd = "imageMath.py -e='a*exp(-1.0*J*b*4.0*{}*{}/{}) * (b!=0)' --a={} --b={} -o {} -t cfloat".format(np.pi, rangePixelSize, radarWavelength, self._insar.interferogram, rectRangeOffset, self._insar.differentialInterferogram) + runCmd(cmd) + + os.chdir('../../') + + + os.chdir('../') + catalog.printToLog(logger, "runIonSubband") + self._insar.procDoc.addAllFromCatalog(catalog) + + +def defineIonDir(): + ''' + define directory names for ionospheric correction + ''' + + ionDir = { + #swath mosaicking directory + 'swathMosaic' : 'mosaic', + #final insar processing directory + 'insar' : 'insar', + #ionospheric correction directory + 'ion' : 'ion', + #subband directory + 'subband' : ['lower', 'upper'], + #final ionospheric phase calculation directory + 'ionCal' : 'ion_cal' + } + + return ionDir + + +def defineIonFilenames(): + pass + + + + + + + diff --git a/components/isceobj/Alos2burstProc/runLookSd.py b/components/isceobj/Alos2burstProc/runLookSd.py new file mode 100644 index 0000000..ed43f6f --- /dev/null +++ b/components/isceobj/Alos2burstProc/runLookSd.py @@ -0,0 +1,57 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml +from contrib.alos2proc.alos2proc import look +from isceobj.Alos2Proc.Alos2ProcPublic import waterBodyRadar + +logger = logging.getLogger('isce.alos2burstinsar.runLookSd') + +def runLookSd(self): + '''take looks + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + #masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + wbdFile = os.path.abspath(self._insar.wbd) + + sdDir = 'sd' + if not os.path.exists(sdDir): + os.makedirs(sdDir) + os.chdir(sdDir) + + sd = isceobj.createImage() + sd.load(self._insar.interferogramSd[0]+'.xml') + width = sd.width + length = sd.length + width2 = int(width / self._insar.numberRangeLooksSd) + length2 = int(length / self._insar.numberAzimuthLooksSd) + + if not ((self._insar.numberRangeLooksSd == 1) and (self._insar.numberAzimuthLooksSd == 1)): + #take looks + for sd, sdMultilook in zip(self._insar.interferogramSd, self._insar.multilookInterferogramSd): + look(sd, sdMultilook, width, self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd, 4, 0, 1) + create_xml(sdMultilook, width2, length2, 'int') + look(os.path.join('../insar', self._insar.latitude), self._insar.multilookLatitudeSd, width, + self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd, 3, 0, 1) + look(os.path.join('../insar', self._insar.longitude), self._insar.multilookLongitudeSd, width, + self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd, 3, 0, 1) + create_xml(self._insar.multilookLatitudeSd, width2, length2, 'double') + create_xml(self._insar.multilookLongitudeSd, width2, length2, 'double') + #water body + waterBodyRadar(self._insar.multilookLatitudeSd, self._insar.multilookLongitudeSd, wbdFile, self._insar.multilookWbdOutSd) + + os.chdir('../') + + catalog.printToLog(logger, "runLookSd") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2burstProc/runPreprocessor.py b/components/isceobj/Alos2burstProc/runPreprocessor.py new file mode 100644 index 0000000..5bc2373 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runPreprocessor.py @@ -0,0 +1,521 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import glob +import logging +import datetime +import numpy as np + +import isceobj +import isceobj.Sensor.MultiMode as MultiMode +from isceobj.Planet.Planet import Planet +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxRdr +from isceobj.Alos2Proc.Alos2ProcPublic import getBboxGeo + +logger = logging.getLogger('isce.alos2burstinsar.runPreprocessor') + +def runPreprocessor(self): + '''Extract images. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + + + #find files + #actually no need to use absolute path any longer, since we are able to find file from vrt now. 27-JAN-2020, CRL. + #denseoffset may still need absolute path when making links + self.masterDir = os.path.abspath(self.masterDir) + self.slaveDir = os.path.abspath(self.slaveDir) + + ledFilesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'LED-ALOS2*-*-*'))) + imgFilesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*-*-*'.format(self.masterPolarization.upper())))) + + ledFilesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'LED-ALOS2*-*-*'))) + imgFilesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*-*-*'.format(self.slavePolarization.upper())))) + + firstFrameMaster = ledFilesMaster[0].split('-')[-3][-4:] + firstFrameSlave = ledFilesSlave[0].split('-')[-3][-4:] + firstFrameImagesMaster = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.masterPolarization.upper(), firstFrameMaster)))) + firstFrameImagesSlave = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.slavePolarization.upper(), firstFrameSlave)))) + + + #determin operation mode + masterMode = os.path.basename(ledFilesMaster[0]).split('-')[-1][0:3] + slaveMode = os.path.basename(ledFilesSlave[0]).split('-')[-1][0:3] + 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'] + + #usable combinations + if (masterMode in spotlightModes) and (slaveMode in spotlightModes): + self._insar.modeCombination = 0 + elif (masterMode in stripmapModes) and (slaveMode in stripmapModes): + self._insar.modeCombination = 1 + elif (masterMode in scansarNominalModes) and (slaveMode in scansarNominalModes): + self._insar.modeCombination = 21 + elif (masterMode in scansarWideModes) and (slaveMode in scansarWideModes): + self._insar.modeCombination = 22 + elif (masterMode in scansarNominalModes) and (slaveMode in stripmapModes): + self._insar.modeCombination = 31 + elif (masterMode in scansarWideModes) and (slaveMode in stripmapModes): + self._insar.modeCombination = 32 + else: + print('\n\nthis mode combination is not possible') + print('note that for ScanSAR-stripmap, ScanSAR must be master\n\n') + raise Exception('mode combination not supported') + + + if self._insar.modeCombination != 21: + print('\n\nburst processing only support {}\n\n'.format(scansarNominalModes)) + raise Exception('mode combination not supported') + + + #determine default number of looks: + self._insar.numberRangeLooks1 = self.numberRangeLooks1 + self._insar.numberAzimuthLooks1 = self.numberAzimuthLooks1 + self._insar.numberRangeLooks2 = self.numberRangeLooks2 + self._insar.numberAzimuthLooks2 = self.numberAzimuthLooks2 + #the following two will be automatically determined by runRdrDemOffset.py + self._insar.numberRangeLooksSim = self.numberRangeLooksSim + self._insar.numberAzimuthLooksSim = self.numberAzimuthLooksSim + self._insar.numberRangeLooksIon = self.numberRangeLooksIon + self._insar.numberAzimuthLooksIon = self.numberAzimuthLooksIon + self._insar.numberRangeLooksSd = self.numberRangeLooksSd + self._insar.numberAzimuthLooksSd = self.numberAzimuthLooksSd + + #force number of looks 1 to 1 + self.numberRangeLooks1 = 1 + self.numberAzimuthLooks1 = 1 + self._insar.numberRangeLooks1 = 1 + self._insar.numberAzimuthLooks1 = 1 + if self._insar.numberRangeLooks2 == None: + self._insar.numberRangeLooks2 = 7 + if self._insar.numberAzimuthLooks2 == None: + self._insar.numberAzimuthLooks2 = 2 + if self._insar.numberRangeLooksIon == None: + self._insar.numberRangeLooksIon = 42 + if self._insar.numberAzimuthLooksIon == None: + self._insar.numberAzimuthLooksIon = 12 + if self._insar.numberRangeLooksSd == None: + self._insar.numberRangeLooksSd = 14 + if self._insar.numberAzimuthLooksSd == None: + self._insar.numberAzimuthLooksSd = 4 + + #define processing file names + self._insar.masterDate = os.path.basename(ledFilesMaster[0]).split('-')[2] + self._insar.slaveDate = os.path.basename(ledFilesSlave[0]).split('-')[2] + self._insar.setFilename(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, + nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, + nrlks2=self._insar.numberRangeLooks2, nalks2=self._insar.numberAzimuthLooks2) + self._insar.setFilenameSd(masterDate=self._insar.masterDate, slaveDate=self._insar.slaveDate, + nrlks1=self._insar.numberRangeLooks1, nalks1=self._insar.numberAzimuthLooks1, + nrlks_sd=self._insar.numberRangeLooksSd, nalks_sd=self._insar.numberAzimuthLooksSd, nsd=3) + + #find frame numbers + if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32): + if (self.masterFrames == None) or (self.slaveFrames == None): + raise Exception('for ScanSAR-stripmap inteferometry, you must set master and slave frame numbers') + #if not set, find frames automatically + if self.masterFrames == None: + self.masterFrames = [] + for led in ledFilesMaster: + frameNumber = os.path.basename(led).split('-')[1][-4:] + if frameNumber not in self.masterFrames: + self.masterFrames.append(frameNumber) + if self.slaveFrames == None: + self.slaveFrames = [] + for led in ledFilesSlave: + frameNumber = os.path.basename(led).split('-')[1][-4:] + if frameNumber not in self.slaveFrames: + self.slaveFrames.append(frameNumber) + #sort frames + self.masterFrames = sorted(self.masterFrames) + self.slaveFrames = sorted(self.slaveFrames) + #check number of frames + if len(self.masterFrames) != len(self.slaveFrames): + raise Exception('number of frames in master dir is not equal to number of frames \ + in slave dir. please set frame number manually') + + + #find swath numbers (if not ScanSAR-ScanSAR, compute valid swaths) + if (self._insar.modeCombination == 0) or (self._insar.modeCombination == 1): + self.startingSwath = 1 + self.endingSwath = 1 + + if self._insar.modeCombination == 21: + if self.startingSwath == None: + self.startingSwath = 1 + if self.endingSwath == None: + self.endingSwath = 5 + + if self._insar.modeCombination == 22: + if self.startingSwath == None: + self.startingSwath = 1 + if self.endingSwath == None: + self.endingSwath = 7 + + #determine starting and ending swaths for ScanSAR-stripmap, user's settings are overwritten + #use first frame to check overlap + if (self._insar.modeCombination == 31) or (self._insar.modeCombination == 32): + if self._insar.modeCombination == 31: + numberOfSwaths = 5 + else: + numberOfSwaths = 7 + overlapSubswaths = [] + for i in range(numberOfSwaths): + overlapRatio = check_overlap(ledFilesMaster[0], firstFrameImagesMaster[i], ledFilesSlave[0], firstFrameImagesSlave[0]) + if overlapRatio > 1.0 / 4.0: + overlapSubswaths.append(i+1) + if overlapSubswaths == []: + raise Exception('There is no overlap area between the ScanSAR-stripmap pair') + self.startingSwath = int(overlapSubswaths[0]) + self.endingSwath = int(overlapSubswaths[-1]) + + #save the valid frames and swaths for future processing + self._insar.masterFrames = self.masterFrames + self._insar.slaveFrames = self.slaveFrames + self._insar.startingSwath = self.startingSwath + self._insar.endingSwath = self.endingSwath + + + ################################################## + #1. create directories and read data + ################################################## + self.master.configure() + self.slave.configure() + self.master.track.configure() + self.slave.track.configure() + for i, (masterFrame, slaveFrame) in enumerate(zip(self._insar.masterFrames, self._insar.slaveFrames)): + #frame number starts with 1 + frameDir = 'f{}_{}'.format(i+1, masterFrame) + if not os.path.exists(frameDir): + os.makedirs(frameDir) + os.chdir(frameDir) + + #attach a frame to master and slave + frameObjMaster = MultiMode.createFrame() + frameObjSlave = MultiMode.createFrame() + frameObjMaster.configure() + frameObjSlave.configure() + self.master.track.frames.append(frameObjMaster) + self.slave.track.frames.append(frameObjSlave) + + #swath number starts with 1 + for j in range(self._insar.startingSwath, self._insar.endingSwath+1): + print('processing frame {} swath {}'.format(masterFrame, j)) + + swathDir = 's{}'.format(j) + if not os.path.exists(swathDir): + os.makedirs(swathDir) + os.chdir(swathDir) + + #attach a swath to master and slave + swathObjMaster = MultiMode.createSwath() + swathObjSlave = MultiMode.createSwath() + swathObjMaster.configure() + swathObjSlave.configure() + self.master.track.frames[-1].swaths.append(swathObjMaster) + self.slave.track.frames[-1].swaths.append(swathObjSlave) + + #setup master + self.master.leaderFile = sorted(glob.glob(os.path.join(self.masterDir, 'LED-ALOS2*{}-*-*'.format(masterFrame))))[0] + if masterMode in scansarModes: + self.master.imageFile = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.masterPolarization.upper(), masterFrame, j))))[0] + else: + self.master.imageFile = sorted(glob.glob(os.path.join(self.masterDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.masterPolarization.upper(), masterFrame))))[0] + self.master.outputFile = self._insar.masterSlc + self.master.useVirtualFile = self.useVirtualFile + #read master + (imageFDR, imageData)=self.master.readImage() + (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.master.readLeader() + self.master.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.master.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.master.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + + #setup slave + self.slave.leaderFile = sorted(glob.glob(os.path.join(self.slaveDir, 'LED-ALOS2*{}-*-*'.format(slaveFrame))))[0] + if slaveMode in scansarModes: + self.slave.imageFile = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*-F{}'.format(self.slavePolarization.upper(), slaveFrame, j))))[0] + else: + self.slave.imageFile = sorted(glob.glob(os.path.join(self.slaveDir, 'IMG-{}-ALOS2*{}-*-*'.format(self.slavePolarization.upper(), slaveFrame))))[0] + self.slave.outputFile = self._insar.slaveSlc + self.slave.useVirtualFile = self.useVirtualFile + #read slave + (imageFDR, imageData)=self.slave.readImage() + (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord)=self.slave.readLeader() + self.slave.setSwath(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.slave.setFrame(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + self.slave.setTrack(leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData) + + os.chdir('../') + self._insar.saveProduct(self.master.track.frames[-1], self._insar.masterFrameParameter) + self._insar.saveProduct(self.slave.track.frames[-1], self._insar.slaveFrameParameter) + os.chdir('../') + self._insar.saveProduct(self.master.track, self._insar.masterTrackParameter) + self._insar.saveProduct(self.slave.track, self._insar.slaveTrackParameter) + + + ################################################## + #2. compute burst synchronization + ################################################## + #burst synchronization may slowly change along a track as a result of the changing relative speed of the two flights + #in one frame, real unsynchronized time is the same for all swaths + unsynTime = 0 + #real synchronized time/percentage depends on the swath burst length (synTime = burstlength - abs(unsynTime)) + #synTime = 0 + synPercentage = 0 + + numberOfFrames = len(self._insar.masterFrames) + numberOfSwaths = self._insar.endingSwath - self._insar.startingSwath + 1 + + for i, frameNumber in enumerate(self._insar.masterFrames): + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + masterSwath = self.master.track.frames[i].swaths[j] + slaveSwath = self.slave.track.frames[i].swaths[j] + #using Piyush's code for computing range and azimuth offsets + midRange = masterSwath.startingRange + masterSwath.rangePixelSize * masterSwath.numberOfSamples * 0.5 + midSensingStart = masterSwath.sensingStart + datetime.timedelta(seconds = masterSwath.numberOfLines * 0.5 / masterSwath.prf) + llh = self.master.track.orbit.rdr2geo(midSensingStart, midRange) + slvaz, slvrng = self.slave.track.orbit.geo2rdr(llh) + ###Translate to offsets + #note that slave range pixel size and prf might be different from master, here we assume there is a virtual slave with same + #range pixel size and prf + rgoff = ((slvrng - slaveSwath.startingRange) / masterSwath.rangePixelSize) - masterSwath.numberOfSamples * 0.5 + azoff = ((slvaz - slaveSwath.sensingStart).total_seconds() * masterSwath.prf) - masterSwath.numberOfLines * 0.5 + + #compute burst synchronization + #burst parameters for ScanSAR wide mode not estimed yet + if self._insar.modeCombination == 21: + scburstStartLine = (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf + azoff + #slave burst start times corresponding to master burst start times (100% synchronization) + scburstStartLines = np.arange(scburstStartLine - 100000*masterSwath.burstCycleLength, \ + scburstStartLine + 100000*masterSwath.burstCycleLength, \ + masterSwath.burstCycleLength) + dscburstStartLines = -((slaveSwath.burstStartTime - slaveSwath.sensingStart).total_seconds() * slaveSwath.prf - scburstStartLines) + #find the difference with minimum absolute value + unsynLines = dscburstStartLines[np.argmin(np.absolute(dscburstStartLines))] + if np.absolute(unsynLines) >= slaveSwath.burstLength: + synLines = 0 + if unsynLines > 0: + unsynLines = slaveSwath.burstLength + else: + unsynLines = -slaveSwath.burstLength + else: + synLines = slaveSwath.burstLength - np.absolute(unsynLines) + + unsynTime += unsynLines / masterSwath.prf + synPercentage += synLines / masterSwath.burstLength * 100.0 + + catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(synLines / masterSwath.burstLength * 100.0), 'runPreprocessor') + + ############################################################################################ + #illustration of the sign of the number of unsynchronized lines (unsynLines) + #The convention is the same as ampcor offset, that is, + # slaveLineNumber = masterLineNumber + unsynLines + # + # |-----------------------| ------------ + # | | ^ + # | | | + # | | | unsynLines < 0 + # | | | + # | | \ / + # | | |-----------------------| + # | | | | + # | | | | + # |-----------------------| | | + # Master Burst | | + # | | + # | | + # | | + # | | + # |-----------------------| + # Slave Burst + # + # + ############################################################################################ + + ##burst parameters for ScanSAR wide mode not estimed yet + elif self._insar.modeCombination == 31: + #scansar is master + scburstStartLine = (masterSwath.burstStartTime - masterSwath.sensingStart).total_seconds() * masterSwath.prf + azoff + #slave burst start times corresponding to master burst start times (100% synchronization) + for k in range(-100000, 100000): + saz_burstx = scburstStartLine + masterSwath.burstCycleLength * k + st_burstx = slaveSwath.sensingStart + datetime.timedelta(seconds=saz_burstx / masterSwath.prf) + if saz_burstx >= 0.0 and saz_burstx <= slaveSwath.numberOfLines -1: + slaveSwath.burstStartTime = st_burstx + slaveSwath.burstLength = masterSwath.burstLength + slaveSwath.burstCycleLength = masterSwath.burstCycleLength + slaveSwath.swathNumber = masterSwath.swathNumber + break + #unsynLines = 0 + #synLines = masterSwath.burstLength + #unsynTime += unsynLines / masterSwath.prf + #synPercentage += synLines / masterSwath.burstLength * 100.0 + catalog.addItem('burst synchronization of frame {} swath {}'.format(frameNumber, swathNumber), '%.1f%%'%(100.0), 'runPreprocessor') + else: + pass + + #overwrite original frame parameter file + if self._insar.modeCombination == 31: + frameDir = 'f{}_{}'.format(i+1, frameNumber) + self._insar.saveProduct(self.slave.track.frames[i], os.path.join(frameDir, self._insar.slaveFrameParameter)) + + #getting average + if self._insar.modeCombination == 21: + unsynTime /= numberOfFrames*numberOfSwaths + synPercentage /= numberOfFrames*numberOfSwaths + elif self._insar.modeCombination == 31: + unsynTime = 0. + synPercentage = 100. + else: + pass + + #record results + if (self._insar.modeCombination == 21) or (self._insar.modeCombination == 31): + self._insar.burstUnsynchronizedTime = unsynTime + self._insar.burstSynchronization = synPercentage + catalog.addItem('burst synchronization averaged', '%.1f%%'%(synPercentage), 'runPreprocessor') + + + ################################################## + #3. compute baseline + ################################################## + #only compute baseline at four corners and center of the master track + bboxRdr = getBboxRdr(self.master.track) + + rangeMin = bboxRdr[0] + rangeMax = bboxRdr[1] + azimuthTimeMin = bboxRdr[2] + azimuthTimeMax = bboxRdr[3] + + azimuthTimeMid = azimuthTimeMin+datetime.timedelta(seconds=(azimuthTimeMax-azimuthTimeMin).total_seconds()/2.0) + rangeMid = (rangeMin + rangeMax) / 2.0 + + points = [[azimuthTimeMin, rangeMin], + [azimuthTimeMin, rangeMax], + [azimuthTimeMax, rangeMin], + [azimuthTimeMax, rangeMax], + [azimuthTimeMid, rangeMid]] + + Bpar = [] + Bperp = [] + #modify Piyush's code for computing baslines + refElp = Planet(pname='Earth').ellipsoid + for x in points: + masterSV = self.master.track.orbit.interpolate(x[0], method='hermite') + target = self.master.track.orbit.rdr2geo(x[0], x[1]) + + slvTime, slvrng = self.slave.track.orbit.geo2rdr(target) + slaveSV = self.slave.track.orbit.interpolateOrbit(slvTime, method='hermite') + + targxyz = np.array(refElp.LLH(target[0], target[1], target[2]).ecef().tolist()) + mxyz = np.array(masterSV.getPosition()) + mvel = np.array(masterSV.getVelocity()) + sxyz = np.array(slaveSV.getPosition()) + + aa = np.linalg.norm(sxyz-mxyz) + costheta = (x[1]*x[1] + aa*aa - slvrng*slvrng)/(2.*x[1]*aa) + + Bpar.append(aa*costheta) + + perp = aa * np.sqrt(1 - costheta*costheta) + direction = np.sign(np.dot( np.cross(targxyz-mxyz, sxyz-mxyz), mvel)) + Bperp.append(direction*perp) + + catalog.addItem('parallel baseline at upperleft of master track', Bpar[0], 'runPreprocessor') + catalog.addItem('parallel baseline at upperright of master track', Bpar[1], 'runPreprocessor') + catalog.addItem('parallel baseline at lowerleft of master track', Bpar[2], 'runPreprocessor') + catalog.addItem('parallel baseline at lowerright of master track', Bpar[3], 'runPreprocessor') + catalog.addItem('parallel baseline at center of master track', Bpar[4], 'runPreprocessor') + + catalog.addItem('perpendicular baseline at upperleft of master track', Bperp[0], 'runPreprocessor') + catalog.addItem('perpendicular baseline at upperright of master track', Bperp[1], 'runPreprocessor') + catalog.addItem('perpendicular baseline at lowerleft of master track', Bperp[2], 'runPreprocessor') + catalog.addItem('perpendicular baseline at lowerright of master track', Bperp[3], 'runPreprocessor') + catalog.addItem('perpendicular baseline at center of master track', Bperp[4], 'runPreprocessor') + + + ################################################## + #4. compute bounding box + ################################################## + masterBbox = getBboxGeo(self.master.track) + slaveBbox = getBboxGeo(self.slave.track) + + catalog.addItem('master bounding box', masterBbox, 'runPreprocessor') + catalog.addItem('slave bounding box', slaveBbox, 'runPreprocessor') + + + catalog.printToLog(logger, "runPreprocessor") + self._insar.procDoc.addAllFromCatalog(catalog) + + + +def check_overlap(ldr_m, img_m, ldr_s, img_s): + from isceobj.Constants import SPEED_OF_LIGHT + + rangeSamplingRateMaster, widthMaster, nearRangeMaster = read_param_for_checking_overlap(ldr_m, img_m) + rangeSamplingRateSlave, widthSlave, nearRangeSlave = read_param_for_checking_overlap(ldr_s, img_s) + + farRangeMaster = nearRangeMaster + (widthMaster-1) * 0.5 * SPEED_OF_LIGHT / rangeSamplingRateMaster + farRangeSlave = nearRangeSlave + (widthSlave-1) * 0.5 * SPEED_OF_LIGHT / rangeSamplingRateSlave + + #This should be good enough, although precise image offsets are not used. + if farRangeMaster <= nearRangeSlave: + overlapRatio = 0.0 + elif farRangeSlave <= nearRangeMaster: + overlapRatio = 0.0 + else: + # 0 1 2 3 + ranges = np.array([nearRangeMaster, farRangeMaster, nearRangeSlave, farRangeSlave]) + rangesIndex = np.argsort(ranges) + overlapRatio = ranges[rangesIndex[2]]-ranges[rangesIndex[1]] / (farRangeMaster-nearRangeMaster) + + return overlapRatio + + +def read_param_for_checking_overlap(leader_file, image_file): + from isceobj.Sensor import xmlPrefix + import isceobj.Sensor.CEOS as CEOS + + #read from leader file + fsampConst = { 104: 1.047915957140240E+08, + 52: 5.239579785701190E+07, + 34: 3.493053190467460E+07, + 17: 1.746526595233730E+07 } + + fp = open(leader_file,'rb') + leaderFDR = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/leader_file.xml'),dataFile=fp) + leaderFDR.parse() + fp.seek(leaderFDR.getEndOfRecordPosition()) + sceneHeaderRecord = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/scene_record.xml'),dataFile=fp) + sceneHeaderRecord.parse() + fp.seek(sceneHeaderRecord.getEndOfRecordPosition()) + + fsamplookup = int(sceneHeaderRecord.metadata['Range sampling rate in MHz']) + rangeSamplingRate = fsampConst[fsamplookup] + fp.close() + #print('{}'.format(rangeSamplingRate)) + + #read from image file + fp = open(image_file, 'rb') + imageFDR = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/image_file.xml'), dataFile=fp) + imageFDR.parse() + fp.seek(imageFDR.getEndOfRecordPosition()) + imageData = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/image_record.xml'), dataFile=fp) + imageData.parseFast() + + width = imageFDR.metadata['Number of pixels per line per SAR channel'] + near_range = imageData.metadata['Slant range to 1st data sample'] + fp.close() + #print('{}'.format(width)) + #print('{}'.format(near_range)) + + return (rangeSamplingRate, width, near_range) + + diff --git a/components/isceobj/Alos2burstProc/runSwathMosaic.py b/components/isceobj/Alos2burstProc/runSwathMosaic.py new file mode 100644 index 0000000..544800a --- /dev/null +++ b/components/isceobj/Alos2burstProc/runSwathMosaic.py @@ -0,0 +1,221 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.runSwathMosaic import swathMosaic +from isceobj.Alos2Proc.runSwathMosaic import swathMosaicParameters +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2burstinsar.runSwathMosaic') + +def runSwathMosaic(self): + '''mosaic subswaths + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = 'mosaic' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if self._insar.endingSwath-self._insar.startingSwath+1 == 1: + import shutil + swathDir = 's{}'.format(masterTrack.frames[i].swaths[0].swathNumber) + + if not os.path.isfile(self._insar.interferogram): + os.symlink(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + shutil.copy2(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + if not os.path.isfile(self._insar.amplitude): + os.symlink(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + shutil.copy2(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + # os.rename(os.path.join('../', swathDir, self._insar.interferogram), self._insar.interferogram) + # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.vrt'), self._insar.interferogram+'.vrt') + # os.rename(os.path.join('../', swathDir, self._insar.interferogram+'.xml'), self._insar.interferogram+'.xml') + # os.rename(os.path.join('../', swathDir, self._insar.amplitude), self._insar.amplitude) + # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.vrt'), self._insar.amplitude+'.vrt') + # os.rename(os.path.join('../', swathDir, self._insar.amplitude+'.xml'), self._insar.amplitude+'.xml') + + #update frame parameters + ######################################################### + frame = masterTrack.frames[i] + infImg = isceobj.createImage() + infImg.load(self._insar.interferogram+'.xml') + #mosaic size + frame.numberOfSamples = infImg.width + frame.numberOfLines = infImg.length + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + frame.startingRange = frame.swaths[0].startingRange + frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate + frame.rangePixelSize = frame.swaths[0].rangePixelSize + #azimuth parameters + frame.sensingStart = frame.swaths[0].sensingStart + frame.prf = frame.swaths[0].prf + frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize + frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval + + #update frame parameters, slave + ######################################################### + frame = slaveTrack.frames[i] + #mosaic size + frame.numberOfSamples = int(frame.swaths[0].numberOfSamples/self._insar.numberRangeLooks1) + frame.numberOfLines = int(frame.swaths[0].numberOfLines/self._insar.numberAzimuthLooks1) + #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE + #range parameters + frame.startingRange = frame.swaths[0].startingRange + frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate + frame.rangePixelSize = frame.swaths[0].rangePixelSize + #azimuth parameters + frame.sensingStart = frame.swaths[0].sensingStart + frame.prf = frame.swaths[0].prf + frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize + frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval + + os.chdir('../') + + #save parameter file + self._insar.saveProduct(masterTrack.frames[i], self._insar.masterFrameParameter) + self._insar.saveProduct(slaveTrack.frames[i], self._insar.slaveFrameParameter) + + os.chdir('../') + + continue + + #choose offsets + numberOfFrames = len(masterTrack.frames) + numberOfSwaths = len(masterTrack.frames[i].swaths) + if self.swathOffsetMatching: + #no need to do this as the API support 2-d list + #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetMatchingMaster + azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster + + else: + #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster + + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + + #list of input files + inputInterferograms = [] + inputAmplitudes = [] + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + inputInterferograms.append(os.path.join('../', swathDir, self._insar.interferogram)) + inputAmplitudes.append(os.path.join('../', swathDir, self._insar.amplitude)) + + #note that frame parameters are updated after mosaicking + #mosaic amplitudes + swathMosaic(masterTrack.frames[i], inputAmplitudes, self._insar.amplitude, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, resamplingMethod=0) + #mosaic interferograms + swathMosaic(masterTrack.frames[i], inputInterferograms, self._insar.interferogram, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=True, resamplingMethod=1) + + create_xml(self._insar.amplitude, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'amp') + create_xml(self._insar.interferogram, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'int') + + #update slave frame parameters here + #no matching for slave, always use geometry + rangeOffsets = self._insar.swathRangeOffsetGeometricalSlave + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalSlave + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + swathMosaicParameters(slaveTrack.frames[i], rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1) + + os.chdir('../') + + #save parameter file + self._insar.saveProduct(masterTrack.frames[i], self._insar.masterFrameParameter) + self._insar.saveProduct(slaveTrack.frames[i], self._insar.slaveFrameParameter) + + os.chdir('../') + + + #mosaic spectral diversity interferograms + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = 'mosaic' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if self._insar.endingSwath-self._insar.startingSwath+1 == 1: + import shutil + swathDir = 's{}'.format(masterTrack.frames[i].swaths[0].swathNumber) + + for sdFile in self._insar.interferogramSd: + if not os.path.isfile(sdFile): + os.symlink(os.path.join('../', swathDir, 'spectral_diversity', sdFile), sdFile) + shutil.copy2(os.path.join('../', swathDir, 'spectral_diversity', sdFile+'.vrt'), sdFile+'.vrt') + shutil.copy2(os.path.join('../', swathDir, 'spectral_diversity', sdFile+'.xml'), sdFile+'.xml') + + os.chdir('../') + os.chdir('../') + continue + + #choose offsets + numberOfFrames = len(masterTrack.frames) + numberOfSwaths = len(masterTrack.frames[i].swaths) + if self.swathOffsetMatching: + #no need to do this as the API support 2-d list + #rangeOffsets = (np.array(self._insar.swathRangeOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetMatchingMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetMatchingMaster + azimuthOffsets = self._insar.swathAzimuthOffsetMatchingMaster + + else: + #rangeOffsets = (np.array(self._insar.swathRangeOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + #azimuthOffsets = (np.array(self._insar.swathAzimuthOffsetGeometricalMaster)).reshape(numberOfFrames, numberOfSwaths) + rangeOffsets = self._insar.swathRangeOffsetGeometricalMaster + azimuthOffsets = self._insar.swathAzimuthOffsetGeometricalMaster + + rangeOffsets = rangeOffsets[i] + azimuthOffsets = azimuthOffsets[i] + + #list of input files + inputSd = [[], [], []] + for j, swathNumber in enumerate(range(self._insar.startingSwath, self._insar.endingSwath + 1)): + swathDir = 's{}'.format(swathNumber) + for k, sdFile in enumerate(self._insar.interferogramSd): + inputSd[k].append(os.path.join('../', swathDir, 'spectral_diversity', sdFile)) + + #mosaic spectral diversity interferograms + for inputSdList, outputSdFile in zip(inputSd, self._insar.interferogramSd): + swathMosaic(masterTrack.frames[i], inputSdList, outputSdFile, + rangeOffsets, azimuthOffsets, self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1, updateFrame=False, phaseCompensation=True, pcRangeLooks=5, pcAzimuthLooks=5, filt=True, resamplingMethod=1) + + for sdFile in self._insar.interferogramSd: + create_xml(sdFile, masterTrack.frames[i].numberOfSamples, masterTrack.frames[i].numberOfLines, 'int') + + os.chdir('../') + os.chdir('../') + + + catalog.printToLog(logger, "runSwathMosaic") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2burstProc/runSwathOffset.py b/components/isceobj/Alos2burstProc/runSwathOffset.py new file mode 100644 index 0000000..d909625 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runSwathOffset.py @@ -0,0 +1,73 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import logging + +import isceobj +from isceobj.Alos2Proc.runSwathOffset import swathOffset + +logger = logging.getLogger('isce.alos2burstinsar.runSwathOffset') + +def runSwathOffset(self): + '''estimate swath offsets. + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + slaveTrack = self._insar.loadTrack(master=False) + + + + for i, frameNumber in enumerate(self._insar.masterFrames): + frameDir = 'f{}_{}'.format(i+1, frameNumber) + os.chdir(frameDir) + + mosaicDir = 'mosaic' + if not os.path.exists(mosaicDir): + os.makedirs(mosaicDir) + os.chdir(mosaicDir) + + if self._insar.endingSwath-self._insar.startingSwath+1 == 1: + os.chdir('../../') + continue + + #compute swath offset + offsetMaster = swathOffset(masterTrack.frames[i], os.path.join(self._insar.masterBurstPrefix, self._insar.masterMagnitude), self._insar.masterSwathOffset, + crossCorrelation=self.swathOffsetMatching, numberOfAzimuthLooks=1) + #only use geometrical offset for slave + offsetSlave = swathOffset(slaveTrack.frames[i], os.path.join(self._insar.slaveBurstPrefix, self._insar.slaveMagnitude), self._insar.slaveSwathOffset, + crossCorrelation=False, numberOfAzimuthLooks=1) + + #initialization + if i == 0: + self._insar.swathRangeOffsetGeometricalMaster = [] + self._insar.swathAzimuthOffsetGeometricalMaster = [] + self._insar.swathRangeOffsetGeometricalSlave = [] + self._insar.swathAzimuthOffsetGeometricalSlave = [] + if self.swathOffsetMatching: + self._insar.swathRangeOffsetMatchingMaster = [] + self._insar.swathAzimuthOffsetMatchingMaster = [] + #self._insar.swathRangeOffsetMatchingSlave = [] + #self._insar.swathAzimuthOffsetMatchingSlave = [] + + #append list directly, as the API support 2-d list + self._insar.swathRangeOffsetGeometricalMaster.append(offsetMaster[0]) + self._insar.swathAzimuthOffsetGeometricalMaster.append(offsetMaster[1]) + self._insar.swathRangeOffsetGeometricalSlave.append(offsetSlave[0]) + self._insar.swathAzimuthOffsetGeometricalSlave.append(offsetSlave[1]) + if self.swathOffsetMatching: + self._insar.swathRangeOffsetMatchingMaster.append(offsetMaster[2]) + self._insar.swathAzimuthOffsetMatchingMaster.append(offsetMaster[3]) + #self._insar.swathRangeOffsetMatchingSlave.append(offsetSlave[2]) + #self._insar.swathAzimuthOffsetMatchingSlave.append(offsetSlave[3]) + + os.chdir('../../') + + catalog.printToLog(logger, "runSwathOffset") + self._insar.procDoc.addAllFromCatalog(catalog) + + diff --git a/components/isceobj/Alos2burstProc/runUnwrapSnaphuSd.py b/components/isceobj/Alos2burstProc/runUnwrapSnaphuSd.py new file mode 100644 index 0000000..2170ed9 --- /dev/null +++ b/components/isceobj/Alos2burstProc/runUnwrapSnaphuSd.py @@ -0,0 +1,199 @@ +# +# Author: Cunren Liang +# Copyright 2015-present, NASA-JPL/Caltech +# + +import os +import shutil +import logging +import datetime +import numpy as np + +import isceobj +from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrap +from isceobj.Alos2Proc.Alos2ProcPublic import snaphuUnwrapOriginal +from isceobj.Alos2Proc.Alos2ProcPublic import runCmd +from contrib.alos2proc.alos2proc import look +from isceobj.Alos2Proc.Alos2ProcPublic import create_xml + +logger = logging.getLogger('isce.alos2burstinsar.runUnwrapSnaphuSd') + +def runUnwrapSnaphuSd(self): + '''unwrap filtered interferogram + ''' + catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) + self.updateParamemetersFromUser() + + masterTrack = self._insar.loadTrack(master=True) + #slaveTrack = self._insar.loadTrack(master=False) + + sdDir = 'sd' + if not os.path.exists(sdDir): + os.makedirs(sdDir) + os.chdir(sdDir) + + + ############################################################ + # STEP 1. unwrap interferogram + ############################################################ + nsd = len(self._insar.filteredInterferogramSd) + img = isceobj.createImage() + img.load(self._insar.filteredInterferogramSd[0]+'.xml') + width = img.width + length = img.length + + if shutil.which('snaphu') != None: + print('\noriginal snaphu program found, use it for unwrapping interferograms') + useOriginalSnaphu = True + #create an amplitude for use + # amplitude = os.path.join('../insar', self._insar.amplitude) + # amplitudeMultilook = 'tmp.amp' + # img = isceobj.createImage() + # img.load(amplitude+'.xml') + # look(amplitude, amplitudeMultilook, img.width, self._insar.numberRangeLooksSd, self._insar.numberAzimuthLooksSd, 4, 1, 1) + else: + useOriginalSnaphu = False + + for sdCoherence, sdInterferogramFilt, sdInterferogramUnwrap in zip(self._insar.multilookCoherenceSd, self._insar.filteredInterferogramSd, self._insar.unwrappedInterferogramSd): + if useOriginalSnaphu: + amplitudeMultilook = 'tmp.amp' + cmd = "imageMath.py -e='sqrt(abs(a));sqrt(abs(a))' --a={} -o {} -t float -s BSQ".format(sdInterferogramFilt, amplitudeMultilook) + runCmd(cmd) + snaphuUnwrapOriginal(sdInterferogramFilt, + sdCoherence, + amplitudeMultilook, + sdInterferogramUnwrap, + costMode = 's', + initMethod = 'mcf') + os.remove(amplitudeMultilook) + os.remove(amplitudeMultilook+'.vrt') + os.remove(amplitudeMultilook+'.xml') + else: + tmid = masterTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*masterTrack.azimuthLineInterval+ + masterTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*masterTrack.azimuthLineInterval) + snaphuUnwrap(masterTrack, tmid, + sdInterferogramFilt, + sdCoherence, + sdInterferogramUnwrap, + self._insar.numberRangeLooks1*self._insar.numberRangeLooksSd, + self._insar.numberAzimuthLooks1*self._insar.numberAzimuthLooksSd, + costMode = 'SMOOTH',initMethod = 'MCF', defomax = 2, initOnly = True) + + #if useOriginalSnaphu: + # os.remove(amplitudeMultilook) + + + ############################################################ + # STEP 2. mask using connected components + ############################################################ + for sdInterferogramUnwrap, sdInterferogramUnwrapMasked in zip(self._insar.unwrappedInterferogramSd, self._insar.unwrappedMaskedInterferogramSd): + cmd = "imageMath.py -e='a_0*(b>0);a_1*(b>0)' --a={} --b={} -s BIL -t float -o={}".format(sdInterferogramUnwrap, sdInterferogramUnwrap+'.conncomp', sdInterferogramUnwrapMasked) + runCmd(cmd) + + + ############################################################ + # STEP 3. mask using water body + ############################################################ + if self.waterBodyMaskStartingStepSd=='unwrap': + wbd = np.fromfile(self._insar.multilookWbdOutSd, dtype=np.int8).reshape(length, width) + + for sdInterferogramUnwrap, sdInterferogramUnwrapMasked in zip(self._insar.unwrappedInterferogramSd, self._insar.unwrappedMaskedInterferogramSd): + unw=np.memmap(sdInterferogramUnwrap, dtype='float32', mode='r+', shape=(length*2, width)) + (unw[0:length*2:2, :])[np.nonzero(wbd==-1)] = 0 + (unw[1:length*2:2, :])[np.nonzero(wbd==-1)] = 0 + unw=np.memmap(sdInterferogramUnwrapMasked, dtype='float32', mode='r+', shape=(length*2, width)) + (unw[0:length*2:2, :])[np.nonzero(wbd==-1)] = 0 + (unw[1:length*2:2, :])[np.nonzero(wbd==-1)] = 0 + + + ############################################################ + # STEP 4. convert to azimuth deformation + ############################################################ + #burst cycle in s + burstCycleLength = masterTrack.frames[0].swaths[0].burstCycleLength / masterTrack.frames[0].swaths[0].prf + + #compute azimuth fmrate + #stack all azimuth fmrates + index = np.array([], dtype=np.float64) + ka = np.array([], dtype=np.float64) + for frame in masterTrack.frames: + for swath in frame.swaths: + startingRangeMultilook = masterTrack.frames[0].swaths[0].startingRange + \ + (self._insar.numberRangeLooks1*self._insar.numberRangeLooksSd-1.0)/2.0*masterTrack.frames[0].swaths[0].rangePixelSize + rangePixelSizeMultilook = self._insar.numberRangeLooks1 * self._insar.numberRangeLooksSd * masterTrack.frames[0].swaths[0].rangePixelSize + index0 = (swath.startingRange + np.arange(swath.numberOfSamples) * swath.rangePixelSize - startingRangeMultilook) / rangePixelSizeMultilook + ka0 = np.polyval(swath.azimuthFmrateVsPixel[::-1], np.arange(swath.numberOfSamples)) + index = np.concatenate((index, index0)) + ka = np.concatenate((ka, ka0)) + p = np.polyfit(index, ka, 3) + #new ka + ka = np.polyval(p, np.arange(width)) + + #compute radar beam footprint velocity at middle track + tmid = masterTrack.sensingStart + datetime.timedelta(seconds=(self._insar.numberAzimuthLooks1-1.0)/2.0*masterTrack.azimuthLineInterval+ + masterTrack.numberOfLines/2.0*self._insar.numberAzimuthLooks1*masterTrack.azimuthLineInterval) + svmid = masterTrack.orbit.interpolateOrbit(tmid, method='hermite') + #earth radius in meters + r = 6371 * 1000.0 + #radar footprint velocity + veln = np.linalg.norm(svmid.getVelocity()) * r / np.linalg.norm(svmid.getPosition()) + print('radar beam footprint velocity at middle track: %8.2f m/s'%veln) + + #phase to defo factor + factor = -1.0* veln / (2.0 * np.pi * ka * burstCycleLength) + + #process unwrapped without mask + sdunw_out = np.zeros((length*2, width)) + flag = np.zeros((length, width)) + wgt = np.zeros((length, width)) + for i in range(nsd): + sdunw = np.fromfile(self._insar.unwrappedInterferogramSd[i], dtype=np.float32).reshape(length*2, width) + sdunw[1:length*2:2, :] *= factor[None, :] / (i+1.0) + sdunw.astype(np.float32).tofile(self._insar.azimuthDeformationSd[i]) + create_xml(self._insar.azimuthDeformationSd[i], width, length, 'rmg') + flag += (sdunw[1:length*2:2, :]!=0) + #since the interferogram is filtered, we only use this light weight + wgt0 = (i+1)**2 + wgt += wgt0 * (sdunw[1:length*2:2, :]!=0) + sdunw_out[0:length*2:2, :] += (sdunw[0:length*2:2, :])**2 + sdunw_out[1:length*2:2, :] += wgt0 * sdunw[1:length*2:2, :] + #output weighting average + index = np.nonzero(flag!=0) + (sdunw_out[0:length*2:2, :])[index] = np.sqrt((sdunw_out[0:length*2:2, :])[index] / flag[index]) + (sdunw_out[1:length*2:2, :])[index] = (sdunw_out[1:length*2:2, :])[index] / wgt[index] + if not self.unionSd: + (sdunw_out[0:length*2:2, :])[np.nonzero(flag + + {2} + MSB + {3} + 8 + {4} + +'''.format(width, length, + self.imageFile, + fileHeaderBytes + lineHeaderBytes, + width*8 + lineHeaderBytes)) + else: + #read sar data line by line + try: + fp2 = open(self.outputFile,'wb') + except IOError as errs: + errno,strerr = errs + print("IOError: %s" % strerr) + return + fp.seek(-lineHeaderBytes, 1) + for line in range(length): + if (((line+1)%1000) == 0): + print("extracting line %6d of %6d" % (line+1, length), end='\r', flush=True) + fp.seek(lineHeaderBytes, 1) + IQLine = np.fromfile(fp, dtype='>f', count=2*width) + self.writeRawData(fp2, IQLine) + #IQLine.tofile(fp2) + print("extracting line %6d of %6d" % (length, length)) + fp2.close() + + #close input image file + fp.close() + + return (imageFDR, imageData) + + + def readLeader(self): + ''' + read meta data from leader + ''' + try: + fp = open(self.leaderFile,'rb') + except IOError as errs: + errno,strerr = errs + print("IOError: %s" % strerr) + return + + # Leader record + leaderFDR = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/leader_file.xml'),dataFile=fp) + leaderFDR.parse() + fp.seek(leaderFDR.getEndOfRecordPosition()) + + # Scene Header + sceneHeaderRecord = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/scene_record.xml'),dataFile=fp) + sceneHeaderRecord.parse() + fp.seek(sceneHeaderRecord.getEndOfRecordPosition()) + + # Platform Position + platformPositionRecord = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/platform_position_record.xml'),dataFile=fp) + platformPositionRecord.parse() + fp.seek(platformPositionRecord.getEndOfRecordPosition()) + + #####Skip attitude information + fp.seek(16384,1) + #####Skip radiometric information + fp.seek(9860,1) + ####Skip the data quality information + fp.seek(1620,1) + ####Skip facility 1-4 + fp.seek(325000 + 511000 + 3072 + 728000, 1) + + ####Read facility 5 + facilityRecord = CEOS.CEOSDB(xml=os.path.join(xmlPrefix,'alos2_slc/facility_record.xml'), dataFile=fp) + facilityRecord.parse() + + ###close file + fp.close() + + return (leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord) + + + def setTrack(self, leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData): + ''' + set track parameters + ''' + track = self.track + + #passDirection + passDirection = sceneHeaderRecord.metadata['Time direction indicator along line direction'] + if passDirection == 'ASCEND': + track.passDirection = 'ascending' + elif passDirection == 'DESCEND': + track.passDirection = 'descending' + else: + raise Exception('Unknown passDirection. passDirection = {0}'.format(passDirection)) + + #pointingDirection + ######ALOS-2 includes this information in clock angle + clockAngle = sceneHeaderRecord.metadata['Sensor clock angle'] + if clockAngle == 90.0: + track.pointingDirection = 'right' + elif clockAngle == -90.0: + track.pointingDirection = 'left' + else: + raise Exception('Unknown look side. Clock Angle = {0}'.format(clockAngle)) + + #operation mode + track.operationMode = self.operationModeDesignator[ + (sceneHeaderRecord.metadata['Sensor ID and mode of operation for this channel'])[10:12] + ] + + #use this instead. 30-JAN-2020 + track.operationMode = os.path.basename(self.leaderFile).split('-')[-1][0:3] + + #radarWavelength + track.radarWavelength = sceneHeaderRecord.metadata['Radar wavelength'] + + #orbit + orb = self.readOrbit(platformPositionRecord) + track.orbit.setOrbitSource(orb.getOrbitSource()) + track.orbit.setOrbitQuality(orb.getOrbitQuality()) + #add orbit from frame + for sv in orb: + addOrbit = True + #Orbit class does not check this + for x in track.orbit: + if x.getTime() == sv.getTime(): + addOrbit = False + break + if addOrbit: + track.orbit.addStateVector(sv) + + # the following are to be set when mosaicking frames. + # 'numberOfSamples', + # 'numberOfLines', + # 'startingRange', + # 'rangeSamplingRate', + # 'rangePixelSize', + # 'sensingStart', + # 'prf', + # 'azimuthPixelSize' + + + def setFrame(self, leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData): + ''' + set frame parameters + ''' + frame = self.track.frames[-1] + + #get frame number from file name + frame.frameNumber = os.path.basename(self.imageFile).split('-')[2][-4:] + frame.processingFacility = sceneHeaderRecord.metadata['Processing facility identifier'] + frame.processingSystem = sceneHeaderRecord.metadata['Processing system identifier'] + frame.processingSoftwareVersion = sceneHeaderRecord.metadata['Processing version identifier'] + #orbit quality + orb = self.readOrbit(platformPositionRecord) + frame.orbitQuality = orb.getOrbitQuality() + + # the following are to be set when mosaicking swaths + # 'numberOfSamples', + # 'numberOfLines', + # 'startingRange', + # 'rangeSamplingRate', + # 'rangePixelSize', + # 'sensingStart', + # 'prf', + # 'azimuthPixelSize' + + + def setSwath(self, leaderFDR, sceneHeaderRecord, platformPositionRecord, facilityRecord, imageFDR, imageData): + ''' + set swath parameters + ''' + swath = self.track.frames[-1].swaths[-1] + operationMode = (sceneHeaderRecord.metadata['Sensor ID and mode of operation for this channel'])[10:12] + + #set swath number here regardless of operation mode, will be updated for ScanSAR later + swath.swathNumber = 1 + + #polarization + polDesignator = {0: 'H', + 1: 'V'} + swath.polarization = '{}{}'.format(polDesignator[imageData.metadata['Transmitted polarization']], + polDesignator[imageData.metadata['Received polarization']]) + + #image dimensions + swath.numberOfSamples = imageFDR.metadata['Number of pixels per line per SAR channel'] + swath.numberOfLines = imageFDR.metadata['Number of SAR DATA records'] + + #range + swath.startingRange = imageData.metadata['Slant range to 1st data sample'] + swath.rangeSamplingRate = self.fsampConst[int(sceneHeaderRecord.metadata['Range sampling rate in MHz'])] + swath.rangePixelSize = Const.c/(2.0*swath.rangeSamplingRate) + swath.rangeBandwidth =abs((sceneHeaderRecord.metadata['Nominal range pulse (chirp) amplitude coefficient linear term']) * + (sceneHeaderRecord.metadata['Range pulse length in microsec']*1.0e-6)) + + #sensingStart + yr = imageData.metadata['Sensor acquisition year'] + dys = imageData.metadata['Sensor acquisition day of year'] + msecs = imageData.metadata['Sensor acquisition milliseconds of day'] + usecs = imageData.metadata['Sensor acquisition micro-seconds of day'] + swath.sensingStart = datetime.datetime(yr,1,1) + datetime.timedelta(days=(dys-1)) + datetime.timedelta(seconds = usecs*1e-6) + + #prf + if operationMode == '08' or operationMode == '09': + # Operation mode + # '00': 'Spotlight mode', + # '01': 'Ultra-fine mode', + # '02': 'High-sensitive mode', + # '03': 'Fine mode', + # '04': 'spare', + # '05': 'spare', + # '08': 'ScanSAR nominal mode', + # '09': 'ScanSAR wide mode', + # '18': 'Full (Quad.) pol./High-sensitive mode', + # '19': 'Full (Quad.) pol./Fine mode', + # '64': 'Manual observation' + #print('ScanSAR mode, using PRF from the line header') + swath.prf = imageData.metadata['PRF'] * 1.0e-3 + else: + #print('not ScanSAR mode, using PRF from leader file') + swath.prf = sceneHeaderRecord.metadata['Pulse Repetition Frequency in mHz']*1.0e-3 + + #azimuth pixel size at swath center on ground + azimuthTime = swath.sensingStart + datetime.timedelta(seconds=swath.numberOfLines/swath.prf/2.0) + orbit = self.readOrbit(platformPositionRecord) + svmid = orbit.interpolateOrbit(azimuthTime, method='hermite') + height = np.linalg.norm(svmid.getPosition()) + velocity = np.linalg.norm(svmid.getVelocity()) + #earth radius in meters + r = 6371 * 1000.0 + swath.azimuthPixelSize = velocity / swath.prf * r / height + swath.azimuthLineInterval = 1.0 / swath.prf + + #doppler + swath.dopplerVsPixel = self.reformatDoppler(sceneHeaderRecord, imageFDR, imageData) + + #azimuth FM rate + azimuthTime = swath.sensingStart + datetime.timedelta(seconds=swath.numberOfLines/swath.prf/2.0) + swath.azimuthFmrateVsPixel = self.computeAzimuthFmrate(sceneHeaderRecord, platformPositionRecord, imageFDR, imageData, azimuthTime) + + + #burst information estimated from azimuth spectrum. Cunren, 14-DEC-2015 + if operationMode == '08' or operationMode == '09': + sceneCenterIncidenceAngle = sceneHeaderRecord.metadata['Incidence angle at scene centre'] + sarChannelId = imageData.metadata['SAR channel indicator'] + #Scan ID starts with 1, ScanSAR = 1 to 7, Except ScanSAR = 0 + scanId = imageData.metadata['Scan ID'] + swath.swathNumber = scanId + + #looks like all ScanSAR nominal modes (WBS,WBD,WWS,WWD) have same burst parameters, so remove the limitation here + #if (sceneCenterIncidenceAngle > 39.032 - 5.0 and sceneCenterIncidenceAngle < 39.032 + 5.0) and (sarChannelId == 2): + if operationMode == '08': + #burst parameters, currently only for the second, dual polarization, ScanSAR nominal mode + #that is the second WBD mode + #p.25 and p.115 of ALOS-2/PALSAR-2 Level 1.1/1.5/2.1/3.1 CEOS SAR Product Format Description + #for the definations of wide swath mode + nbraw = [358, 470, 358, 355, 487] + ncraw = [2086.26, 2597.80, 1886.18, 1779.60, 2211.17] + + swath.burstLength = nbraw[scanId-1] + swath.burstCycleLength = ncraw[scanId-1] + + #this is the prf fraction (total azimuth bandwith) used in extracting burst + #here the total bandwith is 0.93 * prfs[3] for all subswaths, which is the following values: + #[0.7933, 0.6371, 0.8774, 0.9300, 0.7485] + prfs=[2661.847, 3314.512, 2406.568, 2270.575, 2821.225] + swath.prfFraction = 0.93 * prfs[3]/prfs[scanId-1] + + #compute burst start time + if operationMode == '08': + (burstStartTime, burstCycleLengthNew) = self.burstTimeRefining(self.outputFile, + swath.numberOfSamples, + swath.numberOfLines, + swath.prf, + swath.burstLength, + swath.burstCycleLength, + swath.azimuthFmrateVsPixel, + swath.sensingStart, + self.useVirtualFile) + swath.burstStartTime = burstStartTime + swath.burstCycleLength = burstCycleLengthNew + + + def computeAzimuthFmrate(self, sceneHeaderRecord, platformPositionRecord, imageFDR, imageData, azimuthTime): + import copy + ''' + compute azimuth FM rate, copied from Piyush's code. + azimuthTime: middle of the scene should be a good time + ''' + #parameters required + orbit = self.readOrbit(platformPositionRecord) + dopplerVsPixel = self.reformatDoppler(sceneHeaderRecord, imageFDR, imageData) + width = imageFDR.metadata['Number of pixels per line per SAR channel'] + + startingRange = imageData.metadata['Slant range to 1st data sample'] + rangeSamplingRate = self.fsampConst[int(sceneHeaderRecord.metadata['Range sampling rate in MHz'])] + radarWavelength = sceneHeaderRecord.metadata['Radar wavelength'] + + clockAngle = sceneHeaderRecord.metadata['Sensor clock angle'] + if clockAngle == 90.0: + #right + pointingDirection = -1 + elif clockAngle == -90.0: + #left + pointingDirection = 1 + else: + raise Exception('Unknown look side. Clock Angle = {0}'.format(clockAngle)) + + ##We have to compute FM rate here. + ##Cunren's observation that this is all set to zero in CEOS file. + ##Simplification from Cunren's fmrate.py script + ##Should be the same as the one in focus.py + planet = Planet(pname='Earth') + elp = copy.copy(planet.ellipsoid) + svmid = orbit.interpolateOrbit(azimuthTime, method='hermite') + xyz = svmid.getPosition() + vxyz = svmid.getVelocity() + llh = elp.xyz_to_llh(xyz) + hdg = orbit.getENUHeading(azimuthTime) + + elp.setSCH(llh[0], llh[1], hdg) + sch, schvel = elp.xyzdot_to_schdot(xyz, vxyz) + + ##Computeation of acceleration + dist= np.linalg.norm(xyz) + r_spinvec = np.array([0., 0., planet.spin]) + r_tempv = np.cross(r_spinvec, xyz) + inert_acc = np.array([-planet.GM*x/(dist**3) for x in xyz]) + r_tempa = np.cross(r_spinvec, vxyz) + r_tempvec = np.cross(r_spinvec, r_tempv) + axyz = inert_acc - 2 * r_tempa - r_tempvec + + schbasis = elp.schbasis(sch) + schacc = np.dot(schbasis.xyz_to_sch, axyz).tolist()[0] + + ##Jumping back straight into Cunren's script here + centerVel = schvel + centerAcc = schacc + avghgt = llh[2] + radiusOfCurvature = elp.pegRadCur + + fmrate = [] + lookSide = pointingDirection + centerVelNorm = np.linalg.norm(centerVel) + + ##Retaining Cunren's code for computing at every pixel. + ##Can be done every 10th pixel since we only fit a quadratic/ cubic. + ##Also can be vectorized for speed. + + for ii in range(width): + rg = startingRange + ii * 0.5 * Const.c / rangeSamplingRate + #don't forget to flip coefficients + dop = np.polyval(dopplerVsPixel[::-1], ii) + + th = np.arccos(((avghgt+radiusOfCurvature)**2 + rg**2 -radiusOfCurvature**2)/(2.0 * (avghgt + radiusOfCurvature) * rg)) + thaz = np.arcsin(((radarWavelength*dop/(2.0*np.sin(th))) + (centerVel[2] / np.tan(th))) / np.sqrt(centerVel[0]**2 + centerVel[1]**2)) - lookSide * np.arctan(centerVel[1]/centerVel[0]) + + lookVec = [ np.sin(th) * np.sin(thaz), + np.sin(th) * np.cos(thaz) * lookSide, + -np.cos(th)] + + vdotl = np.dot(lookVec, centerVel) + adotl = np.dot(lookVec, centerAcc) + fmratex = 2.0*(adotl + (vdotl**2 - centerVelNorm**2)/rg)/(radarWavelength) + fmrate.append(fmratex) + + ##Fitting order 2 polynomial to FM rate + p = np.polyfit(np.arange(width), fmrate, 2) + azimuthFmrateVsPixel = [p[2], p[1], p[0], 0.] + + return azimuthFmrateVsPixel + + + def reformatDoppler(self, sceneHeaderRecord, imageFDR, imageData): + ''' + reformat Doppler coefficients + ''' + dopplerCoeff = [sceneHeaderRecord.metadata['Doppler center frequency constant term'], + sceneHeaderRecord.metadata['Doppler center frequency linear term']] + + width = imageFDR.metadata['Number of pixels per line per SAR channel'] + startingRange = imageData.metadata['Slant range to 1st data sample'] + rangeSamplingRate = self.fsampConst[int(sceneHeaderRecord.metadata['Range sampling rate in MHz'])] + + rng = startingRange + np.arange(0,width,100) * 0.5 * Const.c / rangeSamplingRate + doppler = dopplerCoeff[0] + dopplerCoeff[1] * rng / 1000. + dfit = np.polyfit(np.arange(0, width, 100), doppler, 1) + dopplerVsPixel = [dfit[1], dfit[0], 0., 0.] + + return dopplerVsPixel + + + def readOrbit(self, platformPositionRecord): + ''' + reformat orbit from platformPositionRecord + ''' + orb=Orbit() + orb.setOrbitSource('leaderfile') + orb.setOrbitQuality(self.orbitElementsDesignator[platformPositionRecord.metadata['Orbital elements designator']]) + + t0 = datetime.datetime(year=platformPositionRecord.metadata['Year of data point'], + month=platformPositionRecord.metadata['Month of data point'], + day=platformPositionRecord.metadata['Day of data point']) + t0 = t0 + datetime.timedelta(seconds=platformPositionRecord.metadata['Seconds of day']) + + #####Read in orbit in inertial coordinates + deltaT = platformPositionRecord.metadata['Time interval between data points'] + numPts = platformPositionRecord.metadata['Number of data points'] + for i in range(numPts): + vec = StateVector() + t = t0 + datetime.timedelta(seconds=i*deltaT) + vec.setTime(t) + + dataPoints = platformPositionRecord.metadata['Positional Data Points'][i] + pos = [dataPoints['Position vector X'], dataPoints['Position vector Y'], dataPoints['Position vector Z']] + vel = [dataPoints['Velocity vector X'], dataPoints['Velocity vector Y'], dataPoints['Velocity vector Z']] + vec.setPosition(pos) + vec.setVelocity(vel) + orb.addStateVector(vec) + + return orb + + + def burstTimeRefining(self, slcFile, numberOfSamples, numberOfLines, pulseRepetitionFrequency, burstLength, burstCycleLength, azimuthFmrateVsPixel, sensingStart, useVirtualFile=True): + ''' + compute start time of raw burst + ''' + #number of lines from start and end of file + #this mainly considers ALOS-2 full-aperture length, should be updated for ALOS-4? + delta_line = 15000 + + #first estimate at file start + start_line1 = delta_line + (burstStartLine1, burstStartTime1, burstStartLineEstimated1) = self.burstTime(slcFile, + numberOfSamples, + numberOfLines, + pulseRepetitionFrequency, + burstLength, + burstCycleLength, + azimuthFmrateVsPixel, + sensingStart, + start_line1, + 1000, + 1, + useVirtualFile) + + #estimate again at file end + #number of burst cycles + num_nc = np.around((numberOfLines - delta_line*2) / burstCycleLength) + start_line2 = int(np.around(start_line1 + num_nc * burstCycleLength)) + (burstStartLine2, burstStartTime2, burstStartLineEstimated2) = self.burstTime(slcFile, + numberOfSamples, + numberOfLines, + pulseRepetitionFrequency, + burstLength, + burstCycleLength, + azimuthFmrateVsPixel, + sensingStart, + start_line2, + 1000, + 1, + useVirtualFile) + + #correct burst cycle value + LineDiffIndex = 0 + LineDiffMin = np.fabs(burstStartLineEstimated1 + burstCycleLength * LineDiffIndex - burstStartLineEstimated2) + for i in range(0, 100000): + LineDiffMinx = np.fabs(burstStartLineEstimated1 + burstCycleLength * i - burstStartLineEstimated2) + if LineDiffMinx <= LineDiffMin: + LineDiffMin = LineDiffMinx + LineDiffIndex = i + burstCycleLengthNew = burstCycleLength - (burstStartLineEstimated1 + burstCycleLength * LineDiffIndex - burstStartLineEstimated2) / LineDiffIndex + + #use correct burstCycleLength to do final estimation + start_line = int(np.around(numberOfLines/2.0)) + (burstStartLine, burstStartTime, burstStartLineEstimated) = self.burstTime(slcFile, + numberOfSamples, + numberOfLines, + pulseRepetitionFrequency, + burstLength, + burstCycleLengthNew, + azimuthFmrateVsPixel, + sensingStart, + start_line, + 1000, + 1, + useVirtualFile) + + #return burstStartTime and refined burstCycleLength + return (burstStartTime, burstCycleLengthNew) + + + def burstTime(self, slcFile, numberOfSamples, numberOfLines, pulseRepetitionFrequency, burstLength, burstCycleLength, azimuthFmrateVsPixel, sensingStart, startLine=500, startColumn=500, pow2=1, useVirtualFile=True): + ''' + compute start time of raw burst + ''' + ####################################################### + #set these parameters + width = numberOfSamples + length = numberOfLines + prf = pulseRepetitionFrequency + nb = burstLength + nc = burstCycleLength + fmrateCoeff = azimuthFmrateVsPixel + sensing_start = sensingStart + saz = startLine #start line to be used (included, index start with 0. default: 500) + srg = startColumn #start column to be used (included, index start with 0. default: 500) + p2 = pow2 #must be 1(default) or power of 2. azimuth fft length = THIS ARGUMENT * next of power of 2 of full-aperture length. + ####################################################### + + def create_lfm(ns, it, offset, k): + ''' + # create linear FM signal + # ns: number of samples + # it: time interval of the samples + # offset: offset + # k: linear FM rate + #offset-centered, this applies to both odd and even cases + ''' + ht = (ns - 1) / 2.0 + t = np.arange(-ht, ht+1.0, 1) + t = (t + offset) * it + cj = np.complex64(1j) + lfm = np.exp(cj * np.pi * k * t**2) + + return lfm + + + def next_pow2(a): + x=2 + while x < a: + x *= 2 + return x + + + def is_power2(num): + '''states if a number is a power of two''' + return num != 0 and ((num & (num - 1)) == 0) + + + if not (p2 == 1 or is_power2(p2)): + raise Exception('pow2 must be 1 or power of 2\n') + + #fmrate, use the convention that ka > 0 + ka = -np.polyval(fmrateCoeff[::-1], np.arange(width)) + + #area to be used for estimation + naz = int(np.round(nc)) #number of lines to be used. + eaz = saz+naz-1 #ending line to be used (included) + caz = int(np.round((saz+eaz)/2.0)) #central line of the lines used. + caz_deramp = (saz+eaz)/2.0 #center of deramp signal (may be fractional line number) + + nrg = 400 #number of columns to be used + erg = srg+nrg-1 #ending column to be used (included) + crg = int(np.round((srg+erg)/2.0)) #central column of the columns used. + + #check parameters + if not (saz >=0 and saz <= length - 1): + raise Exception('wrong starting line\n') + if not (eaz >=0 and eaz <= length - 1): + raise Exception('wrong ending line\n') + if not (srg >=0 and srg <= width - 1): + raise Exception('wrong starting column\n') + if not (erg >=0 and erg <= width - 1): + raise Exception('wrong ending column\n') + + #number of lines of a full-aperture + nfa = int(np.round(prf / ka[crg] / (1.0 / prf))) + #use nfa to determine fft size. fft size can be larger than this + nazfft = next_pow2(nfa) * p2 + + #deramp signal + deramp = np.zeros((naz, nrg), dtype=np.complex64) + for i in range(nrg): + deramp[:, i] = create_lfm(naz, 1.0/prf, 0, -ka[i+srg]) + + #read data, python should be faster + useGdal = False + if useGdal: + from osgeo import gdal + ###Read in chunk of data + ds = gdal.Open(slcFile + '.vrt', gdal.GA_ReadOnly) + data = ds.ReadAsArray(srg, saz, nrg, naz) + ds = None + else: + #!!!hard-coded: ALOS-2 image file header 720 bytes, line header 544 bytes + if useVirtualFile == True: + fileHeader = 720 + lineHeader = 544 + #lineHeader is just integer multiples of complex pixle size, so it's good + lineHeaderSamples = int(lineHeader/np.dtype(np.complex64).itemsize) + slcFile = self.find_keyword(slcFile+'.vrt', 'SourceFilename') + else: + fileHeader = 0 + lineHeader = 0 + lineHeaderSamples = 0 + data = np.memmap(slcFile, np.complex64,'r', offset = fileHeader, shape=(numberOfLines,lineHeaderSamples+numberOfSamples)) + data = data[saz:eaz+1, lineHeaderSamples+srg:lineHeaderSamples+erg+1] + if useVirtualFile == True: + data = data.byteswap() + + #deramp data + datadr = deramp * data + + #spectrum + spec = np.fft.fft(datadr, n=nazfft, axis=0) + + #shift zero-frequency component to center of spectrum + spec = np.fft.fftshift(spec, axes=0) + + specm=np.mean(np.absolute(spec), axis=1) + + #number of samples of the burst in frequncy domain + nbs = int(np.round(nb*(1.0/prf)*ka[crg]/prf*nazfft)); + #number of samples of the burst cycle in frequncy domain + ncs = int(np.round(nc*(1.0/prf)*ka[crg]/prf*nazfft)); + rect = np.ones(nbs, dtype=np.float32) + + #make sure orders of specm and rect are correct, so that peaks + #happen in the same order as their corresponding bursts + corr=np.correlate(specm, rect,'same') + + #find burst spectrum center + ncs_rh = int(np.round((nazfft - ncs) / 2.0)) + #corr_bc = corr[ncs_rh: ncs_rh+ncs] + #offset between spectrum center and center + offset_spec = np.argmax(corr[ncs_rh: ncs_rh+ncs])+ncs_rh - (nazfft - 1.0) / 2.0 + #offset in number of azimuth lines + offset_naz = offset_spec / nazfft * prf / ka[crg] / (1.0/prf) + + #start line of burst (fractional line number) + saz_burst = -offset_naz + caz_deramp - (nb - 1.0) / 2.0 + + #find out the start line of all bursts (fractional line number, + #line index start with 0, line 0 is the first SLC line) + #now only find first burst + for i in range(-100000, 100000): + saz_burstx = saz_burst + nc * i + st_burstx = sensing_start + datetime.timedelta(seconds=saz_burstx * (1.0/prf)) + if saz_burstx >= 0.0 and saz_burstx <= length: + burstStartLine = saz_burstx + burstStartTime = st_burstx + break + burstStartLineEstimated = saz_burst + + #dump spectrum and correlation + debug = False + if debug: + specm_corr = '' + for i in range(nazfft): + specm_corr += '{:6d} {:f} {:6d} {:f}\n'.format(i, specm[i], i, corr[i]) + specm_corr_name = str(sensingStart.year)[2:] + '%02d' % sensingStart.month + '%02d' % sensingStart.day + '_spec_corr.txt' + with open(specm_corr_name, 'w') as f: + f.write(specm_corr) + + return (burstStartLine, burstStartTime, burstStartLineEstimated) + + + def find_keyword(self, xmlfile, keyword): + from xml.etree.ElementTree import ElementTree + + value = None + xmlx = ElementTree(file=open(xmlfile,'r')).getroot() + #try 10 times + for i in range(10): + path='' + for j in range(i): + path += '*/' + value0 = xmlx.find(path+keyword) + if value0 != None: + value = value0.text + break + + return value + + + def writeRawData(self, fp, line): + ''' + Convert complex integer to complex64 format. + ''' + cJ = np.complex64(1j) + data = line[0::2] + cJ * line[1::2] + data.tofile(fp) + + + +if __name__ == '__main__': + + main() + diff --git a/components/isceobj/Sensor/MultiMode/Frame.py b/components/isceobj/Sensor/MultiMode/Frame.py new file mode 100644 index 0000000..d3ff44c --- /dev/null +++ b/components/isceobj/Sensor/MultiMode/Frame.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python3 + +#Author: Cunren Liang, 2015- + +import isce +import datetime +import isceobj +import numpy as np +from iscesys.Component.Component import Component +from iscesys.Traits import datetimeType + + +####List of parameters +FRAME_NUMBER = Component.Parameter('frameNumber', + public_name = 'frame number', + default = None, + type = str, + mandatory = True, + doc = 'frame number in unpacked file names (not in zip file name!)') + +PROCESSING_FACILITY = Component.Parameter('processingFacility', + public_name='processing facility', + default=None, + type = str, + mandatory = False, + doc = 'processing facility information') + +PROCESSING_SYSTEM = Component.Parameter('processingSystem', + public_name='processing system', + default=None, + type = str, + mandatory = False, + doc = 'processing system information') + +PROCESSING_SYSTEM_VERSION = Component.Parameter('processingSoftwareVersion', + public_name='processing software version', + default=None, + type = str, + mandatory = False, + doc = 'processing system software version') + +ORBIT_QUALITY = Component.Parameter('orbitQuality', + public_name='orbit quality', + default=None, + type = str, + mandatory = False, + doc = 'orbit quality. 0: preliminary, 1: decision, 2: high precision') + +#note that following parameters consider range/azimuth number of looks in interferogram formation +#except: rangeSamplingRate, prf + +NUMBER_OF_SAMPLES = Component.Parameter('numberOfSamples', + public_name='number of samples', + default=None, + type=int, + mandatory=True, + doc='width of the burst slc') + +NUMBER_OF_LINES = Component.Parameter('numberOfLines', + public_name='number of lines', + default=None, + type=int, + mandatory=True, + doc='length of the burst slc') + +STARTING_RANGE = Component.Parameter('startingRange', + public_name='starting range', + default=None, + type=float, + mandatory=True, + doc='slant range to first pixel in m') + +RANGE_SAMPLING_RATE = Component.Parameter('rangeSamplingRate', + public_name = 'range sampling rate', + default = None, + type = float, + mandatory = True, + doc = 'range sampling rate in Hz') + +RANGE_PIXEL_SIZE = Component.Parameter('rangePixelSize', + public_name = 'range pixel size', + default = None, + type=float, + mandatory = True, + doc = 'slant range pixel size in m') + +SENSING_START = Component.Parameter('sensingStart', + public_name='sensing start', + default=None, + type=datetimeType, + mandatory=True, + doc='UTC time corresponding to first line of swath SLC') + +PRF = Component.Parameter('prf', + public_name = 'pulse repetition frequency', + default = None, + type = float, + mandatory = True, + doc = 'pulse repetition frequency in Hz') + +AZIMUTH_PIXEL_SIZE = Component.Parameter('azimuthPixelSize', + public_name = 'azimuth pixel size', + default = None, + type=float, + mandatory = True, + doc = 'azimuth pixel size on ground in m') + +AZIMUTH_LINE_INTERVAL = Component.Parameter('azimuthLineInterval', + public_name = 'azimuth line interval', + default = None, + type=float, + mandatory = True, + doc = 'azimuth line interval in s') + +####List of facilities +SWATHS = Component.Facility('swaths', + public_name='swaths', + module = 'iscesys.Component', + factory = 'createTraitSeq', + args=('swath',), + mandatory = False, + doc = 'trait sequence of swath SLCs') + +class Frame(Component): + """A class to represent a frame""" + + family = 'frame' + logging_name = 'isce.frame' + + + + + parameter_list = (FRAME_NUMBER, + PROCESSING_FACILITY, + PROCESSING_SYSTEM, + PROCESSING_SYSTEM_VERSION, + ORBIT_QUALITY, + NUMBER_OF_SAMPLES, + NUMBER_OF_LINES, + STARTING_RANGE, + RANGE_SAMPLING_RATE, + RANGE_PIXEL_SIZE, + SENSING_START, + PRF, + AZIMUTH_PIXEL_SIZE, + AZIMUTH_LINE_INTERVAL + ) + + + facility_list = (SWATHS,) + + + def __init__(self,name=''): + super(Frame, self).__init__(family=self.__class__.family, name=name) + return None + + + def clone(self): + import copy + res = copy.deepcopy(self) + res.image._accessor = None + res.image._factory = None + + return res diff --git a/components/isceobj/Sensor/MultiMode/SConscript b/components/isceobj/Sensor/MultiMode/SConscript new file mode 100644 index 0000000..cde24fc --- /dev/null +++ b/components/isceobj/Sensor/MultiMode/SConscript @@ -0,0 +1,31 @@ +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Walter Szeliga +# NASA Jet Propulsion Laboratory +# California Institute of Technology +# (c) 2010 All Rights Reserved +# +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +#!/usr/bin/env python +import os + +Import('envSensor') +envMultiMode = envSensor.Clone() +project = 'MultiMode' +package = envMultiMode['PACKAGE'] +envMultiMode['PROJECT'] = project +envMultiMode['SENSOR_SCONS_INSTALL'] = os.path.join( + envMultiMode['PRJ_SCONS_INSTALL'], package, 'Sensor',project) +install = envMultiMode['SENSOR_SCONS_INSTALL'] + +listFiles = ['__init__.py','ALOS2.py','Frame.py','Swath.py','Track.py'] + +helpList,installHelp = envMultiMode['HELP_BUILDER'](envMultiMode,'__init__.py',install) + +envMultiMode.Install(installHelp,helpList) +envMultiMode.Alias('install',installHelp) + +envMultiMode.Install(install,listFiles) +envMultiMode.Alias('install',install) diff --git a/components/isceobj/Sensor/MultiMode/Swath.py b/components/isceobj/Sensor/MultiMode/Swath.py new file mode 100644 index 0000000..63b5d80 --- /dev/null +++ b/components/isceobj/Sensor/MultiMode/Swath.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 + +#Author: Cunren Liang, 2015- + +import isce +import datetime +import isceobj +import numpy as np +from iscesys.Component.Component import Component +from isceobj.Image.Image import Image +from isceobj.Orbit.Orbit import Orbit +from isceobj.Util.decorators import type_check +from iscesys.Traits import datetimeType + + +####List of parameters +SWATH_NUMBER = Component.Parameter('swathNumber', + public_name = 'swath number', + default = None, + type = int, + mandatory = True, + doc = 'swath number for bookkeeping') + +POLARIZATION = Component.Parameter('polarization', + public_name = 'polarization', + default = None, + type = str, + mandatory = True, + doc = 'polarization') + +NUMBER_OF_SAMPLES = Component.Parameter('numberOfSamples', + public_name='number of samples', + default=None, + type=int, + mandatory=True, + doc='width of the burst slc') + +NUMBER_OF_LINES = Component.Parameter('numberOfLines', + public_name='number of lines', + default=None, + type=int, + mandatory=True, + doc='length of the burst slc') + +STARTING_RANGE = Component.Parameter('startingRange', + public_name='starting range', + default=None, + type=float, + mandatory=True, + doc='slant range to first pixel in m') + +RANGE_SAMPLING_RATE = Component.Parameter('rangeSamplingRate', + public_name = 'range sampling rate', + default = None, + type = float, + mandatory = True, + doc = 'range sampling rate in Hz') + +RANGE_PIXEL_SIZE = Component.Parameter('rangePixelSize', + public_name = 'range pixel size', + default = None, + type=float, + mandatory = True, + doc = 'slant range pixel size in m') + +RANGE_BANDWIDTH = Component.Parameter('rangeBandwidth', + public_name = 'range bandwidth', + default = None, + type=float, + mandatory = True, + doc = 'range bandwidth in Hz') + +SENSING_START = Component.Parameter('sensingStart', + public_name='sensing start', + default=None, + type=datetimeType, + mandatory=True, + doc='UTC time corresponding to first line of swath SLC') + +PRF = Component.Parameter('prf', + public_name = 'pulse repetition frequency', + default = None, + type = float, + mandatory = True, + doc = 'pulse repetition frequency in Hz') + +AZIMUTH_PIXEL_SIZE = Component.Parameter('azimuthPixelSize', + public_name = 'azimuth pixel size', + default = None, + type=float, + mandatory = True, + doc = 'azimuth pixel size on ground in m') + +AZIMUTH_LINE_INTERVAL = Component.Parameter('azimuthLineInterval', + public_name = 'azimuth line interval', + default = None, + type=float, + mandatory = True, + doc = 'azimuth line interval in s') + +DOPPLER_VS_PIXEL = Component.Parameter('dopplerVsPixel', + public_name = 'doppler vs pixel', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'Doppler (Hz) polynomial coefficients vs range pixel number') + +AZIMUTH_FMRATE_VS_PIXEL = Component.Parameter('azimuthFmrateVsPixel', + public_name = 'azimuth fm rate vs pixel', + default = [], + type = float, + mandatory = True, + container = list, + doc = 'azimuth FM rate (Hz/s) polynomial coefficients vs range pixel number') + +#for ScanSAR full-aperture product +BURST_LENGTH = Component.Parameter('burstLength', + public_name = 'Burst Length', + default = None, + type = float, +# type = int, + mandatory = False, + doc = 'number of pulses in a raw burst') + +BURST_CYCLE_LENGTH = Component.Parameter('burstCycleLength', + public_name = 'Burst cycle length', + default = None, + type = float, + mandatory = False, + doc = 'number of pulses in a raw burst cycle') + +BURST_START_TIME = Component.Parameter('burstStartTime', + public_name='Burst start time', + default=None, + type=datetimeType, + mandatory=False, + doc='start time of a raw burst') + +#for ScanSAR burst-by-burst processing +PRF_FRACTION = Component.Parameter('prfFraction', + public_name = 'prf fraction', + default = None, + type = float, + mandatory = False, + doc = 'fraction of PRF for extracting bursts for bookkeeping') + +NUMBER_OF_BURSTS = Component.Parameter('numberOfBursts', + public_name='number of bursts', + default=None, + type=int, + mandatory=False, + doc='number of bursts in a swath') + +FIRST_BURST_RAW_START_TIME = Component.Parameter('firstBurstRawStartTime', + public_name='start time of first raw burst', + default=None, + type=datetimeType, + mandatory=False, + doc='start time of first raw burst') + +FIRST_BURST_SLC_START_TIME = Component.Parameter('firstBurstSlcStartTime', + public_name='start time of first burst slc', + default=None, + type=datetimeType, + mandatory=False, + doc='start time of first burst slc') + +BURST_SLC_FIRST_LINE_OFFSETS = Component.Parameter('burstSlcFirstLineOffsets', + public_name = 'burst SLC first line offsets', + default = None, + type = int, + mandatory = False, + container = list, + doc = 'burst SLC first line offsets') + +BURST_SLC_NUMBER_OF_SAMPLES = Component.Parameter('burstSlcNumberOfSamples', + public_name='burst slc number of samples', + default=None, + type=int, + mandatory=False, + doc='burst slc width of the burst slc') + +BURST_SLC_NUMBER_OF_LINES = Component.Parameter('burstSlcNumberOfLines', + public_name='burst slc number of lines', + default=None, + type=int, + mandatory=False, + doc='burst slc length of the burst slc') + + +class Swath(Component): + """A class to represent a swath SLC""" + + family = 'swath' + logging_name = 'isce.swath' + + parameter_list = (SWATH_NUMBER, + POLARIZATION, + NUMBER_OF_SAMPLES, + NUMBER_OF_LINES, + STARTING_RANGE, + RANGE_SAMPLING_RATE, + RANGE_PIXEL_SIZE, + RANGE_BANDWIDTH, + SENSING_START, + PRF, + AZIMUTH_PIXEL_SIZE, + AZIMUTH_LINE_INTERVAL, + DOPPLER_VS_PIXEL, + AZIMUTH_FMRATE_VS_PIXEL, + BURST_LENGTH, + BURST_CYCLE_LENGTH, + BURST_START_TIME, + PRF_FRACTION, + NUMBER_OF_BURSTS, + FIRST_BURST_RAW_START_TIME, + FIRST_BURST_SLC_START_TIME, + BURST_SLC_FIRST_LINE_OFFSETS, + BURST_SLC_NUMBER_OF_SAMPLES, + BURST_SLC_NUMBER_OF_LINES + ) + + + def __init__(self,name=''): + super(Swath, self).__init__(family=self.__class__.family, name=name) + return None + + + def clone(self): + import copy + res = copy.deepcopy(self) + res.image._accessor = None + res.image._factory = None + + return res diff --git a/components/isceobj/Sensor/MultiMode/Track.py b/components/isceobj/Sensor/MultiMode/Track.py new file mode 100644 index 0000000..f0f5a11 --- /dev/null +++ b/components/isceobj/Sensor/MultiMode/Track.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 + +#Author: Cunren Liang, 2015- + +import isce +import datetime +import isceobj +import numpy as np +from iscesys.Component.Component import Component +from isceobj.Image.Image import Image +from isceobj.Orbit.Orbit import Orbit +from isceobj.Util.decorators import type_check +from iscesys.Traits import datetimeType + + +####List of parameters +PASS_DIRECTION = Component.Parameter('passDirection', + public_name='pass direction', + default = None, + type=str, + mandatory=True, + doc = 'satellite flying direction, ascending/descending') + +POINTING_DIRECTION = Component.Parameter('pointingDirection', + public_name='pointing direction', + default=None, + type = str, + mandatory = True, + doc = 'antenna point direction: right/left') + +OPERATION_MODE = Component.Parameter('operationMode', + public_name='operation mode', + default=None, + type = str, + mandatory = True, + doc = 'JAXA ALOS-2 operation mode code') + +RADAR_WAVELENGTH = Component.Parameter('radarWavelength', + public_name = 'radarWavelength', + default = None, + type = float, + mandatory = True, + doc = 'radar wavelength in m') + +NUMBER_OF_SAMPLES = Component.Parameter('numberOfSamples', + public_name='number of samples', + default=None, + type=int, + mandatory=True, + doc='width of the burst slc') + +NUMBER_OF_LINES = Component.Parameter('numberOfLines', + public_name='number of lines', + default=None, + type=int, + mandatory=True, + doc='length of the burst slc') + +STARTING_RANGE = Component.Parameter('startingRange', + public_name='starting range', + default=None, + type=float, + mandatory=True, + doc='slant range to first pixel in m') + +RANGE_SAMPLING_RATE = Component.Parameter('rangeSamplingRate', + public_name = 'range sampling rate', + default = None, + type = float, + mandatory = True, + doc = 'range sampling rate in Hz') + +RANGE_PIXEL_SIZE = Component.Parameter('rangePixelSize', + public_name = 'range pixel size', + default = None, + type=float, + mandatory = True, + doc = 'slant range pixel size in m') + +SENSING_START = Component.Parameter('sensingStart', + public_name='sensing start', + default=None, + type=datetimeType, + mandatory=True, + doc='UTC time corresponding to first line of swath SLC') + +PRF = Component.Parameter('prf', + public_name = 'pulse repetition frequency', + default = None, + type = float, + mandatory = True, + doc = 'pulse repetition frequency in Hz') + +AZIMUTH_PIXEL_SIZE = Component.Parameter('azimuthPixelSize', + public_name = 'azimuth pixel size', + default = None, + type=float, + mandatory = True, + doc = 'azimuth pixel size on ground in m') + +AZIMUTH_LINE_INTERVAL = Component.Parameter('azimuthLineInterval', + public_name = 'azimuth line interval', + default = None, + type=float, + mandatory = True, + doc = 'azimuth line interval in s') + +######################################################################################################### +#for dense offset +DOPPLER_VS_PIXEL = Component.Parameter('dopplerVsPixel', + public_name = 'doppler vs pixel', + default = None, + type = float, + mandatory = True, + container = list, + doc = 'Doppler (Hz) polynomial coefficients vs range pixel number') +######################################################################################################### + + +#ProductManager cannot handle two or more layers of createTraitSeq +#use list instead for bookkeeping +#can creat a class Frames(Component) and wrap trait sequence, but it +#leads to more complicated output xml file, which is not good for viewing +FRAMES = Component.Parameter('frames', + public_name = 'frames', + default = [], + #type = float, + mandatory = True, + container = list, + doc = 'sequence of frames') + + +####List of facilities +ORBIT = Component.Facility('orbit', + public_name='orbit', + module='isceobj.Orbit.Orbit', + factory='createOrbit', + args=(), + doc = 'orbit state vectors') + +# FRAMES = Component.Facility('frames', +# public_name='frames', +# module = 'iscesys.Component', +# factory = 'createTraitSeq', +# args=('frame',), +# mandatory = False, +# doc = 'trait sequence of frames') + +class Track(Component): + """A class to represent a track""" + + family = 'track' + logging_name = 'isce.track' +############################################################################## + parameter_list = (PASS_DIRECTION, + POINTING_DIRECTION, + OPERATION_MODE, + RADAR_WAVELENGTH, + NUMBER_OF_SAMPLES, + NUMBER_OF_LINES, + STARTING_RANGE, + RANGE_SAMPLING_RATE, + RANGE_PIXEL_SIZE, + SENSING_START, + PRF, + AZIMUTH_PIXEL_SIZE, + AZIMUTH_LINE_INTERVAL, + DOPPLER_VS_PIXEL, + FRAMES + ) + + facility_list = (ORBIT, + ) + + def __init__(self,name=''): + super(Track, self).__init__(family=self.__class__.family, name=name) + return None + + + def clone(self): + import copy + res = copy.deepcopy(self) + res.image._accessor = None + res.image._factory = None + + return res diff --git a/components/isceobj/Sensor/MultiMode/__init__.py b/components/isceobj/Sensor/MultiMode/__init__.py new file mode 100644 index 0000000..30bea53 --- /dev/null +++ b/components/isceobj/Sensor/MultiMode/__init__.py @@ -0,0 +1,55 @@ +#Author: Cunren Liang, 2015- + +def createSwath(): + from .Swath import Swath + return Swath() + +def createFrame(): + from .Frame import Frame + return Frame() + +def createTrack(): + from .Track import Track + return Track() + + +def createALOS2(name=None): + from .ALOS2 import ALOS2 + return ALOS2() + + +SENSORS = { + 'ALOS2' : createALOS2, + } + +def getFactoriesInfo(): + """ + Returns a dictionary with information on how to create an object Sensor from its factory + """ + return {'MultiModeSensor': + {'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 diff --git a/components/isceobj/Sensor/SConscript b/components/isceobj/Sensor/SConscript index 53d8ee5..0c4492e 100644 --- a/components/isceobj/Sensor/SConscript +++ b/components/isceobj/Sensor/SConscript @@ -57,3 +57,4 @@ SConscript(os.path.join('src', 'SConscript'), SConscript(os.path.join('TOPS','SConscript')) SConscript(os.path.join('GRD', 'SConscript')) SConscript(os.path.join('ScanSAR', 'SConscript')) +SConscript(os.path.join('MultiMode', 'SConscript')) diff --git a/components/isceobj/TopsProc/runIon.py b/components/isceobj/TopsProc/runIon.py index d0c4af6..de9e2a1 100644 --- a/components/isceobj/TopsProc/runIon.py +++ b/components/isceobj/TopsProc/runIon.py @@ -473,7 +473,7 @@ def subband(self, ionParam): #subband rg_filter(tmpFilename, - burst.numberOfSamples, + #burst.numberOfSamples, 2, [os.path.join(lowerDir, tmpFilename2), os.path.join(upperDir, tmpFilename2)], [ionParam.rgBandwidthSub / rangeSamplingRate, ionParam.rgBandwidthSub / rangeSamplingRate], diff --git a/components/mroipac/ampcor/Ampcor.py b/components/mroipac/ampcor/Ampcor.py index 459506e..cee9e45 100755 --- a/components/mroipac/ampcor/Ampcor.py +++ b/components/mroipac/ampcor/Ampcor.py @@ -1,28 +1,20 @@ #!/usr/bin/env python3 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Copyright 2012 California Institute of Technology. ALL RIGHTS RESERVED. +# copyright: 2012 to the present, california institute of technology. +# all rights reserved. united states government sponsorship acknowledged. +# any commercial use must be negotiated with the office of technology transfer +# at the california institute of technology. # -# 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 +# this software may be subject to u.s. export control laws. by accepting this +# software, the user agrees to comply with all applicable u.s. export laws and +# regulations. user has the responsibility to obtain export licenses, or other +# export authority as may be required before exporting such information to +# foreign countries or providing access to foreign persons. # -# 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. +# installation and use of this software is restricted by a license agreement +# between the licensee and the california institute of technology. it is the +# user's responsibility to abide by the terms of the license agreement. # # Author: Giangi Sacco #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -41,7 +33,7 @@ from iscesys.Compatibility import Compatibility Compatibility.checkPythonVersion() from mroipac.ampcor import ampcor from isceobj.Util.mathModule import is_power2 -from isceobj.Util.decorators import use_api +#from isceobj.Util.decorators import use_api WINDOW_SIZE_WIDTH = Component.Parameter('windowSizeWidth', public_name='WINDOW_SIZE_WIDTH', @@ -297,7 +289,7 @@ class Ampcor(Component): DEBUG_FLAG, DISPLAY_FLAG) - @use_api +# @use_api def ampcor(self,slcImage1 = None,slcImage2 = None, band1=None, band2=None): if not (slcImage1 == None): self.slcImage1 = slcImage1 @@ -396,8 +388,8 @@ class Ampcor(Component): #if self.searchWindowSizeHeight >= 2*self.windowSizeHeight : # raise ValueError('Search Window Size Height should be < 2 * Window Size Height') - if self.zoomWindowSize >= min(self.searchWindowSizeWidth, self.searchWindowSizeHeight): - raise ValueError('Zoom window size should be <= Search window size') + #if self.zoomWindowSize >= min(self.searchWindowSizeWidth, self.searchWindowSizeHeight): + # raise ValueError('Zoom window size should be <= Search window size') def checkSkip(self): @@ -519,6 +511,12 @@ class Ampcor(Component): ampcor.setAcrossLooks_Py(self.acrossLooks) ampcor.setDownLooks_Py(self.downLooks) + #reference values + #self.winsizeFilt = 8 + #self.oversamplingFactorFilt = 64 + ampcor.setWinsizeFilt_Py(self.winsizeFilt) + ampcor.setOversamplingFactorFilt_Py(self.oversamplingFactorFilt) + return def setImageDataType1(self, var): @@ -641,6 +639,14 @@ class Ampcor(Component): raise ValueError('Oversampling factor needs to be a power of 2.') self.oversamplingFactor = temp + def setWinsizeFilt(self, var): + temp = int(var) + self.winsizeFilt = temp + + def setOversamplingFactorFilt(self, var): + temp = int(var) + self.oversamplingFactorFilt = temp + def setSearchWindowSizeWidth(self, var): self.searchWindowSizeWidth = int(var) return @@ -822,6 +828,8 @@ class Ampcor(Component): self.scaleFactorX = None self.scaleFactorY = None self.numRows = None + self.winsizeFilt = 1 + self.oversamplingFactorFilt = 64 self.dictionaryOfVariables = { \ 'IMAGETYPE1' : ['imageDataType1', 'str', 'optional'], \ 'IMAGETYPE2' : ['imageDataType2', 'str', 'optional'], \ diff --git a/components/mroipac/ampcor/DenseAmpcor.py b/components/mroipac/ampcor/DenseAmpcor.py index eb4202f..7348245 100755 --- a/components/mroipac/ampcor/DenseAmpcor.py +++ b/components/mroipac/ampcor/DenseAmpcor.py @@ -632,8 +632,8 @@ class DenseAmpcor(Component): if self.searchWindowSizeHeight >= 2*self.windowSizeHeight : raise ValueError('Search Window Size Height should be < 2 * Window Size Height') - if self.zoomWindowSize >= min(self.searchWindowSizeWidth, self.searchWindowSizeHeight): - raise ValueError('Zoom window size should be <= Search window size') + if self.zoomWindowSize > min(self.searchWindowSizeWidth*2+1, self.searchWindowSizeHeight*2+1): + raise ValueError('Zoom window size should be <= Search window size * 2 + 1') if self._stdWriter is None: self._stdWriter = create_writer("log", "", True, filename="denseampcor.log") diff --git a/components/mroipac/ampcor/bindings/ampcormodule.cpp b/components/mroipac/ampcor/bindings/ampcormodule.cpp index 9952ef6..c40a411 100644 --- a/components/mroipac/ampcor/bindings/ampcormodule.cpp +++ b/components/mroipac/ampcor/bindings/ampcormodule.cpp @@ -724,3 +724,27 @@ PyObject * getCov3_C(PyObject* self, PyObject* args) delete [] vectorV; return Py_BuildValue("N",list); } + + + +PyObject* setWinsizeFilt_C(PyObject* self, PyObject* args) +{ + int factor; + if( !PyArg_ParseTuple(args,"i",&factor) ) + { + return NULL; + } + setWinsizeFilt_f(&factor); + return Py_BuildValue("i",0); +} + +PyObject* setOversamplingFactorFilt_C(PyObject* self, PyObject* args) +{ + int factor; + if( !PyArg_ParseTuple(args,"i",&factor) ) + { + return NULL; + } + setOversamplingFactorFilt_f(&factor); + return Py_BuildValue("i",0); +} diff --git a/components/mroipac/ampcor/include/ampcormodule.h b/components/mroipac/ampcor/include/ampcormodule.h index 5a19f69..b3c2fe9 100644 --- a/components/mroipac/ampcor/include/ampcormodule.h +++ b/components/mroipac/ampcor/include/ampcormodule.h @@ -152,6 +152,10 @@ extern "C" PyObject * setScaleFactorX_C(PyObject*, PyObject*); PyObject * setScaleFactorY_C(PyObject*, PyObject*); + void setOversamplingFactorFilt_f(int*); + PyObject* setOversamplingFactorFilt_C(PyObject*, PyObject*); + void setWinsizeFilt_f(int*); + PyObject* setWinsizeFilt_C(PyObject*, PyObject*); } @@ -226,6 +230,9 @@ static PyMethodDef ampcor_methods[] = { "deallocate_cov2Ret_Py", deallocate_cov2Ret_C, METH_VARARGS, " "}, { "deallocate_cov3Ret_Py", deallocate_cov3Ret_C, METH_VARARGS, " "}, + { "setWinsizeFilt_Py", setWinsizeFilt_C, METH_VARARGS, " "}, + { "setOversamplingFactorFilt_Py", setOversamplingFactorFilt_C, METH_VARARGS, " "}, + {NULL, NULL, 0 , NULL} }; diff --git a/components/mroipac/ampcor/include/ampcormoduleFortTrans.h b/components/mroipac/ampcor/include/ampcormoduleFortTrans.h index d88c3cd..ac736f7 100644 --- a/components/mroipac/ampcor/include/ampcormoduleFortTrans.h +++ b/components/mroipac/ampcor/include/ampcormoduleFortTrans.h @@ -67,6 +67,8 @@ #define deallocate_cov2Ret_f deallocate_cov2ret_ #define deallocate_cov3Ret_f deallocate_cov3ret_ + #define setWinsizeFilt_f setwinsizefilt_ + #define setOversamplingFactorFilt_f setoversamplingfactorfilt_ #else #error Unknown translation for FORTRAN external symbols diff --git a/components/mroipac/ampcor/src/ampcor.F b/components/mroipac/ampcor/src/ampcor.F index 6556d44..379de44 100644 --- a/components/mroipac/ampcor/src/ampcor.F +++ b/components/mroipac/ampcor/src/ampcor.F @@ -1,3 +1,14 @@ +!c This program has been upgraded for matching ScanSAR full-aperture images. +!c 1. setting the following two parameters to use: +!c winsize_filt = 8 +!c i_covs_filt = 64 +!c 2. use same original parameter values as you use in the original program for +!c ScanSAR full-aperture image matching. +!c 3. Original matching method is still available by setting winsize_filt to 1. +!c In this case, i_covs_filt has no effects. + +!c Cunren Liang, 25-DEC-2019, Caltech + !c**************************************************************** subroutine ampcor(imgAccessor1, imgAccessor2, band1, band2) @@ -126,6 +137,24 @@ external seconds integer count +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c for ScanSAR full-aperture mode matching + real*4 r_shfty_filt,r_shftx_filt + integer i_shiftx_filt,i_shifty_filt + !integer winsize_filt + integer i_wsyi_filt + integer i_wsyj_filt + integer iii, num_pixel + !integer i_covs_filt, i_cw_filt + integer i_cw_filt + real, dimension(:,:), allocatable :: r_imgi_filt, r_imgj_filt, r_imgc_filt + complex, dimension(:), allocatable :: c_corr_filt, c_corrt_filt + real tmp_corr + integer continue_fine_matching + +!c added to avoid accessing indexes out of bounds (segmentation fault) 02-FEB-2020 + integer x_index +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! write(6,*) 'Input Bands: ', band1, band2 @@ -204,6 +233,48 @@ i_n2wsxj = 2**(nextpower(i_wsxjp)) i_n2wsyj = 2**(nextpower(i_wsyjp)) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c for ScanSAR full-aperture mode matching + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !input parameter reference values: + !winsize_filt should be power of 2 to faciliate subsequent processing + !winsize_filt = 8 + !i_covs_filt = i_covs + !i_covs_filt = 64 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + !better be power of 2 for fft + i_cw_filt = (i_wsyj - i_wsyi) / winsize_filt + i_wsyi_filt = i_wsyi / winsize_filt + i_wsyj_filt = i_wsyj / winsize_filt + + if(winsize_filt .ne. 1)then + write(6,*) '' + write(6,*) ' *** using ScanSAR full-aperture mode for gross offset estimation ***' + write(6,*) 'azimuth multi-looking window size: ', winsize_filt + write(6,*) 'number of azimuth samples before and after multi-looking (master): ', i_wsyi, i_wsyi_filt + write(6,*) 'number of azimuth samples before and after multi-looking (slave): ', i_wsyj, i_wsyj_filt + write(6,*) 'azimuth covariance surface oversampling factor: ', i_covs_filt + write(6,*) 'total number of azimuth samples to be oversampled', i_cw_filt + write(6,*) '' + endif + + if(i_cw_filt .lt. 4)then + write(6,*) 'ERROR - number of samples availabe for estating gross offset is too small:', i_cw_filt + write(6,*) ' the value is computed as 2*i_srchy/winsize_filt' + write(6,*) ' current i_srchy (azimuth search window size):', i_srchy + write(6,*) ' current winsize_filt (azimuth filtering window size):', winsize_filt + return + endif + + if(i_cw_filt .ne. 2**nextpower(i_cw_filt))then + write(6,*) 'WARNING - number of samples availabe for estating gross offset is NOT power of 2:', i_cw_filt + write(6,*) ' the value is computed as 2*i_srchy/winsize_filt' + write(6,*) ' better to make it power of 2 for FFT' + write(6,*) ' current i_srchy (azimuth search window size):', i_srchy + write(6,*) ' current winsize_filt (azimuth filtering window size):', winsize_filt + endif +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !c Set max width to largest of the width i_maxsamp = max(i_samples(1), i_samples(2)) @@ -230,6 +301,15 @@ allocate( c_ossch(i_ovs*i_n2wsxj*i_ovs*i_n2wsyj) ) allocate( c_osref(i_ovs*i_n2wsxi*i_ovs*i_n2wsyi) ) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c for ScanSAR full-aperture mode matching + allocate( r_imgi_filt(i_wsxi,i_wsyi_filt)) + allocate( r_imgj_filt(i_wsxj,i_wsyj_filt)) + allocate( r_imgc_filt(i_wsxj,i_wsyj_filt)) + allocate( c_corr_filt(i_covs_filt*i_cw_filt*i_covs_filt*i_cw_filt) ) + allocate( c_corrt_filt(i_cw_filt*i_cw_filt) ) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !c------------------------------- !c begin ruggedize ... a bunch of input checking @@ -485,13 +565,27 @@ do i_yy = 1,i_wsyi do i_xx = 1,i_wsxi - r_imgi(i_xx,i_yy) = cabs(c_refimg(i_x+i_xx-1,i_yy)) + + x_index = i_x+i_xx-1 + if ((x_index .lt. 1).or.(x_index .gt. i_maxsamp)) then + r_imgi(i_xx,i_yy) = 0.0 + else + r_imgi(i_xx,i_yy) = cabs(c_refimg(x_index,i_yy)) + endif + end do end do do i_yy = 1, i_wsyj do i_xx = 1 , i_wsxj - r_imgj(i_xx,i_yy) = cabs(c_srchimg(i_xlu+i_xx-1-i_srchx+i_grossx,i_yy)) + + x_index = i_xlu+i_xx-1-i_srchx+i_grossx + if ((x_index .lt. 1).or.(x_index .gt. i_maxsamp)) then + r_imgj(i_xx,i_yy) = 0.0 + else + r_imgj(i_xx,i_yy) = cabs(c_srchimg(x_index,i_yy)) + endif + end do end do @@ -504,8 +598,201 @@ call dump_chip_r4(a_debugfile,r_imgj,1,i_wsxj,1,i_wsyj,i_wsxj,i_wsyj) endif -!c correlate the subimages +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c for ScanSAR full-aperture mode matching +!c correlate azimuth-multiple-looked images + if (winsize_filt .ne. 1) then +!c get azimuth-multiple-looked images + do i_yy = 1,i_wsyi_filt + do i_xx = 1,i_wsxi + r_imgi_filt(i_xx,i_yy) = 0. + num_pixel = 0 + do iii = 1,winsize_filt + if(r_imgi(i_xx,(i_yy-1)*winsize_filt+iii) .ne. 0) then + num_pixel = num_pixel + 1 + r_imgi_filt(i_xx,i_yy) = r_imgi_filt(i_xx,i_yy) + r_imgi(i_xx,(i_yy-1)*winsize_filt+iii)**2 + endif + end do + if(num_pixel .ne. 0) then + r_imgi_filt(i_xx,i_yy) = sqrt(r_imgi_filt(i_xx,i_yy)/num_pixel) + endif + end do + end do + + + do i_yy = 1, i_wsyj_filt + do i_xx = 1 , i_wsxj + r_imgj_filt(i_xx,i_yy) = 0. + num_pixel = 0 + do iii = 1,winsize_filt + if(r_imgj(i_xx,(i_yy-1)*winsize_filt+iii) .ne. 0) then + num_pixel = num_pixel + 1 + r_imgj_filt(i_xx,i_yy) = r_imgj_filt(i_xx,i_yy) + r_imgj(i_xx,(i_yy-1)*winsize_filt+iii)**2 + endif + end do + if(num_pixel .ne. 0) then + r_imgj_filt(i_xx,i_yy) = sqrt(r_imgj_filt(i_xx,i_yy)/num_pixel) + endif + end do + end do + +!c correlate images +!c i_avgx = i_avgy = 1 + call correlate(r_imgi_filt,r_imgj_filt,i_wsxi,i_wsyi_filt,i_wsxj, + & i_wsyj_filt,1,1,1,r_meani,r_stdvi,r_meanj, + & r_stdvj,r_peak,r_noise,r_cov,r_eval1, + & r_eval2,r_evec1,r_evec2,r_imgc_filt,i_shiftx_filt,i_shifty_filt,i_edge, + & i_flag,l_debug) + + r_shftx_filt=float(i_shiftx_filt) - i_srchx + i_grossx + r_shfty_filt=float(i_shifty_filt) - float(i_srchy)/winsize_filt + float(i_grossy)/winsize_filt + r_shfty_filt=r_shfty_filt*winsize_filt + + if(i_flag .eq. 0 .and. i_edge(1) .eq. 0 .and. + & i_edge(2) .eq. 0)then !found a potentially good data point + + r_outside = 0.0 + i_cnta = 0 + do l=max(i_shifty_filt-9,1),min(i_shifty_filt+11,i_wsyj_filt-i_wsyi_filt) + do k=max(i_shiftx_filt-9,1),min(i_shiftx_filt+11,i_wsxj-i_wsxi) + i_cnta = i_cnta + 1 + r_outside = r_outside + r_imgc_filt(k,l)**2 + enddo + enddo + r_outside = r_outside - r_peak**2 + r_outside = r_outside/(i_cnta-1) + + r_snr = r_peak**2/max(r_outside,1.e-10) + + if(r_snr .gt. r_snrth .and. r_cov(1) .lt. r_covth .and. r_cov(2) .lt. r_covth)then + continue_fine_matching = 1 + else + continue_fine_matching = 0 + endif + + else + continue_fine_matching = 0 + endif + +!c compute finer offset by oversampling covariance surface + if(continue_fine_matching .ne. 0)then + r_max = 0.0 + r_mean_cor = 0.0 + i_cnta = 0 + i_px = i_shiftx_filt+1 + i_py = i_shifty_filt+1 + + do i_yy=-i_cw_filt/2,i_cw_filt/2-1 + + do i_xx=-i_cw_filt/2,i_cw_filt/2-1 + + i_index = (i_yy+i_cw_filt/2)*i_cw_filt + i_xx + i_cw_filt/2 + 1 + + if (i_xx+i_px .ge. 1 .and. i_xx+i_px .le. (2*i_srchx+1)*1 .and. + & i_yy+i_py .ge. 1 .and. i_yy+i_py .le. (2*i_srchy+1)*1 )then + c_corrt_filt(i_index) = cmplx(abs(r_imgc_filt(i_xx+i_px,i_yy+i_py)/r_peak),0.) + r_mean_cor = r_mean_cor + cabs(c_corrt_filt(i_index)) + i_cnta = i_cnta + 1 + else + c_corrt_filt(i_index) = cmplx(0.0, 0.0) + endif + + if(cabs(c_corrt_filt(i_index)) .gt. r_max)then + r_max = cabs(c_corrt_filt(i_index)) + i_p1 = i_xx + i_p2 = i_yy + endif + + enddo + + enddo + +!c substract off the mean +!c looks like it does not do anything, so can comment out these +!c r_mean_cor = r_mean_cor/max(i_cnta,1) +!c r_mean_cor = 0.0 +!c do i_yy=-i_cw_filt/2,i_cw_filt/2-1 +!c do i_xx=-i_cw_filt/2,i_cw_filt/2-1 +!c i_index = (i_yy+i_cw_filt/2)*i_cw_filt + i_xx + i_cw_filt/2 + 1 +!c c_corrt_filt(i_index) = c_corrt_filt(i_index) - cmplx(r_mean_cor,0.0) +!c enddo +!c enddo + +!c oversample via Fourier transforms +!c forward fft the data + i_nn(1) = i_cw_filt + i_nn(2) = i_cw_filt + i_dir = 1 + call fourn2d(c_corrt_filt,i_nn,i_dir) + +!c spread the spectral data out for inverse transforms + i_nn(1) = i_cw_filt*i_covs_filt + i_nn(2) = i_cw_filt*i_covs_filt + i_dir = -1 + + do k=1,i_nn(2) + do l=1,i_nn(1) + i_index = (k-1)*i_nn(1) + l + c_corr_filt(i_index) = 0.0 + enddo + enddo + + do l=1,i_cw_filt/2 + do k=1,i_cw_filt/2 + i_index = (k-1)*i_nn(1) + l + i_indexi = (k-1)*i_cw_filt + l + c_corr_filt(i_index) = c_corrt_filt(i_indexi) + i_index = l + (i_nn(2)-i_cw_filt/2+k-1)*i_nn(1) + i_indexi = l + (k+i_cw_filt/2-1)*i_cw_filt + c_corr_filt(i_index) = c_corrt_filt(i_indexi) + i_index = i_nn(1)-i_cw_filt/2+l + (k-1)*i_nn(2) + i_indexi = l+i_cw_filt/2 + (k-1)*i_cw_filt + c_corr_filt(i_index) = c_corrt_filt(i_indexi) + i_index = i_nn(1)-i_cw_filt/2+l + (i_nn(2)-i_cw_filt/2+k-1)*i_nn(1) + i_indexi = l+i_cw_filt/2 + (k+i_cw_filt/2-1)*i_cw_filt + c_corr_filt(i_index) = c_corrt_filt(i_indexi) + enddo + enddo + +!c inverse transform + call fourn2d(c_corr_filt,i_nn,i_dir) + + +!c detect the peak + r_max=0. + do i_yy=1,i_cw_filt*i_covs_filt + do i_xx=1,i_cw_filt*i_covs_filt + i_index = (i_yy-1)*i_cw_filt*i_covs_filt + i_xx + tmp_corr = cabs(c_corr_filt(i_index))/((i_cw_filt**2)*(i_cw_filt*i_covs_filt)**2) + if (abs(i_xx-i_cw_filt*i_covs_filt/2) .le. i_covs_filt .and. + & abs(i_yy-i_cw_filt*i_covs_filt/2) .le. i_covs_filt) then + if (tmp_corr .ge. r_max) then + r_max = tmp_corr + i_cpeak(1) = i_xx - i_cw_filt/2*i_covs_filt + i_cpeak(2) = i_yy - i_cw_filt/2*i_covs_filt + endif + endif + enddo + enddo + + r_oscoroff(1) = float(i_cpeak(1)-1)/float(i_covs_filt) + r_oscoroff(2) = float(i_cpeak(2)-1)/float(i_covs_filt) + r_oscoroff(2) = r_oscoroff(2) * winsize_filt + + r_shftx = r_oscoroff(1)/1 + r_shftx_filt + i_xlu - i_x + r_shfty = r_oscoroff(2)/1 + r_shfty_filt + i_ylu - i_y + + !get integer values for subsequent use. note that all four variables + !are used, so they need to be consistent + r_shftx = nint(r_shftx) + r_shfty = nint(r_shfty) + i_shiftx = nint(r_shftx) + i_srchx - i_grossx + i_shifty = nint(r_shfty) + i_srchy - i_grossy + endif + else +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c correlate original images call correlate(r_imgi,r_imgj,i_wsxi,i_wsyi,i_wsxj, & i_wsyj,i_avgx,i_avgy,1,r_meani,r_stdvi,r_meanj, & r_stdvj,r_peak,r_noise,r_cov,r_eval1, @@ -546,9 +833,21 @@ r_snr = r_peak**2/max(r_outside,1.e-10) !ccccc write(6,'(a,1x,2(f20.10,1x))') 'Peak/SNR = ',r_peak,r_snr - if(r_snr .gt. r_snrth .and. r_cov(1) .lt. r_covth .and. r_cov(2) .lt. r_covth)then + continue_fine_matching = 1 + else + continue_fine_matching = 0 + endif + else + continue_fine_matching = 0 + endif +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + endif +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c this is just used to keep the original indentation level + if(1 .eq. 1)then + if(continue_fine_matching .ne. 0)then !c oversample the region around the peak 2 to 1 to estimate the fractional offset !c write the reference image and search image around the peak into arrays @@ -1138,6 +1437,16 @@ deallocate( c_chipsch) deallocate( c_ossch) deallocate( c_osref) + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +!c for ScanSAR full-aperture mode matching + deallocate( r_imgi_filt) + deallocate( r_imgj_filt) + deallocate( r_imgc_filt) + deallocate( c_corr_filt) + deallocate( c_corrt_filt) +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + close(13) close(14) !c close(15) diff --git a/components/mroipac/ampcor/src/ampcorPrintState.F b/components/mroipac/ampcor/src/ampcorPrintState.F index 439b1cf..caf0095 100644 --- a/components/mroipac/ampcor/src/ampcorPrintState.F +++ b/components/mroipac/ampcor/src/ampcorPrintState.F @@ -26,7 +26,9 @@ write(6,*) "r_covth = ",r_covth write(6,*) "l_debug = ",l_debug write(6,*) "l_display = ",l_display - + + write(6,*) "winsize_filt = ",winsize_filt + write(6,*) "i_covs_filt = ",i_covs_filt return end diff --git a/components/mroipac/ampcor/src/ampcorSetState.F b/components/mroipac/ampcor/src/ampcorSetState.F index f803c2f..444b66d 100644 --- a/components/mroipac/ampcor/src/ampcorSetState.F +++ b/components/mroipac/ampcor/src/ampcorSetState.F @@ -198,3 +198,16 @@ r_scaley = var end + subroutine setWinsizeFilt(winsize_filt_val) + use ampcorState + implicit none + integer winsize_filt_val + winsize_filt = winsize_filt_val + end + + subroutine setOversamplingFactorFilt(i_covs_filt_val) + use ampcorState + implicit none + integer i_covs_filt_val + i_covs_filt = i_covs_filt_val + end diff --git a/components/mroipac/ampcor/src/ampcorState.F b/components/mroipac/ampcor/src/ampcorState.F index 8c20497..f586806 100644 --- a/components/mroipac/ampcor/src/ampcorState.F +++ b/components/mroipac/ampcor/src/ampcorState.F @@ -33,4 +33,7 @@ !c we only know the max number of rows. at the end of the ampcor we can get it integer numRowTable + integer winsize_filt + integer i_covs_filt + end module ampcorState diff --git a/contrib/SConscript b/contrib/SConscript index ecc0baf..bfc08a5 100644 --- a/contrib/SConscript +++ b/contrib/SConscript @@ -77,7 +77,9 @@ SConscript(rfi) SConscript('PyCuAmpcor/SConscript') SConscript('splitSpectrum/SConscript') +SConscript('alos2filter/SConscript') SConscript('alos2proc/SConscript') +SConscript('alos2proc_f/SConscript') if os.path.exists('geo_autoRIFT'): SConscript('geo_autoRIFT/SConscript') diff --git a/contrib/alos2filter/SConscript b/contrib/alos2filter/SConscript new file mode 100644 index 0000000..38a9dd2 --- /dev/null +++ b/contrib/alos2filter/SConscript @@ -0,0 +1,25 @@ +#!/usr/bin/env python + +#Cunren Liang, 2015-2018 + +import os + +Import('envcontrib') +envalos2filter = envcontrib.Clone() +package = envcontrib['PACKAGE'] +project = 'alos2filter' +Export('envalos2filter') + + + + +srcScons = os.path.join('src','SConscript') +varDir = os.path.join(envalos2filter['PRJ_SCONS_BUILD'],package,project,'src') +SConscript(srcScons, variant_dir = varDir) + + +install = os.path.join(envcontrib['PRJ_SCONS_INSTALL'],package,project) +listFiles = ['__init__.py','alos2filter.py'] +envcontrib.Install(install,listFiles) +envcontrib.Alias('install',install) + diff --git a/contrib/alos2filter/__init__.py b/contrib/alos2filter/__init__.py new file mode 100644 index 0000000..5f7ce86 --- /dev/null +++ b/contrib/alos2filter/__init__.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 \ No newline at end of file diff --git a/contrib/alos2filter/alos2filter.py b/contrib/alos2filter/alos2filter.py new file mode 100644 index 0000000..3aa349a --- /dev/null +++ b/contrib/alos2filter/alos2filter.py @@ -0,0 +1,17 @@ +import os +import copy +import ctypes +import logging +import isceobj +from xml.etree.ElementTree import ElementTree + +def psfilt1(inputfile, outputfile, width, alpha, fftw, step): + filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2filter.so')) + filters.psfilt1( + ctypes.c_char_p(bytes(inputfile,'utf-8')), + ctypes.c_char_p(bytes(outputfile,'utf-8')), + ctypes.c_int(width), + ctypes.c_double(alpha), + ctypes.c_int(fftw), + ctypes.c_int(step) + ) diff --git a/contrib/alos2filter/src/SConscript b/contrib/alos2filter/src/SConscript new file mode 100644 index 0000000..9d3404d --- /dev/null +++ b/contrib/alos2filter/src/SConscript @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +import os + +Import('envalos2filter') + +install = os.path.join(envalos2filter['PRJ_SCONS_INSTALL'], envalos2filter['PACKAGE'], 'alos2filter') +listFiles = ['psfilt1.c'] + +# -shared +# -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lm +# -lfftw3f_threads -lfftw3f -lpthread -fopenmp -O3 + +#envalos2proc.Append(CFLAGS=['-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64', '-lm', '-shared', '-fopenmp', '-O3']) +#envalos2proc.Append(LIBS=['fftw3f', 'fftw3f_threads', 'pthread']) + +lib = envalos2filter.LoadableModule(target = 'libalos2filter.so', source = listFiles, parse_flags='-fopenmp') +envalos2filter.Install(install,lib) +envalos2filter.Alias('install',install) + + + + diff --git a/contrib/alos2filter/src/psfilt1.c b/contrib/alos2filter/src/psfilt1.c new file mode 100644 index 0000000..941e082 --- /dev/null +++ b/contrib/alos2filter/src/psfilt1.c @@ -0,0 +1,496 @@ +#include +#include +#include +#include + +#define PLUS 1 +#define MINU 2 +#define CHG 3 +#define GUID 4 +#define LSNR 8 +#define VIST 16 +#define BRPT 32 +#define CUT 64 +#define LAWN 128 +#define TREE 128 + +#define NFFT 32 /* size of FFT */ +#define STEP NFFT/2 /* stepsize in range and azimuth for filter */ +#define ALPHA 0.5 /* default exponent for weighting of the spectrum */ + +#define REL_BEGIN 0 /* fseek relative to beginning of file */ +#define REL_CUR 1 /* fseek relative to current position in the file */ +#define REL_EOF 2 /* fseek relative to end of file */ + +#define SQR(a) ( (a)*(a) ) +#define PI 3.14159265359 +#define TWO_PI 6.28318530718 +#define SQRT2 1.41421356237 /* square root of 2 */ +#define RTD 57.2957795131 /* radians to degrees */ +#define DTR .0174532925199 /* degrees to radians */ +#define C 2.99792458e8 + +#define NR_END 1 +#define FREE_ARG char* + +typedef struct{float re,im;} fcomplex; + +void fourn(float *, unsigned int *, int ndim, int isign); +void psd_wgt(fcomplex **cmp, fcomplex **seg_fft, double, int, int, int); + +void start_timing(); /* timing routines */ +void stop_timing(); + +unsigned int nfft[3]; +int xmin=0; /* window column minima */ +int ymin=0; /* window row minima */ +int ymax, xmax; /* interferogram width, window maxima */ + +fcomplex **cmatrix(int nrl, int nrh, int ncl, int nch); +void free_cmatrix(fcomplex **m, int nrl, int nrh, int ncl, int nch); +void nrerror(char error_text[]); +signed char IsFinite(double d); + +int psfilt1(char *inputfile, char *outputfile, int width, double alpha, int fftw, int step) +{ + fcomplex *bufcz, **cmp; /* interferogram line buffer, complex input data, row pointers */ + fcomplex **sm, **seg_fft, *seg_fftb; /* smoothed interferogram, 2d fft of segment */ + fcomplex **tmp, **tmp1; /* arrays of pointers for temp storage of line pointers in circular buffers */ + double **wf, *wfb; /* 2-D weights */ + + float *data; /* pointer to floats for FFT, union with seg_fft */ + //double alpha; /* exponent used to to determine spectal weighting function */ + double rw,azw; /* range and azimuth weights used in window function */ + + int nlines=0; /* number of lines in the file */ + int offs; /* width and height of file segment*/ + //int fftw; /* fft window size*/ + //int step; /* step size in range and azimuth for filtering of interferogram */ + int xw,yh; /* width, height of processed region */ + int i,j,i1,j1; /* loop counters */ + int ndim; /* number of dimensions of FFT */ + int isign; /* direction of FFT */ + int nlc; /* number of guides, number of low correlation pixels */ + int lc; /* line counter */ + + FILE *int_file, *sm_file; + + int k; + float sf; // scale factor for FFT, otherwise FFT will magnify the data by FFT length + // usually the magnitude of the interferogram is very large, so the data are + // multiplied by this factor before FFT, rather than after FFT in this program. + float sf0; // an extra factor to scale the data + sf0 = 1.0; + + + fprintf(stderr,"*** Weighted power spectrum interferogram filter v1.0 clw 19-Feb-97 ***\n"); + if(0){ + //fprintf(stderr,"\nUsage: %s [alpha] [fftw] [step] [xmin] [xmax] [ymin] [ymax]\n\n",argv[0]) ; + + fprintf(stderr,"input parameters: \n"); + fprintf(stderr," interferogram complex interferogram image filename\n"); + fprintf(stderr," smoothed interf. smoothed interferogram filename\n"); + fprintf(stderr," width number of samples/row\n"); + fprintf(stderr," alpha spectrum amplitude scale factor (default=.5)\n"); + fprintf(stderr," fftw fft window size in both range and azimuth directions \n"); + fprintf(stderr," step moving step size in both range and azimuth directions (default = fftw/2)\n"); + fprintf(stderr," xmin offset to starting range pixel (default = 0)\n"); + fprintf(stderr," xmax offset last range pixel (default = width-1)\n"); + fprintf(stderr," ymin offset to starting azimuth row (default = 0)\n"); + fprintf(stderr," ymax offset to last azimuth row (default = nlines-1)\n\n"); + exit(-1); + } + + start_timing(); + int_file = fopen(inputfile,"rb"); + if (int_file == NULL){fprintf(stderr,"cannot open interferogram file: %s\n",inputfile); exit(-1);} + + sm_file = fopen(outputfile,"wb"); + if (sm_file == NULL){fprintf(stderr,"cannot create smoothed interferogram file: %s\n",outputfile); exit(-1);} + + //sscanf(argv[3],"%d",&width); + xmax = width-1; + + fseeko(int_file, 0L, REL_EOF); /* determine # lines in the file */ + nlines=(int)(ftello(int_file)/(width*2*sizeof(float))); + fprintf(stderr,"#lines in the interferogram file: %d\n",nlines); + rewind(int_file); + + + //alpha = ALPHA; + //if(argc >= 4)sscanf(argv[4],"%lf",&alpha); + fprintf(stdout,"spectrum weighting exponent: %8.4f\n",alpha); + + //fftw = NFFT; + //if (argc >5)sscanf(argv[5],"%d",&fftw); + fprintf(stdout,"FFT window size: %5d\n",fftw); + + sf = fftw * fftw * sf0; + + //step = fftw/2; + //if (argc >6)sscanf(argv[6],"%d",&step); + if (step <= 0 || step > fftw){ + fprintf(stdout,"WARNING: wrong step size: %5d, using %5d instead\n",step, fftw/2); + step = fftw/2; + } + fprintf(stdout,"range and azimuth step size (pixels): %5d\n",step); + + ymax=nlines-1; /* default value of ymax */ + //if(argc > 7)sscanf(argv[7],"%d",&xmin); /* window to process */ + //if(argc > 8)sscanf(argv[8],"%d",&xmax); + //if(argc > 9)sscanf(argv[9],"%d",&ymin); + //if(argc > 10)sscanf(argv[10],"%d",&ymax); + + if (ymax > nlines-1){ + ymax = nlines-1; + fprintf(stderr,"WARNING: insufficient #lines in the file for given input range: ymax: %d\n",ymax); + } + + if (xmax > width-1) xmax=width-1; /* check to see if xmax within bounds */ + xw=xmax-xmin+1; /* width of array */ + yh=ymax-ymin+1; /* height of array */ + offs=ymin; /* first line of file to start reading/writing */ + fprintf(stdout,"array width, height, offset: %5d %5d %5d\n",xw,yh,offs); + + cmp = cmatrix(0, fftw-1, -fftw,width+fftw); /* add space around the arrays */ + sm = cmatrix(0,fftw-1,-fftw,width+fftw); + + tmp = (fcomplex **)malloc(sizeof(fcomplex *)*step); + tmp1 = (fcomplex **)malloc(sizeof(fcomplex *)*step); + if (tmp == NULL || tmp1==NULL){fprintf(stderr,"ERROR: failure to allocate space for circular buffer pointers\n"); exit(-1);} + + bufcz = (fcomplex *)malloc(sizeof(fcomplex)*width); + if(bufcz == NULL){fprintf(stderr,"ERROR: failure to allocate space for input line buffer\n"); exit(-1);} + + seg_fftb = (fcomplex *)malloc(sizeof(fcomplex)*fftw*fftw); + if(seg_fftb == NULL){fprintf(stderr,"ERROR: failure to allocate space for FFT data\n"); exit(-1);} + seg_fft = (fcomplex **)malloc(sizeof(fcomplex *)*fftw); + if(seg_fft == NULL){fprintf(stderr,"ERROR: failure to allocate space for FFT data pointers\n"); exit(-1);} + + wfb = (double *)malloc(sizeof(double)*fftw*fftw); + if (wfb == NULL){fprintf(stderr,"ERROR: weight memory allocation failure...\n"); exit(-1);} + wf = (double **)malloc(sizeof(double *)*fftw); + if (wf == NULL){fprintf(stderr,"ERROR: weight pointers memory allocation failure...\n"); exit(-1);} + + for(i=0; i < fftw; i++) seg_fft[i] = seg_fftb + i*fftw; + for(j=0; j < fftw; j++) wf[j] = wfb + j*fftw; + + for(j=0; j < width; j++){bufcz[j].re=0.; bufcz[j].im=0.;} + + for(i=0; i < fftw; i++){ /* initialize circular data buffers */ + for(j= -fftw; j < width+fftw; j++){ + cmp[i][j].re = 0.0; cmp[i][j].im = 0.0; + sm[i][j].re = 0.0; sm[i][j].im = 0.0; + } + } + + for (i=0; i < fftw; i++){ + for (j=0; j < fftw; j++){ + azw = 1.0 - fabs(2.0*(double)(i-fftw/2)/(fftw+1)); + rw = 1.0 - fabs(2.0*(double)(j-fftw/2)/(fftw+1)); + wf[i][j]=azw*rw/(double)(fftw*fftw); +#ifdef DEBUG + fprintf(stderr,"i,j,wf: %5d %5d %12.4e\n",i,j,wf[i][j]); +#endif + } + } + + nfft[1] = fftw; + nfft[2] = nfft[1]; + nfft[0] = 0; + ndim = 2; + isign = 1; /* initialize FFT parameter values, inverse FFT */ + + + fseek(int_file, offs*width*sizeof(fcomplex), REL_BEGIN); /* seek offset to start line of interferogram */ + for (i=0; i < fftw - step; i++){ + fread((char *)cmp[i], sizeof(fcomplex), width, int_file); + for(k = 0; k < width; k++){ + cmp[i][k].re /= sf; + cmp[i][k].im /= sf; + } + } + lc=0; + + for (i=0; i < yh; i += step){ + for(i1=fftw - step; i1 < fftw; i1++){ + fread((char *)cmp[i1], sizeof(fcomplex), width, int_file); + for(k = 0; k < width; k++){ + cmp[i1][k].re /= sf; + cmp[i1][k].im /= sf; + } + if (feof(int_file) != 0){ /* fill with zero if at end of file */ + for(j1= -fftw; j1 < width+fftw; j1++){cmp[i1][j1].re=0.0; cmp[i1][j1].im=0.0;} + } + for(j1= -fftw; j1 < width+fftw; j1++){ + sm[i1][j1].re=0.0; sm[i1][j1].im=0.0; /* clear out area for new sum */ + } + } + if(i%(2*step) == 0)fprintf(stderr,"\rprogress: %3d%%", (int)(i*100/yh + 0.5)); + + for (j=0; j < width; j += step){ + psd_wgt(cmp, seg_fft, alpha, j, i, fftw); + fourn((float *)seg_fft[0]-1,nfft,ndim,isign); /* 2D inverse FFT of region, get back filtered fringes */ + + for (i1=0; i1 < fftw; i1++){ /* save filtered output values */ + for (j1=0; j1 < fftw; j1++){ + if(cmp[i1][j+j1].re !=0.0){ + sm[i1][j+j1].re += wf[i1][j1]*seg_fft[i1][j1].re; + sm[i1][j+j1].im += wf[i1][j1]*seg_fft[i1][j1].im; + } + else{ + sm[i1][j+j1].re=0.0; + sm[i1][j+j1].im=0.0; + } + } + } + } + for (i1=0; i1 < step; i1++){ + if (lc < yh){ + for(k = 0; k < width; k++){ + if(!IsFinite(sm[i1][k].re)) + sm[i1][k].re = 0.0; + if(!IsFinite(sm[i1][k].im)) + sm[i1][k].im = 0.0; + if(!IsFinite(sqrt(sm[i1][k].re*sm[i1][k].re + sm[i1][k].im*sm[i1][k].im))){ + sm[i1][k].re = 0.0; + sm[i1][k].im = 0.0; + } + } + fwrite((char *)sm[i1], sizeof(fcomplex), width, sm_file); + } + lc++; + } + for (i1=0; i1 < step; i1++){tmp[i1] = cmp[i1]; tmp1[i1] = sm[i1];} /* save pointers to lines just written out */ + for (i1=0; i1 < fftw - step; i1++){cmp[i1] = cmp[i1+step]; sm[i1] = sm[i1+step];} /* shift the data just processed */ + for (i1=0; i1 < step; i1++){cmp[fftw - step+i1] = tmp[i1]; sm[fftw - step+i1]=tmp1[i1];} /* copy pointers back */ + } + fprintf(stderr,"\rprogress: %3d%%", 100); + + for(i=lc; i < yh; i++){ /* write null lines of filtered complex data */ + for(k = 0; k < width; k++){ + if(!IsFinite(bufcz[k].re)) + bufcz[k].re = 0.0; + if(!IsFinite(bufcz[k].im)) + bufcz[k].im = 0.0; + if(!IsFinite(sqrt(bufcz[k].re*bufcz[k].re + bufcz[k].im*bufcz[k].im))){ + bufcz[k].re = 0.0; + bufcz[k].im = 0.0; + } + } + fwrite((char *)bufcz, sizeof(fcomplex), width, sm_file); + lc++; + } + + fprintf(stdout,"\nnumber of lines written to file: %d\n",lc); + stop_timing(); + + free(bufcz); + //free_cmatrix(cmp, 0, fftw-1, -fftw,width+fftw); + //free_cmatrix(sm, 0,fftw-1,-fftw,width+fftw); + free(seg_fft); + free(seg_fftb); + free(tmp); + free(tmp1); + free(wf); + free(wfb); + fclose(int_file); + fclose(sm_file); + + return(0); +} + +void psd_wgt(fcomplex **cmp, fcomplex **seg_fft, double alpha, int ix, int iy, int fftw) +/* + subroutine to perform non-linear spectral filtering 17-Feb-97 clw +*/ + +{ + double psd,psd_sc; /* power spectrum, scale factor */ + int i,j; /* loop counters */ + int ndim,isign; /* number of dimensions in fft */ + + int ic; + + unsigned int nfft[3]; + ic = 0; + + ndim=2, isign = -1, nfft[1]=fftw, nfft[2]=fftw, nfft[0]=0; /* fft initialization */ + + for (i=0; i < fftw; i++){ /* load up data array */ + for (j=ix; j < ix+fftw; j++){ + seg_fft[i][j-ix].re = cmp[i][j].re; + seg_fft[i][j-ix].im = cmp[i][j].im; + } + } + + fourn((float *)seg_fft[0]-1, nfft, ndim, isign); /* 2D forward FFT of region */ + + for (i=0; i < fftw; i++){ + for (j=0; j < fftw; j++){ + psd = seg_fft[i][j].re * seg_fft[i][j].re + seg_fft[i][j].im * seg_fft[i][j].im; + psd_sc = pow(psd,alpha/2.); + seg_fft[i][j].re *= psd_sc; + seg_fft[i][j].im *= psd_sc; + } + } +} + + +#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr +void fourn(float data[], unsigned int nn[], int ndim, int isign) +{ + int idim; + unsigned long i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2; + unsigned long ibit,k1,k2,n,nprev,nrem,ntot; + float tempi,tempr; + double theta,wi,wpi,wpr,wr,wtemp; + + for (ntot=1,idim=1;idim<=ndim;idim++) + ntot *= nn[idim]; + nprev=1; + for (idim=ndim;idim>=1;idim--) { + n=nn[idim]; + nrem=ntot/(n*nprev); + ip1=nprev << 1; + ip2=ip1*n; + ip3=ip2*nrem; + i2rev=1; + for (i2=1;i2<=ip2;i2+=ip1) { + if (i2 < i2rev) { + for (i1=i2;i1<=i2+ip1-2;i1+=2) { + for (i3=i1;i3<=ip3;i3+=ip2) { + i3rev=i2rev+i3-i2; + SWAP(data[i3],data[i3rev]); + SWAP(data[i3+1],data[i3rev+1]); + } + } + } + ibit=ip2 >> 1; + while (ibit >= ip1 && i2rev > ibit) { + i2rev -= ibit; + ibit >>= 1; + } + i2rev += ibit; + } + ifp1=ip1; + while (ifp1 < ip2) { + ifp2=ifp1 << 1; + theta=isign*6.28318530717959/(ifp2/ip1); + wtemp=sin(0.5*theta); + wpr = -2.0*wtemp*wtemp; + wpi=sin(theta); + wr=1.0; + wi=0.0; + for (i3=1;i3<=ifp1;i3+=ip1) { + for (i1=i3;i1<=i3+ip1-2;i1+=2) { + for (i2=i1;i2<=ip3;i2+=ifp2) { + k1=i2; + k2=k1+ifp1; + tempr=(float)wr*data[k2]-(float)wi*data[k2+1]; + tempi=(float)wr*data[k2+1]+(float)wi*data[k2]; + data[k2]=data[k1]-tempr; + data[k2+1]=data[k1+1]-tempi; + data[k1] += tempr; + data[k1+1] += tempi; + } + } + wr=(wtemp=wr)*wpr-wi*wpi+wr; + wi=wi*wpr+wtemp*wpi+wi; + } + ifp1=ifp2; + } + nprev *= n; + } +} + +#undef SWAP + +fcomplex **cmatrix(int nrl, int nrh, int ncl, int nch) +/* allocate a fcomplex matrix with subscript range m[nrl..nrh][ncl..nch] */ +{ + int i, nrow=nrh-nrl+1,ncol=nch-ncl+1; + fcomplex **m; + + /* allocate pointers to rows */ + m=(fcomplex **)malloc((size_t)((nrow+NR_END)*sizeof(fcomplex*))); + if (!m) nrerror("ERROR: allocation failure 1 in cmatrix()"); + m += NR_END; + m -= nrl; + + /* allocate rows and set pointers to them */ + m[nrl]=(fcomplex *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(fcomplex))); + if (!m[nrl]) nrerror("ERROR: allocation failure 2 in cmatrix()"); + m[nrl] += NR_END; + m[nrl] -= ncl; + + for(i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol; + + /* return pointer to array of pointers to rows */ + return m; +} + +void free_cmatrix(fcomplex **m, int nrl, int nrh, int ncl, int nch) +/* free a float matrix allocated by matrix() */ +{ + free((FREE_ARG) (m[nrl]+ncl-NR_END)); + free((FREE_ARG) (m+nrl-NR_END)); +} + +void nrerror(char error_text[]) +/* Numerical Recipes standard error handler */ +{ + fprintf(stdout,"Numerical Recipes run-time error...\n"); + fprintf(stdout,"%s\n",error_text); + fprintf(stdout,"...now exiting to system...\n"); + exit(1); +} + +#include +#include +#include +#include +#include + +struct tms buffer; +int user_time, system_time, start_time; + +void start_timing() +{ + start_time = (int) times(&buffer); + user_time = (int) buffer.tms_utime; + system_time = (int) buffer.tms_stime; +} + +void stop_timing() +{ + int end_time,elapsed_time; + int clk_tck; + + clk_tck = (int)sysconf(_SC_CLK_TCK); + + end_time = (int) times(&buffer); + user_time = (int) (buffer.tms_utime - user_time); + system_time = (int) (buffer.tms_stime - system_time); + elapsed_time = (end_time - start_time); + + fprintf(stdout,"\n\nuser time (s): %10.3f\n", (double)user_time/clk_tck); + fprintf(stdout,"system time (s): %10.3f\n", (double)system_time/clk_tck); + fprintf(stdout,"elapsed time (s): %10.3f\n\n", (double) elapsed_time/clk_tck); +} + +/* function: IsFinite() + * -------------------- + * This function takes a double and returns a nonzero value if + * the arguemnt is finite (not NaN and not infinite), and zero otherwise. + * Different implementations are given here since not all machines have + * these functions available. + */ +signed char IsFinite(double d){ + + return(finite(d)); + /* return(isfinite(d)); */ + /* return(!(isnan(d) || isinf(d))); */ + /* return(TRUE) */ +} + diff --git a/contrib/alos2proc/alos2proc.py b/contrib/alos2proc/alos2proc.py index 7e2d485..787e413 100755 --- a/contrib/alos2proc/alos2proc.py +++ b/contrib/alos2proc/alos2proc.py @@ -6,13 +6,12 @@ import copy import ctypes import logging import isceobj +from xml.etree.ElementTree import ElementTree - -def mbf(inputfile, outputfile, nrg, prf, prf_frac, nb, nbg, nboff, bsl, kacoeff, dopcoeff1, dopcoeff2): +def mbf(inputfile, outputfile, prf, prf_frac, nb, nbg, nboff, bsl, kacoeff, dopcoeff1, dopcoeff2): ############################# # inputfile: input file # outputfile: output file - # nrg: file width # prf: PRF # prf_frac: fraction of PRF processed # (represents azimuth bandwidth) @@ -27,8 +26,8 @@ def mbf(inputfile, outputfile, nrg, prf, prf_frac, nb, nbg, nboff, bsl, kacoeff, # (float, the line number of the first line of the full-aperture SLC is zero) # (no need to be first burst, any one is OK) - # kacoeff[0-2]: FM rate coefficients - # (three coefficients of a quadratic polynomial with regard to) + # kacoeff[0-3]: FM rate coefficients + # (four coefficients of a third order polynomial with regard to) # (range sample number. range sample number starts with zero) # dopcoeff1[0-3]: Doppler centroid frequency coefficients of this image @@ -41,18 +40,34 @@ def mbf(inputfile, outputfile, nrg, prf, prf_frac, nb, nbg, nboff, bsl, kacoeff, ############################# #examples: - # kacoeff = [-625.771055784221, 0.007887946763383646, -9.10142814131697e-08] + # kacoeff = [-625.771055784221, 0.007887946763383646, -9.10142814131697e-08, 0.0] # dopcoeff1 = [-0.013424025141940908, -6.820475445542178e-08, 0.0, 0.0] # dopcoeff2 = [-0.013408164465406417, -7.216577938502655e-08, 3.187158113584236e-24, -9.081842749918244e-28] - inputfile2 = copy.deepcopy(inputfile) - outputfile2 = copy.deepcopy(outputfile) - inputfile = bytes(inputfile,'utf-8') - outputfile = bytes(outputfile,'utf-8') + img = isceobj.createSlcImage() + img.load(inputfile + '.xml') + + width = img.getWidth() + length = img.getLength() + + inputimage = find_vrt_file(inputfile+'.vrt', 'SourceFilename') + byteorder = find_vrt_keyword(inputfile+'.vrt', 'ByteOrder') + if byteorder == 'LSB': + byteorder = 0 + else: + byteorder = 1 + imageoffset = find_vrt_keyword(inputfile+'.vrt', 'ImageOffset') + imageoffset = int(imageoffset) + lineoffset = find_vrt_keyword(inputfile+'.vrt', 'LineOffset') + lineoffset = int(lineoffset) + + #lineoffset = lineoffset - width * 8 + #imageoffset = imageoffset - lineoffset + if type(kacoeff) != list: raise Exception('kacoeff must be a python list.\n') - if len(kacoeff) != 3: - raise Exception('kacoeff must have three elements.\n') + if len(kacoeff) != 4: + raise Exception('kacoeff must have four elements.\n') if type(dopcoeff1) != list: raise Exception('dopcoeff1 must be a python list.\n') if len(dopcoeff1) != 4: @@ -64,9 +79,10 @@ def mbf(inputfile, outputfile, nrg, prf, prf_frac, nb, nbg, nboff, bsl, kacoeff, filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2proc.so')) filters.mbf( - ctypes.c_char_p(inputfile), - ctypes.c_char_p(outputfile), - ctypes.c_int(nrg), + ctypes.c_char_p(bytes(inputimage,'utf-8')), + ctypes.c_char_p(bytes(outputfile,'utf-8')), + ctypes.c_int(width), + ctypes.c_int(length), ctypes.c_float(prf), ctypes.c_float(prf_frac), ctypes.c_float(nb), @@ -76,24 +92,26 @@ def mbf(inputfile, outputfile, nrg, prf, prf_frac, nb, nbg, nboff, bsl, kacoeff, (ctypes.c_float * len(kacoeff))(*kacoeff), (ctypes.c_float * len(dopcoeff1))(*dopcoeff1), (ctypes.c_float * len(dopcoeff2))(*dopcoeff2), + ctypes.c_int(byteorder), + ctypes.c_long(imageoffset), + ctypes.c_long(lineoffset) ) - img = isceobj.createSlcImage() - img.load(inputfile2 + '.xml') - img.setFilename(outputfile2) - img.extraFilename = outputfile2 + '.vrt' + #img = isceobj.createSlcImage() + #img.load(inputfile + '.xml') + img.setFilename(outputfile) + img.extraFilename = outputfile + '.vrt' img.setAccessMode('READ') img.renderHdr() -def rg_filter(inputfile, nrg, nout, outputfile, bw, bc, nfilter, nfft, beta, zero_cf, offset): +def rg_filter(inputfile, nout, outputfile, bw, bc, nfilter, nfft, beta, zero_cf, offset): ############################# # inputfile: input file - # nrg file width # nout: number of output files - # outputfile: (value_of_out_1, value_of_out_2, value_of_out_3...) output files - # bw: (value_of_out_1, value_of_out_2, value_of_out_3...) filter bandwidth divided by sampling frequency [0, 1] - # bc: (value_of_out_1, value_of_out_2, value_of_out_3...) filter center frequency divided by sampling frequency + # outputfile: [value_of_out_1, value_of_out_2, value_of_out_3...] output files + # bw: [value_of_out_1, value_of_out_2, value_of_out_3...] filter bandwidth divided by sampling frequency [0, 1] + # bc: [value_of_out_1, value_of_out_2, value_of_out_3...] filter center frequency divided by sampling frequency # nfilter: number samples of the filter (odd). Reference Value: 65 # nfft: number of samples of the FFT. Reference Value: 1024 @@ -103,19 +121,35 @@ def rg_filter(inputfile, nrg, nout, outputfile, bw, bc, nfilter, nfft, beta, zer ############################# #examples - #outputfile = [bytes('result/crop_filt_1.slc','utf-8'), bytes('result/crop_filt_2.slc','utf-8')] + #outputfile = ['result/crop_filt_1.slc', 'result/crop_filt_2.slc'] #bw = [0.3, 0.3] #bc = [0.1, -0.1] - inputfile2 = copy.deepcopy(inputfile) + img = isceobj.createSlcImage() + img.load(inputfile + '.xml') + + width = img.getWidth() + length = img.getLength() + + inputimage = find_vrt_file(inputfile+'.vrt', 'SourceFilename') + byteorder = find_vrt_keyword(inputfile+'.vrt', 'ByteOrder') + if byteorder == 'LSB': + byteorder = 0 + else: + byteorder = 1 + imageoffset = find_vrt_keyword(inputfile+'.vrt', 'ImageOffset') + imageoffset = int(imageoffset) + lineoffset = find_vrt_keyword(inputfile+'.vrt', 'LineOffset') + lineoffset = int(lineoffset) + + #lineoffset = lineoffset - width * 8 + #imageoffset = imageoffset - lineoffset + outputfile2 = copy.deepcopy(outputfile) - - inputfile = bytes(inputfile,'utf-8') - if type(outputfile) != list: raise Exception('outputfile must be a python list.\n') if len(outputfile) != nout: - raise Exception('number of output files is not equal to list length.\n') + raise Exception('number of output files is not equal to outputfile list length.\n') else: tmp = [] for x in outputfile: @@ -125,17 +159,18 @@ def rg_filter(inputfile, nrg, nout, outputfile, bw, bc, nfilter, nfft, beta, zer if type(bw) != list: raise Exception('bw must be a python list.\n') if len(bw) != nout: - raise Exception('number of output files is not equal to list length.\n') + raise Exception('number of output files is not equal to bw list length.\n') if type(bc) != list: raise Exception('bc must be a python list.\n') if len(bc) != nout: - raise Exception('number of output files is not equal to list length.\n') + raise Exception('number of output files is not equal to bc list length.\n') filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2proc.so')) filters.rg_filter( - ctypes.c_char_p(inputfile), - ctypes.c_int(nrg), + ctypes.c_char_p(bytes(inputimage,'utf-8')), + ctypes.c_int(width), + ctypes.c_int(length), ctypes.c_int(nout), (ctypes.c_char_p * len(outputfile))(*outputfile), (ctypes.c_float * len(bw))(*bw), @@ -144,13 +179,286 @@ def rg_filter(inputfile, nrg, nout, outputfile, bw, bc, nfilter, nfft, beta, zer ctypes.c_int(nfft), ctypes.c_float(beta), ctypes.c_int(zero_cf), - ctypes.c_float(offset) + ctypes.c_float(offset), + ctypes.c_int(byteorder), + ctypes.c_long(imageoffset), + ctypes.c_long(lineoffset) ) - img = isceobj.createSlcImage() - img.load(inputfile2 + '.xml') + #img = isceobj.createSlcImage() + #img.load(inputfile + '.xml') for x in outputfile2: img.setFilename(x) img.extraFilename = x + '.vrt' img.setAccessMode('READ') img.renderHdr() + + +def resamp(slc2, rslc2, rgoff_file, azoff_file, nrg1, naz1, prf, dopcoeff, rgcoef=[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], azcoef=[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], azpos_off=0.0, verbose=0): + ############################# + # mandatory: + # slc2: slave image + # rslc2: resampled slave image + # rgoff_file: range offset file. if no range offset file, specify 'fake' + # azoff_file: azimuth offset file. if no azimuth offset file, specify 'fake' + # nrg1: number of columns in master image + # naz1: number of lines in master image + # prf: PRF of slave image + # dopcoeff[0]-[3]: Doppler centroid frequency coefficents + # optional: + # rgcoef[0]-[9]: range offset polynomial coefficents. First of two fit results of resamp_roi + # azcoef[0]-[9]: azimuth offset polynomial coefficents. First of two fit results of resamp_roi + # azpos_off: azimuth position offset. Azimuth line number (column 3) of first offset in culled offset file + # verbose: if not zero, print resampling info + ############################# + + #examples: + # dopcoeff = [-0.013424025141940908, -6.820475445542178e-08, 0.0, 0.0] + + img = isceobj.createSlcImage() + img.load(slc2 + '.xml') + + width = img.getWidth() + length = img.getLength() + + inputimage = find_vrt_file(slc2+'.vrt', 'SourceFilename') + byteorder = find_vrt_keyword(slc2+'.vrt', 'ByteOrder') + if byteorder == 'LSB': + byteorder = 0 + else: + byteorder = 1 + imageoffset = find_vrt_keyword(slc2+'.vrt', 'ImageOffset') + imageoffset = int(imageoffset) + lineoffset = find_vrt_keyword(slc2+'.vrt', 'LineOffset') + lineoffset = int(lineoffset) + + #lineoffset = lineoffset - width * 8 + #imageoffset = imageoffset - lineoffset + + if type(dopcoeff) != list: + raise Exception('dopcoeff must be a python list.\n') + if len(dopcoeff) != 4: + raise Exception('dopcoeff must have four elements.\n') + if type(rgcoef) != list: + raise Exception('rgcoef must be a python list.\n') + if len(rgcoef) != 10: + raise Exception('rgcoef must have 10 elements.\n') + if type(azcoef) != list: + raise Exception('azcoef must be a python list.\n') + if len(azcoef) != 10: + raise Exception('azcoef must have 10 elements.\n') + + filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2proc.so')) + filters.resamp( + ctypes.c_char_p(bytes(inputimage,'utf-8')), + ctypes.c_char_p(bytes(rslc2,'utf-8')), + ctypes.c_char_p(bytes(rgoff_file,'utf-8')), + ctypes.c_char_p(bytes(azoff_file,'utf-8')), + ctypes.c_int(nrg1), + ctypes.c_int(naz1), + ctypes.c_int(width), + ctypes.c_int(length), + ctypes.c_float(prf), + (ctypes.c_float * len(dopcoeff))(*dopcoeff), + (ctypes.c_float * len(rgcoef))(*rgcoef), + (ctypes.c_float * len(azcoef))(*azcoef), + ctypes.c_float(azpos_off), + ctypes.c_int(byteorder), + ctypes.c_long(imageoffset), + ctypes.c_long(lineoffset), + ctypes.c_int(verbose) + ) + + #img = isceobj.createSlcImage() + #img.load(inputfile + '.xml') + img.setFilename(rslc2) + img.extraFilename = rslc2 + '.vrt' + img.setWidth(nrg1) + img.setLength(naz1) + img.setAccessMode('READ') + img.renderHdr() + + +def mosaicsubswath(outputfile, nrgout, nazout, delta, diffflag, n, inputfile, nrgin, nrgoff, nazoff, phc, oflag): + ''' + outputfile: (char) output file + nrgout: (int) number of output samples + nazout: (int) number of output lines + delta: (int) edge to be removed of the overlap area (number of samples) + diffflag: (int) whether output the overlap area as two-band BIL image. 0: yes, otherwise: no + n: (int) number of input file + inputfile: (char list) [value_of_out_1, value_of_out_2, value_of_out_3...] input files to mosaic + nrgin: (int list) [value_of_out_1, value_of_out_2, value_of_out_3...] input file widths + nrgoff: (int list) [value_of_out_1, value_of_out_2, value_of_out_3...] input file range offsets + nazoff: (int list) [value_of_out_1, value_of_out_2, value_of_out_3...] input file azimuth offsets + phc: (float list) [value_of_out_1, value_of_out_2, value_of_out_3...] input file compensation phase + oflag: (int list) [value_of_out_1, value_of_out_2, value_of_out_3...] overlap area mosaicking flag + + for each frame + range offset is relative to the first sample of last subswath + azimuth offset is relative to the uppermost line + ''' + + if type(inputfile) != list: + raise Exception('inputfile must be a python list.\n') + if len(inputfile) != n: + raise Exception('number of input files is not equal to inputfile list length.\n') + else: + inputfile = [bytes(x,'utf-8') for x in inputfile] + + filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2proc.so')) + filters.mosaicsubswath( + ctypes.c_char_p(bytes(outputfile,'utf-8')), + ctypes.c_int(nrgout), + ctypes.c_int(nazout), + ctypes.c_int(delta), + ctypes.c_int(diffflag), + ctypes.c_int(n), + (ctypes.c_char_p * len(inputfile))(*inputfile), + (ctypes.c_int * len(nrgin))(*nrgin), + (ctypes.c_int * len(nrgoff))(*nrgoff), + (ctypes.c_int * len(nazoff))(*nazoff), + (ctypes.c_float * len(phc))(*phc), + (ctypes.c_int * len(oflag))(*oflag) + ) + + +def look(inputfile, outputfile, nrg, nrlks, nalks, ft=0, sum=0, avg=0): + ''' + inputfile: input file + outputfile: output file + nrg: file width + nrlks: number of looks in range (default: 4) + nalks: number of looks in azimuth (default: 4) + ft: file type (default: 0) + 0: signed char + 1: int + 2: float + 3: double + 4: complex (real and imagery: float) + 5: complex (real and imagery: double) + sum: sum method (default: 0) + 0: simple sum + 1: power sum (if complex, do this for each channel seperately) + avg: take average (default: 0) + 0: no + 1: yes + ''' + + filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2proc.so')) + filters.look( + ctypes.c_char_p(bytes(inputfile,'utf-8')), + ctypes.c_char_p(bytes(outputfile,'utf-8')), + ctypes.c_long(nrg), + ctypes.c_int(nrlks), + ctypes.c_int(nalks), + ctypes.c_int(ft), + ctypes.c_int(sum), + ctypes.c_int(avg) + ) + + +def extract_burst(inputf, outputf, prf, prf_frac, nb, nbg, bsl, kacoeff, dopcoeff, az_ratio, min_line_offset): + ''' + see extract_burst.c for usage + ''' + + img = isceobj.createSlcImage() + img.load(inputf + '.xml') + + width = img.getWidth() + length = img.getLength() + + inputimage = find_vrt_file(inputf+'.vrt', 'SourceFilename') + byteorder = find_vrt_keyword(inputf+'.vrt', 'ByteOrder') + if byteorder == 'LSB': + byteorder = 0 + else: + byteorder = 1 + imageoffset = find_vrt_keyword(inputf+'.vrt', 'ImageOffset') + imageoffset = int(imageoffset) + lineoffset = find_vrt_keyword(inputf+'.vrt', 'LineOffset') + lineoffset = int(lineoffset) + + if type(kacoeff) != list: + raise Exception('kacoeff must be a python list.\n') + if len(kacoeff) != 4: + raise Exception('kacoeff must have four elements.\n') + if type(dopcoeff) != list: + raise Exception('dopcoeff must be a python list.\n') + if len(dopcoeff) != 4: + raise Exception('dopcoeff must have four elements.\n') + + filters = ctypes.cdll.LoadLibrary(os.path.join(os.path.dirname(__file__),'libalos2proc.so')) + filters.extract_burst( + ctypes.c_char_p(bytes(inputimage,'utf-8')), + ctypes.c_char_p(bytes(outputf,'utf-8')), + ctypes.c_int(width), + ctypes.c_int(length), + ctypes.c_float(prf), + ctypes.c_float(prf_frac), + ctypes.c_float(nb), + ctypes.c_float(nbg), + ctypes.c_float(bsl), + (ctypes.c_float * len(kacoeff))(*kacoeff), + (ctypes.c_float * len(dopcoeff))(*dopcoeff), + ctypes.c_float(az_ratio), + ctypes.c_float(min_line_offset), + ctypes.c_int(byteorder), + ctypes.c_long(imageoffset), + ctypes.c_long(lineoffset) + ) + + #img = isceobj.createSlcImage() + #img.load(inputfile + '.xml') + #img.setFilename(outputfile) + #img.extraFilename = outputfile + '.vrt' + #img.setAccessMode('READ') + #img.renderHdr() + + +def find_vrt_keyword(xmlfile, keyword): + from xml.etree.ElementTree import ElementTree + + value = None + xmlx = ElementTree(file=open(xmlfile,'r')).getroot() + #try 10 times + for i in range(10): + path='' + for j in range(i): + path += '*/' + value0 = xmlx.find(path+keyword) + if value0 != None: + value = value0.text + break + + return value + + + +def find_vrt_file(xmlfile, keyword, relative_path=True): + ''' + find file in vrt in another directory + xmlfile: vrt file + relative_path: True: return relative (to current directory) path of the file + False: return absolute path of the file + ''' + import os + #get absolute directory of xmlfile + xmlfile_dir = os.path.dirname(os.path.abspath(xmlfile)) + #find source file path + file = find_vrt_keyword(xmlfile, keyword) + #get absolute path of source file + file = os.path.abspath(os.path.join(xmlfile_dir, file)) + #get relative path of source file + if relative_path: + file = os.path.relpath(file, './') + return file + + + + + + + + diff --git a/contrib/alos2proc/src/SConscript b/contrib/alos2proc/src/SConscript index 43e15c5..98a0456 100644 --- a/contrib/alos2proc/src/SConscript +++ b/contrib/alos2proc/src/SConscript @@ -5,7 +5,7 @@ import os Import('envalos2proc') install = os.path.join(envalos2proc['PRJ_SCONS_INSTALL'], envalos2proc['PACKAGE'], 'alos2proc') -listFiles = ['lib_array.c', 'lib_cpx.c', 'lib_file.c', 'lib_func.c', 'mbf.c', 'rg_filter.c'] +listFiles = ['lib_array.c', 'lib_cpx.c', 'lib_file.c', 'lib_func.c', 'mbf.c', 'rg_filter.c', 'resamp.c', 'mosaicsubswath.c', 'look.c', 'extract_burst.c'] # -shared # -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -lm @@ -14,7 +14,7 @@ listFiles = ['lib_array.c', 'lib_cpx.c', 'lib_file.c', 'lib_func.c', 'mbf.c', 'r #envalos2proc.Append(CFLAGS=['-D_LARGEFILE64_SOURCE', '-D_FILE_OFFSET_BITS=64', '-lm', '-shared', '-fopenmp', '-O3']) #envalos2proc.Append(LIBS=['fftw3f', 'fftw3f_threads', 'pthread']) -lib = envalos2proc.LoadableModule(target = 'libalos2proc.so', source = listFiles) +lib = envalos2proc.LoadableModule(target = 'libalos2proc.so', source = listFiles, parse_flags='-fopenmp') envalos2proc.Install(install,lib) envalos2proc.Alias('install',install) diff --git a/contrib/alos2proc/src/extract_burst.c b/contrib/alos2proc/src/extract_burst.c new file mode 100644 index 0000000..60a3c0d --- /dev/null +++ b/contrib/alos2proc/src/extract_burst.c @@ -0,0 +1,576 @@ +////////////////////////////////////// +// Cunren Liang, NASA JPL/Caltech +// Copyright 2017 +////////////////////////////////////// + + +#include "resamp.h" +#include + +#define SWAP4(a) (*(unsigned int *)&(a) = (((*(unsigned int *)&(a) & 0x000000ff) << 24) | ((*(unsigned int *)&(a) & 0x0000ff00) << 8) | ((*(unsigned int *)&(a) >> 8) & 0x0000ff00) | ((*(unsigned int *)&(a) >> 24) & 0x000000ff))) + + +int extract_burst(char *inputf, char *outputf, int nrg, int naz, float prf, float prf_frac, float nb, float nbg, float bsl, float *kacoeff, float *dopcoeff, float az_ratio, float min_line_offset, int byteorder, long imageoffset, long lineoffset){ + FILE *infp; + FILE *outfp; + FILE *infofp; + + char output_filename[512]; + char burst_num[512]; + + fcomplex **in; //data read in + fcomplex **out; //data written to output file + fcomplex **filter; //multi-band bandpass filter + fcomplex **deramp; //deramp signal + + fcomplex *data; //data to be filtered. + + //int nrg; //file width + //int naz; //file length + int naz_burst_in; //number of lines of the input burst + int naz_burst_out; //number of lines of the output burst + + //float prf; + float pri; // 1.0/prf + //float prf_frac; // azimuth bandwidth used for burst extraction = prf_frac * prf + //float kacoeff[3]; //FM rate along range (experessed by quadratic polynomial + //as a function of range sample number) + //float dopcoeff[4]; //doppler centroid frequency along range (expressed by quadratic polynomial + //as a function of range sample number). this image + + //float nb; //burst length in terms of pri. number of lines + //float nbg; //burst gap length in terms of pri. number of lines + //float bsl; //burst start line, input float + float bcl; //burst center line, float + float bfw; //burst bandwidth + //float az_ratio; //azimuth sampling interval of output burst: az_ratio * pri; + + float *ka; //azimuth fm rate + float *dop; //doppler centroid frequency + float *nfa; + + float *start_line; //burst imaged area start line number for each column + float *end_line; //burst imaged area ending line number for each column + + float min_line; //minimum of start_line + float max_line; //maximum of end_line + int min_line_column; //column of minimum + int max_line_column; //column of maximum + + int *output_start; //relative start line in the output burst for each column + int *output_end; //relative end line in the output burst for each column + + int min_line_in; //first line of input burst + float min_line_out; //first line of output burst + float min_line_out_first; //first line of first output burst + int offset_from_first_burst; //offset between first burst and this burst in az_ratio * pri + int offset_from_first_burst0; //offset between first burst and last burst in az_ratio * pri + + //float min_line_offset; // the offset of first line of output burst in pri, compared with roundfi(min_line) + // this is mainly used to adjust the output burst location. so usually can be set to 0 + + int burst_index; + int burst_index_tmp; + int burst_index_first; + + int nfft; //fft length + int nfilter; //filter length, MUST BE ODD + int hnfilter; //half filter length + float beta; //kaiser window beta of filter + float sc; //constant to scale the data read in to avoid large values during fft and ifft + + //resampling parameters + float beta_resamp; //beta of kaiser window of resampling kernal + int n; //number of samples to be used in the resampling(odd) + int m; //multiples of n, so that a lookup table can be generated(even) + + int hn; //half of n + int hnm; //half of n*m + float *sincc; //sinc coefficents + float *kaiserc; // kaiser window coefficents + float *kernel; // sincc*kaiserc + + float tmpa, tmpb, tmpc; //temperal variables effective for a longer time + float tmp1, tmp2, tmp3; //temperal variables effective for a shorter time + fcomplex reramp; + int index; + + int i, j, k; + + fftwf_plan p_forward; + fftwf_plan p_backward; + +/*****************************************************************************/ +//I just put these parametes which can be set here. These can also be set via +//arguments before running the programs if modifying the code to accept these +//arguments. + //min_line_offset = 0.0; + + //filtering parameters + beta = 1.0; + nfilter = 257; //MUST BE ODD + sc = 10000.0; + + //resampling parameters + beta_resamp = 2.5; + n = 9; //MUST BE ODD + m = 10000; //MUST BE EVEN + +/*****************************************************************************/ + + if(0){ + //if(argc != 18){ + fprintf(stderr, "\nusage: %s inputf outputf nrg naz prf prf_frac nb nbg bsl kacoeff[0-3] dopcoeff[0-3] az_ratio min_line_offset byteorder imageoffset lineoffset\n"); + fprintf(stderr, "\nmandatory:\n"); + fprintf(stderr, " inputf: input file\n"); + fprintf(stderr, " outputf: prefix of output files\n"); + fprintf(stderr, " nrg: file width\n"); + fprintf(stderr, " naz: file length\n"); + fprintf(stderr, " prf: PRF\n"); + fprintf(stderr, " prf_frac: fraction of PRF used for burst generation\n"); + fprintf(stderr, " (represents azimuth bandwidth)\n"); + fprintf(stderr, " nb: number of lines in a burst\n"); + fprintf(stderr, " (float, in terms of 1/PRF)\n"); + fprintf(stderr, " nbg: number of lines in a burst gap\n"); + fprintf(stderr, " (float, in terms of 1/PRF)\n"); + fprintf(stderr, " bsl: start line number of a burst\n"); + fprintf(stderr, " (float, the line number of the first line of the full-aperture SLC is zero)\n"); + fprintf(stderr, " (no need to be first burst, any one is OK)\n"); + + fprintf(stderr, " kacoeff[0-3]: FM rate coefficients\n"); + fprintf(stderr, " (four coefficients of a third order polynomial with regard to)\n"); + fprintf(stderr, " (range sample number. range sample number starts with zero)\n"); + + fprintf(stderr, " dopcoeff[0-3]: Doppler centroid frequency coefficients of this image\n"); + fprintf(stderr, " (four coefficients of a third order polynomial with regard to)\n"); + fprintf(stderr, " (range sample number. range sample number starts with zero)\n"); + fprintf(stderr, " az_ratio: line interval of output burst: az_ratio * (1/PRF)\n"); + fprintf(stderr, " min_line_offset: adjust output line location by this offset\n"); + fprintf(stderr, " (in terms of 1/PRF, within [-50/PRF, 50/PRF])\n"); + fprintf(stderr, " (offset < 0, start earlier than original)\n"); + fprintf(stderr, " (offset = 0, original)\n"); + fprintf(stderr, " (offset > 0, start later than original)\n"); + + fprintf(stderr, "byteorder: (0) LSB, little endian; (1) MSB, big endian of intput file\n"); + fprintf(stderr, "imageoffset: offset from start of the image of input file\n"); + fprintf(stderr, "lineoffset: length of each line of input file\n\n"); + + exit(1); + } + + infofp = openfile("extract_burst.txt", "w"); + + //open files + infp = openfile(inputf, "rb"); + //nrg = atoi(argv[3]); + //prf = atof(argv[4]); + //prf_frac = atof(argv[5]); + //nb = atof(argv[6]); + //nbg = atof(argv[7]); + //bsl = atof(argv[8]); + + //kacoeff[0] = atof(argv[9]); + //kacoeff[1] = atof(argv[10]); + //kacoeff[2] = atof(argv[11]); + + //dopcoeff[0] = atof(argv[12]); + //dopcoeff[1] = atof(argv[13]); + //dopcoeff[2] = atof(argv[14]); + //dopcoeff[3] = atof(argv[15]); + + //az_ratio = atof(argv[16]); + //min_line_offset = atof(argv[17]); + + + fprintf(infofp, "\n\ninput parameters:\n"); + fprintf(infofp, "input file: %s\n", inputf); + fprintf(infofp, "prefix of output files: %s\n", outputf); + fprintf(infofp, "nrg: %d\n", nrg); + fprintf(infofp, "prf: %f\n", prf); + fprintf(infofp, "prf_frac: %f\n", prf_frac); + fprintf(infofp, "nb: %f\n", nb); + fprintf(infofp, "nbg: %f\n", nbg); + fprintf(infofp, "bsl: %f\n", bsl); + + fprintf(infofp, "kacoeff: %f, %f, %f, %f\n", kacoeff[0], kacoeff[1], kacoeff[2], kacoeff[3]); + fprintf(infofp, "dopcoeff1: %f, %f, %f, %f\n", dopcoeff[0], dopcoeff[1], dopcoeff[2], dopcoeff[3]); + + fprintf(infofp, "az_ratio: %f\n", az_ratio); + fprintf(infofp, "offset: %f\n\n", min_line_offset); + + if(fabs(min_line_offset) > 50.0){ + fprintf(stderr, "offset too big!\n"); + exit(1); + } + + if(nfilter % 2 != 1){ + fprintf(stderr, "filter length must be odd!\n"); + exit(1); + } + + if(n % 2 != 1){ + fprintf(stderr, "resample kernal length must be odd!\n"); + exit(1); + } + if(n < 7){ + fprintf(stderr, "resample kernal length too small!\n"); + exit(1); + } + + if(m % 2 != 0){ + fprintf(stderr, "m must be even!\n"); + exit(1); + } + if(m < 1000){ + fprintf(stderr, "m too small!\n"); + exit(1); + } + + pri = 1.0/prf; + hnfilter = (nfilter - 1) / 2; + + hn = n / 2; + hnm = n * m / 2; + + + //naz = file_length(infp, nrg, sizeof(fcomplex)); + fprintf(infofp, "file width: %d, file length: %d\n\n", nrg, naz); + + ka = array1d_float(nrg); + dop = array1d_float(nrg); + nfa = array1d_float(nrg); + + start_line = array1d_float(nrg); + end_line = array1d_float(nrg); + output_start = array1d_int(nrg); + output_end = array1d_int(nrg); + + sincc = vector_float(-hnm, hnm); + kaiserc = vector_float(-hnm, hnm); + kernel = vector_float(-hnm, hnm); + + //initialize sinc coefficents + sinc(n, m, sincc); + kaiser(n, m, kaiserc, beta_resamp); + for(i = -hnm; i <= hnm; i++) + kernel[i] = kaiserc[i] * sincc[i]; + + //calculate some range variant variables + for(i = 0; i < nrg; i++){ + //azimuth FM rate. we follow the convention ka > 0 + ka[i] = kacoeff[3] * i * i * i + kacoeff[2] * i * i + kacoeff[1] * i + kacoeff[0]; + ka[i] = -ka[i]; + + //doppler centroid frequency + dop[i] = dopcoeff[0] + dopcoeff[1] * i + dopcoeff[2] * i * i + dopcoeff[3] * i * i * i; + //dop[i] *= prf; + + //full-aperture length + nfa[i] = prf * prf_frac / ka[i] / pri; + } + + tmp1 = -1.0; //maximum oversampling ratio + tmp2 = 10000000000.0; //minimum oversampling ratio + for(i = 0; i < nrg; i++){ + tmp3 = 1.0 / (az_ratio * pri) / (nb * pri * ka[i]); + if(tmp3 > tmp1) + tmp1 = tmp3; + if(tmp3 < tmp2) + tmp2 = tmp3; + } + + fprintf(infofp, "azimuth oversampling ratio of output burst, minimum: %6.2f, maximum: %6.2f\n\n", tmp2, tmp1); + + + //find burst starting line closest to first line and after first line + //to make sure the bsl used in the following is not too big to avoid overflow + //bsl is defined by 0 = first line of input SLC, this defines the absolute line numbers used in the following + //here we stop at burst_index_tmp + for(i = -100000; i < 100000; i++){ + tmp1 = bsl + (nb + nbg) * i; + if(tmp1 >= 0){ + bsl = tmp1; + burst_index_tmp = i; + break; + } + } + + //starting and ending lines for each column + for(i = 0; i < nrg; i++){ + //starting index + start_line[i] = bsl + (nb - 1.0) / 2.0 + dop[i] / ka[i] / pri - (nfa[i] - nb - 1.0) / 2.0; + //ending index + end_line[i] = bsl + (nb - 1.0) / 2.0 + dop[i] / ka[i] / pri + (nfa[i] - nb - 1.0) / 2.0; + } + + //starting and ending lines for the whole block + min_line = start_line[0]; + max_line = end_line[0]; + for(i = 0; i < nrg; i++){ + if(start_line[i] <= min_line){ + min_line = start_line[i]; + min_line_column = i; + } + if(end_line[i] >= max_line){ + max_line = end_line[i]; + max_line_column = i; + } + } + + //number of lines of the input burst + naz_burst_in = roundfi((max_line - min_line) + 2 * hnfilter); + //number of lines of the output burst + naz_burst_out = roundfi((max_line - min_line) / az_ratio); + //to make circular convolution equivalent to linear convolution + nfft = next_pow2(naz_burst_in + nfilter - 1); + + fprintf(infofp, "for all the output bursts:\n"); + fprintf(infofp, "input data block length: %d\n", naz_burst_in); + fprintf(infofp, "output burst length: %d\n", naz_burst_out); + fprintf(infofp, "fft length: %d\n\n", nfft); + + //calculate relative start and end lines in the output burst + for(i = 0; i < nrg; i++){ + output_start[i] = roundfi((start_line[i] - min_line) / az_ratio); //made sure: first line has output. Include this start line + output_end[i] = naz_burst_out - 1 + roundfi((end_line[i] - max_line) / az_ratio); //made sure: last line has output. Include this end line + } + + in = array2d_fcomplex(naz_burst_in, nrg); + out = array2d_fcomplex(naz_burst_out, nrg); + deramp = array2d_fcomplex(naz_burst_in, nrg); + filter = array2d_fcomplex(nrg, nfft); + data = array1d_fcomplex(nfft); + + fprintf(infofp, "calculating filter...\n\n"); + + //create plans before initializing data, because FFTW_MEASURE overwrites the in/out arrays. + p_forward = fftwf_plan_dft_1d(nfft, (fftwf_complex*)data, (fftwf_complex*)data, FFTW_FORWARD, FFTW_ESTIMATE); + p_backward = fftwf_plan_dft_1d(nfft, (fftwf_complex*)data, (fftwf_complex*)data, FFTW_BACKWARD, FFTW_ESTIMATE); + + //create filter, ZERO center frequency for all columns + for(i = 0; i < nrg; i++){ + bfw = nb * pri * ka[i]; + //create filter: first sample corresponding to first fully convolution sample + bandpass_filter(bfw/prf, 0.0/prf, nfilter, nfft, (nfilter-1)/2, beta, filter[i]); + //forward fft + //four1((float *)filter[i] - 1, nfft, -1); + //data = filter[i]; + memcpy((void *) data, (const void *) filter[i], (size_t) nfft * sizeof(fcomplex)); + fftwf_execute(p_forward); + //filter[i] = data; + memcpy((void *) filter[i], (const void *) data, (size_t) nfft * sizeof(fcomplex)); + } + + + //let's extract burst now, start from burst_index_tmp where we stop last time + burst_index_first = burst_index_tmp - 1; + tmpa = min_line; //save min_line caculated last time + offset_from_first_burst0 = 0; + for(burst_index = burst_index_tmp; burst_index < 100000; burst_index++){ + + //burst first line number + tmpb = bsl + (burst_index - burst_index_tmp) * (nb + nbg); + //burst center line number + bcl = tmpb + (nb - 1.0) / 2.0; + //minimum line of imaged area of the burst + min_line = tmpa + (burst_index - burst_index_tmp) * (nb + nbg); + //minimum line of input burst + min_line_in = roundfi(min_line) - hnfilter; + + //skip bursts that are not or partly in the image + if(min_line_in < 0) + continue; + //stop at last burst that is fully in the image + if(min_line_in + naz_burst_in - 1 > naz - 1) + break; + + +/********************************************************* + (int) + min_line_in + ------ + (float) | | (float) + min_line | | min_line_out + ------ | | ------ + | | | | | | + | | ====> | | ====> | | + | | | | | | + ------ | | ------ + burst imaged | | output burst + area ------ + burst read in +*********************************************************/ + + //first burst + if(burst_index_first == burst_index_tmp - 1){ + burst_index_first = burst_index; + + min_line_out = roundfi(min_line) + min_line_offset; + + min_line_out_first = min_line_out; + offset_from_first_burst = 0; + + fprintf(infofp, "line number of first line of original SLC is 0.\n"); + fprintf(infofp, "line number of first line of first output burst in original SLC (1.0/prf): %f\n", min_line_out); + fprintf(infofp, "bsl of first output burst: %f\n\n", tmpb); + } + //adjust starting line of following bursts + else{ + min_line_out = min_line + min_line_offset; + offset_from_first_burst = roundfi((min_line_out - min_line_out_first) / az_ratio); + tmp1 = offset_from_first_burst - (min_line_out - min_line_out_first) / az_ratio; + min_line_out = min_line_out + tmp1 * az_ratio; + } + + fprintf(infofp, "extracting burst %3d\n", burst_index - burst_index_first + 1); + fprintf(infofp, "offset from first burst: %5d, offset from last burst: %5d (az_ratio/prf)\n\n", offset_from_first_burst, offset_from_first_burst - offset_from_first_burst0); + offset_from_first_burst0 = offset_from_first_burst; + + //read data block + //fseeko(infp, (size_t)min_line_in * (size_t)nrg * sizeof(fcomplex), SEEK_SET); + //readdata((fcomplex *)in[0], (size_t)naz_burst_in * (size_t)nrg * sizeof(fcomplex), infp); + + fseeko(infp, (size_t)imageoffset + (size_t)min_line_in * (size_t)lineoffset, SEEK_SET); + for(i = 0; i < naz_burst_in; i++){ + if(i!=0) + fseek(infp, lineoffset-(size_t)nrg*sizeof(fcomplex), SEEK_CUR); + readdata((fcomplex *)in[i], (size_t)nrg * sizeof(fcomplex), infp); + } + + if(byteorder!=0){ + //printf("swapping bytes...\n"); + for(i = 0; i < naz_burst_in; i++) + for(j = 0; j < nrg; j++){ + SWAP4(in[i][j].re); + SWAP4(in[i][j].im); + } + } + + //create deramping signal: make center of azimuth spectrum ZERO + for(i = 0; i < nrg; i++){ + for(j = 0; j < naz_burst_in; j++){ + //distance from raw burst center in number of lines + tmp1 = j + min_line_in - bcl; + tmp2 = - PI * ka[i] * (tmp1 * pri) * (tmp1 * pri); + deramp[j][i].re = cos(tmp2); + deramp[j][i].im = sin(tmp2); + } + } + + //do the filtering column by column + for(i = 0; i < nrg; i++){ + //prepare data + for(j = 0; j < nfft; j++){ + if(j < naz_burst_in){ + data[j].re = in[j][i].re / sc; + data[j].im = in[j][i].im / sc; + } + else{ + data[j].re = 0.0; + data[j].im = 0.0; + } + } + + //deramp the data + for(j = 0; j < naz_burst_in; j++){ + data[j] = cmul(data[j], deramp[j][i]); + } + + //forward fft + //four1((float *)data - 1, nfft, -1); + fftwf_execute(p_forward); + + //multiplication in the frequency domain + for(j = 0; j < nfft; j++) + data[j] = cmul(data[j], filter[i][j]); + + //backward fft + //four1((float *)data - 1, nfft, 1); + fftwf_execute(p_backward); + + //put filtered data back + for(j = 0; j < naz_burst_in; j++){ + in[j][i].re = data[j].re * sc / nfft; + in[j][i].im = data[j].im * sc / nfft; + } + } + + //zero output + for(i = 0; i < naz_burst_out; i++){ + for(j = 0; j < nrg; j++){ + out[i][j].re = 0.0; + out[i][j].im = 0.0; + } + } + + //do the resampling column by column + for(i = 0; i < nrg; i++){ + //resampling to output grid + for(j = 0; j < naz_burst_out; j++){ + if((j < output_start[i]) || (j > output_end[i])) + continue; + + //location of output line in the data block read in + tmp1 = min_line_out + j * az_ratio - min_line_in; + + //interpolation + for(k = -hn; k <= hn; k++){ + index = roundfi(tmp1) + k; + tmp2 = index - tmp1; + + if( (index < 0) || (index > naz_burst_in - 1) ) + continue; + //verified: roundfi(tmp2*m) won't be out of [-hnm, hnm], if no computation error of floating point + out[j][i].re += in[index][i].re * kernel[roundfi(tmp2*m)]; + out[j][i].im += in[index][i].im * kernel[roundfi(tmp2*m)]; + } + + //reramp + tmp1 = j * az_ratio + min_line_out - bcl; + tmp2 = PI * ka[i] * (tmp1 * pri) * (tmp1 * pri); + reramp.re = cos(tmp2); + reramp.im = sin(tmp2); + + out[j][i] = cmul(out[j][i], reramp); + + } + } + + //write to file + strcpy(output_filename, outputf); + sprintf(burst_num, "_%02d.slc", burst_index - burst_index_first + 1); + strcat(output_filename, burst_num); + + outfp = openfile(output_filename, "wb"); + writedata((fcomplex *)out[0], (size_t)naz_burst_out * (size_t)nrg * sizeof(fcomplex), outfp); + fclose(outfp); + } + + fprintf(infofp, "total number of bursts extracted: %3d\n\n", burst_index - burst_index_first); + + fftwf_destroy_plan(p_forward); + fftwf_destroy_plan(p_backward); + + free_array1d_float(ka); + free_array1d_float(dop); + free_array1d_float(nfa); + + free_array1d_float(start_line); + free_array1d_float(end_line); + free_array1d_int(output_start); + free_array1d_int(output_end); + + free_vector_float(sincc, -hnm, hnm); + free_vector_float(kaiserc, -hnm, hnm); + free_vector_float(kernel, -hnm, hnm); + + free_array2d_fcomplex(in); + free_array2d_fcomplex(out); + free_array2d_fcomplex(deramp); + free_array2d_fcomplex(filter); + free_array1d_fcomplex(data); + + //close files + fclose(infp); + fclose(infofp); +} \ No newline at end of file diff --git a/contrib/alos2proc/src/look.c b/contrib/alos2proc/src/look.c new file mode 100644 index 0000000..d99831a --- /dev/null +++ b/contrib/alos2proc/src/look.c @@ -0,0 +1,327 @@ +////////////////////////////////////// +// Cunren Liang, NASA JPL/Caltech +// Copyright 2017 +////////////////////////////////////// + + +//a program for taking looks for single band file + +#include "resamp.h" + +int look(char *inputfile, char *outputfile, long nrg, int nrlks, int nalks, int ft, int sum, int avg){ + + FILE *infp; + FILE *outfp; + + signed char *in0; + int *in1; + float *in2; + double *in3; + fcomplex *in4; + dcomplex *in5; + + signed char *out0; + int *out1; + float *out2; + double *out3; + fcomplex *out4; + dcomplex *out5; + + int sum_nz; + double sum1, sum2; + + long index; + + long naz; + long nrg1, naz1; + //int nrlks, nalks; + + //int ft, sum, avg; + + int i, j; + int ii, jj; + + + // if(argc < 4){ + // fprintf(stderr, "\nUsage: %s infile outfile nrg [nrlks] [nalks] [ft] [sum] [avg]\n", argv[0]); + // fprintf(stderr, " infile: input file\n"); + // fprintf(stderr, " outfile: output file\n"); + // fprintf(stderr, " nrg: file width\n"); + // fprintf(stderr, " nrlks: number of looks in range (default: 4)\n"); + // fprintf(stderr, " nalks: number of looks in azimuth (default: 4)\n"); + // fprintf(stderr, " ft: file type (default: 0)\n"); + // fprintf(stderr, " 0: signed char\n"); + // fprintf(stderr, " 1: int\n"); + // fprintf(stderr, " 2: float\n"); + // fprintf(stderr, " 3: double\n"); + // fprintf(stderr, " 4: complex (real and imagery: float)\n"); + // fprintf(stderr, " 5: complex (real and imagery: double)\n"); + // fprintf(stderr, " sum: sum method (default: 0)\n"); + // fprintf(stderr, " 0: simple sum\n"); + // fprintf(stderr, " 1: power sum (if complex, do this for each channel seperately)\n"); + // fprintf(stderr, " avg: take average (default: 0)\n"); + // fprintf(stderr, " 0: no\n"); + // fprintf(stderr, " 1: yes\n\n"); + + // exit(1); + // } + + infp = openfile(inputfile, "rb"); + outfp = openfile(outputfile, "wb"); + + //nrg = atoi(argv[3]); + + //if(argc > 4) + // nrlks = atoi(argv[4]); + //else + // nrlks = 4; + + //if(argc > 5) + // nalks = atoi(argv[5]); + //else + // nalks = 4; + + //if(argc > 6) + // ft = atoi(argv[6]); + //else + // ft = 0; + + //if(argc > 7) + // sum = atoi(argv[7]); + //else + // sum = 0; + + //if(argc > 8) + // avg = atoi(argv[8]); + //else + // avg = 0; + + nrg1 = nrg / nrlks; + + if(ft == 0){ + in0 = array1d_char(nrg*nalks); + out0 = array1d_char(nrg1); + naz = file_length(infp, nrg, sizeof(signed char)); + } + else if(ft == 1){ + in1 = array1d_int(nrg*nalks); + out1 = array1d_int(nrg1); + naz = file_length(infp, nrg, sizeof(int)); + } + else if(ft == 2){ + in2 = array1d_float(nrg*nalks); + out2 = array1d_float(nrg1); + naz = file_length(infp, nrg, sizeof(float)); + } + else if(ft == 3){ + in3 = array1d_double(nrg*nalks); + out3 = array1d_double(nrg1); + naz = file_length(infp, nrg, sizeof(double)); + } + else if(ft == 4){ + in4 = array1d_fcomplex(nrg*nalks); + out4 = array1d_fcomplex(nrg1); + naz = file_length(infp, nrg, sizeof(fcomplex)); + } + else if(ft == 5){ + in5 = array1d_dcomplex(nrg*nalks); + out5 = array1d_dcomplex(nrg1); + naz = file_length(infp, nrg, sizeof(dcomplex)); + } + else{ + fprintf(stderr, "Error: file type not supported.\n\n"); + exit(1); + } + + naz1 = naz / nalks; + + for(i = 0; i < naz1; i++){ + + if((i + 1) % 100 == 0) + fprintf(stderr,"processing line: %6d of %6d\r", i+1, naz1); + + //read data + if(ft == 0){ + readdata((signed char *)in0, (size_t)nalks * (size_t)nrg * sizeof(signed char), infp); + } + else if(ft == 1){ + readdata((int *)in1, (size_t)nalks * (size_t)nrg * sizeof(int), infp); + } + else if(ft == 2){ + readdata((float *)in2, (size_t)nalks * (size_t)nrg * sizeof(float), infp); + } + else if(ft == 3){ + readdata((double *)in3, (size_t)nalks * (size_t)nrg * sizeof(double), infp); + } + else if(ft == 4){ + readdata((fcomplex *)in4, (size_t)nalks * (size_t)nrg * sizeof(fcomplex), infp); + } + else if(ft == 5){ + readdata((dcomplex *)in5, (size_t)nalks * (size_t)nrg * sizeof(dcomplex), infp); + } + + //process data + for(j = 0; j < nrg1; j++){ + //get sum + sum_nz = 0; + sum1 = 0.0; + sum2 = 0.0; + for(ii = 0; ii < nalks; ii++){ + for(jj = 0; jj < nrlks; jj++){ + index = ii * nrg + j * nrlks + jj; + if(ft == 0){ + if(in0[index] != 0){ + if(sum == 0) + sum1 += in0[index]; + else + sum1 += in0[index] * in0[index]; + sum_nz += 1; + } + } + else if(ft == 1){ + if(in1[index] != 0){ + if(sum == 0) + sum1 += in1[index]; + else + sum1 += in1[index] * in1[index]; + sum_nz += 1; + } + } + else if(ft == 2){ + if(in2[index] != 0){ + if(sum == 0) + sum1 += in2[index]; + else + sum1 += in2[index] * in2[index]; + sum_nz += 1; + } + } + else if(ft == 3){ + if(in3[index] != 0){ + if(sum == 0) + sum1 += in3[index]; + else + sum1 += in3[index] * in3[index]; + sum_nz += 1; + } + } + else if(ft == 4){ + if(in4[index].re != 0 || in4[index].im != 0){ + if(sum ==0){ + sum1 += in4[index].re; + sum2 += in4[index].im; + } + else{ + sum1 += in4[index].re * in4[index].re; + sum2 += in4[index].im * in4[index].im; + } + sum_nz += 1; + } + } + else if(ft == 5){ + if(in5[index].re != 0 || in5[index].im != 0){ + if(sum == 0){ + sum1 += in5[index].re; + sum2 += in5[index].im; + } + else{ + sum1 += in5[index].re * in5[index].re; + sum2 += in5[index].im * in5[index].im; + } + sum_nz += 1; + } + } + } + } + + //preprocessing + if(avg == 1){ + if(sum_nz != 0){ + sum1 /= sum_nz; + if(ft == 4 || ft == 5) + sum2 /= sum_nz; + } + } + if(sum == 1){ + if(sum_nz != 0){ + sum1 = sqrt(sum1); + if(ft == 4 || ft ==5) + sum2 = sqrt(sum2); + } + } + + //get data + if(ft == 0){ + out0[j] = (signed char)(roundfi(sum1)); + } + else if(ft == 1){ + out1[j] = (int)(roundfi(sum1)); + } + else if(ft == 2){ + out2[j] = sum1; + } + else if(ft == 3){ + out3[j] = sum1; + } + else if(ft == 4){ + out4[j].re = sum1; + out4[j].im = sum2; + } + else if(ft == 5){ + out5[j].re = sum1; + out5[j].im = sum2; + } + } + + //write data + if(ft == 0){ + writedata((signed char *)out0, nrg1 * sizeof(signed char), outfp); + } + else if(ft == 1){ + writedata((int *)out1, nrg1 * sizeof(int), outfp); + } + else if(ft == 2){ + writedata((float *)out2, nrg1 * sizeof(float), outfp); + } + else if(ft == 3){ + writedata((double *)out3, nrg1 * sizeof(double), outfp); + } + else if(ft == 4){ + writedata((fcomplex *)out4, nrg1 * sizeof(fcomplex), outfp); + } + else if(ft == 5){ + writedata((dcomplex *)out5, nrg1 * sizeof(dcomplex), outfp); + } + } + fprintf(stderr,"processing line: %6d of %6d\n", naz1, naz1); + + //clear up + if(ft == 0){ + free_array1d_char(in0); + free_array1d_char(out0); + } + else if(ft == 1){ + free_array1d_int(in1); + free_array1d_int(out1); + } + else if(ft == 2){ + free_array1d_float(in2); + free_array1d_float(out2); + } + else if(ft == 3){ + free_array1d_double(in3); + free_array1d_double(out3); + } + else if(ft == 4){ + free_array1d_fcomplex(in4); + free_array1d_fcomplex(out4); + } + else if(ft == 5){ + free_array1d_dcomplex(in5); + free_array1d_dcomplex(out5); + } + fclose(infp); + fclose(outfp); + + return 0; +} diff --git a/contrib/alos2proc/src/mbf.c b/contrib/alos2proc/src/mbf.c index ffcb350..9fb5aeb 100644 --- a/contrib/alos2proc/src/mbf.c +++ b/contrib/alos2proc/src/mbf.c @@ -6,14 +6,17 @@ #include "resamp.h" #include +#include +#define SWAP4(a) (*(unsigned int *)&(a) = (((*(unsigned int *)&(a) & 0x000000ff) << 24) | ((*(unsigned int *)&(a) & 0x0000ff00) << 8) | ((*(unsigned int *)&(a) >> 8) & 0x0000ff00) | ((*(unsigned int *)&(a) >> 24) & 0x000000ff))) -int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, float nb, float nbg, float nboff, float bsl, float *kacoeff, float *dopcoeff1, float *dopcoeff2){ +int mbf(char *inputfile, char *outputfile, int nrg, int naz, float prf, float prf_frac, float nb, float nbg, float nboff, float bsl, float *kacoeff, float *dopcoeff1, float *dopcoeff2, int byteorder, long imageoffset, long lineoffset){ /* inputfile: input file outputfile: output file nrg: file width + naz: file length prf: PRF prf_frac: fraction of PRF processed (represents azimuth bandwidth) @@ -28,8 +31,8 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f (float, the line number of the first line of the full-aperture SLC is zero) (no need to be first burst, any one is OK) - kacoeff[0-2]: FM rate coefficients - (three coefficients of a quadratic polynomial with regard to) + kacoeff[0-3]: FM rate coefficients + (four coefficients of a third order polynomial with regard to) (range sample number. range sample number starts with zero) dopcoeff1[0-3]: Doppler centroid frequency coefficients of this image @@ -40,6 +43,9 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f (four coefficients of a third order polynomial with regard to) (range sample number. range sample number starts with zero) + byteorder: (0) LSB, little endian; (1) MSB, big endian of intput file + imageoffset: offset from start of the image of input file + lineoffset: length of each line of input file */ FILE *infp; @@ -54,7 +60,7 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f fcomplex *data; //data to be filtered. //int nrg; //file width - int naz; //file length + //int naz; //file length //float prf; //assume prf are the same //float prf_frac; // azimuth processed bandwidth = prf_frac * prf //float nb; //burst length in terms of pri. number of lines @@ -168,17 +174,36 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f printf("nboff: %f\n", nboff); printf("bsl: %f\n", bsl); - printf("kacoeff: %f, %f, %f\n", kacoeff[0], kacoeff[1], kacoeff[2]); + printf("kacoeff: %f, %f, %f, %f\n", kacoeff[0], kacoeff[1], kacoeff[2], kacoeff[3]); printf("dopcoeff1: %f, %f, %f, %f\n", dopcoeff1[0], dopcoeff1[1], dopcoeff1[2], dopcoeff1[3]); printf("dopcoeff2: %f, %f, %f, %f\n", dopcoeff2[0], dopcoeff2[1], dopcoeff2[2], dopcoeff2[3]); + if(byteorder == 0){ + printf("inputfile byte order: little endian\n"); + } + else{ + printf("inputfile byte order: big endian\n"); + } + printf("input file image offset [byte]: %ld\n", imageoffset); + printf("input file line offset [byte]: %ld\n", lineoffset); + if(imageoffset < 0){ + fprintf(stderr, "image offset must be >= 0\n"); + exit(1); + } + if(lineoffset < 0){ + fprintf(stderr, "lineoffset offset must be >= 0\n"); + exit(1); + } if(nfilter % 2 != 1){ fprintf(stderr, "filter length must be odd!\n"); exit(1); } - naz = file_length(infp, nrg, sizeof(fcomplex)); + //naz = file_length(infp, nrg, sizeof(fcomplex)); + //fseeko(infp,0L,SEEK_END); + //naz = (ftello(infp) - imageoffset) / (lineoffset + nrg*sizeof(fcomplex)); + //rewind(infp); printf("file width: %d, file length: %d\n\n", nrg, naz); @@ -216,14 +241,14 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f for(i = 0; i < nrg; i++){ //azimuth FM rate. we follow the convention ka > 0 - ka[i] = kacoeff[2] * i * i + kacoeff[1] * i + kacoeff[0]; + ka[i] = kacoeff[3] * i * i * i + kacoeff[2] * i * i + kacoeff[1] * i + kacoeff[0]; ka[i] = -ka[i]; //doppler centroid frequency dop1[i] = dopcoeff1[0] + dopcoeff1[1] * i + dopcoeff1[2] * i * i + dopcoeff1[3] * i * i * i; - dop1[i] *= prf; + //dop1[i] *= prf; dop2[i] = dopcoeff2[0] + dopcoeff2[1] * i + dopcoeff2[2] * i * i + dopcoeff2[3] * i * i * i; - dop2[i] *= prf; + //dop2[i] *= prf; //full aperture length nfa[i] = prf * prf_frac / ka[i] / pri; @@ -299,9 +324,47 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f } } - - //read in data - readdata((fcomplex *)in[0], (size_t)naz * (size_t)nrg * sizeof(fcomplex), infp); +/////////////////////////////////////////////////////////////////////////////////////// + //This section is for reading data + printf("reading data...\n"); + + //skip image header + fseek(infp, imageoffset, SEEK_SET); + + for(i = 0; i < naz; i++){ + if(i!=0) + fseek(infp, lineoffset-(size_t)nrg*sizeof(fcomplex), SEEK_CUR); + readdata((fcomplex *)in[i], (size_t)nrg * sizeof(fcomplex), infp); + } + + //read image data + //if(lineoffset == 0){ + // readdata((fcomplex *)in[0], (size_t)naz * (size_t)nrg * sizeof(fcomplex), infp); + //} + //else{ + // for(i = 0; i < naz; i++){ + // fseek(infp, lineoffset, SEEK_CUR); + // readdata((fcomplex *)in[i], (size_t)nrg * sizeof(fcomplex), infp); + // } + //} + + //swap bytes + if(byteorder!=0){ + printf("swapping bytes...\n"); + for(i = 0; i < naz; i++) + for(j = 0; j < nrg; j++){ + SWAP4(in[i][j].re); + SWAP4(in[i][j].im); + } + } + + int debug=0; + if(debug){ + printf("%f, %f\n", in[0][0].re, in[0][0].im); + printf("%f, %f\n", in[100][100].re, in[100][100].im); + printf("%f, %f\n", in[naz-1][nrg-1].re, in[naz-1][nrg-1].im); + } +/////////////////////////////////////////////////////////////////////////////////////// //initialize output data //for(j = 0; j < naz; j++){ @@ -311,7 +374,7 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f // } //} - + printf("filtering image...\n"); for(i = 0; i < nrg; i++){ if((i + 1) % 100 == 0 || (i+1) == nrg) @@ -566,6 +629,7 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f }//i: each column + printf("writing filtering result...\n"); writedata((fcomplex *)in[0], (size_t)naz * (size_t)nrg * sizeof(fcomplex), outfp); //free arrays @@ -590,9 +654,3 @@ int mbf(char *inputfile, char *outputfile, int nrg, float prf, float prf_frac, f return 0; }//end main() - - -////////////////////////////////////////////////////////////////////////////////////////////////////// - - - diff --git a/contrib/alos2proc/src/mosaicsubswath.c b/contrib/alos2proc/src/mosaicsubswath.c new file mode 100644 index 0000000..bd23ac5 --- /dev/null +++ b/contrib/alos2proc/src/mosaicsubswath.c @@ -0,0 +1,386 @@ +////////////////////////////////////// +// Cunren Liang, NASA JPL/Caltech +// Copyright 2017 +////////////////////////////////////// + + +// program for mosaicking multiple consecutive subswaths +// Cunren Liang, 03-JUN-2015 +// JPL/Caltech + +////////////////////////////////////////////////////////////////// +//update history +//12-APR-2016, CL. output data of both adjacent subswaths as BIL +// file, instead of output the difference. +////////////////////////////////////////////////////////////////// + + +#include "resamp.h" + +//int main(int argc, char *argv[]){ +int mosaicsubswath(char *outputfile, int nrgout, int nazout, int delta, int diffflag, int n, char **inputfile, int *nrgin, int *nrgoff, int *nazoff, float *phc, int *oflag){ + + FILE **infp; + FILE *outfp; + + fcomplex **in; + fcomplex *out, out1, out2; + //fcomplex *leftoverlap; + //fcomplex *rightoverlap; + fcomplex tmp; + int cnt; + + //int n; + //int *nrgin; + int *nazin; + //int *nrgoff; + //int *nazoff; + //int *oflag; + //int nrgout; + //int nazout; + int nrginmax; + + int los, loe, low; //start, end and width of left overlap area + int ros, roe, row; //start, end and width of right overlap area + int cnw; //width of center area + + int paroff; + int parcyc; + + char diffname[256][256]; + FILE **difffp; + fcomplex **diff; + fcomplex **diff2; + //int diffflag; + //diffflag = 0; + + int ns; + float r; + + int i, j, k, l; + + //int delta; //edge to be removed of the overlap area (number of samples) + //delta = 20; + + + // if(argc < 5){ + // fprintf(stderr, "\nUsage: %s outputfile nrgout nazout delta diffflag n [inputfile0] [nrgin0] [nrgoff0] [nazoff0] [oflag0] (repeat...)\n\n", argv[0]); + // fprintf(stderr, " for each frame\n"); + // fprintf(stderr, " range offset is relative to the first sample of last subswath\n"); + // fprintf(stderr, " azimuth offset is relative to the uppermost line\n\n"); + // exit(1); + // } + + + //read mandatory parameters + outfp = openfile(outputfile, "wb"); + //nrgout = atoi(argv[2]); + //nazout = atoi(argv[3]); + //delta = atoi(argv[4]); + //diffflag = atoi(argv[5]); + //n = atoi(argv[6]); + + + //allocate memory + infp = array1d_FILE(n); + //nrgin = array1d_int(n); + nazin = array1d_int(n); + //nrgoff = array1d_int(n); //nrgoff must be <= 0 + //nazoff = array1d_int(n); //nazoff must be <= 0 + //oflag = array1d_int(n); + + difffp = array1d_FILE(n - 1); + + //read optional parameters + paroff = 6; + parcyc = 5; + for(i = 0; i < n; i++){ + infp[i] = openfile(inputfile[i], "rb"); + //nrgin[i] = atoi(argv[paroff + parcyc*i + 2]); + //nrgoff[i] = atoi(argv[paroff + parcyc*i + 3]); + //nazoff[i] = atoi(argv[paroff + parcyc*i + 4]); + //oflag[i] = atoi(argv[paroff + parcyc*i + 5]); + nazin[i] = file_length(infp[i], nrgin[i], sizeof(fcomplex)); + if(nrgoff[i] > 0){ + fprintf(stderr,"Error: positive range offset: %d\n\n", nrgoff[i]); + exit(1); + } + if(nazoff[i] > 0){ + fprintf(stderr,"Error: positive azimuth offset: %d\n\n", nazoff[i]); + exit(1); + } + if(nazout < nazin[i] - nazoff[i]){ + fprintf(stderr,"Error: ouput length < nazin[%d] - nazoff[%d], %d, %d\n\n", i, i, nazout, nazin[i] - nazoff[i]); + exit(1); + } + } + + //find max width + nrginmax = nrgin[0]; + for(i = 0; i < n; i++) + if(nrgin[i] > nrginmax) + nrginmax = nrgin[i]; + + in = array2d_fcomplex(n, nrginmax); + out = array1d_fcomplex(nrgout); + //out1 = array1d_fcomplex(nrginmax); + //out2 = array1d_fcomplex(nrginmax); + diff = array2d_fcomplex(n-1, nrginmax); + diff2 = array2d_fcomplex(n-1, nrginmax); + + if(diffflag == 0) + for(i = 0; i < n - 1; i++){ + sprintf(diffname[i], "%d-%d.int", i, i+1); + difffp[i] = openfile(diffname[i], "wb"); + } + + + for(i = 0; i < nazout; i++){ + + if((i + 1) % 1000 == 0) + fprintf(stderr,"processing line: %6d of %6d\r", i + 1, nazout); + if(i + 1 == nazout) + fprintf(stderr,"processing line: %6d of %6d\n\n", i + 1, nazout); + + //prepare for writing data + for(j = 0; j < nrgout; j++){ + out[j].re = 0.0; + out[j].im = 0.0; + } + + //prepare for reading data + for(j = 0; j < n; j++){ + for(k = 0; k < nrginmax; k++){ + in[j][k].re = 0.0; + in[j][k].im = 0.0; + } + } + + for(j = 0; j < n; j++){ + if(i + nazoff[j] >= 0 && i + nazoff[j] <= nazin[j] - 1) + readdata((fcomplex *)in[j], nrgin[j] * sizeof(fcomplex), infp[j]); + + if(phc[j]!=0.0){ + tmp.re = cos(phc[j]); + tmp.im = sin(phc[j]); + for(k = 0; k < nrgin[j]; k++) + in[j][k] = cmul(in[j][k], tmp); + } + } + + + cnt = 0; + for(j = 0; j < n; j++){ + + //we follow the following convention: line and column number start with 0. + //left overlap area of subswath j + if(j != 0){ + los = - nrgoff[j]; + loe = nrgin[j-1] - 1; + low = loe - los + 1; + if(low < delta * 2){ + fprintf(stderr,"Error: not enough overlap area between subswath: %d and %d\n\n", j-1, j); + exit(1); + } + } + else{ + los = 0; + loe = 0; + low = 0; + } + + //right overlap area of subswath j + if(j != n - 1){ + ros = - nrgoff[j+1]; + roe = nrgin[j] - 1; + row = roe - ros + 1; + if(row < delta * 2){ + fprintf(stderr,"Error: not enough overlap area between subswath: %d and %d\n\n", j, j+1); + exit(1); + } + } + else{ + ros = 0; + roe = 0; + row = 0; + } + + //center non-overlap area of subswath j + //should add a check here? + cnw = nrgin[j] - low - row; + + //deal with center non-overlap area. + //this only excludes the right overlap area for the first subswath + //this only excludes the left overlap area for the last subswath + for(k = 0; k < cnw; k++){ + out[cnt + k].re = in[j][low + k].re; + out[cnt + k].im = in[j][low + k].im; + } + cnt += cnw; + + //deal with right overlap area of subswath j, which is also the left overlap area + //of subswath j + 1 (next subswath) + + //for last subswath, just skip + if(j == n - 1){ + break; + } + + + for(k = 0; k < nrginmax; k++){ + diff[j][k].re = 0.0; + diff[j][k].im = 0.0; + diff2[j][k].re = 0.0; + diff2[j][k].im = 0.0; + } + + for(k = 0; k < row; k++){ + + + out1.re = in[j][low + cnw + k].re; + out1.im = in[j][low + cnw + k].im; + out2.re = in[j+1][k].re; + out2.im = in[j+1][k].im; + + //left edge of overlap area + //use current subswath: subswath j + if(k < delta){ + out[cnt + k].re = out1.re; + out[cnt + k].im = out1.im; + } + else if(k >= delta && k < row - delta){ + + //output difference of overlap area + //diffflag 0: subswath j phase - subswath j+1 phase + if(diffflag == 0){ + if(out1.re != 0.0 && out1.im != 0.0 && out2.re != 0.0 && out2.im != 0.0){ + //diff[j][k - delta] = cmul(out1, cconj(out2)); + diff[j][k - delta] = out1; + diff2[j][k - delta] = out2; + } + } + //diffflag 1: subswath j - subswath j+1 + //else if(diffflag == 1){ + // if(out1.re != 0.0 && out1.im != 0.0 && out2.re != 0.0 && out2.im != 0.0){ + // diff[j][k - delta].re = out1.re - out2.re; + // diff[j][k - delta].im = out1.im - out2.im; + // } + //} + else{ + ; + } + + //mosaic overlap area + //case 0: mosaic at the center of overlap area + if(oflag[j] == 0){ + if(k < row / 2){ + //avoid holes, Cunren Liang, Dec. 18, 2015. + if(out1.re != 0.0 && out1.im != 0.0){ + out[cnt + k].re = out1.re; + out[cnt + k].im = out1.im; + } + else{ + out[cnt + k].re = out2.re; + out[cnt + k].im = out2.im; + } + } + else{ + //avoid holes, Cunren Liang, Dec. 18, 2015. + if(out2.re != 0.0 && out2.im != 0.0){ + out[cnt + k].re = out2.re; + out[cnt + k].im = out2.im; + } + else{ + out[cnt + k].re = out1.re; + out[cnt + k].im = out1.im; + } + } + } + //case 1: mosaic at the right egde of overlap area + else if(oflag[j] == 1){ + out[cnt + k].re = out1.re; + out[cnt + k].im = out1.im; + } + //case 2: mosaic at the left edge of overlap area + else if(oflag[j] == 2){ + out[cnt + k].re = out2.re; + out[cnt + k].im = out2.im; + } + //case 3: add overlap area + else if(oflag[j] == 3){ + out[cnt + k].re = out1.re + out2.re; + out[cnt + k].im = out1.im + out2.im; + + if(out1.re != 0.0 && out1.im != 0.0 && out2.re != 0.0 && out2.im != 0.0){ + out[cnt + k].re /= 2.0; + out[cnt + k].im /= 2.0; + } + + } + //case 4: add by weight determined by distance to overlap center + //perform overlapp area smoothing using a method discribed in: + //C. Liang, Q. Zeng, J. Jia, J. Jiao, and X. Cui, ScanSAR interferometric processing + //using existing standard InSAR software for measuring large scale land deformation + //Computers & Geosciences, 2013. + else{ + l = k - delta + 1; // l start with 1 + ns = row - 2 * delta; + + if(out1.re != 0.0 && out1.im != 0.0 && out2.re != 0.0 && out2.im != 0.0){ + r = sqrt((out1.re * out1.re + out1.im * out1.im) / (out2.re * out2.re + out2.im * out2.im)); + out[cnt + k].re = ((ns - l + 0.5) * out1.re + r * (l - 0.5) * out2.re) / ns; + out[cnt + k].im = ((ns - l + 0.5) * out1.im + r * (l - 0.5) * out2.im) / ns; + } + else{ + out[cnt + k].re = out1.re + out2.re; + out[cnt + k].im = out1.im + out2.im; + } + } + //cnt += row - 2 * delta; + } + //right edge of overlap area + //use next subswath: subswath j+1 + //else if(k >= row - delta){ + else{ + out[cnt + k].re = out2.re; + out[cnt + k].im = out2.im; + } + //cnt += 1; + } + cnt += row; + + if(diffflag == 0){ + writedata((fcomplex *)diff[j], (row - 2 * delta) * sizeof(fcomplex), difffp[j]); + writedata((fcomplex *)diff2[j], (row - 2 * delta) * sizeof(fcomplex), difffp[j]); + } + + } //loop of j, subswath + writedata((fcomplex *)out, nrgout * sizeof(fcomplex), outfp); + } //loop of i, output line + + for(i = 0; i < n; i++) + fclose(infp[i]); + fclose(outfp); + + if(diffflag == 0) + for(i = 0; i < n - 1; i++) + fclose(difffp[i]); + + free_array1d_FILE(infp); + free_array1d_FILE(difffp); + + free_array2d_fcomplex(in); + free_array1d_fcomplex(out); + + //free_array1d_int(nrgin); + free_array1d_int(nazin); + //free_array1d_int(nrgoff); //nrgoff must be <= 0 + //free_array1d_int(nazoff); //nazoff must be <= 0 + //free_array1d_int(oflag); + + free_array2d_fcomplex(diff); + free_array2d_fcomplex(diff2); + + return 0; + +} diff --git a/contrib/alos2proc/src/resamp.c b/contrib/alos2proc/src/resamp.c new file mode 100644 index 0000000..0ada755 --- /dev/null +++ b/contrib/alos2proc/src/resamp.c @@ -0,0 +1,401 @@ +////////////////////////////////////// +// Cunren Liang, NASA JPL/Caltech +// Copyright 2017 +////////////////////////////////////// +//update: add default value azpos_off = 0.0; 12-DEC-2019 +//update: normalization of resampling kernals. 12-DEC-2019 + + +#include "resamp.h" + +#define SWAP4(a) (*(unsigned int *)&(a) = (((*(unsigned int *)&(a) & 0x000000ff) << 24) | ((*(unsigned int *)&(a) & 0x0000ff00) << 8) | ((*(unsigned int *)&(a) >> 8) & 0x0000ff00) | ((*(unsigned int *)&(a) >> 24) & 0x000000ff))) + +void normalize_kernel(float *kernel, long start_index, long end_index); + +int resamp(char *slc2, char *rslc2, char *rgoff_file, char *azoff_file, int nrg1, int naz1, int nrg2, int naz2, float prf, float *dopcoeff, float *rgcoef, float *azcoef, float azpos_off, int byteorder, long imageoffset, long lineoffset, int verbose){ + /* + mandatory: + slc2: slave image + rslc2: resampled slave image + rgoff_file: range offset file. if no range offset file, specify fake + azoff_file: azimuth offset file. if no azimuth offset file, specify fake + nrg1: number of columns in master image + naz1: number of lines in master image + nrg2: number of columns in slave image + naz2: number of lines in slave image + prf: PRF of slave image + dopcoeff[0]-[3]: Doppler centroid frequency coefficents + optional: + rgcoef[0]-[9]: range offset polynomial coefficents. First of two fit results of resamp_roi + azcoef[0]-[9]: azimuth offset polynomial coefficents. First of two fit results of resamp_roi + azpos_off: azimuth position offset. Azimuth line number (column 3) of first offset in culled offset file + + byteorder: (0) LSB, little endian; (1) MSB, big endian of intput file + imageoffset: offset from start of the image of input file + lineoffset: length of each line of input file + */ + + FILE *slc2fp; + FILE *rslc2fp; + FILE *rgoffp; + FILE *azoffp; + int rgflag; + int azflag; + //int nrg1; + //int naz1; + //int nrg2; + //int naz2; + //float prf; + //float dopcoeff[4]; + //float rgcoef[10]; + //float azcoef[10]; + //float azpos_off; + float beta; + int n; + int m; + int interp_method; + int edge_method; + float rgpos; + float azpos; + float rgoff; + float azoff; + float rgoff1; + float azoff1; + float *rgoff2; + float *azoff2; + float rg2; + float az2; + int rgi2; + int azi2; + float rgf; + float azf; + int rgfn; + int azfn; + int hnm; + int hn; + float *sincc; + float *kaiserc; + float *kernel; + float *rgkernel; + float *azkernel; + fcomplex *azkernel_fc; + fcomplex *rgrs; + fcomplex *azca; + fcomplex *rgrsb; + fcomplex *azrs; + float *dop; + float dopx; + fcomplex **inb; + int i, j, k, k1, k2; + int tmp1, tmp2; + int zero_flag; + float ftmp1, ftmp2; + fcomplex fctmp1, fctmp2; + beta = 2.5; + n = 9; + m = 10000; + interp_method = 0; + edge_method = 0; + + + slc2fp = openfile(slc2, "rb"); + rslc2fp = openfile(rslc2, "wb"); + rgflag = 0; + azflag = 0; + if (strcmp(rgoff_file, "fake") == 0){ + rgflag = 0; + printf("range offset file not provided\n"); + } + else{ + rgflag = 1; + rgoffp = openfile(rgoff_file, "rb"); + } + if (strcmp(azoff_file, "fake") == 0){ + azflag = 0; + printf("azimuth offset file not provided\n"); + } + else{ + azflag = 1; + azoffp = openfile(azoff_file, "rb"); + } + //nrg1 = atoi(argv[5]); + //naz1 = atoi(argv[6]); + //nrg2 = atoi(argv[7]); + //naz2 = atoi(argv[8]); + //prf = atof(argv[9]); + //for(i = 0; i < 4; i++){ + // dopcoeff[i] = atof(argv[10+i]); + //} + //for(i = 0; i < 10; i++){ + // if(argc > 14 + i) + // rgcoef[i] = atof(argv[14+i]); + // else + // rgcoef[i] = 0.0; + //} + //for(i = 0; i < 10; i++){ + // if(argc > 24 + i) + // azcoef[i] = atof(argv[24+i]); + // else + // azcoef[i] = 0.0; + //} + //if(argc > 34) + // azpos_off = atof(argv[34]); + //else + // azpos_off = 0.0; + if(verbose != 0){ + printf("\n\ninput parameters:\n"); + printf("slc2: %s\n", slc2); + printf("rslc2: %s\n", rslc2); + printf("rgoff_file: %s\n", rgoff_file); + printf("azoff_file: %s\n\n", azoff_file); + printf("nrg1: %d\n", nrg1); + printf("naz1: %d\n", naz1); + printf("nrg2: %d\n", nrg2); + printf("naz2: %d\n\n", naz2); + printf("prf: %f\n\n", prf); + for(i = 0; i < 4; i++){ + printf("dopcoeff[%d]: %e\n", i, dopcoeff[i]); + } + printf("\n"); + for(i = 0; i < 10; i++){ + printf("rgcoef[%d]: %e\n", i, rgcoef[i]); + } + printf("\n"); + for(i = 0; i < 10; i++){ + printf("azcoef[%d]: %e\n", i, azcoef[i]); + } + printf("\n"); + printf("azpos_off: %f\n\n", azpos_off); + + if(byteorder == 0){ + printf("inputfile byte order: little endian\n"); + } + else{ + printf("inputfile byte order: big endian\n"); + } + printf("input file image offset [byte]: %ld\n", imageoffset); + printf("input file line offset [byte]: %ld\n", lineoffset); + } + + if(imageoffset < 0){ + fprintf(stderr, "image offset must be >= 0\n"); + exit(1); + } + if(lineoffset < 0){ + fprintf(stderr, "lineoffset offset must be >= 0\n"); + exit(1); + } + +hn = n / 2; +hnm = n * m / 2; +rgoff2 = array1d_float(nrg1); +azoff2 = array1d_float(nrg1); +sincc = vector_float(-hnm, hnm); +kaiserc = vector_float(-hnm, hnm); +kernel = vector_float(-hnm, hnm); +rgkernel = vector_float(-hn, hn); +azkernel = vector_float(-hn, hn); +azkernel_fc = vector_fcomplex(-hn, hn); +rgrs = vector_fcomplex(-hn, hn); +azca = vector_fcomplex(-hn, hn); +rgrsb = vector_fcomplex(-hn, hn); +azrs = array1d_fcomplex(nrg1); +dop = array1d_float(nrg2); +inb = array2d_fcomplex(naz2, nrg2); +sinc(n, m, sincc); +kaiser(n, m, kaiserc, beta); +for(i = -hnm; i <= hnm; i++) + kernel[i] = kaiserc[i] * sincc[i]; +if(verbose != 0) +printf("\n"); +for(i = 0; i < nrg2; i++){ + dop[i] = dopcoeff[0] + dopcoeff[1] * i + dopcoeff[2] * i * i + dopcoeff[3] * i * i * i; + //get rid of this bad convention from roi_pac + //dop[i] *= prf; + if(verbose != 0) + if(i % 500 == 0) + printf("range sample: %5d, doppler centroid frequency: %8.2f Hz\n", i, dop[i]); +} +if(verbose != 0) +printf("\n"); + +////////////////////////////////////////////////////////////////////////////////////////////// +//skip image header +fseek(slc2fp, imageoffset, SEEK_SET); + +for(i = 0; i < naz2; i++){ + if(i!=0) + fseek(slc2fp, lineoffset - (size_t)nrg2 * sizeof(fcomplex), SEEK_CUR); + readdata((fcomplex *)inb[i], (size_t)nrg2 * sizeof(fcomplex), slc2fp); +} + +//read image data +//if(lineoffset == 0){ +// readdata((fcomplex *)inb[0], (size_t)naz2 * (size_t)nrg2 * sizeof(fcomplex), slc2fp); +//} +//else{ +// for(i = 0; i < naz2; i++){ +// fseek(slc2fp, lineoffset, SEEK_CUR); +// readdata((fcomplex *)inb[i], (size_t)nrg2 * sizeof(fcomplex), slc2fp); +// } +//} +//swap bytes +if(byteorder!=0){ + printf("swapping bytes...\n"); + for(i = 0; i < naz2; i++) + for(j = 0; j < nrg2; j++){ + SWAP4(inb[i][j].re); + SWAP4(inb[i][j].im); + } +} +////////////////////////////////////////////////////////////////////////////////////////////// + +for(i = 0; i < naz1; i++){ + if((i + 1) % 100 == 0) + fprintf(stderr,"processing line: %6d of %6d\r", i+1, naz1); + if (rgflag == 1){ + readdata((float *)rgoff2, nrg1 * sizeof(float), rgoffp); + } + if (azflag == 1){ + readdata((float *)azoff2, nrg1 * sizeof(float), azoffp); + } + for(j = 0; j < nrg1; j++){ + azrs[j].re = 0.0; + azrs[j].im = 0.0; + } + for(j = 0; j < nrg1; j++){ + rgpos = j; + azpos = i - azpos_off; + rgoff1 = rgcoef[0] + azpos*(rgcoef[2] + \ + azpos*(rgcoef[5] + azpos*rgcoef[9])) + \ + rgpos*(rgcoef[1] + rgpos*(rgcoef[4] + \ + rgpos*rgcoef[8])) + \ + rgpos*azpos*(rgcoef[3] + azpos*rgcoef[6] + \ + rgpos*rgcoef[7]); + azoff1 = azcoef[0] + azpos*(azcoef[2] + \ + azpos*(azcoef[5] + azpos*azcoef[9])) + \ + rgpos*(azcoef[1] + rgpos*(azcoef[4] + \ + rgpos*azcoef[8])) + \ + rgpos*azpos*(azcoef[3] + azpos*azcoef[6] + \ + rgpos*azcoef[7]); + if (rgflag == 1){ + rgoff = rgoff1 + rgoff2[j]; + } + else{ + rgoff = rgoff1; + } + if (azflag == 1){ + azoff = azoff1 + azoff2[j]; + } + else{ + azoff = azoff1; + } + rg2 = j + rgoff; + az2 = i + azoff; + rgi2 = roundfi(rg2); + azi2 = roundfi(az2); + rgf = rg2 - rgi2; + azf = az2 - azi2; + rgfn = roundfi(rgf * m); + azfn = roundfi(azf * m); + for(k = -hn; k <= hn; k++){ + tmp1 = k * m - rgfn; + tmp2 = k * m - azfn; + if(tmp1 > hnm) tmp1 = hnm; + if(tmp2 > hnm) tmp2 = hnm; + if(tmp1 < -hnm) tmp1 = -hnm; + if(tmp2 < -hnm) tmp2 = -hnm; + rgkernel[k] = kernel[tmp1]; + azkernel[k] = kernel[tmp2]; + } + normalize_kernel(rgkernel, -hn, hn); + normalize_kernel(azkernel, -hn, hn); + for(k1 = -hn; k1 <= hn; k1++){ + rgrs[k1].re = 0.0; + rgrs[k1].im = 0.0; + if(edge_method == 0){ + if(azi2 < hn || azi2 > naz2 - 1 - hn || rgi2 < hn || rgi2 > nrg2 - 1 - hn){ + continue; + } + } + else if(edge_method == 1){ + if(azi2 < 0 || azi2 > naz2 - 1 || rgi2 < 0 || rgi2 > nrg2 - 1){ + continue; + } + } + else{ + if(azi2 < -hn || azi2 > naz2 - 1 + hn || rgi2 < -hn || rgi2 > nrg2 - 1 + hn){ + continue; + } + } + for(k2 = -hn; k2 <= hn; k2++){ + if(azi2 + k1 < 0 || azi2 + k1 > naz2 - 1 || rgi2 + k2 < 0 || rgi2 + k2 > nrg2 - 1) + continue; + rgrs[k1].re += inb[azi2 + k1][rgi2 + k2].re * rgkernel[k2]; + rgrs[k1].im += inb[azi2 + k1][rgi2 + k2].im * rgkernel[k2]; + } + } + for(k = -hn; k <= hn; k++){ + if(rgrs[k].re == 0.0 && rgrs[k].im == 0.0) + continue; + dopx = dopcoeff[0] + dopcoeff[1] * rg2 + dopcoeff[2] * rg2 * rg2 + dopcoeff[3] * rg2 * rg2 * rg2; + //get rid of this bad convention from roi_pac + //dopx *= prf; + ftmp1 = 2.0 * PI * dopx * k / prf; + azca[k].re = cos(ftmp1); + azca[k].im = sin(ftmp1); + if(interp_method == 0){ + rgrsb[k] = cmul(rgrs[k], cconj(azca[k])); + azrs[j].re += rgrsb[k].re * azkernel[k]; + azrs[j].im += rgrsb[k].im * azkernel[k]; + } + else{ + azkernel_fc[k].re = azca[k].re * azkernel[k]; + azkernel_fc[k].im = azca[k].im * azkernel[k]; + azrs[j] = cadd(azrs[j], cmul(rgrs[k], azkernel_fc[k])); + } + } + if(interp_method == 0){ + ftmp1 = 2.0 * PI * dopx * azf / prf; + fctmp1.re = cos(ftmp1); + fctmp1.im = sin(ftmp1); + azrs[j] = cmul(azrs[j], fctmp1); + } + } + writedata((fcomplex *)azrs, nrg1 * sizeof(fcomplex), rslc2fp); +} +fprintf(stderr,"processing line: %6d of %6d\n", naz1, naz1); +free_array1d_float(rgoff2); +free_array1d_float(azoff2); +free_vector_float(sincc, -hnm, hnm); +free_vector_float(kaiserc, -hnm, hnm); +free_vector_float(kernel, -hnm, hnm); +free_vector_float(rgkernel, -hn, hn); +free_vector_float(azkernel, -hn, hn); +free_vector_fcomplex(azkernel_fc, -hn, hn); +free_vector_fcomplex(rgrs, -hn, hn); +free_vector_fcomplex(azca, -hn, hn); +free_vector_fcomplex(rgrsb, -hn, hn); +free_array1d_fcomplex(azrs); +free_array1d_float(dop); +free_array2d_fcomplex(inb); +fclose(slc2fp); +fclose(rslc2fp); +if (rgflag == 1){ + fclose(rgoffp); +} +if (azflag == 1){ + fclose(azoffp); +} +return 0; +} +void normalize_kernel(float *kernel, long start_index, long end_index){ + double sum; + long i; + sum = 0.0; + for(i = start_index; i <= end_index; i++) + sum += kernel[i]; + if(sum!=0) + for(i = start_index; i <= end_index; i++) + kernel[i] /= sum; +} diff --git a/contrib/alos2proc/src/rg_filter.c b/contrib/alos2proc/src/rg_filter.c index 6017366..224047b 100644 --- a/contrib/alos2proc/src/rg_filter.c +++ b/contrib/alos2proc/src/rg_filter.c @@ -8,8 +8,9 @@ #include #include +#define SWAP4(a) (*(unsigned int *)&(a) = (((*(unsigned int *)&(a) & 0x000000ff) << 24) | ((*(unsigned int *)&(a) & 0x0000ff00) << 8) | ((*(unsigned int *)&(a) >> 8) & 0x0000ff00) | ((*(unsigned int *)&(a) >> 24) & 0x000000ff))) -int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, float *bc, int nfilter, int nfft, float beta, int zero_cf, float offset){ +int rg_filter(char *inputfile, int nrg, int naz, int nout, char **outputfile, float *bw, float *bc, int nfilter, int nfft, float beta, int zero_cf, float offset, int byteorder, long imageoffset, long lineoffset){ /* inputfile: input file nrg file width @@ -23,6 +24,10 @@ int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, beta: kaiser window beta. Reference Value: 1.0 zero_cf: if bc != 0.0, move center frequency to zero? 0: Yes (Reference Value). 1: No. offset: offset (in samples) of linear phase for moving center frequency. Reference Value: 0.0 + + byteorder: (0) LSB, little endian; (1) MSB, big endian of intput file + imageoffset: offset from start of the image of input file + lineoffset: length of each line of input file */ /////////////////////////////// @@ -64,7 +69,7 @@ int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, //int nout; //number of output files //int nrg; //file width - int naz; //file length + //int naz; //file length //int nfft; //fft length //int nfilter; //filter length @@ -107,7 +112,10 @@ int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, /*****************************************************************************/ infp = openfile(inputfile, "rb"); - naz = file_length(infp, nrg, sizeof(fcomplex)); + //naz = file_length(infp, nrg, sizeof(fcomplex)); + //fseeko(infp,0L,SEEK_END); + //naz = (ftello(infp) - imageoffset) / (lineoffset + nrg*sizeof(fcomplex)); + //rewind(infp); printf("file width: %d, file length: %d\n\n", nrg, naz); if(nout < 1){ fprintf(stderr, "there should be at least one output file!\n"); @@ -128,6 +136,23 @@ int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, exit(1); } + if(byteorder == 0){ + printf("inputfile byte order: little endian\n"); + } + else{ + printf("inputfile byte order: big endian\n"); + } + printf("input file image offset [byte]: %ld\n", imageoffset); + printf("input file line offset [byte]: %ld\n", lineoffset); + if(imageoffset < 0){ + fprintf(stderr, "image offset must be >= 0\n"); + exit(1); + } + if(lineoffset < 0){ + fprintf(stderr, "lineoffset offset must be >= 0\n"); + exit(1); + } + //compute block processing parameters hnfilter = (nfilter - 1) / 2; nblock_in = nfft - nfilter + 1; @@ -211,6 +236,11 @@ int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, } fftwf_destroy_plan(p_forward_filter); + + //skip image header + if(imageoffset != 0) + fseek(infp, imageoffset, SEEK_SET); + //process data for(i = 0; i < naz; i++){ //progress report @@ -220,7 +250,17 @@ int rg_filter(char *inputfile, int nrg, int nout, char **outputfile, float *bw, fprintf(stderr,"\n\n"); //read data + if(i != 0) + fseek(infp, lineoffset-(size_t)nrg * sizeof(fcomplex), SEEK_CUR); readdata((fcomplex *)in, (size_t)nrg * sizeof(fcomplex), infp); + //swap bytes + if(byteorder!=0){ + for(j = 0; j < nrg; j++){ + SWAP4(in[j].re); + SWAP4(in[j].im); + } + } + #pragma omp parallel for private(j) shared(nrg,in, zeroflag, sc) for(j = 0; j < nrg; j++){ if(in[j].re != 0.0 || in[j].im != 0.0){ diff --git a/contrib/alos2proc_f/SConscript b/contrib/alos2proc_f/SConscript new file mode 100644 index 0000000..50b46a3 --- /dev/null +++ b/contrib/alos2proc_f/SConscript @@ -0,0 +1,23 @@ +#!/usr/bin/env python +import os +import sys + +Import('envcontrib') +envalos2procF = envcontrib.Clone() +package = envalos2procF['PACKAGE'] # 'contrib' +project = 'alos2proc_f' +envalos2procF['PROJECT'] = project +Export('envalos2procF') + +SConscript('src/SConscript', variant_dir = os.path.join(envalos2procF['PRJ_SCONS_BUILD'],package,project,'src')) +SConscript('include/SConscript') + +if envalos2procF['CYTHON3']: + print("cython3 found.") + SConscript('pyx/SConscript') +else: + print("cython3 is required to build the alos2proc_f bindings.") + print("The alos2proc_f bindings will not be built. Please install cython3.") + +install_main = os.path.join(envalos2procF['PRJ_SCONS_INSTALL'], package, project) +envalos2procF.Install(install_main,'__init__.py') diff --git a/contrib/alos2proc_f/__init__.py b/contrib/alos2proc_f/__init__.py new file mode 100644 index 0000000..5f7ce86 --- /dev/null +++ b/contrib/alos2proc_f/__init__.py @@ -0,0 +1 @@ +#!/usr/bin/env python3 \ No newline at end of file diff --git a/contrib/alos2proc_f/include/SConscript b/contrib/alos2proc_f/include/SConscript new file mode 100644 index 0000000..b4a1ace --- /dev/null +++ b/contrib/alos2proc_f/include/SConscript @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import os + +Import('envalos2procF') +build = os.path.join(envalos2procF['PRJ_SCONS_BUILD'], envalos2procF['PACKAGE'], 'alos2proc_f', 'include') +envalos2procF.AppendUnique(CPPPATH = [build]) +envalos2procF.Install(build, ['alos2proc_f.h']) +envalos2procF.Alias('install',build) diff --git a/contrib/alos2proc_f/include/alos2proc_f.h b/contrib/alos2proc_f/include/alos2proc_f.h new file mode 100644 index 0000000..510d4fd --- /dev/null +++ b/contrib/alos2proc_f/include/alos2proc_f.h @@ -0,0 +1,21 @@ +#ifndef __ALOS2_F_H__ +#define __ALOS2_F_H__ + +// define the C binding interfaces +#ifdef __cplusplus +extern "C" { +#endif + +void c_fitoff(const char *, const char *, const double *, const double *, const int *); +void c_rect(const char *, const char *, const int *, const int *, const int *, const int *, + const double *, const double *, const double *, const double *, const double *, const double *, + const char *, const char *); +void c_rect_with_looks(const char *, const char *, const int *, const int *, const int *, const int *, + const double *, const double *, const double *, const double *, const double *, const double *, + const int *, const int *, const int *, const int *, + const char *, const char *); +#ifdef __cplusplus +} +#endif + +#endif // __ALOS2_F_H__ diff --git a/contrib/alos2proc_f/pyx/SConscript b/contrib/alos2proc_f/pyx/SConscript new file mode 100644 index 0000000..0fc9d3f --- /dev/null +++ b/contrib/alos2proc_f/pyx/SConscript @@ -0,0 +1,35 @@ +#!/usr/bin/env python + +import os + +Import('envalos2procF') +package = envalos2procF['PACKAGE'] # 'library' +project = envalos2procF['PROJECT'] # 'isceLib' +build = envalos2procF['PRJ_LIB_DIR'] + +envalos2procF['CMAKE_CXX_STANDARD'] = '11' + +install_main = os.path.join(envalos2procF['PRJ_SCONS_INSTALL'], package, project) +install_src = os.path.join(install_main, 'src') # location of the built object files +install_pyx = os.path.join(install_main, 'pyx') # location of the Cythonizing outputs + +envalos2procF.Append(CXXFLAGS=['-fopenmp', '-O3']) + +pyx_files=['alos2proc_f.pyx'] + +a = envalos2procF.Command(os.path.join(install_pyx,'alos2proc_f.cc'), 'alos2proc_f.pyx', 'cython3 $SOURCE -o $TARGET --cplus') # Cythonize the alos2proc_f.pyx file to the install dir +b = envalos2procF.SharedObject(target=os.path.join(install_pyx,'alos2proc_f.o'), source=os.path.join(install_pyx,'alos2proc_f.cc')) # Build the Cythonized alos2proc_f.pyx + +objs_with_paths = [] +objs_with_paths.append(os.path.join(install_pyx,'alos2proc_f.o')) # Add newly-Cythonized alos2proc_f.pyx object + +libList = ['libalos2proc_f'] +envalos2procF.PrependUnique(LIBS = libList) + +# Build Python module from shared objects +c = envalos2procF.LoadableModule(target=os.path.join(install_main,'alos2proc_f.abi3.so'), source=objs_with_paths) + +# Use Depends() command to make sure that changing the .pyx files rebuilds the Python module +Depends(a, pyx_files) # Re-Cythonize alos2proc_f.pyx +Depends(b, pyx_files) # Rebuild alos2proc_f.o +Depends(c, pyx_files) # Rebuild alos2proc_f Python module diff --git a/contrib/alos2proc_f/pyx/alos2proc_f.pyx b/contrib/alos2proc_f/pyx/alos2proc_f.pyx new file mode 100644 index 0000000..f6a2004 --- /dev/null +++ b/contrib/alos2proc_f/pyx/alos2proc_f.pyx @@ -0,0 +1,32 @@ +#include "alos2proc_f.h" + +cdef extern from "alos2proc_f.h": + void c_fitoff(const char *, const char *, const double *, const double *, const int *); + void c_rect(const char *, const char *, const int *, const int *, const int *, const int *, + const double *, const double *, const double *, const double *, const double *, const double *, + const char *, const char *); + void c_rect_with_looks(const char *, const char *, const int *, const int *, const int *, const int *, + const double *, const double *, const double *, const double *, const double *, const double *, + const int *, const int *, const int *, const int *, + const char *, const char *); + + +def fitoff(str infile, str outfile, double nsig, double maxrms, int minpoint): + c_fitoff(infile.encode(), outfile.encode(), &nsig, &maxrms, &minpoint) + return + +def rect(str infile, str outfile, int ndac, int nddn, int nrac, int nrdn, + double a, double b, double c, double d, double e, double f, + str filetype, str intstyle): + c_rect(infile.encode(), outfile.encode(), &ndac, &nddn, &nrac, &nrdn, + &a, &b, &c, &d, &e, &f, filetype.encode(), intstyle.encode()) + return + +def rect_with_looks(str infile, str outfile, int ndac, int nddn, int nrac, int nrdn, + double a, double b, double c, double d, double e, double f, + int lac, int ldn, int lac0, int ldn0, + str filetype, str intstyle): + c_rect_with_looks(infile.encode(), outfile.encode(), &ndac, &nddn, &nrac, &nrdn, + &a, &b, &c, &d, &e, &f, &lac, &ldn, &lac0, &ldn0, + filetype.encode(), intstyle.encode()) + return diff --git a/contrib/alos2proc_f/src/SConscript b/contrib/alos2proc_f/src/SConscript new file mode 100644 index 0000000..1b94644 --- /dev/null +++ b/contrib/alos2proc_f/src/SConscript @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +import os + +Import('envalos2procF') +build = envalos2procF['PRJ_LIB_DIR'] + +listFiles = ['bilinear.f', 'curvature.f', 'interp.f', 'lincomb.f', 'matvec.f', + 'rect.f', 'convert_sch_to_xyz.f', 'enubasis.f', 'intpcoefnorm.f', + 'look_coord_conv.f', 'norm.f', 'rect_with_looks.f', 'tranmat.f', + 'cross.f', 'fitoff.f', 'latlon.f', 'matmat.f', 'radar_to_xyz.f', + 'schbasis.f', 'cbind.f90'] + +lib = envalos2procF.Library(target = 'libalos2proc_f', source = listFiles, SHLIBPREFIX='') +envalos2procF.Install(build,lib) +envalos2procF.Alias('install',build) diff --git a/contrib/alos2proc_f/src/bilinear.f b/contrib/alos2proc_f/src/bilinear.f new file mode 100644 index 0000000..35156e2 --- /dev/null +++ b/contrib/alos2proc_f/src/bilinear.f @@ -0,0 +1,74 @@ + subroutine bilinear(r_pnt1,r_pnt2,r_pnt3,r_pnt4,r_x,r_y,r_h) + +c**************************************************************** +c** +c** FILE NAME: bilinear.for +c** +c** DATE WRITTEN: 2/16/91 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION:This routine will take four points +c** and do a bilinear interpolation to get the value for a point +c** assumed to lie in the interior of the 4 points. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real r_pnt1(3) !point in quadrant 1 + real r_pnt2(3) !point in quadrant 2 + real r_pnt3(3) !point in quadrant 3 + real r_pnt4(3) !point in quadrant 4 + real r_x !x coordinate of point + real r_y !y coordinate of point + +c OUTPUT VARIABLES: + real r_h !interpolated vaule + +c LOCAL VARIABLES: + real r_t1,r_t2,r_h1b,r_h2b,r_y1b,r_y2b + real r_diff + +c DATA STATEMENTS:none + +C FUNCTION STATEMENTS:none + +c PROCESSING STEPS: + +c first find interpolation points in x direction + + r_diff=(r_pnt2(1)-r_pnt1(1)) + if ( r_diff .ne. 0 ) then + r_t1 = (r_x - r_pnt1(1))/r_diff + else + r_t1 = r_pnt1(1) + endif + r_diff=(r_pnt4(1)-r_pnt3(1)) + if ( r_diff .ne. 0 ) then + r_t2 = (r_x - r_pnt3(1))/r_diff + else + r_t2 = r_pnt4(1) + endif + r_h1b = (1.-r_t1)*r_pnt1(3) + r_t1*r_pnt2(3) + r_h2b = (1.-r_t2)*r_pnt3(3) + r_t2*r_pnt4(3) + +c now interpolate in y direction + + r_y1b = r_t1*(r_pnt2(2)-r_pnt1(2)) + r_pnt1(2) + r_y2b = r_t2*(r_pnt4(2)-r_pnt3(2)) + r_pnt3(2) + + r_diff=r_y2b-r_y1b + if ( r_diff .ne. 0 ) then + r_h = ((r_h2b-r_h1b)/r_diff)*(r_y-r_y1b) + r_h1b + else + r_h = r_y2b + endif + end diff --git a/contrib/alos2proc_f/src/cbind.f90 b/contrib/alos2proc_f/src/cbind.f90 new file mode 100644 index 0000000..cf5ece2 --- /dev/null +++ b/contrib/alos2proc_f/src/cbind.f90 @@ -0,0 +1,42 @@ +!**************************************************************** +!** Fortran interfaces for C binding +!**************************************************************** + + subroutine c_fitoff(infile,outfile,nsig,maxrms,minpoint) bind(c, name="c_fitoff") + use iso_c_binding, only : c_double, c_char, c_int + implicit none + external fitoff + + ! input parameters + character(kind=c_char), dimension(*), intent(in) :: infile, outfile + real(kind=c_double), intent(in) :: nsig, maxrms + integer(kind=c_int), intent(in) :: minpoint + + ! call + call fitoff(infile,outfile,nsig,maxrms,minpoint) + end subroutine + + subroutine c_rect(infile,outfile,ndac,nddn,nrac,nrdn,a,b,c,d,e,f,filetype,intstyle) bind(c, name="c_rect") + use iso_c_binding, only : c_double, c_char, c_int + implicit none + external rect + + character(kind=c_char), dimension(*), intent(in) :: infile, outfile, intstyle, filetype + integer(kind=c_int), intent(in) :: ndac, nddn, nrac, nrdn + real(kind=c_double), intent(in) :: a,b,c,d,e,f + + call rect(infile,outfile,ndac,nddn,nrac,nrdn,a,b,c,d,e,f,filetype,intstyle) + end subroutine + + subroutine c_rect_with_looks(infile,outfile,ndac,nddn,nrac,nrdn,a,b,c,d,e,f,lac,ldn,lac0,ldn0,filetype,intstyle) bind(c, name="c_rect_with_looks") + use iso_c_binding, only : c_double, c_char, c_int + implicit none + external rect_with_looks + + character(kind=c_char), dimension(*), intent(in) :: infile, outfile, intstyle, filetype + integer(kind=c_int), intent(in) :: ndac, nddn, nrac, nrdn + real(kind=c_double), intent(in) :: a,b,c,d,e,f + integer(kind=c_int), intent(in) :: lac, ldn, lac0, ldn0 + + call rect_with_looks(infile,outfile,ndac,nddn,nrac,nrdn,a,b,c,d,e,f,lac,ldn,lac0,ldn0,filetype,intstyle) + end subroutine diff --git a/contrib/alos2proc_f/src/convert_sch_to_xyz.f b/contrib/alos2proc_f/src/convert_sch_to_xyz.f new file mode 100644 index 0000000..7618c90 --- /dev/null +++ b/contrib/alos2proc_f/src/convert_sch_to_xyz.f @@ -0,0 +1,108 @@ +c**************************************************************** + + subroutine convert_sch_to_xyz(ptm,r_schv,r_xyzv,i_type) + +c**************************************************************** +c** +c** FILE NAME: convert_sch_to_xyz.for +c** +c** DATE WRITTEN:1/15/93 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: This routine applies the affine matrix +c** provided to convert the sch coordinates xyz WGS-84 coordintes or +c** the inverse transformation. +c** +c** ROUTINES CALLED:latlon,matvec +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + +c structure /pegtrans/ !transformation parameters +c real*8 r_mat(3,3) +c real*8 r_matinv(3,3) +c real*8 r_ov(3) +c real*8 r_radcur +c end structure +c record /pegtrans/ ptm + + type pegtrans + sequence + real (8) r_mat(3,3) + real (8) r_matinv(3,3) + real (8) r_ov(3) + real (8) r_radcur + end type pegtrans + type (pegtrans) ptm + + real*8 r_schv(3) !sch coordinates of a point + real*8 r_xyzv(3) !WGS-84 coordinates of a point + integer i_type !i_type = 0 sch => xyz ; + !i_type = 1 xyz => sch + +c OUTPUT VARIABLES: see input + +c LOCAL VARIABLES: + integer i_t + real*8 r_schvt(3),r_llh(3) +c structure /ellipsoid/ +c real*8 r_a +c real*8 r_e2 +c end structure +c record /ellipsoid/ sph + + type ellipsoid + sequence + real (8) r_a + real (8) r_e2 + end type ellipsoid + type (ellipsoid) sph + +c DATA STATEMENTS: + +C FUNCTION STATEMENTS:none + +c PROCESSING STEPS: + +c compute the linear portion of the transformation + + sph%r_a = ptm%r_radcur + sph%r_e2 = 0.0d0 + + if(i_type .eq. 0)then + + r_llh(1) = r_schv(2)/ptm%r_radcur + r_llh(2) = r_schv(1)/ptm%r_radcur + r_llh(3) = r_schv(3) + + i_t = 1 + call latlon(sph,r_schvt,r_llh,i_t) + call matvec(ptm%r_mat,r_schvt,r_xyzv) + call lincomb(1.d0,r_xyzv,1.d0,ptm%r_ov,r_xyzv) + + elseif(i_type .eq. 1)then + + call lincomb(1.d0,r_xyzv,-1.d0,ptm%r_ov,r_schvt) + call matvec(ptm%r_matinv,r_schvt,r_schv) + i_t = 2 + call latlon(sph,r_schv,r_llh,i_t) + + r_schv(1) = ptm%r_radcur*r_llh(2) + r_schv(2) = ptm%r_radcur*r_llh(1) + r_schv(3) = r_llh(3) + + endif + + end + + + + diff --git a/contrib/alos2proc_f/src/cross.f b/contrib/alos2proc_f/src/cross.f new file mode 100644 index 0000000..800032e --- /dev/null +++ b/contrib/alos2proc_f/src/cross.f @@ -0,0 +1,43 @@ + +c**************************************************************** + + subroutine cross(r_u,r_v,r_w) + +c**************************************************************** +c** +c** FILE NAME: cross.f +c** +c** DATE WRITTEN: 8/3/90 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: The subroutine takes two vectors and returns +c** their cross product. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_v(3),r_u(3) !3x1 vectors + +c OUTPUT VARIABLES: + real*8 r_w(3) + +c LOCAL VARIABLES: + +c PROCESSING STEPS: + +c compute vector norm + + r_w(1) = r_u(2)*r_v(3) - r_u(3)*r_v(2) + r_w(2) = r_u(3)*r_v(1) - r_u(1)*r_v(3) + r_w(3) = r_u(1)*r_v(2) - r_u(2)*r_v(1) + + end diff --git a/contrib/alos2proc_f/src/curvature.f b/contrib/alos2proc_f/src/curvature.f new file mode 100644 index 0000000..aa3d32f --- /dev/null +++ b/contrib/alos2proc_f/src/curvature.f @@ -0,0 +1,55 @@ +c**************************************************************** +c +c Various curvature functions +c +c +c**************************************************************** +c** +c** FILE NAME: curvature.f +c** +c** DATE WRITTEN: 12/02/93 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: This routine computes the curvature for +c** of various types required for ellipsoidal or spherical earth +c** calculations. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + real*8 function reast(r_a,r_e2,r_lat) + + implicit none + real*8 r_a,r_e2,r_lat + + reast = r_a/sqrt(1.d0 - r_e2*sin(r_lat)**2) + + end + + real*8 function rnorth(r_a,r_e2,r_lat) + + implicit none + real*8 r_a,r_e2,r_lat + + rnorth = (r_a*(1.d0 - r_e2))/(1.d0 - r_e2*sin(r_lat)**2)**(1.5d0) + + end + + real*8 function rdir(r_a,r_e2,r_hdg,r_lat) + + implicit none + real*8 r_a,r_e2,r_lat,r_hdg,r_re,r_rn,reast,rnorth + + r_re = reast(r_a,r_e2,r_lat) + r_rn = rnorth(r_a,r_e2,r_lat) + + rdir = (r_re*r_rn)/(r_re*cos(r_hdg)**2 + r_rn*sin(r_hdg)**2) + + end + diff --git a/contrib/alos2proc_f/src/enubasis.f b/contrib/alos2proc_f/src/enubasis.f new file mode 100644 index 0000000..9e6cd90 --- /dev/null +++ b/contrib/alos2proc_f/src/enubasis.f @@ -0,0 +1,65 @@ +c**************************************************************** + + subroutine enubasis(r_lat,r_lon,r_enumat) + +c**************************************************************** +c** +c** FILE NAME: enubasis.f +c** +c** DATE WRITTEN: 7/22/93 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION:Takes a lat and lon and returns a +c** change of basis matrix from ENU to geocentric coordinates. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c**************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_lat !latitude (deg) + real*8 r_lon !longitude (deg) + +c OUTPUT VARIABLES: + real*8 r_enumat(3,3) + +c LOCAL VARIABLES: + real*8 r_slt,r_clt,r_clo,r_slo + +c DATA STATEMENTS: + +C FUNCTION STATEMENTS: + +c PROCESSING STEPS: + + r_clt = cos(r_lat) + r_slt = sin(r_lat) + r_clo = cos(r_lon) + r_slo = sin(r_lon) + +c North vector + + r_enumat(1,2) = -r_slt*r_clo + r_enumat(2,2) = -r_slt*r_slo + r_enumat(3,2) = r_clt + +c East vector + + r_enumat(1,1) = -r_slo + r_enumat(2,1) = r_clo + r_enumat(3,1) = 0.d0 + +c Up vector + + r_enumat(1,3) = r_clt*r_clo + r_enumat(2,3) = r_clt*r_slo + r_enumat(3,3) = r_slt + + end + diff --git a/contrib/alos2proc_f/src/fitoff.f b/contrib/alos2proc_f/src/fitoff.f new file mode 100644 index 0000000..bf4b2c8 --- /dev/null +++ b/contrib/alos2proc_f/src/fitoff.f @@ -0,0 +1,1232 @@ +CPOD +CPOD=pod +CPOD +CPOD=head1 USAGE +CPOD +CPOD Usage: fitoff infile outfile nsig maxrms minpoints' +CPOD nsig = number of standard deviations to threshold' +CPOD maxrms = do not threshold beyond this rms value' +CPOD minpoints = do not proceed below this number of points' +CPOD +CPOD=head1 FUNCTION +CPOD +CPOD FUNCTIONAL DESCRIPTION: culls outliers from a 2-d offset file +CPOD +CPOD This program replaces cull_points. Fitoff takes a file of offsets, +CPOD iteratively removes points beyond NSIG standard deviations from the mean, +CPOD and quits when a fit is succesfully achieved or warns that a fit can't +CPOD be made with the inputed parameters. The output is a reduced file +CPOD of offsets and the affine transformation used to relate the offsets. +CPOD +CPOD Program stops after completed minimum number of iterations +CPOD and if one of the following is true: +CPOD 1. rmsx and rmsy are both < maxrms; or +CPOD 2. n < minpoints; or +CPOD 3. iter > maximum iterations (set = 30 below); or +CPOD 4. solution length not changing and (1.) not acheived +CPOD +CPOD A successful fit is achieved only with the first criteria, the other 3 +CPOD output garbage for the offset points +CPOD +CPOD values successful with some ampcor.off: +CPOD nsig = 1.5; % number of standard deviations to threshold +CPOD maxrms = 0.05; % don't threshold beyond this rms value +CPOD minpoints = 50; % don't proceed below this number of points +CPOD +CPOD for ampcor_gross use smaller number of points, perhaps 10 +CPOD +CPOD values successful with some ampmag.off: +CPOD nsig = 1.5; %number of standard deviations to threshold +CPOD maxrms = 0.5; %don't threshold beyond this rms value +CPOD minpoints = 50; %don't proceed below this number of points +CPOD +CPOD for ampmag_low_res use smaller number of points, perhaps 10 +CPOD +CPOD=head1 ROUTINES CALLED +CPOD +CPOD +CPOD=head1 CALLED BY +CPOD +CPOD +CPOD=head1 FILES USED +CPOD +CPOD an input offset file that is in the format of an output of ampcor +CPOD +CPOD=head1 FILES CREATED +CPOD +CPOD a culled offset file that is in the format of an output of ampcor +CPOD +CPOD=head1 DIAGNOSTIC FILES +CPOD +CPOD stdout has an affine transformation summary +CPOD +CPOD=head1 HISTORY +CPOD +CPOD Original Routines: Mark Simons +CPOD +CPOD=head1 LAST UPDATE +CPOD Date Changed Reason Changed +CPOD ------------ ---------------- +CPOD +CPOD par Jan 26 '04 +CPOD EJF Jul 10, 2005 modified output format to handle offsets < -100000 +CPOD EJF Mar 29, 2006 removed all "pause" statements to avoid hung processing +CPOD=cut + subroutine fitoff(infile,outfile,nsig,maxrms,minpoint) +c Define variables for main program; n = columns, m = rows + IMPLICIT NONE + integer*4 file1, file2, nmax, n,i,imax,mmax + integer*4 miniter, k, iter + parameter(nmax=8) +c Mmax = twice the maximum number of data points + parameter(mmax=100000) + real*8 x1o(mmax), dx(mmax), dy(mmax), x2o(mmax) + real*8 y1o(mmax), y2o(mmax) + real*8 snr(mmax), r_covac(mmax), r_covdn(mmax), r_covx(mmax) + real*8 a(mmax,nmax),b(mmax),a_old(mmax,nmax),c(mmax) + real*8 resx(mmax), resy(mmax),threshx,threshy,b_old(mmax) + real*8 numerator, denominator, per_soln_length + real*8 per_soln_length_last, delta_length + logical change + +c variables from command line + integer*4 iargc,narg,maxiter, minpoint + character*80 infile, outfile,nsigs,maxrmss,minpoints + real*8 nsig,maxrms + +c variables for l2 norm subroutines = dsvdcmp.f, dsvbksb.f, dpythag.f + logical l1norm + integer m, np, mp + real*8 v(nmax,nmax),w(nmax),u(mmax,nmax),x(nmax),x_prev(nmax) + +c variables for l1 norm subroutine = l1.f + integer n2,m2, s(mmax) + real*8 toler,e(mmax) + +c variables for statistics subroutine = dmoment.f + integer p + real*8 rmsx,rmsy,xsdev,ysdev,sdev,data(mmax) + +c variables for computing rotation matrix + real*8 d(2),f(2),r_rotang,r_rtod,pi + real*8 r_u(2),r_u2,r_rot(2,2),r_aff(2,2),r_scale1,r_scale2,r_skew + logical sing + + pi = 3.14159265359d0 + + r_rtod = 180.d0/pi + +c set logical for solution length changing and satisfing Rms criteria +c equal to true + change= .true. + +c set unit numbers for the input and output files + file1 = 13 + file2 = 14 + +c set the minimum number of iterations that must be executed + miniter = 3 + +c set value for maxiter, program will quit when this number is exceeded + maxiter = 30 + +c use L1 norm if true, L2 norm if false + l1norm = .true. + + per_soln_length = 0. + +c*****get values from command line +c narg = iargc() +c if(narg.ne.5) then +c write(6,*) +c & 'Usage: fitoff infile outfile nsig maxrms minpoints' +c write(6,*) 'nsig = number of standard deviations to threshold' +c write(6,*) 'maxrms = do not threshold beyond this rms value' +c write(6,*) +c & 'minpoints = do not proceed below this number of points' +c stop +c else +c call getarg(1,infile) +c call getarg(2,outfile) +c call getarg(3,nsigs) +c call getarg(4,maxrmss) +c call getarg(5,minpoints) +c endif +c read(nsigs, *) nsig +c read(maxrmss, *) maxrms +c read(minpoints, *) minpoint + +c*****read offsets + + open(unit=file1, file=infile, status='old') + +c create output file + open(unit=file2,file=outfile) + + i = 1 + + Do while(.true.) + read(file1,*,end=71,err=70) x1o(i), dx(i), y1o(i), dy(i), + > snr(i), r_covac(i), r_covdn(i), r_covx(i) + x2o(i) = x1o(i) + dx(i) + y2o(i) = y1o(i) + dy(i) + imax = i + i=i + 1 + end do + + 70 write(*,*) ' > Problem reading file <' + 71 continue + close(file1) + + if (imax.gt.100000) write(6,*) + > ' > Exceeded data array size = mmax <' + + +c now setup matrices to solve overdetermined system of equations: +c [x2] [m1 m2] [x1] [m5] +c [ ] = [ ] x [ ] + [ ] +c [y2] [m3 m4] [y1] [m6] +c +c ^ ^ ^ ^ +c | | X = solution vector | +c B A = affine translation +c vector transformation matrix vector + + do iter =1,maxiter+1 + + do k = 1,(2*imax) + +c create the matrix B + + if (k.le.imax) then + b(k)=x2o(k) + else + b(k)=y2o(k-imax) + endif + +c create the matrix A + + if (k.le.imax) then + a(k,1)=x1o(k) + else + a(k,1)=0.0d0 + endif + + if (k.le.imax) then + a(k,2)=y1o(k) + else + a(k,2)=0.0d0 + endif + + if (k.le.imax) then + a(k,3)=0.0d0 + else + a(k,3)=x1o(k-imax) + endif + + if (k.le.imax) then + a(k,4)=0.0d0 + else + a(k,4)=y1o(k-imax) + endif + + if (k.le.imax) then + a(k,5)=1. + else + a(k,5)=0.0d0 + endif + + if (k.le.imax) then + a(k,6)=0.0d0 + else + a(k,6)=1.0 + endif + + end do + + if (.not.(l1norm)) then + +c use L2 Norm to compute M matrix, from Numerical Recipes (p. 57) +c n = number of columns, m = number of rows + + n = 6 + m = 2*imax + np = nmax + mp = mmax + +c save the A matrix before using svdcmp, because it will be destroyed + do k = 1,np + do i = 1, m + a_old(i,k) = a(i,k) + end do + end do + + do k = 1,m + b_old(k) = b(k) + end do + + call dsvdcmp(a,m,n,mp,np,w,v) + + do k = 1,n + do i = 1, m + u(i,k) = a(i,k) + end do + end do + + call dsvbksb(u,w,v,m,n,mp,np,b,x) + + endif + +c use L1 norm to compute M matrix + + if (l1norm) then + + n = 6 + m = 2*imax + n2 = n + 2 + m2 = m + 2 + toler = 1.0d-20 + +c save b and a arrays since they are destroyed in subroutines + do k = 1,n + do i = 1, m + a_old(i,k) = a(i,k) + end do + end do + + do k = 1,m + b_old(k) = b(k) + end do + + call L1(M,N,M2,N2,A,B,TOLER,X,E,S) + + endif + +c multiple A and X together and compute residues + call mmul(M,N,A_OLD,X,C) + + do k = 1,(2*imax) + if (k.le.imax) then + resx(k) = c(k) - b_old(k) + else + resy(k-imax) = c(k) - b_old(k) + endif + end do + + p = imax + rmsy = 0.0d0 + rmsx = 0.0d0 + +c compute statistics for x coordinates: standard deviation, mean, & rms + + do k = 1,(imax) + data(k)= resx(k) + rmsx = rmsx + resx(k)**2. + end do + + call dmoment(data,p,sdev) + rmsx = sqrt(rmsx/imax) + xsdev = sdev + + +c compute statistics for y coordinates + + do k = 1,(imax) + data(k)= resy(k) + rmsy = rmsy + resy(k)**2. + end do + + call dmoment(data,p,sdev) + rmsy = sqrt(rmsy/imax) + ysdev = sdev + + if (rmsx.gt.maxrms) then + threshx = nsig*xsdev + else + threshx = 99999 + endif + + if (rmsy.gt.maxrms) then + threshy = nsig*ysdev + else + threshy = 99999 + endif + +c determine whether to remove points for next iteration + if ((rmsx.gt.maxrms).or.(rmsy.gt.maxrms)) then +c determine which points to save for next iteration + i = 0 + do k = 1,imax + if ((abs(resx(k)).lt.threshx) + > .and.(abs(resy(k)).lt.threshy)) then + i = i + 1 + x2o(i) = x2o(k) + x1o(i) = x1o(k) + y2o(i) = y2o(k) + y1o(i) = y1o(k) + snr(i) = snr(k) + r_covac(i) = r_covac(k) + r_covdn(i) = r_covdn(k) + r_covx(i) = r_covx(k) + endif + end do + imax = i + endif + +c if fewer than minpoints, quit and output warning + if (imax.le.minpoint) goto 97 + +c if rms fit is good enough, then quit program + if ((rmsx.lt.maxrms).and.(rmsy.lt.maxrms)) goto 99 + + if (iter.gt.1) then + numerator = 0.0d0 + denominator = 0.0d0 +c if the soln. length does not change between iterations, and solution fit +c doesn't match specified parameters, then quit + + do k = 1,6 + numerator = numerator + (x(k) - x_prev(k))**2. + denominator = (x_prev(k))**2. + denominator + end do + per_soln_length = sqrt(numerator/denominator)*100. + end if + + if (iter.ge.miniter) then + delta_length = (per_soln_length - + > per_soln_length_last) + + if ((delta_length.eq.0).and. + > ((rmsx.gt.maxrms).or.(rmsy.gt.maxrms))) then + change = .false. + goto 96 + endif + + endif + + per_soln_length_last = per_soln_length + + do k = 1,6 + x_prev(k) = x(k) + end do + + + end do + +c exceeded maximum number of iterations, output garbage + write(unit=file2,fmt=95) -9999, -9999., -9999, -9999., -9999., + > -9999., -9999., -9999. + 95 format(i6,1x,f10.3,1x,i6,5(1x,f10.3)) + close(file2) + write(6,*) 'WARNING: Exceeded maximum number of iterations' + +c solution length not changing and fit parameters not achieved + 96 if (.not.change) then + write(6,*) 'WARNING: Solution length is not changing,' + write(6,*) 'but does not meet fit criteria' + endif + +c Fewer than minimum number of points, output garbage + 97 write(unit=file2,fmt=95) -9999, -9999., -9999, -9999., -9999., + > -9999., -9999., -9999. + close(file2) + if (imax.le.minpoint) then + write(6,*) 'WARNING: Fewer than minimum points, there are only' + > ,imax + endif + + 99 write(6,*) ' ' + if (((iter.lt.maxiter).and.(imax.gt.minpoint)).and. + > (change)) then + write(6,*) ' << Fitoff Program >> ' + write(6,*) ' ' + + write(6,*) ' ' + write(6,*) 'Number of points remaining =', imax + write(6,*) ' ' + + write(6,*) ' ' + write(6,*) 'RMS in X = ', rmsx, ' RMS in Y = ', rmsy + write(6,*) ' ' + +c write the offsets to the output file + do i = 1,imax + dx(i) = x2o(i) - x1o(i) + dy(i) = y2o(i) - y1o(i) + write(file2,100) int(x1o(i)), dx(i), int(y1o(i)), dy(i), + > snr(i), r_covac(i), r_covdn(i), r_covx(i) + 100 format(i6,1x,f10.3,1x,i6,1x,f11.3,1x,f10.5,3(1x,f10.6)) + end do + close(file2) + +c Decompose matrix and examine residuals + + write(6,*) ' ' + write(6,*) ' Matrix Analysis ' + write(6,*) ' ' + + write(6,*) ' Affine Matrix ' + write(6,*) ' ' + write(6,101) x(1), x(2) + write(6,101) x(3), x(4) + 101 format(1x,f15.10,1x,f15.10) + write(6,*) ' ' + write(6,*) 'Translation Vector' + write(6,*) ' ' + write(6,102) x(5),x(6) + 102 format(1x,f11.3,1x,f11.3,1x) + +c decompose affine matrix to find rotation matrix using QR decomposition +c R is an upper triangular matrix and Q is an orthogonal matrix such +c that A = QR. For our 2 X 2 matrix we can consider +c T +c Q A = R, where Q is a Housholder matrix, which is also a rotation matrix +c Subroutine qrdcmp ( Numerical recipes, pg 92) returns the u vectors +c used to compute Q1 in r_aff(1,1). r_aff(1,2), d(1) and d(2) are +c the diagonal terms of the R matrix, while r_aff(1,2) is the other +c point in the R matrix and these can be used to find the scale and +c skew terms + + r_aff(1,1) = x(1) + r_aff(1,2) = x(2) + r_aff(2,1) = x(3) + r_aff(2,2) = x(4) + + call qrdcmp(r_aff,2,2,f,d,sing) + + r_u(1) = r_aff(1,1) + r_u(2) = r_aff(2,1) + + r_u2 = .5d0*(r_u(1)**2 + r_u(2)**2) + + r_rot(1,1) = (1.d0 - (r_u(1)**2/r_u2)) + r_rot(1,2) = -(r_u(1)*r_u(2))/r_u2 + r_rot(2,1) = -(r_u(1)*r_u(2))/r_u2 + r_rot(2,2) = (1.d0 - (r_u(2)**2/r_u2)) + + if(d(1) .lt. 0)then + r_rot(1,1) = -r_rot(1,1) + r_rot(2,1) = -r_rot(2,1) + d(1) = -d(1) + r_aff(1,2) = -r_aff(1,2) + elseif(d(2) .lt. 0)then + r_rot(1,2) = -r_rot(1,2) + r_rot(2,2) = -r_rot(2,2) + d(2) = -d(2) + endif + + r_scale1 = abs(d(1)) + r_scale2 = abs(d(2)) + + r_skew = r_aff(1,2)/d(1) + + r_rotang = atan2(r_rot(2,1),r_rot(1,1)) + + write(6,*) ' ' + write(6,*) ' Rotation Matrix ' + write(6,*) ' ' + write(6,101) r_rot(1,1),r_rot(1,2) + write(6,101) r_rot(2,1),r_rot(2,2) + write(6,*) ' ' + write(6,*) 'Rotation Angle (deg) = ',r_rotang*r_rtod + write(6,*) ' ' + write(6,*) ' Axis Scale Factors' + write(6,*) ' ' + write(6,103) r_scale1,r_scale2 + 103 format(1x,f11.7,1x,f11.7) + write(6,*) ' ' + write(6,*) ' Skew Term' + write(6,*) ' ' + write(6,104) r_skew + 104 format(1x,f11.7) + + endif + + end + +C ALGORITHM 478 COLLECTED ALGORITHMS FROM ACM. +C ALGORITHM APPEARED IN COMM. ACM, VOL. 17, NO. 06, +C P. 319. +C NOTE: this version is modified to allow double precision + SUBROUTINE L1(M,N,M2,N2,A,B,TOLER,X,E,S) +C THIS SUBROUTINE USES A MODIFICATION OF THE SIMPLEX METHOD +C OF LINEAR PROGRAMMING TO CALCULATE AN L1 SOLUTION TO AN +C OVER-DETERMINED SYSTEM OF LINEAR EQUATIONS. +C DESCRIPTION OF PARAMETERS. +C M NUMBER OF EQUATIONS. +C N NUMBER OF UNKNOWNS (M.GE.N). +C M2 SET EQUAL TO M+2 FOR ADJUSTABLE DIMENSIONS. +C N2 SET EQUAL TO N+2 FOR ADJUSTABLE DIMENSIONS. +C A TWO DIMENSIONAL REAL ARRAY OF SIZE (M2,N2). +C ON ENTRY, THE COEFFICIENTS OF THE MATRIX MUST BE +C STORED IN THE FIRST M ROWS AND N COLUMNS OF A. +C THESE VALUES ARE DESTROYED BY THE SUBROUTINE. +C B ONE DIMENSIONAL REAL ARRAY OF SIZE M. ON ENTRY, B +C MUST CONTAIN THE RIGHT HAND SIDE OF THE EQUATIONS. +C THESE VALUES ARE DESTROYED BY THE SUBROUTINE. +C TOLER A SMALL POSITIVE TOLERANCE. EMPIRICAL EVIDENCE +C SUGGESTS TOLER=10**(-D*2/3) WHERE D REPRESENTS +C THE NUMBER OF DECIMAL DIGITS OF ACCURACY AVALABLE +C (SEE DESCRIPTION). +C X ONE DIMENSIONAL REAL ARRAY OF SIZE N. ON EXIT, THIS +C ARRAY CONTAINS A SOLUTION TO THE L1 PROBLEM. +C E ONE DIMENSIONAL REAL ARRAY OF SIZE M. ON EXIT, THIS +C ARRAY CONTAINS THE RESIDUALS IN THE EQUATIONS. +C S INTEGER ARRAY OF SIZE M USED FOR WORKSPACE. +C ON EXIT FROM THE SUBROUTINE, THE ARRAY A CONTAINS THE +C FOLLOWING INFORMATION. +C A(M+1,N+1) THE MINIMUM SUM OF THE ABSOLUTE VALUES OF +C THE RESIDUALS. +C A(M+1,N+2) THE RANK OF THE MATRIX OF COEFFICIENTS. +C A(M+2,N+1) EXIT CODE WITH VALUES. +C 0 - OPTIMAL SOLUTION WHICH IS PROBABLY NON- +C UNIQUE (SEE DESCRIPTION). +C 1 - UNIQUE OPTIMAL SOLUTION. +C 2 - CALCULATIONS TERMINATED PREMATURELY DUE TO +C ROUNDING ERRORS. +C A(M+2,N+2) NUMBER OF SIMPLEX ITERATIONS PERFORMED. + Implicit None + INTEGER m,m1,m2,n,n1,n2,NMAX,MMAX + PARAMETER (NMAX=8) + PARAMETER (MMAX=100000) + REAL*8 SUM + REAL*8 MIN, MAX, A(Mmax,Nmax), X(Nmax), E(Mmax), B(Mmax) + INTEGER OUT, S(Mmax) + LOGICAL STAGE, TEST +c define variables in program whose type were assumed implicitly + integer i,j,kr,k,kl,kount,in,l + real*8 d, pivot,toler,big +C BIG MUST BE SET EQUAL TO ANY VERY LARGE REAL CONSTANT. +C ITS VALUE HERE IS APPROPRIATE FOR THE IBM 370. +c DATA BIG/1.E75/ +C ITS VALUE HERE IS APPROPRIATE FOR SGI + DATA BIG/1.E38/ +C INITIALIZATION. + M1 = M + 1 + N1 = N + 1 + DO 10 J=1,N + A(M2,J) = J + X(J) = 0.0d0 + 10 CONTINUE + DO 40 I=1,M + A(I,N2) = N + I + A(I,N1) = B(I) + IF (B(I).GE.0.0d0) GO TO 30 + DO 20 J=1,N2 + A(I,J) = -A(I,J) + 20 CONTINUE + 30 E(I) = 0.0d0 + 40 CONTINUE +C COMPUTE THE MARGINAL COSTS. + DO 60 J=1,N1 + SUM = 0.0D0 + DO 50 I=1,M + SUM = SUM + A(I,J) + 50 CONTINUE + A(M1,J) = SUM + 60 CONTINUE +C STAGE I. +C DETERMINE THE VECTOR TO ENTER THE BASIS. + STAGE = .TRUE. + KOUNT = 0 + KR = 1 + KL = 1 + 70 MAX = -1. + DO 80 J=KR,N + IF (ABS(A(M2,J)).GT.N) GO TO 80 + D = ABS(A(M1,J)) + IF (D.LE.MAX) GO TO 80 + MAX = D + IN = J + 80 CONTINUE + IF (A(M1,IN).GE.0.0d0) GO TO 100 + DO 90 I=1,M2 + A(I,IN) = -A(I,IN) + 90 CONTINUE +C DETERMINE THE VECTOR TO LEAVE THE BASIS. + 100 K = 0 + DO 110 I=KL,M + D = A(I,IN) + IF (D.LE.TOLER) GO TO 110 + K = K + 1 + B(K) = A(I,N1)/D + S(K) = I + TEST = .TRUE. + 110 CONTINUE + 120 IF (K.GT.0) GO TO 130 + TEST = .FALSE. + GO TO 150 + 130 MIN = BIG + DO 140 I=1,K + IF (B(I).GE.MIN) GO TO 140 + J = I + MIN = B(I) + OUT = S(I) + 140 CONTINUE + B(J) = B(K) + S(J) = S(K) + K = K - 1 +C CHECK FOR LINEAR DEPENDENCE IN STAGE I. + 150 IF (TEST .OR. .NOT.STAGE) GO TO 170 + DO 160 I=1,M2 + D = A(I,KR) + A(I,KR) = A(I,IN) + A(I,IN) = D + 160 CONTINUE + KR = KR + 1 + GO TO 260 + 170 IF (TEST) GO TO 180 + A(M2,N1) = 2. + GO TO 350 + 180 PIVOT = A(OUT,IN) + IF (A(M1,IN)-PIVOT-PIVOT.LE.TOLER) GO TO 200 + DO 190 J=KR,N1 + D = A(OUT,J) + A(M1,J) = A(M1,J) - D - D + A(OUT,J) = -D + 190 CONTINUE + A(OUT,N2) = -A(OUT,N2) + GO TO 120 +C PIVOT ON A(OUT,IN). + 200 DO 210 J=KR,N1 + IF (J.EQ.IN) GO TO 210 + A(OUT,J) = A(OUT,J)/PIVOT + 210 CONTINUE +c DO 230 I=1,M1 +c IF (I.EQ.OUT) GO TO 230 +c D = A(I,IN) +c DO 220 J=KR,N1 +c IF (J.EQ.IN) GO TO 220 +c A(I,J) = A(I,J) - D*A(OUT,J) +c 220 CONTINUE +c 230 CONTINUE +c impliment time saving change suggested in Barrodale and Roberts - collected +c algorithms from CACM + DO 220 J = KR,N1 + IF (J.EQ.IN) GO TO 220 + CALL COL(A(1,J),A(1,IN),A(OUT,J),M1,OUT) + 220 CONTINUE + DO 240 I=1,M1 + IF (I.EQ.OUT) GO TO 240 + A(I,IN) = -A(I,IN)/PIVOT + 240 CONTINUE + A(OUT,IN) = 1./PIVOT + D = A(OUT,N2) + A(OUT,N2) = A(M2,IN) + A(M2,IN) = D + KOUNT = KOUNT + 1 + IF (.NOT.STAGE) GO TO 270 +C INTERCHANGE ROWS IN STAGE I. + KL = KL + 1 + DO 250 J=KR,N2 + D = A(OUT,J) + A(OUT,J) = A(KOUNT,J) + A(KOUNT,J) = D + 250 CONTINUE + 260 IF (KOUNT+KR.NE.N1) GO TO 70 +C STAGE II. + STAGE = .FALSE. +C DETERMINE THE VECTOR TO ENTER THE BASIS. + 270 MAX = -BIG + DO 290 J=KR,N + D = A(M1,J) + IF (D.GE.0.0d0) GO TO 280 + IF (D.GT.(-2.)) GO TO 290 + D = -D - 2. + 280 IF (D.LE.MAX) GO TO 290 + MAX = D + IN = J + 290 CONTINUE + IF (MAX.LE.TOLER) GO TO 310 + IF (A(M1,IN).GT.0.0d0) GO TO 100 + DO 300 I=1,M2 + A(I,IN) = -A(I,IN) + 300 CONTINUE + A(M1,IN) = A(M1,IN) - 2. + GO TO 100 +C PREPARE OUTPUT. + 310 L = KL - 1 + DO 330 I=1,L + IF (A(I,N1).GE.0.0d0) GO TO 330 + DO 320 J=KR,N2 + A(I,J) = -A(I,J) + 320 CONTINUE + 330 CONTINUE + A(M2,N1) = 0.0d0 + IF (KR.NE.1) GO TO 350 + DO 340 J=1,N + D = ABS(A(M1,J)) + IF (D.LE.TOLER .OR. 2.-D.LE.TOLER) GO TO 350 + 340 CONTINUE + A(M2,N1) = 1. + 350 DO 380 I=1,M + K = A(I,N2) + D = A(I,N1) + IF (K.GT.0) GO TO 360 + K = -K + D = -D + 360 IF (I.GE.KL) GO TO 370 + X(K) = D + GO TO 380 + 370 K = K - N + E(K) = D + 380 CONTINUE + A(M2,N2) = KOUNT + A(M1,N2) = N1 - KR + SUM = 0.0D0 + DO 390 I=KL,M + SUM = SUM + A(I,N1) + 390 CONTINUE + A(M1,N1) = SUM + RETURN + END + + SUBROUTINE COL(V1,V2,MLT,M1,IOUT) + IMPLICIT NONE + INTEGER M1,I,IOUT + REAL*8 V1(M1),V2(M1),MLT + DO 1 I = 1,M1 + IF (I.EQ.IOUT) GO TO 1 + V1(I)=V1(I)-V2(I)*MLT + 1 CONTINUE + RETURN + END + +c The following three programs are used to find the L2 norm + SUBROUTINE dsvbksb(u,w,v,m,n,mp,np,b,x) + Implicit None + INTEGER m,mp,n,np,NMAX,MMAX + PARAMETER (NMAX=8) + PARAMETER (MMAX=100000) +c DOUBLE PRECISION b(mp),u(mp,np),v(np,np),w(np),x(np) + REAL*8 b(mmax),u(mmax,nmax),v(nmax,nmax),w(nmax),x(nmax) + INTEGER i,j,jj + DOUBLE PRECISION s,tmp(NMAX) + do 12 j=1,n + s=0.0d0 + if(w(j).ne.0.0d0)then + do 11 i=1,m + s=s+u(i,j)*b(i) +11 continue + s=s/w(j) + endif + tmp(j)=s +12 continue + do 14 j=1,n + s=0.0d0 + do 13 jj=1,n + s=s+v(j,jj)*tmp(jj) +13 continue + x(j)=s +14 continue + return + END + + SUBROUTINE dsvdcmp(a,m,n,mp,np,w,v) + Implicit None + INTEGER m,mp,n,np,NMAX,MMAX + PARAMETER (NMAX=8) + PARAMETER (MMAX=100000) +c DOUBLE PRECISION a(mp,np),v(np,np),w(np) + REAL*8 a(mmax,nmax),v(nmax,nmax),w(nmax) +CU USES dpythag + INTEGER i,its,j,jj,k,l,nm + DOUBLE PRECISION anorm,c,f,g,h,s,scale,x,y,z,rv1(NMAX),dpythag + g=0.0d0 + scale=0.0d0 + anorm=0.0d0 + do 25 i=1,n + l=i+1 + rv1(i)=scale*g + g=0.0d0 + s=0.0d0 + scale=0.0d0 + if(i.le.m)then + do 11 k=i,m + scale=scale+abs(a(k,i)) +11 continue + if(scale.ne.0.0d0)then + do 12 k=i,m + a(k,i)=a(k,i)/scale + s=s+a(k,i)*a(k,i) +12 continue + f=a(i,i) + g=-sign(sqrt(s),f) + h=f*g-s + a(i,i)=f-g + do 15 j=l,n + s=0.0d0 + do 13 k=i,m + s=s+a(k,i)*a(k,j) +13 continue + f=s/h + do 14 k=i,m + a(k,j)=a(k,j)+f*a(k,i) +14 continue +15 continue + do 16 k=i,m + a(k,i)=scale*a(k,i) +16 continue + endif + endif + w(i)=scale *g + g=0.0d0 + s=0.0d0 + scale=0.0d0 + if((i.le.m).and.(i.ne.n))then + do 17 k=l,n + scale=scale+abs(a(i,k)) +17 continue + if(scale.ne.0.0d0)then + do 18 k=l,n + a(i,k)=a(i,k)/scale + s=s+a(i,k)*a(i,k) +18 continue + f=a(i,l) + g=-sign(sqrt(s),f) + h=f*g-s + a(i,l)=f-g + do 19 k=l,n + rv1(k)=a(i,k)/h +19 continue + do 23 j=l,m + s=0.0d0 + do 21 k=l,n + s=s+a(j,k)*a(i,k) +21 continue + do 22 k=l,n + a(j,k)=a(j,k)+s*rv1(k) +22 continue +23 continue + do 24 k=l,n + a(i,k)=scale*a(i,k) +24 continue + endif + endif + anorm=max(anorm,(abs(w(i))+abs(rv1(i)))) +25 continue + do 32 i=n,1,-1 + if(i.lt.n)then + if(g.ne.0.0d0)then + do 26 j=l,n + v(j,i)=(a(i,j)/a(i,l))/g +26 continue + do 29 j=l,n + s=0.0d0 + do 27 k=l,n + s=s+a(i,k)*v(k,j) +27 continue + do 28 k=l,n + v(k,j)=v(k,j)+s*v(k,i) +28 continue +29 continue + endif + do 31 j=l,n + v(i,j)=0.0d0 + v(j,i)=0.0d0 +31 continue + endif + v(i,i)=1.0d0 + g=rv1(i) + l=i +32 continue + do 39 i=min(m,n),1,-1 + l=i+1 + g=w(i) + do 33 j=l,n + a(i,j)=0.0d0 +33 continue + if(g.ne.0.0d0)then + g=1.0d0/g + do 36 j=l,n + s=0.0d0 + do 34 k=l,m + s=s+a(k,i)*a(k,j) +34 continue + f=(s/a(i,i))*g + do 35 k=i,m + a(k,j)=a(k,j)+f*a(k,i) +35 continue +36 continue + do 37 j=i,m + a(j,i)=a(j,i)*g +37 continue + else + do 38 j= i,m + a(j,i)=0.0d0 +38 continue + endif + a(i,i)=a(i,i)+1.0d0 +39 continue + do 49 k=n,1,-1 + do 48 its=1,30 + do 41 l=k,1,-1 + nm=l-1 + if((abs(rv1(l))+anorm).eq.anorm) goto 2 + if((abs(w(nm))+anorm).eq.anorm) goto 1 +41 continue +1 c=0.0d0 + s=1.0d0 + do 43 i=l,k + f=s*rv1(i) + rv1(i)=c*rv1(i) + if((abs(f)+anorm).eq.anorm) goto 2 + g=w(i) + h=dpythag(f,g) + w(i)=h + h=1.0d0/h + c= (g*h) + s=-(f*h) + do 42 j=1,m + y=a(j,nm) + z=a(j,i) + a(j,nm)=(y*c)+(z*s) + a(j,i)=-(y*s)+(z*c) +42 continue +43 continue +2 z=w(k) + if(l.eq.k)then + if(z.lt.0.0d0)then + w(k)=-z + do 44 j=1,n + v(j,k)=-v(j,k) +44 continue + endif + goto 3 + endif +! if(its.eq.30) pause 'no convergence in svdcmp' + if(its.eq.30) then + write (6,*) 'fitoff: no convergence in svdcmp, quitting' + stop + endif + x=w(l) + nm=k-1 + y=w(nm) + g=rv1(nm) + h=rv1(k) + f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0d0*h*y) + g=dpythag(f,1.0d0) + f=((x-z)*(x+z)+h*((y/(f+sign(g,f)))-h))/x + c=1.0d0 + s=1.0d0 + do 47 j=l,nm + i=j+1 + g=rv1(i) + y=w(i) + h=s*g + g=c*g + z=dpythag(f,h) + rv1(j)=z + c=f/z + s=h/z + f= (x*c)+(g*s) + g=-(x*s)+(g*c) + h=y*s + y=y*c + do 45 jj=1,n + x=v(jj,j) + z=v(jj,i) + v(jj,j)= (x*c)+(z*s) + v(jj,i)=-(x*s)+(z*c) +45 continue + z=dpythag(f,h) + w(j)=z + if(z.ne.0.0d0)then + z=1.0d0/z + c=f*z + s=h*z + endif + f= (c*g)+(s*y) + x=-(s*g)+(c*y) + do 46 jj=1,m + y=a(jj,j) + z=a(jj,i) + a(jj,j)= (y*c)+(z*s) + a(jj,i)=-(y*s)+(z*c) +46 continue +47 continue + rv1(l)=0.0d0 + rv1(k)=f + w(k)=x +48 continue +3 continue +49 continue + return + END + + FUNCTION dpythag(a,b) + Implicit None +c DOUBLE PRECISION a,b,dpythag +c DOUBLE PRECISION absa,absb + Real*8 a,b,dpythag + Real*8 absa,absb + absa=abs(a) + absb=abs(b) + if(absa.gt.absb)then + dpythag=absa*sqrt(1.0d0+(absb/absa)**2) + else + if(absb.eq.0.0d0)then + dpythag=0.0d0 + else + dpythag=absb*sqrt(1.0d0+(absa/absb)**2) + endif + endif + return + END + + SUBROUTINE MMUL (M,N,A_OLD,X,C) + Implicit None + +C *****PARAMETERS: + Integer nmax, mmax, M, N + Parameter (nmax=8) + Parameter (mmax=100000) + REAL*8 a_old(mmax,nmax),x(nmax),c(mmax) + + INTEGER NA,NB,NC,L + +C *****LOCAL VARIABLES: + INTEGER I,K + + NA = M + NB = nmax + NC = M + N = nmax + L = 1 + +C *****SUBROUTINES CALLED: +C NONE +C +C ------------------------------------------------------------------ +C +C *****PURPOSE: +C THIS SUBROUTINE COMPUTES THE MATRIX PRODUCT A*B AND STORES THE +C RESULT IN THE ARRAY C. A IS M X N, B IS N X L, AND C IS +C M X L. THE ARRAY C MUST BE DISTINCT FROM BOTH A AND B. +C +C *****PARAMETER DESCRIPTION: +C ON INPUT: +C NA ROW DIMENSION OF THE ARRAY CONTAINING A AS DECLARED +C IN THE CALLING PROGRAM DIMENSION STATEMENT; +C +C NB ROW DIMENSION OF THE ARRAY CONTAINING B AS DECLARED +C IN THE CALLING PROGRAM DIMENSION STATEMENT; +C +C NC ROW DIMENSION OF THE ARRAY CONTAINING C AS DECLARED +C IN THE CALLING PROGRAM DIMENSION STATEMENT; +C +C L NUMBER OF COLUMNS OF THE MATRICES B AND C; +C +C M NUMBER OF ROWS OF THE MATRICES A AND C; +C +C N NUMBER OF COLUMNS OF THE MATRIX A AND NUMBER OF ROWS +C OF THE MATRIX B; +C +C A AN M X N MATRIX; +C +C B AN N X L MATRIX. +C +C ON OUTPUT: +C +C C AN M X L ARRAY CONTAINING A*B. +C +C *****HISTORY: +C WRITTEN BY ALAN J. LAUB (ELEC. SYS. LAB., M.I.T., RM. 35-331, +C CAMBRIDGE, MA 02139, PH.: (617)-253-2125), SEPTEMBER 1977. +C MOST RECENT VERSION: SEP. 21, 1977. +C +C ------------------------------------------------------------------ +C + DO 10 I=1,M + C(I)=0.0d0 +10 CONTINUE + DO 30 K=1,N + DO 20 I=1,M + C(I)=C(I)+a_old(I,K)*x(K) +20 CONTINUE +30 CONTINUE + RETURN + + END + +c Modify Numerical Recipes program moment.f to compute only +c standard deviation and allow double precision + SUBROUTINE dmoment(data,p,sdev) + Implicit None + INTEGER p + REAL*8 adev,ave,curt,sdev,skew,var,data(p) + INTEGER j + REAL*8 t,s,ep +! if(p.le.1)pause 'p must be at least 2 in moment' + if(p.le.1) then + write (6,*) 'fitoff: p must be at least 2 in moment' + write (6,*) ' culling points failed' + stop + endif + s=0.0d0 + do 11 j=1,p + s=s+data(j) +11 continue + ave=s/p + adev=0.0d0 + var=0.0d0 + skew=0.0d0 + curt=0.0d0 + ep=0. + do 12 j=1,p + s=data(j)-ave + t=s*s + var=var+t +12 continue + adev=adev/p + var=(var-ep**2/p)/(p-1) + sdev=sqrt(var) + return + END + +c This program is used to find the rotation matrix from the affine matrix + SUBROUTINE qrdcmp(a,n,np,c,d,sing) + INTEGER n,np + REAL*8 a(np,np),c(n),d(n) + LOGICAL sing + INTEGER i,j,k + REAL*8 scale,sigma,sum,tau + sing=.false. + scale=0. + do 17 k=1,n-1 + do 11 i=k,n + scale=max(scale,abs(a(i,k))) +11 continue + if(scale.eq.0.)then + sing=.true. + c(k)=0. + d(k)=0. + else + do 12 i=k,n + a(i,k)=a(i,k)/scale +12 continue + sum=0. + do 13 i=k,n + sum=sum+a(i,k)**2 +13 continue + sigma=sign(sqrt(sum),a(k,k)) + a(k,k)=a(k,k)+sigma + c(k)=sigma*a(k,k) + d(k)=-scale*sigma + do 16 j=k+1,n + sum=0. + do 14 i=k,n + sum=sum+a(i,k)*a(i,j) +14 continue + tau=sum/c(k) + do 15 i=k,n + a(i,j)=a(i,j)-tau*a(i,k) +15 continue +16 continue + endif +17 continue + d(n)=a(n,n) + if(d(n).eq.0.)sing=.true. + return + END +C (C) Copr. 1986-92 Numerical Recipes Software $23#1yR.3Z9. diff --git a/contrib/alos2proc_f/src/interp.f b/contrib/alos2proc_f/src/interp.f new file mode 100644 index 0000000..ae0ff1c --- /dev/null +++ b/contrib/alos2proc_f/src/interp.f @@ -0,0 +1,47 @@ + real*4 function interp(ix, iy, xfrac, yfrac, rvs, iac, ioff) + +c integer*4 CMAX +c parameter (CMAX = 7000) + integer*4 ix, iy, n, first, iac, ioff + real*8 xfrac, yfrac + !real*4 rvs(0:2*iac-1,*) + !the upper defination makes the index of the second dimension (row) start with 1 + !I change it as follows, as both dimensions require index starting with 0 + !1-JUN-2015, Cunren Liang + real*4 rvs(0:2*iac-1,0:100000000) + + + complex temp(8) + real*4 xintp(0:65544) + data first/1/ + save xintp, first + +c* we want to do a 8192 x (8-pt sinc) interpolation of the original data, choosing +c* the resulting nearest neighbor. + + if(first .eq. 1) then + call intp_coef_norm(8192,xintp) + first = 0 + end if + n = 0 + + ifrac = 8 * nint(xfrac * 8192.) +c write (*,*) '1 ',frac,ifrac + do i = iy - 3 , iy + 4 + n = n + 1 + temp(n) = cmplx(0.0,0.0) + do k = -3 , 4 + temp(n) = temp(n) + rvs(ix+k+ioff,i) * xintp(ifrac+k+3) + end do + enddo + + ifrac = 8 * nint(yfrac * 8192.) +c write (*,*) '2 ', frac,ifrac + cinterp = cmplx(0.,0.) + do k = -3 , 4 + cinterp = cinterp + temp(k+4) * xintp(ifrac+k+3) + end do + interp = real(cinterp) + return + end + diff --git a/contrib/alos2proc_f/src/intpcoefnorm.f b/contrib/alos2proc_f/src/intpcoefnorm.f new file mode 100644 index 0000000..dfbaf2d --- /dev/null +++ b/contrib/alos2proc_f/src/intpcoefnorm.f @@ -0,0 +1,58 @@ + subroutine intp_coef_norm(nfilter,xintp) + + implicit none + integer*4 i,j,k,nfilter + real*4 x,y,pi, sum + real*4 xintp(0:65544) + + pi = 4.*atan(1.) +c compute the interpolation factors + do i=0,nfilter + j = i*8 + x = real(i)/real(nfilter) + y = sin(pi*x)/pi + if(x.ne.0.0 .and. x.ne.1.0) then + + xintp(j ) = -y/(3.0+x) + xintp(j+1) = y/(2.0+x) + xintp(j+2) = -y/(1.0+x) + xintp(j+3) = y/x + xintp(j+4) = y/(1.0-x) + xintp(j+5) = -y/(2.0-x) + xintp(j+6) = y/(3.0-x) + xintp(j+7) = -y/(4.0-x) + +c normalize by the sum of the squares + + sum = 0. + do k = 0 , 7 + sum = sum + xintp(j+k)**2 + end do +c sum = sqrt(sum) + do k = 0 , 7 + xintp(j+k) = xintp(j+k) / sum + end do + + else if( x.eq.0.0) then + xintp(j ) = 0.0 + xintp(j+1) = 0.0 + xintp(j+2) = 0.0 + xintp(j+3) = 1.0 + xintp(j+4) = 0.0 + xintp(j+5) = 0.0 + xintp(j+6) = 0.0 + xintp(j+7) = 0.0 + else if( x.eq.1.0) then + xintp(j ) = 0.0 + xintp(j+1) = 0.0 + xintp(j+2) = 0.0 + xintp(j+3) = 0.0 + xintp(j+4) = 1.0 + xintp(j+5) = 0.0 + xintp(j+6) = 0.0 + xintp(j+7) = 0.0 + end if + end do + + return + end diff --git a/contrib/alos2proc_f/src/latlon.f b/contrib/alos2proc_f/src/latlon.f new file mode 100644 index 0000000..9e4abbe --- /dev/null +++ b/contrib/alos2proc_f/src/latlon.f @@ -0,0 +1,91 @@ +c**************************************************************** + subroutine latlon(elp,r_v,r_llh,i_type) + +c**************************************************************** +c** +c** FILE NAME: latlon.f +c** +c** DATE WRITTEN:7/22/93 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION:This program converts a vector to +c** lat,lon and height above the reference ellipsoid or given a +c** lat,lon and height produces a geocentric vector. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c**************************************************************** + + implicit none + +c INPUT VARIABLES: + integer i_type !1=lat,lon to vector,2= vector to lat,lon +c structure /ellipsoid/ +c real*8 r_a +c real*8 r_e2 +c end structure +c record /ellipsoid/ elp + + type ellipsoid + sequence + real (8) r_a + real (8) r_e2 + end type ellipsoid + type (ellipsoid) elp + + real*8 r_v(3) !geocentric vector (meters) + real*8 r_llh(3) !latitude (deg -90 to 90),longitude (deg -180 to 180),height + +c OUTPUT VARIABLES: see input + +c LOCAL VARIABLES: + integer i_ft + real*8 pi,r_dtor,r_re,r_q2,r_q3,r_b,r_q + real*8 r_p,r_tant,r_theta,r_a,r_e2 + +c DATA STATEMENTS: + data pi /3.141592653589793238d0/ + data r_dtor /1.74532925199d-2/ + +C FUNCTION STATEMENTS: + +c PROCESSING STEPS: + + r_a = elp%r_a + r_e2 = elp%r_e2 + + if(i_type .eq. 1)then !convert lat,lon to vector + + r_re = r_a/sqrt(1.d0 - r_e2*sin(r_llh(1))**2) + + r_v(1) = (r_re + r_llh(3))*cos(r_llh(1))*cos(r_llh(2)) + r_v(2) = (r_re + r_llh(3))*cos(r_llh(1))*sin(r_llh(2)) + r_v(3) = (r_re*(1.d0-r_e2) + r_llh(3))*sin(r_llh(1)) + + elseif(i_type .eq. 2)then !convert vector to lat,lon + + r_q2 = 1.d0/(1.d0 - r_e2) + r_q = sqrt(r_q2) + r_q3 = r_q2 - 1.d0 + r_b = r_a*sqrt(1.d0 - r_e2) + + r_llh(2) = atan2(r_v(2),r_v(1)) + + r_p = sqrt(r_v(1)**2 + r_v(2)**2) + r_tant = (r_v(3)/r_p)*r_q + r_theta = atan(r_tant) + r_tant = (r_v(3) + r_q3*r_b*sin(r_theta)**3)/ + + (r_p - r_e2*r_a*cos(r_theta)**3) + r_llh(1) = atan(r_tant) + r_re = r_a/sqrt(1.d0 - r_e2*sin(r_llh(1))**2) + r_llh(3) = r_p/cos(r_llh(1)) - r_re + + endif + + end + diff --git a/contrib/alos2proc_f/src/lincomb.f b/contrib/alos2proc_f/src/lincomb.f new file mode 100644 index 0000000..7d61347 --- /dev/null +++ b/contrib/alos2proc_f/src/lincomb.f @@ -0,0 +1,46 @@ +c**************************************************************** + + subroutine lincomb(r_k1,r_u,r_k2,r_v,r_w) + +c**************************************************************** +c** +c** FILE NAME: lincomb.f +c** +c** DATE WRITTEN: 8/3/90 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: The subroutine forms the linear combination +c** of two vectors. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_u(3) !3x1 vector + real*8 r_v(3) !3x1 vector + real*8 r_k1 !scalar + real*8 r_k2 !scalar + +c OUTPUT VARIABLES: + real*8 r_w(3) !3x1 vector + +c LOCAL VARIABLES:none + +c PROCESSING STEPS: + +c compute linear combination + + r_w(1) = r_k1*r_u(1) + r_k2*r_v(1) + r_w(2) = r_k1*r_u(2) + r_k2*r_v(2) + r_w(3) = r_k1*r_u(3) + r_k2*r_v(3) + + end + diff --git a/contrib/alos2proc_f/src/look_coord_conv.f b/contrib/alos2proc_f/src/look_coord_conv.f new file mode 100644 index 0000000..2813179 --- /dev/null +++ b/contrib/alos2proc_f/src/look_coord_conv.f @@ -0,0 +1,44 @@ +c**************************************************************** + + subroutine look_coord_conv(l0,x0,l,x) + +c**************************************************************** +c** +c** FILE NAME: look_coord_conv.f +c** +c** DATE WRITTEN: 4/20/2017 +c** +c** PROGRAMMER:Cunren Liang +c** +c** FUNCTIONAL DESCRIPTION: The subroutine calculates the +c** coordinate x with number of looks l corresponding to +c** x0 with number of looks l0 +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + integer l0 + real*8 x0 + integer l + + +c OUTPUT VARIABLES:see input + +c LOCAL VARIABLES: + real*8 x + +c PROCESSING STEPS: + +c compute x + + x = x0 * l0 / l + (l0-l)/(2.0*l) + + end diff --git a/contrib/alos2proc_f/src/matmat.f b/contrib/alos2proc_f/src/matmat.f new file mode 100644 index 0000000..228deae --- /dev/null +++ b/contrib/alos2proc_f/src/matmat.f @@ -0,0 +1,48 @@ +c**************************************************************** + + subroutine matmat(r_a,r_b,r_c) + +c**************************************************************** +c** +c** FILE NAME: matmat.for +c** +c** DATE WRITTEN: 8/3/90 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: The subroutine takes two 3x3 matrices +c** and multiplies them to return another 3x3 matrix. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_a(3,3),r_b(3,3) !3x3 matrix + +c OUTPUT VARIABLES: + real*8 r_c(3,3) !3x3 matrix + +c LOCAL VARIABLES: + integer i + +c PROCESSING STEPS: + +c compute matrix product + + do i=1,3 + r_c(i,1) = r_a(i,1)*r_b(1,1) + r_a(i,2)*r_b(2,1) + + + r_a(i,3)*r_b(3,1) + r_c(i,2) = r_a(i,1)*r_b(1,2) + r_a(i,2)*r_b(2,2) + + + r_a(i,3)*r_b(3,2) + r_c(i,3) = r_a(i,1)*r_b(1,3) + r_a(i,2)*r_b(2,3) + + + r_a(i,3)*r_b(3,3) + enddo + + end diff --git a/contrib/alos2proc_f/src/matvec.f b/contrib/alos2proc_f/src/matvec.f new file mode 100644 index 0000000..de9a24f --- /dev/null +++ b/contrib/alos2proc_f/src/matvec.f @@ -0,0 +1,47 @@ + +c**************************************************************** + + subroutine matvec(r_t,r_v,r_w) + +c**************************************************************** +c** +c** FILE NAME: matvec.f +c** +c** DATE WRITTEN: 7/20/90 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: The subroutine takes a 3x3 matrix +c** and a 3x1 vector a multiplies them to return another 3x1 +c** vector. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_t(3,3) !3x3 matrix + real*8 r_v(3) !3x1 vector + +c OUTPUT VARIABLES: + real*8 r_w(3) !3x1 vector + +c LOCAL VARIABLES:none + +c PROCESSING STEPS: + +c compute matrix product + + r_w(1) = r_t(1,1)*r_v(1) + r_t(1,2)*r_v(2) + r_t(1,3)*r_v(3) + r_w(2) = r_t(2,1)*r_v(1) + r_t(2,2)*r_v(2) + r_t(2,3)*r_v(3) + r_w(3) = r_t(3,1)*r_v(1) + r_t(3,2)*r_v(2) + r_t(3,3)*r_v(3) + + end + + diff --git a/contrib/alos2proc_f/src/norm.f b/contrib/alos2proc_f/src/norm.f new file mode 100644 index 0000000..10fc8ef --- /dev/null +++ b/contrib/alos2proc_f/src/norm.f @@ -0,0 +1,40 @@ +c**************************************************************** + + subroutine norm(r_v,r_n) + +c**************************************************************** +c** +c** FILE NAME: norm.f +c** +c** DATE WRITTEN: 8/3/90 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: The subroutine takes vector and returns +c** its norm. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_v(3) !3x1 vector + +c OUTPUT VARIABLES:see input + +c LOCAL VARIABLES: + real*8 r_n + +c PROCESSING STEPS: + +c compute vector norm + + r_n = sqrt(r_v(1)**2 + r_v(2)**2 + r_v(3)**2) + + end diff --git a/contrib/alos2proc_f/src/radar_to_xyz.f b/contrib/alos2proc_f/src/radar_to_xyz.f new file mode 100644 index 0000000..fde3708 --- /dev/null +++ b/contrib/alos2proc_f/src/radar_to_xyz.f @@ -0,0 +1,137 @@ +c**************************************************************** + + subroutine radar_to_xyz(elp,peg,ptm) + +c**************************************************************** +c** +c** FILE NAME: radar_to_xyz.for +c** +c** DATE WRITTEN:1/15/93 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION:This routine computes the transformation +c** matrix and translation vector needed to get between radar (s,c,h) +c** coordinates and (x,y,z) WGS-84 coordinates. +c** +c** ROUTINES CALLED:euler, +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + +c structure /ellipsoid/ +c real*8 r_a +c real*8 r_e2 +c end structure +c record /ellipsoid/ elp + +c structure /peg/ +c real*8 r_lat +c real*8 r_lon +c real*8 r_hdg +c end structure +c record /peg/ peg + + type ellipsoid + sequence + real (8) r_a + real (8) r_e2 + end type ellipsoid + type (ellipsoid) elp + + type pegtype + sequence + real (8) r_lat + real (8) r_lon + real (8) r_hdg + end type pegtype + type (pegtype) peg + +c OUTPUT VARIABLES: + +c structure /pegtrans/ +c real*8 r_mat(3,3) +c real*8 r_matinv(3,3) +c real*8 r_ov(3) +c real*8 r_radcur +c end structure +c record /pegtrans/ ptm + + type pegtrans + sequence + real (8) r_mat(3,3) + real (8) r_matinv(3,3) + real (8) r_ov(3) + real (8) r_radcur + end type pegtrans + type (pegtrans) ptm + +c LOCAL VARIABLES: + integer i,j,i_type + real*8 pi,r_radcur,r_llh(3),r_p(3),r_slt,r_clt,r_clo,r_slo,r_up(3) + real*8 r_chg,r_shg,rdir + +c DATA STATEMENTS:none + +C FUNCTION STATEMENTS: + external rdir + +c PROCESSING STEPS: + +c first determine the rotation matrix + + r_clt = cos(peg%r_lat) + r_slt = sin(peg%r_lat) + r_clo = cos(peg%r_lon) + r_slo = sin(peg%r_lon) + r_chg = cos(peg%r_hdg) + r_shg = sin(peg%r_hdg) + + ptm%r_mat(1,1) = r_clt*r_clo + ptm%r_mat(1,2) = -r_shg*r_slo - r_slt*r_clo*r_chg + ptm%r_mat(1,3) = r_slo*r_chg - r_slt*r_clo*r_shg + ptm%r_mat(2,1) = r_clt*r_slo + ptm%r_mat(2,2) = r_clo*r_shg - r_slt*r_slo*r_chg + ptm%r_mat(2,3) = -r_clo*r_chg - r_slt*r_slo*r_shg + ptm%r_mat(3,1) = r_slt + ptm%r_mat(3,2) = r_clt*r_chg + ptm%r_mat(3,3) = r_clt*r_shg + + do i=1,3 + do j=1,3 + ptm%r_matinv(i,j) = ptm%r_mat(j,i) + enddo + enddo + +c find the translation vector + + ptm%r_radcur = rdir(elp%r_a,elp%r_e2,peg%r_hdg,peg%r_lat) + + i_type = 1 + r_llh(1) = peg%r_lat + r_llh(2) = peg%r_lon + r_llh(3) = 0.0d0 + call latlon(elp,r_p,r_llh,i_type) + + r_clt = cos(peg%r_lat) + r_slt = sin(peg%r_lat) + r_clo = cos(peg%r_lon) + r_slo = sin(peg%r_lon) + r_up(1) = r_clt*r_clo + r_up(2) = r_clt*r_slo + r_up(3) = r_slt + + do i=1,3 + ptm%r_ov(i) = r_p(i) - ptm%r_radcur*r_up(i) + enddo + + end + + diff --git a/contrib/alos2proc_f/src/rect.f b/contrib/alos2proc_f/src/rect.f new file mode 100644 index 0000000..cd74443 --- /dev/null +++ b/contrib/alos2proc_f/src/rect.f @@ -0,0 +1,391 @@ + subroutine rect(infile,outfile,ndac,nddn,nrac,nrdn,a,b,c,d,e,f,filetype,intstyle) +c +c***************************************************************************** +c** +c** FILE NAME: rect.f +c** +c** DATE WRITTEN: 27-Nov-98 +c** +c** PROGRAMMER: P.A.Rosen +c** +c** FUNCTIONAL DESCRIPTION: This program adjusts an image +c** by affine transformation and interpolation +c** +c** UPDATE LOG: Cunren Liang, 24-APR-2015 +c** updated to support file types: real, double +c** and support the case that input and output file sizes are different +C** +c** Cunren LIANG, 03-JUN-2015 +c** 1. there is 1 pixel offset in the output, which is corrected. +c** +c** +c***************************************************************************** + + + implicit none + +c integer CMAX, RMAX +c parameter (CMAX = 7000, RMAX = 7200) +c real*4 rvs(0:2*CMAX-1,0:RMAX-1) +c complex*8 carr(0:20000) +c real*4 arr(0:40000) + +c input of resampling + REAL*4, DIMENSION(:,:), ALLOCATABLE :: rvs + +c variables for reading data +c For byte format *****GP 01-05****** + INTEGER*1, DIMENSION(:), ALLOCATABLE :: barr + real*4, DIMENSION(:), ALLOCATABLE :: rarr + real*8, DIMENSION(:), ALLOCATABLE :: darr + COMPLEX*8, DIMENSION(:), ALLOCATABLE :: carr + +c output of resampling + REAL*4, DIMENSION(:), ALLOCATABLE :: arr + + real*4 pt1(3),pt2(3),pt3(3),pt4(3) + real*8 colval, rowval, ocolval, orowval + real*8 ifrac, jfrac + real*8 a,b,c,d,e,f + real*4 interp + + integer oi, oj, i, j, k, ift, iis + integer iargc, ndac, nddn, nrac, nrdn, ierr + integer nac + integer psize + + character*180 fname, infile, outfile, intstyle, filetype + + integer rdflen + character*255 rdfval + character*255 rdfcullsp,rdfdata + character*255 a_rdtmp + + save rvs + +c if(iargc() .eq. 0) then +c write(*,*) 'usage: rect rect.rdf' +c stop +c end if + +c call getarg(1,fname) + +c call rdf_init('ERRFILE=SCREEN') +c write(6,'(a)') 'Reading command file data...' +c call rdf_read(fname) + +c a_rdtmp = rdfval('Input Image File Name','-') +c read(unit=a_rdtmp,fmt='(a)') infile +c a_rdtmp = rdfval('Output Image File Name','-') +c read(unit=a_rdtmp,fmt='(a)') outfile +c a_rdtmp = rdfval('Input Dimensions','-') +c read(unit=a_rdtmp,fmt=*) ndac, nddn +c a_rdtmp = rdfval('Output Dimensions','-') +c read(unit=a_rdtmp,fmt=*) nrac, nrdn +c a_rdtmp = rdfval('Affine Matrix Row 1','-') +c read(unit=a_rdtmp,fmt=*) a, b +c a_rdtmp = rdfval('Affine Matrix Row 2','-') +c read(unit=a_rdtmp,fmt=*) c, d +c a_rdtmp = rdfval('Affine Offset Vector','-') +c read(unit=a_rdtmp,fmt=*) e, f +c a_rdtmp = rdfval('File Type','-') +c read(unit=a_rdtmp,fmt='(a)') filetype +c a_rdtmp = rdfval('Interpolation Method','-') +c read(unit=a_rdtmp,fmt='(a)') intstyle + +c if(ndac .gt. CMAX) stop 'Increase column array dimension in rect' +c if(nddn .gt. RMAX) stop 'Increase row array dimension in rect' + + ift = 0 + psize = 8 + if(index(filetype,'RMG') .ne. 0)then + ift = 1 + psize = 8 + write (*,*) 'Assuming RMG file type ' +c For byte format *****GP 01-05****** + elseif(index(filetype,'BYTE') .ne. 0)then + ift = 2 + psize = 1 + write (*,*) 'Assuming byte file type ' + elseif(index(filetype,'REAL') .ne. 0)then + ift = 3 + psize = 4 + write (*,*) 'Assuming real*4 file type ' + elseif(index(filetype,'DOUBLE') .ne. 0)then + ift = 4 + psize = 8 + write (*,*) 'Assuming double (real*8) file type ' + else + write (*,*) 'Assuming complex file type ' + endif + + iis = 0 + if(index(intstyle,'Bilinear') .ne. 0)then + iis = 1 + write (*,*) 'Assuming Bilinear Interpolation ' + elseif(index(intstyle,'Sinc') .ne. 0)then + iis = 2 + write (*,*) 'Assuming Sinc Interpolation ' + else + write (*,*) 'Assuming Nearest Neighbor ' + end if + +c input of resampling + if(ift .le. 1) then + ALLOCATE( rvs(0:2*ndac-1,0:nddn-1) ) + else + ALLOCATE( rvs(0:ndac-1,0:nddn-1) ) + end if + write(*,*) 'Allocated a map of dimension ',ndac,nddn + +c variable for reading data + + if(ndac .gt. nrac) then + nac = ndac + else + nac = nrac + end if + ALLOCATE( carr(0:2*nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac +c there is no need to allocate an array for rmg type +c For byte format *****GP 01-05****** + ALLOCATE( barr(0:nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac + ALLOCATE( rarr(0:nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac + ALLOCATE( darr(0:nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac + + +c output of resampling + if(ift .le. 1) then + ALLOCATE( arr(0:2*nrac-1) ) + else + ALLOCATE( arr(0:nrac-1) ) + end if + write(*,*) 'Allocated array of dimension ',nrac + + write (*,*) 'opening files ...' + +c open files + open(11,file=infile,form='unformatted', + . access='direct',recl=psize*ndac,status='old') + open(12,file=outfile,form='unformatted', + . access='direct',recl=psize*nrac,status='unknown') + +c forcing NN interpolation for byte format +c if(ift .eq. 2) then +c iis = 0 +c end if + + +c read in the data + + write (*,*) 'reading data ...' + + if(ift .eq. 0) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (carr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = real(carr(k)) + rvs(k+ndac,j) = aimag(carr(k)) + end do + end do + elseif(ift .eq. 1) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (rvs(k,j),k=0,2*ndac-1) + if(ierr .ne. 0) goto 999 + end do + elseif(ift .eq. 2) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (barr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = barr(k) + end do + end do + elseif(ift .eq. 3) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (rarr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = rarr(k) + end do + end do + else + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (darr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = darr(k) + end do + end do + end if + + 999 write (*,*) 'finished read ',j,' now interpolating ...' + +c do the interpolation + + do j = 0 , nrdn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + rowval = dble(j) + + if(iis .eq. 0) then ! nearest neighbor + + do i = 0 , nrac-1 + colval = dble(i) + ocolval = a * colval + b * rowval + e + orowval = c * colval + d * rowval + f + oi = nint(ocolval) + oj = nint(orowval) + if(.not.(oi .lt. 0 .or. oi .ge. ndac .or. oj .lt. 0 .or + $ . oj .ge. nddn)) then + arr(i) = rvs(oi,oj) + if(ift .le. 1) then + arr(i+nrac) = rvs(oi+ndac,oj) + end if + else + arr(i) = 0. + if(ift .le. 1) then + arr(i+nrac) = 0. + end if + end if + end do + + elseif(iis. eq. 1) then ! bilinear interpolation + + do i = 0 , nrac-1 + colval = dble(i) + ocolval = a * colval + b * rowval + e + orowval = c * colval + d * rowval + f + oi = nint(ocolval) + oj = nint(orowval) + ifrac = (ocolval - oi) + jfrac = (orowval - oj) + if(ifrac .lt. 0.d0) then + oi = oi - 1 + ifrac = (ocolval - oi) + end if + if(jfrac .lt. 0.d0) then + oj = oj - 1 + jfrac = (orowval - oj) + end if + if(.not.(oi .lt. 0 .or. oi .ge. ndac-1 .or. oj .lt. 0 .or + $ . oj .ge. nddn-1)) then + pt1(1) = 0. + pt1(2) = 0. + pt1(3) = rvs(oi,oj) + pt2(1) = 1. + pt2(2) = 0. + pt2(3) = rvs(oi+1,oj) + pt3(1) = 0. + pt3(2) = 1. + pt3(3) = rvs(oi,oj+1) + pt4(1) = 1. + pt4(2) = 1. + pt4(3) = rvs(oi+1,oj+1) + call bilinear(pt1,pt2,pt3,pt4,sngl(ifrac),sngl(jfrac),arr(i)) + if(ift .le. 1) then + pt1(1) = 0. + pt1(2) = 0. + pt1(3) = rvs(oi+ndac,oj) + pt2(1) = 1. + pt2(2) = 0. + pt2(3) = rvs(oi+1+ndac,oj) + pt3(1) = 0. + pt3(2) = 1. + pt3(3) = rvs(oi+ndac,oj+1) + pt4(1) = 1. + pt4(2) = 1. + pt4(3) = rvs(oi+1+ndac,oj+1) + call bilinear(pt1,pt2,pt3,pt4,sngl(ifrac),sngl(jfrac),arr(i+nrac)) + end if + else + arr(i) = 0. + if(ift .le. 1) then + arr(i+nrac) = 0. + end if + end if + end do + + + elseif(iis. eq. 2) then ! sinc interpolation + + do i = 0 , nrac-1 + colval = dble(i) + ocolval = a * colval + b * rowval + e + orowval = c * colval + d * rowval + f + oi = nint(ocolval) + oj = nint(orowval) + ifrac = (ocolval - oi) + jfrac = (orowval - oj) + if(ifrac .lt. 0.d0) then + oi = oi - 1 + ifrac = (ocolval - oi) + end if + if(jfrac .lt. 0.d0) then + oj = oj - 1 + jfrac = (orowval - oj) + end if + +! if(.not.(oi .lt. 4 .or. oi .ge. ndac-3 .or. oj .lt. 4 .or +! $ . oj .ge. nddn-3)) then +! I changed the upper sentence, as I have debug the array problem in interp.f, Cunren Liang, 03-JUN-2015 + if(.not.(oi .lt. 4 .or. oi .ge. ndac-4 .or. oj .lt. 4 .or + $ . oj .ge. nddn-4)) then + arr(i) = interp(oi, oj, ifrac, jfrac, rvs, ndac, 0) + if(ift .le. 1) then + arr(i+nrac) = interp(oi, oj, ifrac, jfrac, rvs, ndac, ndac) + end if + else + arr(i) = 0. + if(ift .le. 1) then + arr(i+nrac) = 0. + end if + end if + end do + + end if + + if(ift .eq. 0) then + do k = 0 , nrac -1 + carr(k) = cmplx(arr(k),arr(k+nrac)) + end do + write(12,rec=j+1) (carr(k),k=0,nrac-1) + elseif(ift .eq. 1) then + write(12,rec=j+1) (arr(k),k=0,2*nrac-1) + elseif(ift .eq. 2) then + do k = 0 , nrac -1 + barr(k) = arr(k) + end do + write(12,rec=j+1) (barr(k),k=0,nrac-1) + elseif(ift .eq. 3) then + do k = 0 , nrac -1 + rarr(k) = arr(k) + end do + write(12,rec=j+1) (rarr(k),k=0,nrac-1) + else + do k = 0 , nrac -1 + darr(k) = arr(k) + end do + write(12,rec=j+1) (darr(k),k=0,nrac-1) + end if + + end do + + DEALLOCATE(rvs) + DEALLOCATE(carr) + DEALLOCATE(barr) + DEALLOCATE(rarr) + DEALLOCATE(darr) + DEALLOCATE(arr) + + close(unit=11) + close(unit=12) + end diff --git a/contrib/alos2proc_f/src/rect_with_looks.f b/contrib/alos2proc_f/src/rect_with_looks.f new file mode 100644 index 0000000..a0b85bc --- /dev/null +++ b/contrib/alos2proc_f/src/rect_with_looks.f @@ -0,0 +1,427 @@ + subroutine rect_with_looks(infile,outfile,ndac,nddn,nrac,nrdn,a,b,c,d,e,f,lac,ldn,lac0,ldn0,filetype,intstyle) +c +c***************************************************************************** +c** +c** FILE NAME: rect.f +c** +c** DATE WRITTEN: 27-Nov-98 +c** +c** PROGRAMMER: P.A.Rosen +c** +c** FUNCTIONAL DESCRIPTION: This program adjusts an image +c** by affine transformation and interpolation +c** +c** UPDATE LOG: Cunren Liang, 24-APR-2015 +c** 1. support file types: real, double +c** for double, after reading in, data are saved in float variables +c** for caculation, and data written out get values from float variables. +c** 2. support the case that input and output file sizes are different +c** 3. support affine transformation coefficients estimated from multilook +c** images. In this case, the program assumes that, the locations of the +c** offset estimations start from (0, 0). The images handled by this program +c** also start from (0, 0). +C** +c** Cunren LIANG, 03-JUN-2015 +c** 1. there is 1 pixel offset in the output, which is corrected. +c** +c** Cunren Liang, 20-APR-2017 +C** 1. support original image of multiple looks +c** +c** +c** +c***************************************************************************** + + + implicit none + +c integer CMAX, RMAX +c parameter (CMAX = 7000, RMAX = 7200) +c real*4 rvs(0:2*CMAX-1,0:RMAX-1) +c complex*8 carr(0:20000) +c real*4 arr(0:40000) + +c input of resampling + REAL*4, DIMENSION(:,:), ALLOCATABLE :: rvs + +c variables for reading data +c For byte format *****GP 01-05****** + INTEGER*1, DIMENSION(:), ALLOCATABLE :: barr + real*4, DIMENSION(:), ALLOCATABLE :: rarr + real*8, DIMENSION(:), ALLOCATABLE :: darr + COMPLEX*8, DIMENSION(:), ALLOCATABLE :: carr + +c output of resampling + REAL*4, DIMENSION(:), ALLOCATABLE :: arr + + real*4 pt1(3),pt2(3),pt3(3),pt4(3) + real*8 colval, rowval, ocolval, orowval, ocolval_tmp, orowval_tmp + real*8 ifrac, jfrac + real*8 a,b,c,d,e,f + real*4 interp + + integer oi, oj, i, j, k, ift, iis + integer iargc, ndac, nddn, nrac, nrdn, ierr + integer nac + integer psize + integer lac, ldn + integer lac0, ldn0 + + character*180 fname, infile, outfile, intstyle, filetype + + integer rdflen + character*255 rdfval + character*255 rdfcullsp,rdfdata + character*255 a_rdtmp + + save rvs + +c if(iargc() .eq. 0) then +c write(*,*) 'usage: rect rect.rdf' +c stop +c end if + +c call getarg(1,fname) + +c call rdf_init('ERRFILE=SCREEN') +c write(6,'(a)') 'Reading command file data...' +c call rdf_read(fname) + +c a_rdtmp = rdfval('Input Image File Name','-') +c read(unit=a_rdtmp,fmt='(a)') infile +c a_rdtmp = rdfval('Output Image File Name','-') +c read(unit=a_rdtmp,fmt='(a)') outfile +c a_rdtmp = rdfval('Input Dimensions','-') +c read(unit=a_rdtmp,fmt=*) ndac, nddn +c a_rdtmp = rdfval('Output Dimensions','-') +c read(unit=a_rdtmp,fmt=*) nrac, nrdn +c a_rdtmp = rdfval('Affine Matrix Row 1','-') +c read(unit=a_rdtmp,fmt=*) a, b +c a_rdtmp = rdfval('Affine Matrix Row 2','-') +c read(unit=a_rdtmp,fmt=*) c, d +c a_rdtmp = rdfval('Affine Offset Vector','-') +c read(unit=a_rdtmp,fmt=*) e, f +c a_rdtmp = rdfval('Looks of the Offsets','-') +c read(unit=a_rdtmp,fmt=*) lac, ldn +c a_rdtmp = rdfval('Looks of the Image File','-') +c read(unit=a_rdtmp,fmt=*) lac0, ldn0 +c a_rdtmp = rdfval('File Type','-') +c read(unit=a_rdtmp,fmt='(a)') filetype +c a_rdtmp = rdfval('Interpolation Method','-') +c read(unit=a_rdtmp,fmt='(a)') intstyle + +c if(ndac .gt. CMAX) stop 'Increase column array dimension in rect' +c if(nddn .gt. RMAX) stop 'Increase row array dimension in rect' + + ift = 0 + psize = 8 + if(index(filetype,'RMG') .ne. 0)then + ift = 1 + psize = 8 + write (*,*) 'Assuming RMG file type ' +c For byte format *****GP 01-05****** + elseif(index(filetype,'BYTE') .ne. 0)then + ift = 2 + psize = 1 + write (*,*) 'Assuming byte file type ' + elseif(index(filetype,'REAL') .ne. 0)then + ift = 3 + psize = 4 + write (*,*) 'Assuming real*4 file type ' + elseif(index(filetype,'DOUBLE') .ne. 0)then + ift = 4 + psize = 8 + write (*,*) 'Assuming double (real*8) file type ' + else + write (*,*) 'Assuming complex file type ' + endif + + iis = 0 + if(index(intstyle,'Bilinear') .ne. 0)then + iis = 1 + write (*,*) 'Assuming Bilinear Interpolation ' + elseif(index(intstyle,'Sinc') .ne. 0)then + iis = 2 + write (*,*) 'Assuming Sinc Interpolation ' + else + write (*,*) 'Assuming Nearest Neighbor ' + end if + +c input of resampling + if(ift .le. 1) then + ALLOCATE( rvs(0:2*ndac-1,0:nddn-1) ) + else + ALLOCATE( rvs(0:ndac-1,0:nddn-1) ) + end if + write(*,*) 'Allocated a map of dimension ',ndac,nddn + +c variable for reading data + + if(ndac .gt. nrac) then + nac = ndac + else + nac = nrac + end if + ALLOCATE( carr(0:2*nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac +c there is no need to allocate an array for rmg type +c For byte format *****GP 01-05****** + ALLOCATE( barr(0:nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac + ALLOCATE( rarr(0:nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac + ALLOCATE( darr(0:nac-1) ) + write(*,*) 'Allocated an array of dimension ',nac + + +c output of resampling + if(ift .le. 1) then + ALLOCATE( arr(0:2*nrac-1) ) + else + ALLOCATE( arr(0:nrac-1) ) + end if + write(*,*) 'Allocated array of dimension ',nrac + + write (*,*) 'opening files ...' + +c open files + open(11,file=infile,form='unformatted', + . access='direct',recl=psize*ndac,status='old') + open(12,file=outfile,form='unformatted', + . access='direct',recl=psize*nrac,status='unknown') + +c forcing NN interpolation for byte format +c if(ift .eq. 2) then +c iis = 0 +c end if + + +c read in the data + + write (*,*) 'reading data ...' + + if(ift .eq. 0) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (carr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = real(carr(k)) + rvs(k+ndac,j) = aimag(carr(k)) + end do + end do + elseif(ift .eq. 1) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (rvs(k,j),k=0,2*ndac-1) + if(ierr .ne. 0) goto 999 + end do + elseif(ift .eq. 2) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (barr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = barr(k) + end do + end do + elseif(ift .eq. 3) then + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (rarr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = rarr(k) + end do + end do + else + do j = 0 , nddn-1 + if(mod(j,4096) .eq. 0) write (*,*) j + read(11,rec=j+1,iostat=ierr) (darr(k),k=0,ndac-1) + if(ierr .ne. 0) goto 999 + do k = 0 , ndac -1 + rvs(k,j) = darr(k) + end do + end do + end if + + 999 write (*,*) 'finished read ',j,' now interpolating ...' + +c do the interpolation + + do j = 0 , nrdn-1 + if(mod(j,4096) .eq. 0) write (*,*) j +c rowval = dble(j) +c rowval = (rowval - (ldn - 1.0) / 2.0) / ldn + call look_coord_conv(ldn0, dble(j), ldn, rowval) + + if(iis .eq. 0) then ! nearest neighbor + + do i = 0 , nrac-1 +c colval = dble(i) +c colval = (colval - (lac - 1.0) / 2.0) / lac + call look_coord_conv(lac0, dble(i), lac, colval) + ocolval_tmp = a * colval + b * rowval + e + orowval_tmp = c * colval + d * rowval + f +c ocolval = ocolval * lac + (lac - 1.0) / 2.0 +c orowval = orowval * ldn + (ldn - 1.0) / 2.0 + call look_coord_conv(ldn, orowval_tmp, ldn0, orowval) + call look_coord_conv(lac, ocolval_tmp, lac0, ocolval) + oi = nint(ocolval) + oj = nint(orowval) + if(.not.(oi .lt. 0 .or. oi .ge. ndac .or. oj .lt. 0 .or + $ . oj .ge. nddn)) then + arr(i) = rvs(oi,oj) + if(ift .le. 1) then + arr(i+nrac) = rvs(oi+ndac,oj) + end if + else + arr(i) = 0. + if(ift .le. 1) then + arr(i+nrac) = 0. + end if + end if + end do + + elseif(iis. eq. 1) then ! bilinear interpolation + + do i = 0 , nrac-1 +c colval = dble(i) +c colval = (colval - (lac - 1.0) / 2.0) / lac + call look_coord_conv(lac0, dble(i), lac, colval) + ocolval_tmp = a * colval + b * rowval + e + orowval_tmp = c * colval + d * rowval + f +c ocolval = ocolval * lac + (lac - 1.0) / 2.0 +c orowval = orowval * ldn + (ldn - 1.0) / 2.0 + call look_coord_conv(ldn, orowval_tmp, ldn0, orowval) + call look_coord_conv(lac, ocolval_tmp, lac0, ocolval) + oi = nint(ocolval) + oj = nint(orowval) + ifrac = (ocolval - oi) + jfrac = (orowval - oj) + if(ifrac .lt. 0.d0) then + oi = oi - 1 + ifrac = (ocolval - oi) + end if + if(jfrac .lt. 0.d0) then + oj = oj - 1 + jfrac = (orowval - oj) + end if + if(.not.(oi .lt. 0 .or. oi .ge. ndac-1 .or. oj .lt. 0 .or + $ . oj .ge. nddn-1)) then + pt1(1) = 0. + pt1(2) = 0. + pt1(3) = rvs(oi,oj) + pt2(1) = 1. + pt2(2) = 0. + pt2(3) = rvs(oi+1,oj) + pt3(1) = 0. + pt3(2) = 1. + pt3(3) = rvs(oi,oj+1) + pt4(1) = 1. + pt4(2) = 1. + pt4(3) = rvs(oi+1,oj+1) + call bilinear(pt1,pt2,pt3,pt4,sngl(ifrac),sngl(jfrac),arr(i)) + if(ift .le. 1) then + pt1(1) = 0. + pt1(2) = 0. + pt1(3) = rvs(oi+ndac,oj) + pt2(1) = 1. + pt2(2) = 0. + pt2(3) = rvs(oi+1+ndac,oj) + pt3(1) = 0. + pt3(2) = 1. + pt3(3) = rvs(oi+ndac,oj+1) + pt4(1) = 1. + pt4(2) = 1. + pt4(3) = rvs(oi+1+ndac,oj+1) + call bilinear(pt1,pt2,pt3,pt4,sngl(ifrac),sngl(jfrac),arr(i+nrac)) + end if + else + arr(i) = 0. + if(ift .le. 1) then + arr(i+nrac) = 0. + end if + end if + end do + + + elseif(iis. eq. 2) then ! sinc interpolation + + do i = 0 , nrac-1 +c colval = dble(i) +c colval = (colval - (lac - 1.0) / 2.0) / lac + call look_coord_conv(lac0, dble(i), lac, colval) + ocolval_tmp = a * colval + b * rowval + e + orowval_tmp = c * colval + d * rowval + f +c ocolval = ocolval * lac + (lac - 1.0) / 2.0 +c orowval = orowval * ldn + (ldn - 1.0) / 2.0 + call look_coord_conv(ldn, orowval_tmp, ldn0, orowval) + call look_coord_conv(lac, ocolval_tmp, lac0, ocolval) + oi = nint(ocolval) + oj = nint(orowval) + ifrac = (ocolval - oi) + jfrac = (orowval - oj) + if(ifrac .lt. 0.d0) then + oi = oi - 1 + ifrac = (ocolval - oi) + end if + if(jfrac .lt. 0.d0) then + oj = oj - 1 + jfrac = (orowval - oj) + end if + +! if(.not.(oi .lt. 4 .or. oi .ge. ndac-3 .or. oj .lt. 4 .or +! $ . oj .ge. nddn-3)) then +! I changed the upper sentence, as I have debug the array problem in interp.f, Cunren Liang, 03-JUN-2015 + if(.not.(oi .lt. 4 .or. oi .ge. ndac-4 .or. oj .lt. 4 .or + $ . oj .ge. nddn-4)) then + arr(i) = interp(oi, oj, ifrac, jfrac, rvs, ndac, 0) + if(ift .le. 1) then + arr(i+nrac) = interp(oi, oj, ifrac, jfrac, rvs, ndac, ndac) + end if + else + arr(i) = 0. + if(ift .le. 1) then + arr(i+nrac) = 0. + end if + end if + end do + + end if + + if(ift .eq. 0) then + do k = 0 , nrac -1 + carr(k) = cmplx(arr(k),arr(k+nrac)) + end do + write(12,rec=j+1) (carr(k),k=0,nrac-1) + elseif(ift .eq. 1) then + write(12,rec=j+1) (arr(k),k=0,2*nrac-1) + elseif(ift .eq. 2) then + do k = 0 , nrac -1 + barr(k) = arr(k) + end do + write(12,rec=j+1) (barr(k),k=0,nrac-1) + elseif(ift .eq. 3) then + do k = 0 , nrac -1 + rarr(k) = arr(k) + end do + write(12,rec=j+1) (rarr(k),k=0,nrac-1) + else + do k = 0 , nrac -1 + darr(k) = arr(k) + end do + write(12,rec=j+1) (darr(k),k=0,nrac-1) + end if + + end do + + DEALLOCATE(rvs) + DEALLOCATE(carr) + DEALLOCATE(barr) + DEALLOCATE(rarr) + DEALLOCATE(darr) + DEALLOCATE(arr) + + close(unit=11) + close(unit=12) + end diff --git a/contrib/alos2proc_f/src/schbasis.f b/contrib/alos2proc_f/src/schbasis.f new file mode 100644 index 0000000..00d8df9 --- /dev/null +++ b/contrib/alos2proc_f/src/schbasis.f @@ -0,0 +1,95 @@ +c**************************************************************** + + subroutine schbasis(ptm,r_sch,r_xyzschmat,r_schxyzmat) + +c**************************************************************** +c** +c** FILE NAME: schbasis.f +c** +c** DATE WRITTEN: 10/01/97 +c** +c** PROGRAMMER: Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: This routine computes the transformation +c** matrix from xyz to a local sch frame. +c** +c** ROUTINES CALLED: +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + +c structure /pegtrans/ !peg transformation parameters +c real*8 r_mat(3,3) +c real*8 r_matinv(3,3) +c real*8 r_ov(3) +c real*8 r_radcur +c end structure +c record /pegtrans/ ptm + + type pegtrans + sequence + real (8) r_mat(3,3) + real (8) r_matinv(3,3) + real (8) r_ov(3) + real (8) r_radcur + end type pegtrans + + type (pegtrans) ptm + + real*8 r_sch(3) !SCH position + +c OUTPUT VARIABLES: + + real*8 r_xyzschmat(3,3) + real*8 r_schxyzmat(3,3) + +c LOCAL VARIABLES: + + real*8 r_coss,r_cosc,r_sins,r_sinc + real*8 r_xyzv(3),r_llh(3),r_schhdg + real*8 r_matschxyzp(3,3) + +c DATA STATEMENTS: none + +C FUNCTION STATEMENTS: + +c PROCESSING STEPS: + +c compute transformation from a sch local basis to X'Y'Z' basis + + r_coss = cos(r_sch(1)/ptm%r_radcur) + r_sins = sin(r_sch(1)/ptm%r_radcur) + + r_cosc = cos(r_sch(2)/ptm%r_radcur) + r_sinc = sin(r_sch(2)/ptm%r_radcur) + + r_matschxyzp(1,1) = -r_sins + r_matschxyzp(1,2) = -r_sinc*r_coss + r_matschxyzp(1,3) = r_coss*r_cosc + r_matschxyzp(2,1) = r_coss + r_matschxyzp(2,2) = -r_sinc*r_sins + r_matschxyzp(2,3) = r_sins*r_cosc + r_matschxyzp(3,1) = 0.0 + r_matschxyzp(3,2) = r_cosc + r_matschxyzp(3,3) = r_sinc + +c compute sch to xyz matrix + + call matmat(ptm%r_mat,r_matschxyzp,r_schxyzmat) + +c get the inverse + + call tranmat(r_schxyzmat,r_xyzschmat) + + end + + + + diff --git a/contrib/alos2proc_f/src/tranmat.f b/contrib/alos2proc_f/src/tranmat.f new file mode 100644 index 0000000..8c4df36 --- /dev/null +++ b/contrib/alos2proc_f/src/tranmat.f @@ -0,0 +1,46 @@ +c**************************************************************** + + subroutine tranmat(r_a,r_b) + +c**************************************************************** +c** +c** FILE NAME: tranmat.f +c** +c** DATE WRITTEN: 8/3/90 +c** +c** PROGRAMMER:Scott Hensley +c** +c** FUNCTIONAL DESCRIPTION: The subroutine takes a 3x3 matrix +c** and computes its transpose. +c** +c** ROUTINES CALLED:none +c** +c** NOTES: none +c** +c** UPDATE LOG: +c** +c***************************************************************** + + implicit none + +c INPUT VARIABLES: + real*8 r_a(3,3) !3x3 matrix + +c OUTPUT VARIABLES: + real*8 r_b(3,3) !3x3 matrix + +c LOCAL VARIABLES: + integer i,j + +c PROCESSING STEPS: + +c compute matrix product + + do i=1,3 + do j=1,3 + r_b(i,j) = r_a(j,i) + enddo + enddo + + end + diff --git a/examples/input_files/alos2/alos2App.xml b/examples/input_files/alos2/alos2App.xml new file mode 100644 index 0000000..e11558b --- /dev/null +++ b/examples/input_files/alos2/alos2App.xml @@ -0,0 +1,308 @@ + + + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + + [3055] + [3055] + + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/alos2_tutorial.txt b/examples/input_files/alos2/alos2_tutorial.txt new file mode 100644 index 0000000..daba993 --- /dev/null +++ b/examples/input_files/alos2/alos2_tutorial.txt @@ -0,0 +1,350 @@ +###################################################################################### +# Tutorial for InSAR Applications alos2App.py and alos2burstApp.py +# Cunren Liang, JPL/Caltech, March 2020 +###################################################################################### + +The alos2App.py is designed to process all possible InSAR combinations of ALOS-2 multi-mode +data. ALOS-2 can acquire data in spotlight, stripmap and ScanSAR modes. In each mode, the +data may have different sample size, coverage, look side (right/left), range band, azimuth band, +wavelength, and so on. In addition, the two images used for interferometry can be acquired in +different acquistion modes such as ScanSAR-stripmap interferometry. As long as the master and +slave images meet the following requirements: + +1. acquired on the same track +2. have enough spatial coverage +3. have enough range overlap band +4. have enough azimuth overlap band + +an interferogram can be created by alos2App.py. These basically include spotlight-spotlight +interferometry, stripmap-stripmap interferometry, ScanSAR-stripmap interferometry and ScanSAR-ScanSAR +interometry. Note that even in same-mode interferometry, master and slave may be acquired in +different sub-modes. Support for spotlight mode will soon be added. + +As a summary for alos2App.py, ONE COMMAND TO PROCESS THEM ALL. + +For ScanSAR-ScanSAR interferomery, alos2App.py implements the full-aperture workflow, while +alos2burstApp.py, which only supports ScanSAR-ScanSAR interferometry, implements the standard +burst-by-burst workflow. Both alos2App.py and alos2burstApp.py use full-aperture products from +JAXA, since the current JAXA burst products are not usable for InSAR. Note that you are still +recommended to use alos2App.py for ScanSAR-ScanSAR interferometry. When using alos2burstApp.py, +you can also get along-track deformation, but usually contaminated by azimuth ionoshperic shifts. +On the other hand, this provides a way of looking at large-scale azimuth shifts caused by ionosphere. + + +########################################### +# 0. SOFTWARE FEATURES +########################################### + +Basically the software supports +* Regular InSAR processing (All possible acquisition mode combinations) +* Burst Spectral Diversity (SD) or Multiple Aperture InSAR (MAI) (ScanSAR) +* Pixel offset (spotlight/stripmap) +* Ionospheric correction (all possible acquistion mode combinations) + + +SOFTWARE CAPABILITIES +* One app to process them all +* Support all ALOS-2 acquisition modes +* Support making interferograms across all three wavelengths +* Both full-aperture and burst-by-burst ScanSAR InSAR workflows implemented +* ScanSAR system parameters estimated from azimuth spectrum +* Automatic estimation of the start times of raw burst from azimuth spectrum +* High precision burst synchronization calculation +* MBF filter for removing non-overlap spectra caused by burst misalignment and Doppler centroid + frequency difference +* High precision estimation of offsets between subswaths and frames +* High precision mosaic of subswaths and frames +* Automatic ionospheric correction + +* Burst extraction from full-aperture ScanSAR data +* Burst-by-burst ScanSAR InSAR processing +* Azimuth or along-track offset from ScanSAR burst Spectral Diversity (SD) or Multiple Aperture + InSAR (MAI) +* Ionospheric correction for burst-by-burst ScanSAR interferometry + + +SOFTWARE EFFICIENCY +* Optimized workflow to reduce processing time +* Using virtual files to reduce the huge amount of input/output +* Using OpenMP to speed up for loops +* Using CUDA GPU to speed up some of the programs + +While processing time depends on computer configurations, we can expect a ScanSAR-ScanSAR pair to be +processed in 2~3 hours, including ionospheric correction. + + +SOFTWARE ROBUSTNESS +* Enhanced robustness for an automatic processing system +* Upgraded programs considering the properties of multi-mode InSAR images to enable robust processing + + +USER FRIENDLY +one same command and one same input file to process all acquistion modes + + +########################################### +# 1. PREPARE DATA +########################################### + +1. ALOS-2 data +For each acquistion date, unpack data of all frames to a directory. There are usually multiple polarizations +in the data. Normally we only process HH polarization, so you can only extract HH polarizations from the +zip files to save space. If you want to process other polarizations, extract those polarization instead. + +2. DEM and water body +If you only process one InSAR pair, there is no need to download DEM and water body. The program will +do it for you. However, if you want to process a stack of interferograms, we recommend downloading DEM +and water body by yourself and set the parameters in the input file; otherwise, the program will download +DEM and water body each time it processes a pair. See input file on how to download DEM and water +body. + + +########################################### +# 2. SET PARAMETERS +########################################### + +1. Input files alos2App.xml (input of alos2App.py) and alos2burstApp.xml (input of alos2burstApp.py) +can be found in "examples/input_files/alos2" in the package. Normally you only need alos2App.py to +process all kinds of InSAR combinations. + +2. Set the following parameters in the input file: + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + + + [3055] + [3055] + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + +3. If you want to process a stack of interferograms, you can geocode the products to the same area by +setting the following parameters: + + + None + +If you want to do more customized processing, explore all other available parameters in the input file. + + +4. If it still does not work, check the example input files in folder "examples/input_files/alos2/example_input_files", +which includes all possible InSAR combinations. + +To find the acquisition mode code, check the unpacked ALOS-2 product. For example, in the following +file name + +IMG-HH-ALOS2183010685-171012-FBDR1.1__A + ^^^ +FBD (indicated by ^) is the acquisition mode code. Here is the list of acquistion modes: + + Operation Mode | Mode (AUIG2) | Mode (in file name) +-------------------------------------------------------------- + spotlight | SPT | SBS +-------------------------------------------------------------- + stripmap | SM1 | UBS, UBD + | SM2 | HBS, HBD, HBQ + | SM3 | FBS, FBD, FBQ +-------------------------------------------------------------- + ScanSAR | WD1 | WBS, WBD, WWS, WWD + | WD2 | VBS, VBD + +Note that, in ScanSAR-stripmap interferometry, ScanSAR must be master! + + +########################################### +# 3. PROCESS DATA +########################################### + +1. Run alos2App.py or alos2burstApp.py as other apps in ISCE after setting up input file. For example, +alos2App.py --steps + +2. If you want to run an individual step, you can run a command like +alos2App.py --dostep=form_int + +3. You can also specifiy the starting and ending steps, for example, +alos2App.py --start=form_int --end=diff_int + + +########################################### +# 4. CHECK RESULTS +########################################### + +*.track.xml: parameters common to a track. + +f*_*/*.frame.xml: parameters specific to a frame. + +alos2Proc.xml: processing parameters, such as baselines, ScanSAR burst synchronization, number of offsets +used to do matching etc. + +f*_*/mosaic/swath_offset_*.txt: a comparison of the swath offsets computed from parameter and estimated +from overlap areas. Only for multi-swath data such as ScanSAR. + +insar/frame_offset_*.txt: a comparision of the frame offsets computed from parameter and estimated from +overlap areas. Only for multi-frame data. + + +PICKLE: You can find explanations about each data file in the xml files. + +f*_*: folders containing the frame processing results. + +insar: users should be mostly interested in this folder. For the explanations of the files, please refer +to the xml files in folder "explanations". You can find the differential interferograms without and with +ionospheric correction if you have chosen to do ionospheric correction. For example, +diff_150405-150503_5rlks_28alks.int: interferoram without ionospheric correction +diff_150405-150503_5rlks_28alks_ori.int: interferogram with ionospheric correction + +ion: folder for computing ionospheric phase. subband interferograms are created in folders "lower" and +"upper", and final computations are done in "ion_cal". + +dense_offset: dense offset processing results. In this folder: +*_coreg.slc: coregistered slave image. Offsets used to do resampling include geomtrical offsets + residual +offsets from cross-correlation. + + +########################################### +# 5. FINAL RESULTS +########################################### + +File names shown here are from particular pairs, you need to find your corresponding ones. For all sign +conventions, we assume master is the earlier acquistion. If your master is the later acquistion, the sign +will be opposite! + + +1. Regular InSAR LOS Deformation + +without mask from phase unwrapping: +insar/filt_150405-150503_5rlks_28alks.unw.geo +with mask from phase unwrapping: +insar/filt_150405-150503_5rlks_28alks_msk.unw.geo + +These are InSAR phase [first date (150405) - second date (150503)] in radians. you can convert these to +deformation by multiplying them by wavelength/(4*PI), where you can find wavelength in track parameter +file 150405.track.xml. Note that ALOS-2 has three wavelengths, you should use the wavelength from this +file instead of other sources. + ++ sign: moving away from satellite. This is theoretically and experimentally verified. +(e.g. hawaii/alos2/a089/180508-180522/filt_diff_180508-180522_8rlks_16alks_msk.unw.geo) + + +2. ScanSAR Spectral Diversity (SD) or Multiple Aperture InSAR (MAI) + +SD/MAI mainly contains along-track deformation and along-track offset caused by ionosphere. + +without mask from phase unwrapping: +sd/azd_1_150405-150503_14rlks_4alks.unw.geo +sd/azd_2_150405-150503_14rlks_4alks.unw.geo +sd/azd_3_150405-150503_14rlks_4alks.unw.geo +sd/azd_150405-150503_14rlks_4alks.unw.geo + +with mask from phase unwrapping: +sd/azd_1_150405-150503_14rlks_4alks_msk.unw.geo +sd/azd_2_150405-150503_14rlks_4alks_msk.unw.geo +sd/azd_3_150405-150503_14rlks_4alks_msk.unw.geo +sd/azd_150405-150503_14rlks_4alks_msk.unw.geo + +The unit of these files is meter. Here the numbers 1, 2 and 3 mean the number of burst cycles +in-between the foward and backward looks in MAI. The larger the number is, the more sensitive the measure +is to the along-track deformation. Therefore, we expect number 3 has highest signal to noise ratio (SNR). +The final one without this number is the weight average of all the three. While number 3 has the highest +SNR, it also has the highest probability of phase unwrapping errors, especially near the ruptures in an +earthquake. Users should carefully check if there are phase unwrapping errors, as in regular InSAR +processing. + ++ sign: moving toward radar flying direction. This is experimentally verified. +(e.g. 1. hawaii/alos2/d185/sd/azd_180120-180512_28rlks_8alks_msk.unw.geo, 2. iran_2017/d71/171004-171115_burst) + + +3. Stripmap Pixel Offset + +pixel offset file, 1st band: range offset, 2nd band: azimuth offset +dense_offset/141114-160415_denseoffset.off.geo +SNR file +dense_offset/141114-160415_denseoffset.snr.geo + +The unit of the pixel offsets is number of range/azimuth pixels. You can convert them to range or azimuth +deformation using range/azimuth pixel sizes, which you can find in the track parameter file: +141114.track.xml. + ++ sign (Range offset): moving away from satellite ++ sign (azimuth offset): moving toward radar flying direction + + +########################################### +# 6. KNOWN ISSUES +########################################### + +1. Issues with Ionospheric Correction +According to our experience, ionospheric correction works for most of the interferograms. Because it +relies on coherence and phase unwrapping, it does not work in some cases. These include: + +(1) data have low coherence +(2) the majority of the imaged area is low coherence area like lake, ocean... +(3) the imaged area is completely divided into several isolated areas by low coherence areas, such as + islands. + +In addition to the above issues, there are also data-mode-related issues. +(1) ScanSAR-ScanSAR interferometry. While you can process one single subswath, it's better to process +more than one subswath if the addistional subswath has good coherence. This is good for ionospheric +correction. + +(2) ScanSAR-stripmap interferometry and interferometry with data of different range bands. Because of +the small effective number of looks and the possible small overlap of the two range bands, ionospheric +correciton is likely not working well. + +(3) Range distortions in JAXA product. This mostly happens in stripmap-stripmap interferometry using +data not covering Japan. If you see very dense fringes in the corrected inteferogram, probably it is +caused by this problem. This has been reported to JAXA and JAXA is working on debugging the focusing +program. + +UPDATE: On November 20, 2018 (JST), JAXA updated the software for PALSAR-2 standard products. Therefore, +if your product is ordered after this time, you don't have this problem. + + +2. How do I improve ionospheric correction? +Sometimes you may find that the ionospheric phase automatically calculated using default parameters +are not good enough. In this case, you may want to adjust the parameters by yourself in the input file. +In particular, if your scene covers an area with two or more isolated areas and you are interested in +one of the areas, you can mask out the other areas by setting +"areas masked out in ionospheric phase estimation". + +After updating the input file, you can re-do ionospheric correction by running: +alos2App.py --dostep=ion_filt +or +alos2burstApp.py --dostep=ion_filt + + +3. Master and slave have different wavelengths +If master and slave are acquired in different acquistion modes, it's likely that they have different +wavelengths, If master and slave have different wavelengths, the resulting interferogram might have a +residual range ramp. This is probably caused by the relative wavelength errors of the two wavelengths. + + +4. ScanSAR burst synchronization +For ScanSAR data acquired before February 8, 2015, chances of having enough burst synchronization for +interferometry is very low. If the master image, slave image or both are acquired before this date, the +interferogram will be probably full of noise and not useful. + + +########################################### +# 7. REFRENCES +########################################### +The methods and algorithms implemented can be found in the following papers. + +1. ScanSAR or multi-mode InSAR processing +C. Liang and E. J. Fielding, "Interferometry with ALOS-2 full-aperture ScanSAR data," +IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2739-2750, May 2017. + +2. Ionospheric correction, burst-by-burst ScanSAR processing, and burst-mode spectral diversity (SD) or +multi-aperture InSAR (MAI) processing +C. Liang and E. J. Fielding, "Measuring azimuth deformation with L-band ALOS-2 ScanSAR interferometry," +IEEE Transactions on Geoscience and Remote Sensing, vol. 55, no. 5, pp. 2725-2738, May 2017. + +3. Ionospheric correction +C. Liang, Z. Liu, E. J. Fielding, and R. Bürgmann, "InSAR time series analysis of L-band wide-swath SAR +data acquired by ALOS-2," +IEEE Transactions on Geoscience and Remote Sensing, vol. 56, no. 8, pp. 4492-4506, Aug. 2018. + diff --git a/examples/input_files/alos2/alos2burstApp.xml b/examples/input_files/alos2/alos2burstApp.xml new file mode 100644 index 0000000..d9bd25c --- /dev/null +++ b/examples/input_files/alos2/alos2burstApp.xml @@ -0,0 +1,293 @@ + + + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + + [3055] + [3055] + + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar/1/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-scansar/1/alos2App.xml new file mode 100644 index 0000000..2e8e8da --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar/1/alos2App.xml @@ -0,0 +1,298 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055] + [3055] + 1 + 1 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar/2/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-scansar/2/alos2App.xml new file mode 100644 index 0000000..c8b78bc --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar/2/alos2App.xml @@ -0,0 +1,298 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055] + [3055] + 1 + 5 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar/3/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-scansar/3/alos2App.xml new file mode 100644 index 0000000..8e0f312 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar/3/alos2App.xml @@ -0,0 +1,298 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055, 3100] + [3055, 3100] + 1 + 1 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar/4/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-scansar/4/alos2App.xml new file mode 100644 index 0000000..abbb3a5 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar/4/alos2App.xml @@ -0,0 +1,298 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055, 3100] + [3055, 3100] + 1 + 5 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar_7s/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-scansar_7s/alos2App.xml new file mode 100644 index 0000000..42437e6 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar_7s/alos2App.xml @@ -0,0 +1,298 @@ + + + + + ../../z_common_data/insarzd_test_dataset/kumamoto/a135/150209 + ../../z_common_data/insarzd_test_dataset/kumamoto/a135/160418 + [0650] + [0650] + 1 + 7 + + ../../z_common_data/insarzd_test_dataset/kumamoto/dem/demLat_N29_N37_Lon_E125_E133.dem.wgs84 + ../../z_common_data/insarzd_test_dataset/kumamoto/dem/3/demLat_N29_N37_Lon_E125_E133.dem.wgs84 + ../../z_common_data/insarzd_test_dataset/kumamoto/wbd/swbdLat_N29_N37_Lon_E125_E133.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar_burst/1/alos2burstApp.xml b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/1/alos2burstApp.xml new file mode 100644 index 0000000..068d8c2 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/1/alos2burstApp.xml @@ -0,0 +1,282 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055] + [3055] + 1 + 1 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar_burst/2/alos2burstApp.xml b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/2/alos2burstApp.xml new file mode 100644 index 0000000..a034937 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/2/alos2burstApp.xml @@ -0,0 +1,282 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055] + [3055] + 1 + 5 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar_burst/3/alos2burstApp.xml b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/3/alos2burstApp.xml new file mode 100644 index 0000000..69d393e --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/3/alos2burstApp.xml @@ -0,0 +1,282 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055, 3100] + [3055, 3100] + 1 + 1 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-scansar_burst/4/alos2burstApp.xml b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/4/alos2burstApp.xml new file mode 100644 index 0000000..bd79853 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-scansar_burst/4/alos2burstApp.xml @@ -0,0 +1,282 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150405 + ../../../z_common_data/insarzd_test_dataset/gorkha/d048/150503 + [3055, 3100] + [3055, 3100] + 1 + 5 + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-stripmap/1/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-stripmap/1/alos2App.xml new file mode 100644 index 0000000..5e06b14 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-stripmap/1/alos2App.xml @@ -0,0 +1,296 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/140809 + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/150725 + [0550] + [0540] + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/scansar-stripmap/2/alos2App.xml b/examples/input_files/alos2/example_input_files/scansar-stripmap/2/alos2App.xml new file mode 100644 index 0000000..bcef8e9 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/scansar-stripmap/2/alos2App.xml @@ -0,0 +1,296 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/140809 + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/150725 + [0550, 0550, 0550, 0550] + [0540, 0550, 0560, 0570] + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/software_test.txt b/examples/input_files/alos2/example_input_files/software_test.txt new file mode 100644 index 0000000..3cbd898 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/software_test.txt @@ -0,0 +1,25 @@ + Combination | Description | Result +==================================================================================== +stripmap-stripmap | 1: regular one frame | + | 2: regular two frames (interferogram+offset) | + | 3: different wavelengths one frame | + | 4: different wavelengths three frames | +------------------------------------------------------------------------------------ +ScanSAR-stripmap | 1: one frame | + | 2: four frames | +------------------------------------------------------------------------------------ +ScanSAR-ScanSAR | 1: one frame one subswath | +(5-subswath mode) | 2: one frame all subswaths | + | 3: two frames one subswath | + | 4: two frames all subswaths | +------------------------------------------------------------------------------------ +ScanSAR-ScanSAR | 1: one frame one subswath | +(5-subswath mode) | 2: one frame all subswaths | +(burst-by-burst | 3: two frames one subswath | +processing) | 4: two frames all subswaths | +------------------------------------------------------------------------------------ +ScanSAR-ScanSAR | one frame all subswaths | +(7-subswath mode) | | +------------------------------------------------------------------------------------ + + diff --git a/examples/input_files/alos2/example_input_files/stripmap-stripmap/1/alos2App.xml b/examples/input_files/alos2/example_input_files/stripmap-stripmap/1/alos2App.xml new file mode 100644 index 0000000..9d85778 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/stripmap-stripmap/1/alos2App.xml @@ -0,0 +1,296 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/kumamoto/d028l/141114 + ../../../z_common_data/insarzd_test_dataset/kumamoto/d028l/160415 + [2920] + [2920] + + ../../../z_common_data/insarzd_test_dataset/kumamoto/dem/demLat_N29_N37_Lon_E125_E133.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/kumamoto/dem/3/demLat_N29_N37_Lon_E125_E133.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/kumamoto/wbd/swbdLat_N29_N37_Lon_E125_E133.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/stripmap-stripmap/2/alos2App.xml b/examples/input_files/alos2/example_input_files/stripmap-stripmap/2/alos2App.xml new file mode 100644 index 0000000..3d86775 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/stripmap-stripmap/2/alos2App.xml @@ -0,0 +1,298 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/kumamoto/d028l/141114 + ../../../z_common_data/insarzd_test_dataset/kumamoto/d028l/160415 + [2920, 2930] + [2920, 2930] + + ../../../z_common_data/insarzd_test_dataset/kumamoto/dem/demLat_N29_N37_Lon_E125_E133.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/kumamoto/dem/3/demLat_N29_N37_Lon_E125_E133.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/kumamoto/wbd/swbdLat_N29_N37_Lon_E125_E133.wbd + + True + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/stripmap-stripmap/3/alos2App.xml b/examples/input_files/alos2/example_input_files/stripmap-stripmap/3/alos2App.xml new file mode 100644 index 0000000..4b1c9c4 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/stripmap-stripmap/3/alos2App.xml @@ -0,0 +1,296 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/150502 + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/150725 + [0540] + [0540] + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/stripmap-stripmap/4/alos2App.xml b/examples/input_files/alos2/example_input_files/stripmap-stripmap/4/alos2App.xml new file mode 100644 index 0000000..7644def --- /dev/null +++ b/examples/input_files/alos2/example_input_files/stripmap-stripmap/4/alos2App.xml @@ -0,0 +1,296 @@ + + + + + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/150502 + ../../../z_common_data/insarzd_test_dataset/gorkha/a157/150725 + [0540, 0550, 0560] + [0540, 0550, 0560] + + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + ../../../z_common_data/insarzd_test_dataset/gorkha/dem/3/demLat_N22_N33_Lon_E078_E092.dem.wgs84 + /net/kraken/nobak/cunrenl/z_common_data/insarzd_test_dataset/gorkha/wbd/swbdLat_N22_N33_Lon_E078_E092.wbd + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/input_files/alos2/example_input_files/test1.sh b/examples/input_files/alos2/example_input_files/test1.sh new file mode 100644 index 0000000..e4ad7a4 --- /dev/null +++ b/examples/input_files/alos2/example_input_files/test1.sh @@ -0,0 +1,54 @@ +#scansar-scansar +########################## +cd scansar-scansar/1 +alos2App.py --steps +cd ../../ + +cd scansar-scansar/2 +alos2App.py --steps +cd ../../ + +cd scansar-scansar/3 +alos2App.py --steps +cd ../../ + +cd scansar-scansar/4 +alos2App.py --steps +cd ../../ + + +#scansar-stripmap +########################## +cd scansar-stripmap/1 +alos2App.py --steps +cd ../../ + +cd scansar-stripmap/2 +alos2App.py --steps +cd ../../ + + +#stripmap-stripmap +########################## +cd stripmap-stripmap/1 +alos2App.py --steps +cd ../../ + +cd stripmap-stripmap/2 +alos2App.py --steps +cd ../../ + +cd stripmap-stripmap/3 +alos2App.py --steps +cd ../../ + +cd stripmap-stripmap/4 +alos2App.py --steps +cd ../../ + + +#scansar-scansar_7s +########################## +cd scansar-scansar_7s +alos2App.py --steps +cd ../ diff --git a/examples/input_files/alos2/example_input_files/test2.sh b/examples/input_files/alos2/example_input_files/test2.sh new file mode 100644 index 0000000..991a18e --- /dev/null +++ b/examples/input_files/alos2/example_input_files/test2.sh @@ -0,0 +1,16 @@ +#scansar-scansar_burst +cd scansar-scansar_burst/1 +alos2burstApp.py --steps +cd ../../ + +cd scansar-scansar_burst/2 +alos2burstApp.py --steps +cd ../../ + +cd scansar-scansar_burst/3 +alos2burstApp.py --steps +cd ../../ + +cd scansar-scansar_burst/4 +alos2burstApp.py --steps +cd ../../