ISCE_INSAR/components/stdproc/stdproc/estamb/Estamb.py

995 lines
40 KiB
Python
Executable File

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Copyright 2013 California Institute of Technology. ALL RIGHTS RESERVED.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# United States Government Sponsorship acknowledged. This software is subject to
# U.S. export control laws and regulations and has been classified as 'EAR99 NLR'
# (No [Export] License Required except when exporting to an embargoed country,
# end user, or in support of a prohibited end use). By downloading this software,
# the user agrees to comply with all applicable U.S. export laws and regulations.
# The user has the responsibility to obtain export licenses, or other export
# authority as may be required before exporting this software to any 'EAR99'
# embargoed foreign country or citizen of those countries.
#
# Author: Piyush Agram
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import isce
from isceobj.Image.Image import Image
from iscesys.Component.Component import Component, Port
from stdproc.stdproc.estamb import estamb
NUMBER_GOOD_BYTES = Component.Parameter('numberGoodBytes',
public_name='NUMBER_GOOD_BYTES',
default=None,
type=int,
mandatory=True,
doc='Number of bytes used in a range line in the raw image'
)
NUMBER_BYTES_PER_LINE = Component.Parameter('numberBytesPerLine',
public_name='NUMBER_BYTES_PER_LINE',
default=None,
type=int,
mandatory=True,
doc='Number of bytes per line in the raw image'
)
FIRST_LINE = Component.Parameter('firstLine',
public_name='FIRST_LINE',
default=None,
type=int,
mandatory=True,
doc='First line processed in the raw image'
)
NUMBER_VALID_PULSES = Component.Parameter('numberValidPulses',
public_name='NUMBER_VALID_PULSES',
default=None,
type=int,
mandatory=True,
doc='Number of lines to be stored from each azimuth patch'
)
FIRST_SAMPLE = Component.Parameter('firstSample',
public_name='FIRST_SAMPLE',
default=None,
type=int,
mandatory=True,
doc='First valid sample in the range line'
)
NUMBER_PATCHES = Component.Parameter('numberPatches',
public_name='NUMBER_PATCHES',
default=1,
type=int,
mandatory=False,
doc='Number of patches used.'
)
START_RANGE_BIN = Component.Parameter('startRangeBin',
public_name='START_RANGE_BIN',
default=1,
type=int,
mandatory=False,
doc='Starting bin in the range direction. If negative, indicates near range extension.'
)
NUMBER_RANGE_BIN = Component.Parameter('numberRangeBin',
public_name='NUMBER_RANGE_BIN',
default=None,
type=int,
mandatory=True,
doc='Number of range bins to output. If greater than that of raw image, indicates near/far range extension.'
)
AZIMUTH_PATCH_SIZE = Component.Parameter('azimuthPatchSize',
public_name='AZIMUTH_PATCH_SIZE',
default=None,
type=int,
mandatory=True,
doc='Number of lines in an azimuth patch'
)
OVERLAP = Component.Parameter('overlap',
public_name='OVERLAP',
default=0,
type=int,
mandatory=False,
doc='Overlap between consecutive azimuth patches'
)
RAN_FFTOV = Component.Parameter('ranfftov',
public_name='RAN_FFTOV',
default=65536,
type=int,
mandatory=False,
doc='FFT size for offset video'
)
RAN_FFTIQ = Component.Parameter('ranfftiq',
public_name='RAN_FFTIQ',
default=32768,
type=int,
mandatory=False,
doc='FFT size for I/Q processing'
)
CALTONE_LOCATION = Component.Parameter('caltoneLocation',
public_name='CALTONE_LOCATION',
default=0,
type=int,
mandatory=False,
doc='Location of the calibration tone'
)
PLANET_LOCAL_RADIUS = Component.Parameter('planetLocalRadius',
public_name='PLANET_LOCAL_RADIUS',
default=None,
type=float,
mandatory=True,
doc='Local radius of the planet'
)
BODY_FIXED_VELOCITY = Component.Parameter('bodyFixedVelocity',
public_name='BODY_FIXED_VELOCITY',
default=None,
type=float,
mandatory=True,
doc='Platform velocity'
)
SPACECRAFT_HEIGHT = Component.Parameter('spacecraftHeight',
public_name='SPACECRAFT_HEIGHT',
default=None,
type=float,
mandatory=True,doc='Spacecraft height'
)
PRF = Component.Parameter('prf',
public_name='PRF',
default=None,
type=float,
mandatory=True,
doc='Pulse repetition frequency'
)
INPHASE_VALUE = Component.Parameter('inPhaseValue',
public_name='INPHASE_VALUE',
default=None,
type=float,
mandatory=True,
doc=''
)
QUADRATURE_VALUE = Component.Parameter('quadratureValue',
public_name='QUADRATURE_VALUE',
default=None,
type=float,
mandatory=True,
doc=''
)
AZIMUTH_RESOLUTION = Component.Parameter('azimuthResolution',
public_name='AZIMUTH_RESOLUTION',
default=None,
type=float,
mandatory=True,
doc='Desired azimuth resolution for determining azimuth B/W'
)
RANGE_SAMPLING_RATE = Component.Parameter('rangeSamplingRate',
public_name='RANGE_SAMPLING_RATE',
default=None,
type=float,
mandatory=True,
doc='Sampling frequency of the range pixels'
)
CHIRP_SLOPE = Component.Parameter('chirpSlope',
public_name='CHIRP_SLOPE',
default=None,
type=float,
mandatory=True,
doc='Frequency slope of the transmitted chirp'
)
RANGE_PULSE_DURATION = Component.Parameter('rangePulseDuration',
public_name='RANGE_PULSE_DURATION',
default=None,
type=float,
mandatory=True,
doc='Range pulse duration'
)
RADAR_WAVELENGTH = Component.Parameter('radarWavelength',
public_name='RADAR_WAVELENGTH',
default=None,
type=float,
mandatory=True,
doc='Radar wavelength'
)
RANGE_FIRST_SAMPLE = Component.Parameter('rangeFirstSample',
public_name='RANGE_FIRST_SAMPLE',
default=None,
type=float,
mandatory=True,
doc='Range of the first sample in meters'
)
IQ_FLIP = Component.Parameter('IQFlip',
public_name='IQ_FLIP',
default='n',
type=str,
mandatory=False,
doc='If I/Q channels are flipped in the raw data file'
)
POSITION = Component.Parameter('position',
public_name='POSITION',
default=[],
container=list,
type=float,
mandatory=True,
doc='Position vector'
)
TIME = Component.Parameter('time',
public_name='TIME',
default=[],
container=list,
type=float,
mandatory=True,
doc='Time vector'
)
DOPPLER_CENTROID_COEFFICIENTS = Component.Parameter(
'dopplerCentroidCoefficients',
public_name='DOPPLER_CENTROID_COEFFICIENTS',
default=[],
container=list,
type=float,
mandatory=True,
doc='Doppler centroid coefficients'
)
ENTROPY = Component.Parameter('entropy',
public_name='ENTROPY',
default=[],
container=list,
type=float,
mandatory=False,
private=True,
doc='ENTROPY'
)
MINIMUM_AMBIGUITY = Component.Parameter('minAmb',
public_name='MINIMUM_AMBIGUITY',
default = -3,
mandatory = None,
doc = 'Minimum doppler ambiguity for search window.'
)
MAXIMUM_AMBIGUITY = Component.Parameter('maxAmb',
public_name='MAXIMUM_AMBIGUITY',
default = 3,
mandatory = None,
doc = 'Maximum doppler ambiguity for search window.'
)
DOPPLER_AMBIGUITY = Component.Parameter('dopplerAmbiguity',
public_name='DOPPLER_AMBIGUITY',
default=None,
mandatory=False,
private=True,
doc='Doppler ambiguity estimated by estamb'
)
## This decorator takes a setter and only executes it if the argument is True
def set_if_true(func):
"""Decorate a setter to only set if the value is nonzero"""
def new_func(self, var):
if var:
func(self, var)
return new_func
#@pickled
class Estamb(Component):
dont_pickle_me = ()
parameter_list = (NUMBER_GOOD_BYTES,
NUMBER_BYTES_PER_LINE,
FIRST_LINE,
NUMBER_VALID_PULSES,
FIRST_SAMPLE,
NUMBER_PATCHES,
START_RANGE_BIN,
NUMBER_RANGE_BIN,
AZIMUTH_PATCH_SIZE,
OVERLAP,
RAN_FFTOV,
RAN_FFTIQ,
CALTONE_LOCATION,
PLANET_LOCAL_RADIUS,
BODY_FIXED_VELOCITY,
SPACECRAFT_HEIGHT,
PRF,
INPHASE_VALUE,
QUADRATURE_VALUE,
AZIMUTH_RESOLUTION,
RANGE_SAMPLING_RATE,
CHIRP_SLOPE,
RANGE_PULSE_DURATION,
RADAR_WAVELENGTH,
RANGE_FIRST_SAMPLE,
IQ_FLIP,
POSITION,
TIME,
DOPPLER_CENTROID_COEFFICIENTS,
ENTROPY,
DOPPLER_AMBIGUITY,
MINIMUM_AMBIGUITY,
MAXIMUM_AMBIGUITY
)
_vars = (
Component.Variable('numberGoodBytes', int, True),
Component.Variable('numberBytesPerLine', int, True),
Component.Variable('firstLine', int, False),
Component.Variable('numberValidPulses', int, True),
Component.Variable('firstSample', int, True),
Component.Variable('numberPatches', int, True),
Component.Variable('startRangeBin', int, False),
Component.Variable('numberRangeBin', int, True),
Component.Variable('azimuthPatchSize', int, False),
Component.Variable('overlap', int, False),
Component.Variable('ranfftov', int, False),
Component.Variable('ranfftiq', int, False),
Component.Variable('caltoneLocation', float, True),
Component.Variable('planetLocalRadius', float, True),
Component.Variable('bodyFixedVelocity', float, True),
Component.Variable('spacecraftHeight', float, True),
Component.Variable('prf', float, True),
Component.Variable('inPhaseValue', float, True),
Component.Variable('quadratureValue', float, True),
Component.Variable('azimuthResolution', float, True),
Component.Variable('rangeSamplingRate', float, True),
Component.Variable('chirpSlope', float, True),
Component.Variable('rangePulseDuration', float, True),
Component.Variable('radarWavelength', float, True),
Component.Variable('rangeFirstSample', float, True),
Component.Variable('IQFlip', str, True),
Component.Variable('position', '', True),
Component.Variable('time', float, True),
Component.Variable(
'dopplerCentroidCoefficients',
float,
True
),
Component.Variable('minAmb', int, False),
Component.Variable('maxAmb', int, False),
)
maxAzPatchSize = 32768
def estamb(self):
for item in self.inputPorts:
item()
self.computeRangeParams()
try:
self.rawAccessor = self.rawImage.getImagePointer()
except AttributeError:
self.logger.error("Error in accessing image pointers")
raise AttributeError
self.computePatchParams()
self.allocateArrays()
self.setDefaults()
self.setState()
estamb.estamb_Py(self.rawAccessor)
self.getState()
self.deallocateArrays()
return self.entropy, self.dopplerAmbiguity
@staticmethod
def nxPower(num):
power=0
k=0
while power < num:
k+=1
power=2**k
return k
def computeRangeParams(self):
'''Ensure that the given range parameters are valid.'''
from isceobj.Constants import SPEED_OF_LIGHT
import isceobj
self.rangeChirpExtensionPoints = 0
if self.startRangeBin <= 0:
raise ValueError('startRangeBin should be greater than or equal to 1')
self.logger.info('Number of Range Bins: %d'%self.numberRangeBin)
self.slcWidth = self.numberRangeBin + self.rangeChirpExtensionPoints + (self.startRangeBin - 1)
delr = self.rangeSamplingRate
#Will be set here and passed on to Fortran. - Piyush
self.startingRange = self.rangeFirstSample + (self.startRangeBin - 1 - self.rangeChirpExtensionPoints) * SPEED_OF_LIGHT*0.5/self.rangeSamplingRate
def computePatchParams(self):
from isceobj.Constants import SPEED_OF_LIGHT
chunksize=1024
rawFileSize = self.rawImage.getLength() * self.rawImage.getWidth()
linelength = int(self.rawImage.getXmax())
synthApertureSamps = (
self.radarWavelength* (self.startingRange + self.slcWidth*SPEED_OF_LIGHT*0.5/self.rangeSamplingRate)
*self.prf/(self.antennaLength*self.bodyFixedVelocity))
nSAS = int((synthApertureSamps-1)/chunksize)+1
chunkedSAS = chunksize*nSAS
nxP = self.nxPower(nSAS)
azP = chunksize*2*(2**nxP) #Patchsize
nV = azP-chunkedSAS #Numbervalid
if self.azimuthPatchSize:
if self.azimuthPatchSize != 2**self.nxPower(self.azimuthPatchSize):
self.azimuthPatchSize = 2**self.nxPower(self.azimuthPatchSize)
self.logger.info(
"Patch size must equal power of 2. Resetting to %d" %
self.azimuthPatchSize
)
if self.azimuthPatchSize and self.numberValidPulses:
if (self.azimuthPatchSize < self.numberValidPulses or
self.azimuthPatchSize < chunkedSAS+chunksize):
self.azimuthPatchSize = azP
self.numberValidPulses = nV
elif self.numberValidPulses > self.azimuthPatchSize-chunkedSAS:
self.logger.info(
"Number of valid pulses specified is too large for full linear convolution. Should be less than %d" % self.azimuthPatchSize-chunkedSAS)
self.logger.info(
"Continuing with specified value of %d" %
self.numberValidPulses
)
elif self.azimuthPatchSize and not self.numberValidPulses:
if self.azimuthPatchSize < chunkedSAS+chunksize:
self.azimuthPatchSize = azP
self.numberValidPulses = nV
else:
self.numberValidPulses = self.azimuthPatchSize-chunkedSAS
if self.numberValidPulses > self.azimuthPatchSize-chunkedSAS:
self.logger.info(
"Number of valid pulses specified is too large for full linear convolution. Should be less than %d" %
self.azimuthPatchSize-chunkedSAS
)
self.logger.info(
"Continuing with specified value of %d" %
self.numberValidPulses
)
elif not self.azimuthPatchSize and self.numberValidPulses:
self.azimuthPatchSize=2**self.nxPower(self.numberValidPulses+
synthApertureSamps)
if self.azimuthPatchSize > self.maxAzPatchSize:
self.logger.info(
"%d is a rather large patch size. Check that the number of valid pulses is in a reasonable range. Proceeding anyway..." %
self.azimuthPatchSize
)
elif not self.azimuthPatchSize and not self.numberValidPulses:
self.azimuthPatchSize=azP
self.numberValidPulses=nV
overhead = self.azimuthPatchSize - self.numberValidPulses
if not self.numberPatches:
self.numberPatches = (
1+int(
(rawFileSize/float(linelength)-overhead)/
self.numberValidPulses
)
)
def getState(self):
self.entropy = estamb.getEntropy_Py(
(self.maxAmb - self.minAmb+ 1)
)
self.dopplerAmbiguity = self.entropy.index(max(self.entropy)) + self.minAmb
def setDefaults(self):
if self.firstLine is None:
self.firstLine = self.numberPatches * self.numberValidPulses
def setState(self):
estamb.setStdWriter_Py(int(self.stdWriter))
estamb.setNumberGoodBytes_Py(int(self.numberGoodBytes))
estamb.setNumberBytesPerLine_Py(int(self.numberBytesPerLine))
estamb.setFirstLine_Py(int(self.firstLine))
estamb.setNumberValidPulses_Py(int(self.numberValidPulses))
estamb.setFirstSample_Py(int(self.firstSample))
estamb.setNumberPatches_Py(int(self.numberPatches))
estamb.setStartRangeBin_Py(int(self.startRangeBin))
estamb.setNumberRangeBin_Py(int(self.numberRangeBin))
estamb.setRangeChirpExtensionPoints_Py(
int(self.rangeChirpExtensionPoints)
)
estamb.setAzimuthPatchSize_Py(int(self.azimuthPatchSize))
estamb.setOverlap_Py(int(self.overlap))
estamb.setRanfftov_Py(int(self.ranfftov))
estamb.setRanfftiq_Py(int(self.ranfftiq))
estamb.setDebugFlag_Py(int(self.debugFlag))
estamb.setCaltoneLocation_Py(float(self.caltoneLocation))
estamb.setPlanetLocalRadius_Py(float(self.planetLocalRadius))
estamb.setBodyFixedVelocity_Py(float(self.bodyFixedVelocity))
estamb.setSpacecraftHeight_Py(float(self.spacecraftHeight))
estamb.setPRF_Py(float(self.prf))
estamb.setInPhaseValue_Py(float(self.inPhaseValue))
estamb.setQuadratureValue_Py(float(self.quadratureValue))
estamb.setAzimuthResolution_Py(float(self.azimuthResolution))
estamb.setRangeSamplingRate_Py(float(self.rangeSamplingRate))
estamb.setChirpSlope_Py(float(self.chirpSlope))
estamb.setRangePulseDuration_Py(float(self.rangePulseDuration))
estamb.setRadarWavelength_Py(float(self.radarWavelength))
estamb.setRangeFirstSample_Py(float(self.rangeFirstSample))
estamb.setRangeSpectralWeighting_Py(float(self.rangeSpectralWeighting))
estamb.setSpectralShiftFraction_Py(float(self.spectralShiftFraction))
estamb.setIMRC1_Py(int(self.imrc1Accessor))
estamb.setIMMocomp_Py(int(self.immocompAccessor))
estamb.setIMRCAS1_Py(int(self.imrcas1Accessor))
estamb.setIMRCRM1_Py(int(self.imrcrm1Accessor))
estamb.setTransDat_Py(int(self.transAccessor))
estamb.setIQFlip_Py(self.IQFlip)
estamb.setDeskewFlag_Py(self.deskewFlag)
estamb.setSecondaryRangeMigrationFlag_Py(
self.secondaryRangeMigrationFlag
)
estamb.setPosition_Py(self.position,
self.dim1_position,
self.dim2_position)
estamb.setVelocity_Py(self.velocity,
self.dim1_velocity,
self.dim2_velocity)
estamb.setTime_Py(self.time,
self.dim1_time)
estamb.setDopplerCentroidCoefficients_Py(
self.dopplerCentroidCoefficients,
self.dim1_dopplerCentroidCoefficients
)
estamb.setPegPoint_Py(self.pegLatitude,
self.pegLongitude,
self.pegHeading)
estamb.setPlanet_Py(self.spin, self.gm)
estamb.setEllipsoid_Py(self.a, self.e2)
estamb.setSlcWidth_Py(self.slcWidth)
estamb.setStartingRange_Py(self.startingRange)
estamb.setLookSide_Py(self.lookSide)
estamb.setShift_Py(self.shift) ##KK,ML 2013-07-15
estamb.setMinAmb_Py(int(self.minAmb))
estamb.setMaxAmb_Py(int(self.maxAmb))
def setRawImage(self, raw):
self.rawImage = raw
def setNumberGoodBytes(self, var):
self.numberGoodBytes = int(var)
def setNumberBytesPerLine(self, var):
self.numberBytesPerLine = int(var)
def setFirstLine(self, var):
self.firstLine = int(var)
def setLookSide(self, var):
self.lookSide = int(var)
@set_if_true
def setNumberValidPulses(self, var):
self.numberValidPulses = int(var)
def setFirstSample(self, var):
self.firstSample = int(var)
@set_if_true
def setNumberPatches(self,var):
self.numberPatches = int(var)
def setStartRangeBin(self, var):
self.startRangeBin = int(var)
def setStartingRange(self, var):
self.startingRange = float(var)
def setNumberRangeBin(self, var):
self.numberRangeBin = int(var)
@set_if_true
def setAzimuthPatchSize(self, var):
self.azimuthPatchSize = int(var)
def setOverlap(self, var):
self.overlap = int(var)
def setRanfftov(self, var):
self.ranfftov = int(var)
def setRanfftiq(self, var):
self.ranfftiq = int(var)
def setCaltoneLocation(self, var):
self.caltoneLocation = float(var)
def setPlanetLocalRadius(self, var):
self.planetLocalRadius = float(var)
def setBodyFixedVelocity(self, var):
self.bodyFixedVelocity = float(var)
def setSpacecraftHeight(self, var):
self.spacecraftHeight = float(var)
def setPRF(self, var):
self.prf = float(var)
def setInPhaseValue(self, var):
self.inPhaseValue = float(var)
def setQuadratureValue(self, var):
self.quadratureValue = float(var)
def setAzimuthResolution(self, var):
self.azimuthResolution = float(var)
def setRangeSamplingRate(self, var):
self.rangeSamplingRate = float(var)
def setChirpSlope(self, var):
self.chirpSlope = float(var)
def setRangePulseDuration(self, var):
self.rangePulseDuration = float(var)
def setRadarWavelength(self, var):
self.radarWavelength = float(var)
def setRangeFirstSample(self, var):
self.rangeFirstSample = float(var)
def setIQFlip(self, var):
self.IQFlip = str(var)
def setPosition(self, var):
self.position = var
def setVelocity(self, var):
self.velocity = var
def setTime(self, var):
self.time = var
def setSlcWidth(self, var):
self.slcWidth = var
def setDopplerCentroidCoefficients(self, var):
self.dopplerCentroidCoefficients = var
def _testArraySize(self,*args):
"""Test for array dimesions that are zero or smaller"""
for dimension in args:
if (dimension <= 0):
self.logger.error("Error, trying to allocate zero size array")
raise ValueError
def allocateArrays(self):
# Set array sizes from their arrays
try:
self.dim1_position = len(self.position)
self.dim2_position = len(self.position[0])
self.dim1_velocity = len(self.velocity)
self.dim2_velocity = len(self.velocity[0])
self.dim1_time = len(self.time)
self.dim1_dopplerCentroidCoefficients = len(self.dopplerCentroidCoefficients)
except TypeError:
self.logger.error("Some input arrays were not set")
raise TypeError
# Test that the arrays have a size greater than zero
self._testArraySize(self.dim1_position,self.dim2_position)
self._testArraySize(self.dim1_velocity,self.dim2_velocity)
self._testArraySize(self.dim1_time)
self._testArraySize(self.dim1_dopplerCentroidCoefficients)
# Allocate the arrays
estamb.allocate_sch_Py(self.dim1_position, self.dim2_position)
estamb.allocate_vsch_Py(self.dim1_velocity, self.dim2_velocity)
estamb.allocate_time_Py(self.dim1_time)
estamb.allocate_dopplerCoefficients_Py(self.dim1_dopplerCentroidCoefficients)
estamb.allocate_entropy_Py(int(self.maxAmb - self.minAmb + 1))
def deallocateArrays(self):
estamb.deallocate_sch_Py()
estamb.deallocate_vsch_Py()
estamb.deallocate_time_Py()
estamb.deallocate_dopplerCoefficients_Py()
estamb.deallocate_entropy_Py()
pass
def addRawImage(self):
image = self.inputPorts['rawImage']
if image:
if isinstance(image, Image):
self.rawImage = image
self.numberBytesPerLine = self.rawImage.getWidth()
self.numberGoodBytes = self.rawImage.getNumberGoodBytes()
self.firstSample = int(self.rawImage.getXmin()/2)
else:
self.logger.error(
"Object %s must be an instance of Image" % image
)
raise TypeError
def addOrbit(self):
orbit = self.inputPorts['orbit']
if orbit:
try:
time,position,velocity,offset = orbit._unpackOrbit()
self.time = time
self.position = position
self.velocity = velocity
except AttributeError:
self.logger.error(
"Object %s requires an _unpackOrbit() method" %
orbit.__class__
)
raise AttributeError
def addFrame(self):
frame = self.inputPorts['frame']
if frame:
try:
self.rangeFirstSample = frame.getStartingRange()
self.rangeLastSample = frame.getFarRange()
instrument = frame.getInstrument()
self.inPhaseValue = instrument.getInPhaseValue()
self.quadratureValue = instrument.getQuadratureValue()
self.rangeSamplingRate = instrument.getRangeSamplingRate()
self.chirpSlope = instrument.getChirpSlope()
self.rangePulseDuration = instrument.getPulseLength()
self.radarWavelength = instrument.getRadarWavelength()
self.prf = instrument.getPulseRepetitionFrequency()
self.antennaLength = instrument.getPlatform().getAntennaLength()
self.azimuthResolution = self.antennaLength/2.0
except AttributeError as strerr:
self.logger.error(strerr)
raise AttributeError
def addPlanet(self):
planet = self.inputPorts['planet']
if planet:
try:
self.spin = planet.spin
self.gm = planet.GM
ellipsoid = planet.ellipsoid
self.a = ellipsoid.a
self.e2 = ellipsoid.e2
except AttributeError as strerr:
self.logger.error(strerr)
raise AttributeError
def addPeg(self):
peg = self.inputPorts['peg']
if peg:
try:
self.pegLatitude = peg.getLatitude()
self.pegLongitude = peg.getLongitude()
self.pegHeading = peg.getHeading()
self.planetLocalRadius = peg.getRadiusOfCurvature()
except AttributeError as strerr:
self.logger.error(strerr)
raise AttributeError
def addDoppler(self):
doppler = self.inputPorts['doppler']
if doppler:
try:
self.dopplerCentroidCoefficients = (
doppler.getDopplerCoefficients(inHz=False)
)
self.dim1_dopplerCentroidCoefficients = len(
self.dopplerCentroidCoefficients
)
except AttributeError as strerr:
self.logger.error(strerr)
raise AttributeError
def _parameters(self):
"""Define the user configurable parameters for this application"""
for item in self.__class__.parameter_list:
try:
setattr(self,
item.attrname,
self.parameter(item.attrname,
public_name=item.public_name,
default=item.default,
units=None,
doc=item.doc,
type=item.type,
mandatory=item.mandatory
)
)
except AttributeError:
message = (
"Failed to set parameter %s type %s in %s" %
(str(item), item.__class__.__name__, repr(self))
)
raise AttributeError(message)
pass
return None
def _facilities(self):
self.rawImage = self.facility('rawImage',public_name='rawImage',module='isceobj.Image',factory='createRawImage',
mandatory=True,doc='Raw Image object')
def createPorts(self):
self.inputPorts['rawImage'] = self.addRawImage
self.inputPorts['orbit'] = self.addOrbit
self.inputPorts['frame'] = self.addFrame
self.inputPorts['peg'] = self.addPeg
self.inputPorts['planet'] = self.addPlanet
self.inputPorts['doppler'] = self.addDoppler
return None
logging_name = 'isce.estamb'
def __init__(self, name=None):
super(Estamb, self).__init__('estamb', name)
self.rawImage = None
self.numberGoodBytes = None
self.numberBytesPerLine = None
self.numberRangeBin = None
self.firstSample = None
self.lookSide = -1 #By default right looking (to be consistent with old code)
# These pertain to the image, but aren't explicitly set
self.firstLine = None
self.numberValidPulses = None
self.startRangeBin = 1
self.shift = -0.5 ##KK,ML 2013-07-15
# Planet information
# the code does not actually uses the ones set to -9999,
## but they are passed so they
# need to be set
self.a = -9999
self.e2 = -9999
self.spin = -9999
self.gm = -9999
# Peg Information
self.pegLatitude = -9999#see comment above
self.pegLongitude = -9999
self.pegHeading = -9999
self.planetLocalRadius = None
self.bodyFixedVelocity = None
self.spacecraftHeight = None
# Instrument Information
self.prf = None
self.inPhaseValue = None
self.quadratureValue = None
self.azimuthResolution = 5
self.rangeSamplingRate = None
self.chirpSlope = None
self.rangePulseDuration = None
self.radarWavelength = None
# Frame Information
self.rangeFirstSample = None
# Orbit Information
self.position = []
self.dim1_position = None
self.dim2_position = None
self.velocity = []
self.dim1_velocity = None
self.dim2_velocity = None
self.time = []
self.dim1_time = None
# Doppler Information
self.dopplerCentroidCoefficients = []
self.dim1_dopplerCentroidCoefficients = None
# These are options
self.numberAzimuthLooks = None
self.numberPatches = None
self.caltoneLocation = 0
self.rangeChirpExtensionPoints = 0
self.azimuthPatchSize = None
self.overlap = 0
self.ranfftov = 65536
self.ranfftiq = 32768
self.debugFlag = 0
self.rangeSpectralWeighting = 1
self.spectralShiftFraction = 0
self.imrc1Accessor = 0
self.immocompAccessor = 0
self.imrcas1Accessor = 0
self.imrcrm1Accessor = 0
self.transAccessor = 0
self.rawAccessor = 0
self.slcAccessor = 0
self.slcWidth = 0
self.IQFlip = 'n'
self.deskewFlag = 'n'
self.secondaryRangeMigrationFlag = 'n'
self.minAmb = -3
self.maxAmb = 3
# These are output
self.entropy = []
self.dopplerAmbiguity = 0
self.createPorts()
self.dictionaryOfOutputVariables = {
'ENTROPY' : 'entropy' ,
'DOPPLER_AMBIGUITY' : 'dopplerAmbiguity'
}
## Set dictionary of Variables (more to refactor..)
for d in (
item.to_dict() for item in self.__class__._vars
):
self.dictionaryOfVariables.update(d)
self.descriptionOfVariables = {}
self.mandatoryVariables = []
self.optionalVariables = []
self.initOptionalAndMandatoryLists()
return None
pass
if __name__ == '__main__':
'''Sample implementation. Estimates ambiguity on the reference.'''
import isceobj
import stdproc
from iscesys.StdOEL.StdOELPy import create_writer
def load_pickle(step='orbit2sch'):
import cPickle
insarObj = cPickle.load(open('PICKLE/{0}'.format(step), 'rb'))
return insarObj
def runEstamb(insar):
import copy
stdWriter = create_writer("log", "", True, filename="estamb.log")
objRaw = insar.referenceRawImage.copy(access_mode='read')
v,h = insar.vh()
objFormSlc = stdproc.createestamb()
objFormSlc.minAmb = -3
objFormSlc.maxAmb = 3
# objFormSlc.setAzimuthPatchSize(8192)
# objFormSlc.setNumberValidPulses(6144)
objFormSlc.setBodyFixedVelocity(v)
objFormSlc.setSpacecraftHeight(h)
objFormSlc.setFirstLine(5000)
objFormSlc.setNumberPatches(1)
objFormSlc.setNumberRangeBin(insar._referenceFrame.numberRangeBins)
objFormSlc.setLookSide(insar._lookSide)
doppler = copy.deepcopy(insar.referenceDoppler)
# doppler.fractionalCentroid = 0.39
doppler.linearTerm = 0.
doppler.quadraticTerm = 0.
doppler.cubicTerm = 0.
print ("Focusing Reference image")
objFormSlc.stdWriter = stdWriter
entropy, Amb = objFormSlc(rawImage=objRaw,
orbit=insar.referenceOrbit,
frame=insar.referenceFrame,
planet=insar.referenceFrame.instrument.platform.planet,
doppler=doppler,
peg=insar.peg)
objRaw.finalizeImage()
stdWriter.finalize()
print ('Input Doppler: ', doppler.fractionalCentroid)
print ('Doppler Ambiguity: ', Amb)
####The main driver
iObj = load_pickle()
runEstamb(iObj)