def getBbox(frame, zrange=[-500., 9000.], geom='zero doppler', margin=0.05): ''' Get bounding box. ''' from isceobj.Util.Poly2D import Poly2D #### Reference box r0 = frame.startingRange rmax = frame.getFarRange() t0 = frame.getSensingStart() t1 = frame.getSensingStop() tdiff = (t1 - t0).total_seconds() wvl = frame.instrument.getRadarWavelength() lookSide = frame.instrument.platform.pointingDirection tarr = [] for ind in range(11): tarr.append(t0 + datetime.timedelta(seconds=ind * tdiff / 10.0)) if geom.lower().startswith('native'): coeff = frame._dopplerVsPixel doppler = Poly2D() doppler._meanRange = r0 doppler._normRange = frame.instrument.rangePixelSize doppler.initPoly(azimuthOrder=0, rangeOrder=len(coeff) - 1, coeffs=[coeff]) print('Using native doppler information for bbox estimation') else: doppler = Poly2D() doppler.initPoly(azimuthOrder=0, rangeOrder=0, coeffs=[[0.]]) llh = [] for z in zrange: for taz in tarr: for rng in [r0, rmax]: pt = frame.orbit.rdr2geo(taz, rng, doppler=doppler, height=z, wvl=wvl, side=lookSide) ###If nan, use nadir point if np.sum(np.isnan(pt)): sv = frame.orbit.interpolateOrbit(taz, method='hermite') pt = frame.ellipsoid.xyz_to_llh(sv.getPosition()) llh.append(pt) llh = np.array(llh) minLat = np.min(llh[:, 0]) - margin maxLat = np.max(llh[:, 0]) + margin minLon = np.min(llh[:, 1]) - margin maxLon = np.max(llh[:, 1]) + margin return [minLat, maxLat, minLon, maxLon]
def resampSecondary(reference, burst, doppler, azpoly, flatten=False): ''' Resample burst by burst. ''' inimg = isceobj.createSlcImage() base = os.path.basename(reference) inimg.load(os.path.join(reference, base + '_orig.slc.xml')) inimg.setAccessMode('READ') width = inimg.getWidth() length = inimg.getLength() prf = burst.getInstrument().getPulseRepetitionFrequency() coeffs = [2 * np.pi * val / prf for val in doppler._coeffs] zcoeffs = [0. for val in coeffs] dpoly = Poly2D() dpoly.initPoly(rangeOrder=doppler._order, azimuthOrder=1, coeffs=[zcoeffs, coeffs]) apoly = Poly2D() apoly.setMeanRange(azpoly._mean) apoly.setNormRange(azpoly._norm) apoly.initPoly(rangeOrder=azpoly._order, azimuthOrder=0, coeffs=[azpoly._coeffs]) print('Shifts: ', apoly(1, 1), apoly(10240, 10240)) rObj = stdproc.createResamp_slc() rObj.slantRangePixelSpacing = burst.getInstrument().getRangePixelSize() rObj.radarWavelength = burst.getInstrument().getRadarWavelength() rObj.azimuthCarrierPoly = dpoly rObj.azimuthOffsetsPoly = apoly rObj.imageIn = inimg imgOut = isceobj.createSlcImage() imgOut.setWidth(width) imgOut.filename = os.path.join(reference, base + '.slc') imgOut.setAccessMode('write') rObj.flatten = flatten rObj.outputWidth = width rObj.outputLines = length rObj.resamp_slc(imageOut=imgOut) imgOut.renderHdr() return imgOut
def createPoly(polyType='2d', family=None, name=None): pol = None if polyType == '2d': pol = Poly2D(family, name) else: pol = Poly1D(family, name) return pol
def getAzRg(frame,llh): ''' Return line pixel position. ''' nl = frame.getImage().getLength() - 1 np = frame.getImage().getWidth() - 1 coeffs = frame._dopplerVsPixel if coeffs is None: coeffs = [0.] pol = Poly2D() pol._meanRange = frame.startingRange pol._normRange = frame.instrument.rangePixelSize pol.initPoly(azimuthOrder=0, rangeOrder=len(coeffs)-1, coeffs=[coeffs]) taz, rgm = frame.orbit.geo2rdr(list(llh)[1:], side=frame.instrument.platform.pointingDirection, doppler=pol, wvl=frame.instrument.getRadarWavelength()) line = (taz - frame.sensingStart).total_seconds() * frame.PRF pixel = (rgm - frame.startingRange) / frame.getInstrument().getRangePixelSize() if (line < 0) or (line > nl): return None if (pixel < 0) or (pixel > np): return None return (line, pixel)
def geo2rdr(self, llh, side=-1, planet=None, doppler=None, wvl=None): ''' Takes a lat, lon, height triplet and returns azimuth time and range. Assumes zero doppler for now. ''' from isceobj.Planet.Planet import Planet from isceobj.Util.Poly2D import Poly2D if doppler is None: doppler = Poly2D() doppler.initPoly(azimuthOrder=0, rangeOrder=0, coeffs=[[0.]]) wvl = 0.0 if planet is None: refElp = Planet(pname='Earth').ellipsoid else: refElp = planet.ellipsoid xyz = refElp.llh_to_xyz(llh) delta = (self.maxTime - self.minTime).total_seconds() * 0.5 tguess = self.minTime + datetime.timedelta(seconds=delta) outOfBounds = False # Start the previous guess tracking with dummy value t_prev_guess = tguess + datetime.timedelta(seconds=10) for ii in range(51): try: sv = self.interpolateOrbit(tguess, method='hermite') except: outOfBounds = True break pos = np.array(sv.getPosition()) vel = np.array(sv.getVelocity()) dr = xyz - pos rng = np.linalg.norm(dr) dopfact = np.dot(dr, vel) fdop = doppler(DTU.seconds_since_midnight(tguess), rng) * wvl * 0.5 fdopder = (0.5 * wvl * doppler(DTU.seconds_since_midnight(tguess), rng + 10.0) - fdop) / 10.0 fn = dopfact - fdop * rng c1 = -np.dot(vel, vel) c2 = (fdop / rng + fdopder) fnprime = c1 + c2 * dopfact tguess = tguess - datetime.timedelta(seconds=fn / fnprime) if abs(tguess - t_prev_guess).total_seconds() < 5e-9: break else: t_prev_guess = tguess if outOfBounds: raise Exception('Interpolation time out of bounds') return tguess, rng
def runTopoCPU(info, demImage, dop=None, nativedop=False, legendre=False): from zerodop.topozero import createTopozero from isceobj.Planet.Planet import Planet if not os.path.isdir(info.outdir): os.makedirs(info.outdir) #####Run Topo planet = Planet(pname='Earth') topo = createTopozero() topo.slantRangePixelSpacing = info.slantRangePixelSpacing topo.prf = info.prf topo.radarWavelength = info.radarWavelength topo.orbit = info.orbit topo.width = info.width // info.numberRangeLooks topo.length = info.length // info.numberAzimuthLooks topo.wireInputPort(name='dem', object=demImage) topo.wireInputPort(name='planet', object=planet) topo.numberRangeLooks = info.numberRangeLooks topo.numberAzimuthLooks = info.numberAzimuthLooks topo.lookSide = info.lookSide topo.sensingStart = info.sensingStart + datetime.timedelta(seconds=( (info.numberAzimuthLooks - 1) / 2) / info.prf) topo.rangeFirstSample = info.rangeFirstSample + ( (info.numberRangeLooks - 1) / 2) * info.slantRangePixelSpacing topo.demInterpolationMethod = 'BIQUINTIC' if legendre: topo.orbitInterpolationMethod = 'LEGENDRE' topo.latFilename = info.latFilename topo.lonFilename = info.lonFilename topo.losFilename = info.losFilename topo.heightFilename = info.heightFilename topo.incFilename = info.incFilename topo.maskFilename = info.maskFilename if nativedop and (dop is not None): try: coeffs = dop._coeffs except: coeffs = dop doppler = Poly2D() doppler.setWidth(info.width // info.numberRangeLooks) doppler.setLength(info.length // info.numberAzimuthLooks) doppler.initPoly(rangeOrder=len(coeffs) - 1, azimuthOrder=0, coeffs=[coeffs]) else: print('Zero doppler') doppler = None topo.polyDoppler = doppler topo.topo() return
def setDefaults(self): if self.ellipsoidMajorSemiAxis is None: self.ellipsoidMajorSemiAxis = CN.EarthMajorSemiAxis if self.ellipsoidEccentricitySquared is None: self.ellipsoidEccentricitySquared = CN.EarthEccentricitySquared if self.lookSide is None: self.lookSide = -1 if self.isMocomp is None: self.isMocomp = (8192 - 2048) / 2 if self.topophaseFlatFilename == '': self.topophaseFlatFilename = 'topophase.flat' self.logger.warning( 'The topophase flat file has been given the default name %s' % (self.topophaseFlatFilename)) if self.topophaseMphFilename == '': self.topophaseMphFilename = 'topophase.mph' self.logger.warning( 'The topophase mph file has been given the default name %s' % (self.topophaseMphFilename)) if self.dumpRangeFiles is None: self.dumpRangeFiles = False if self.dumpRangeFiles: if self.slaveRangeFilename == '': self.slaveRangeFilename = 'slaverange.rdr' self.logger.warning( 'Slave range file has been given the default name %s' % (self.slaveRangeFilename)) if self.masterRangeFilename == '': self.masterRangeFilename = 'masterrange.rdr' self.logger.warning( 'Master range file has been given the default name %s' % (self.masterRangeFilename)) if self.polyDoppler is None: polyDop = Poly2D(name=self.name + '_correctPoly') polyDop.setNormRange(1.0 / (1.0 * self.numberRangeLooks)) polyDop.setNormAzimuth(1.0 / (1.0 * self.numberAzimuthLooks)) polyDop.setMeanRange(0.0) polyDop.setMeanAzimuth(0.0) polyDop.setWidth(self.width) polyDop.setLength(self.length) polyDop.initPoly(rangeOrder=len(self.dopplerCentroidCoeffs) - 1, azimuthOrder=0, coeffs=[self.dopplerCentroidCoeffs]) self.polyDoppler = polyDop
def topo(burst: BurstSLC, time, span, doppler=0, wvl=0.056): '''Compute Lat/Lon from inputs''' # Provide a zero doppler polygon in case 0 is given if doppler == 0: doppler = Poly2D() doppler.initPoly(rangeOrder=1, azimuthOrder=0, coeffs=[[0, 0]]) pass # compute the lonlat grid latlon = burst.orbit.rdr2geo(time, span, doppler=doppler, wvl=wvl) return latlon
def topo(burst, time, Range, doppler=0, wvl=0.056): '''Function that return the lon lat information for a given time, range, and doppler''' ###Planet parameters elp = Planet(pname='Earth').ellipsoid # Provide a zero doppler polygon in case 0 is given if doppler is 0: doppler = Poly2D() doppler.initPoly(rangeOrder=1, azimuthOrder=0, coeffs=[[0, 0]]) # compute the lonlat grid latlon = burst.orbit.rdr2geo(time, Range, doppler=doppler, wvl=wvl) return latlon
def runTopo(self): from zerodop.topozero import createTopozero from isceobj.Planet.Planet import Planet logger.info("Running topo") #IU.copyAttributes(demImage, objDem) geometryDir = self.insar.geometryDirname os.makedirs(geometryDir, exist_ok=True) demFilename = self.verifyDEM() objDem = isceobj.createDemImage() objDem.load(demFilename + '.xml') info = self._insar.loadProduct(self._insar.masterSlcCropProduct) intImage = info.getImage() planet = info.getInstrument().getPlatform().getPlanet() topo = createTopozero() topo.slantRangePixelSpacing = 0.5 * SPEED_OF_LIGHT / info.rangeSamplingRate topo.prf = info.PRF topo.radarWavelength = info.radarWavelegth topo.orbit = info.orbit topo.width = intImage.getWidth() topo.length = intImage.getLength() topo.wireInputPort(name='dem', object=objDem) topo.wireInputPort(name='planet', object=planet) topo.numberRangeLooks = 1 topo.numberAzimuthLooks = 1 topo.lookSide = info.getInstrument().getPlatform().pointingDirection topo.sensingStart = info.getSensingStart() topo.rangeFirstSample = info.startingRange topo.demInterpolationMethod = 'BIQUINTIC' topo.latFilename = os.path.join(geometryDir, self.insar.latFilename + '.full') topo.lonFilename = os.path.join(geometryDir, self.insar.lonFilename + '.full') topo.losFilename = os.path.join(geometryDir, self.insar.losFilename + '.full') topo.heightFilename = os.path.join(geometryDir, self.insar.heightFilename + '.full') # topo.incFilename = os.path.join(info.outdir, 'inc.rdr') # topo.maskFilename = os.path.join(info.outdir, 'mask.rdr') ####Doppler adjustment dop = [x / 1.0 for x in info._dopplerVsPixel] doppler = Poly2D() doppler.setWidth(topo.width // topo.numberRangeLooks) doppler.setLength(topo.length // topo.numberAzimuthLooks) if self._insar.masterGeometrySystem.lower().startswith('native'): doppler.initPoly(rangeOrder=len(dop) - 1, azimuthOrder=0, coeffs=[dop]) else: doppler.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.]]) topo.polyDoppler = doppler topo.topo() # Record the inputs and outputs from isceobj.Catalog import recordInputsAndOutputs recordInputsAndOutputs(self._insar.procDoc, topo, "runTopo", logger, "runTopo") self._insar.estimatedBbox = [ topo.minimumLatitude, topo.maximumLatitude, topo.minimumLongitude, topo.maximumLongitude ] return topo
def runFineResamp(self): ''' Create coregistered overlap slaves. ''' swathList = self._insar.getValidSwathList(self.swaths) for swath in swathList: ####Load slave metadata master = self._insar.loadProduct( os.path.join(self._insar.masterSlcProduct, 'IW{0}.xml'.format(swath))) slave = self._insar.loadProduct( os.path.join(self._insar.slaveSlcProduct, 'IW{0}.xml'.format(swath))) dt = slave.bursts[0].azimuthTimeInterval dr = slave.bursts[0].rangePixelSize ###Output directory for coregistered SLCs outdir = os.path.join(self._insar.fineCoregDirname, 'IW{0}'.format(swath)) if not os.path.isdir(outdir): os.makedirs(outdir) ###Directory with offsets offdir = os.path.join(self._insar.fineOffsetsDirname, 'IW{0}'.format(swath)) ####Indices w.r.t master minBurst, maxBurst = self._insar.commonMasterBurstLimits(swath-1) slaveBurstStart, slaveBurstEnd = self._insar.commonSlaveBurstLimits(swath-1) if minBurst == maxBurst: print('Skipping processing of swath {0}'.format(swath)) continue relShifts = getRelativeShifts(master, slave, minBurst, maxBurst, slaveBurstStart) print('Shifts IW-{0}: '.format(swath), relShifts) ####Can corporate known misregistration here apoly = Poly2D() apoly.initPoly(rangeOrder=0,azimuthOrder=0,coeffs=[[0.]]) rpoly = Poly2D() rpoly.initPoly(rangeOrder=0,azimuthOrder=0,coeffs=[[0.]]) misreg_az = self._insar.slaveTimingCorrection / dt misreg_rg = self._insar.slaveRangeCorrection / dr coreg = createTOPSSwathSLCProduct() coreg.configure() for ii in range(minBurst, maxBurst): jj = slaveBurstStart + ii - minBurst masBurst = master.bursts[ii] slvBurst = slave.bursts[jj] try: offset = relShifts[jj] except: raise Exception('Trying to access shift for slave burst index {0}, which may not overlap with master for swath {1}'.format(jj, swath)) outname = os.path.join(outdir, 'burst_%02d.slc'%(ii+1)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = {'azpoly' : apoly, 'rgpoly' : rpoly, 'rangeOff' : os.path.join(offdir, 'range_%02d.off'%(ii+1)), 'azimuthOff': os.path.join(offdir, 'azimuth_%02d.off'%(ii+1))} ###For future - should account for azimuth and range misreg here .. ignoring for now. azCarrPoly, dpoly = slave.estimateAzimuthCarrierPolynomials(slvBurst, offset = -1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly outimg = resampSlave(masBurst, slvBurst, rdict, outname) minAz, maxAz, minRg, maxRg = getValidLines(slvBurst, rdict, outname, misreg_az = misreg_az - offset, misreg_rng = misreg_rg) # copyBurst = copy.deepcopy(masBurst) copyBurst = masBurst.clone() adjustValidSampleLine(copyBurst, slvBurst, minAz=minAz, maxAz=maxAz, minRng=minRg, maxRng=maxRg) copyBurst.image.filename = outimg.filename print('After: ', copyBurst.firstValidLine, copyBurst.numValidLines) coreg.bursts.append(copyBurst) ####################################################### coreg.numberOfBursts = len(coreg.bursts) self._insar.saveProduct(coreg, os.path.join(self._insar.fineCoregDirname, 'IW{0}.xml'.format(swath)))
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
def runTopoGPU(self): ''' Try with GPU module. ''' from isceobj.Planet.Planet import Planet from zerodop.GPUtopozero.GPUtopozero import PyTopozero from isceobj import Constants as CN from isceobj.Util.Poly2D import Poly2D from iscesys import DateTimeUtil as DTU swathList = self._insar.getValidSwathList(self.swaths) ####Catalog for logging catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name) ####Load in DEM demfilename = self.verifyDEM() catalog.addItem('Dem Used', demfilename, 'topo') frames = [] swaths = [] swathStarts = [] for swath in swathList: #####Load the master product master = self._insar.loadProduct( os.path.join(self._insar.masterSlcProduct, 'IW{0}.xml'.format(swath))) numCommon = self._insar.numberOfCommonBursts[swath - 1] startIndex = self._insar.commonBurstStartMasterIndex[swath - 1] if numCommon > 0: catalog.addItem('Number of common bursts IW-{0}'.format(swath), self._insar.numberOfCommonBursts[swath - 1], 'topo') master.bursts = master.bursts[startIndex:startIndex + numCommon] master.numberOfBursts = numCommon frames.append(master) swaths.append(swath) swathStarts.append(startIndex) if len(frames) == 0: raise Exception( 'There is no common region between the two dates to process') topSwath = min(frames, key=lambda x: x.sensingStart) leftSwath = min(frames, key=lambda x: x.startingRange) bottomSwath = max(frames, key=lambda x: x.sensingStop) rightSwath = max(frames, key=lambda x: x.farRange) r0 = leftSwath.startingRange rmax = rightSwath.farRange dr = frames[0].bursts[0].rangePixelSize t0 = topSwath.sensingStart tmax = bottomSwath.sensingStop dt = frames[0].bursts[0].azimuthTimeInterval wvl = frames[0].bursts[0].radarWavelength width = int(np.round((rmax - r0) / dr) + 1) lgth = int(np.round((tmax - t0).total_seconds() / dt) + 1) polyDoppler = Poly2D(name='topsApp_dopplerPoly') polyDoppler.setWidth(width) polyDoppler.setLength(lgth) 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(width) slantRangeImage.setLength(lgth) slantRangeImage.setNormRange(1.0) slantRangeImage.setNormAzimuth(1.0) slantRangeImage.setMeanRange(0.) slantRangeImage.setMeanAzimuth(0.) slantRangeImage.initPoly(rangeOrder=1, azimuthOrder=0, coeffs=[[r0, dr]]) slantRangeImage.createPoly2D() dirname = self._insar.geometryDirname os.makedirs(dirname, exist_ok=True) latImage = isceobj.createImage() latImage.initImage(os.path.join(dirname, 'lat.rdr'), 'write', width, 'DOUBLE') latImage.createImage() lonImage = isceobj.createImage() lonImage.initImage(os.path.join(dirname, 'lon.rdr'), 'write', width, 'DOUBLE') lonImage.createImage() losImage = isceobj.createImage() losImage.initImage(os.path.join(dirname, 'los.rdr'), 'write', width, 'FLOAT', bands=2, scheme='BIL') losImage.setCaster('write', 'DOUBLE') losImage.createImage() heightImage = isceobj.createImage() heightImage.initImage(os.path.join(dirname, 'hgt.rdr'), 'write', width, 'DOUBLE') heightImage.createImage() demImage = isceobj.createDemImage() demImage.load(demfilename + '.xml') demImage.setCaster('read', 'FLOAT') demImage.createImage() orb = self._insar.getMergedOrbit(frames) pegHdg = np.radians(orb.getENUHeading(t0)) elp = Planet(pname='Earth').ellipsoid 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(dr) topo.set_r0(r0) topo.set_pegHdg(pegHdg) topo.set_prf(1.0 / dt) topo.set_t0(DTU.seconds_since_midnight(t0)) topo.set_wvl(wvl) 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(-1) topo.set_extraIter(10) topo.set_length(lgth) topo.set_width(width) 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() 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 ####Start creating VRTs to point to global topo output for swath, frame, istart in zip(swaths, frames, swathStarts): outname = os.path.join(dirname, 'IW{0}'.format(swath)) os.makedirs(outname, exist_ok=True) for ind, burst in enumerate(frame.bursts): top = int(np.rint((burst.sensingStart - t0).total_seconds() / dt)) bottom = top + burst.numberOfLines left = int(np.rint((burst.startingRange - r0) / dr)) right = left + burst.numberOfSamples buildVRT(os.path.join(dirname, 'lat.rdr'), os.path.join(outname, 'lat_%02d.rdr' % (ind + istart + 1)), [width, lgth], [top, bottom, left, right], bands=1, dtype='DOUBLE') buildVRT(os.path.join(dirname, 'lon.rdr'), os.path.join(outname, 'lon_%02d.rdr' % (ind + istart + 1)), [width, lgth], [top, bottom, left, right], bands=1, dtype='DOUBLE') buildVRT(os.path.join(dirname, 'hgt.rdr'), os.path.join(outname, 'hgt_%02d.rdr' % (ind + istart + 1)), [width, lgth], [top, bottom, left, right], bands=1, dtype='DOUBLE') buildVRT(os.path.join(dirname, 'los.rdr'), os.path.join(outname, 'los_%02d.rdr' % (ind + istart + 1)), [width, lgth], [top, bottom, left, right], bands=2, dtype='FLOAT') catalog.addItem( 'Subset for IW{0}-B{1}'.format(swath, ind + 1 + istart), 'Lines: {0}-{1} out of {2}, Pixels: {3}-{4} out of {5}'.format( top, bottom, lgth, left, right, width), 'topo') # print('IW{0}-B{1}: {2} - {3}/ {4}, {5} - {6} /{7}'.format(swath, ind+1+istart, top, bottom, lgth, left, right, width)) catalog.printToLog(logger, "runTopo") self._insar.procDoc.addAllFromCatalog(catalog) return
subbandFrequencyCenter, 257, 2048, 0.1, 0, 0.0) slcList = [slc, slcLower, slcUpper] slcListResampled = [ dates[idate] + '.slc', dates[idate] + '_{}.slc'.format(subbandPrefix[0]), dates[idate] + '_{}.slc'.format(subbandPrefix[1]) ] slcListRemoved = [slcLower, slcUpper] else: slcList = [slc] slcListResampled = [dates[idate] + '.slc'] slcListRemoved = [] #1. compute offset polynomial if idate == dateIndexReference: rangePoly = Poly2D() rangePoly.initPoly( rangeOrder=1, azimuthOrder=0, coeffs=[[(swathReferenceResampled.startingRange - swathReference.startingRange) / swathReference.rangePixelSize, swathReferenceResampled.rangePixelSize / swathReference.rangePixelSize - 1.0]]) azimuthPoly = Poly2D() azimuthPoly.initPoly( rangeOrder=0, azimuthOrder=1, coeffs=[ [(swathReferenceResampled.sensingStart -
def resampSecondary(burst, offdir, outname, doppler, azpoly, rgpoly, reference=None, flatten=False, zero=False, dims=None): ''' Resample burst by burst. ''' if offdir is not None: rgname = os.path.join(offdir, 'range.off') azname = os.path.join(offdir, 'azimuth.off') rngImg = isceobj.createImage() rngImg.load(rgname + '.xml') rngImg.setAccessMode('READ') aziImg = isceobj.createImage() aziImg.load(azname + '.xml') aziImg.setAccessMode('READ') width = rngImg.getWidth() length = rngImg.getLength() else: rngImg = None aziImg = None if dims is None: raise Exception('No offset image / dims provided.') width = dims[1] length = dims[0] inimg = isceobj.createSlcImage() inimg.load(burst.getImage().filename + '.xml') inimg.setAccessMode('READ') prf = burst.getInstrument().getPulseRepetitionFrequency() if zero: factor = 0.0 else: factor = 1.0 try: print('Polynomial doppler provided') coeffs = [factor * 2 * np.pi * val / prf for val in doppler._coeffs] except: print('List of coefficients provided') coeffs = [factor * 2 * np.pi * val / prf for val in doppler] zcoeffs = [0. for val in coeffs] dpoly = Poly2D() # dpoly.initPoly(rangeOrder=len(coeffs)-1, azimuthOrder=1, coeffs=[zcoeffs,coeffs]) dpoly.initPoly(rangeOrder=len(coeffs) - 1, azimuthOrder=0, coeffs=[coeffs]) rObj = stdproc.createResamp_slc() rObj.slantRangePixelSpacing = burst.getInstrument().getRangePixelSize() rObj.radarWavelength = burst.getInstrument().getRadarWavelength() rObj.dopplerPoly = dpoly rObj.azimuthOffsetsPoly = azpoly rObj.rangeOffsetsPoly = rgpoly rObj.imageIn = inimg imgOut = isceobj.createSlcImage() imgOut.setWidth(width) outdir = os.path.dirname(outname) os.makedirs(outdir, exist_ok=True) if zero: imgOut.filename = os.path.join(outname) else: imgOut.filename = os.path.join(outname) imgOut.setAccessMode('write') rObj.flatten = flatten rObj.outputWidth = width rObj.outputLines = length rObj.residualRangeImage = rngImg rObj.residualAzimuthImage = aziImg if reference is not None: rObj.startingRange = burst.startingRange rObj.referenceStartingRange = reference.startingRange rObj.referenceSlantRangePixelSpacing = reference.getInstrument( ).getRangePixelSize() rObj.referenceWavelength = reference.getInstrument( ).getRadarWavelength() rObj.resamp_slc(imageOut=imgOut) imgOut.renderHdr() return imgOut
def main(iargs=None): ''' Create coregistered overlap secondarys. ''' inps = cmdLineParse(iargs) referenceSwathList = ut.getSwathList(inps.reference) secondarySwathList = ut.getSwathList(inps.secondary) swathList = list(sorted(set(referenceSwathList+secondarySwathList))) #if os.path.abspath(inps.reference) == os.path.abspath(inps.secondary): # print('secondary is the same as reference, only performing subband filtering') for swath in swathList: ####Load secondary metadata reference = ut.loadProduct( os.path.join(inps.reference , 'IW{0}.xml'.format(swath))) secondary = ut.loadProduct( os.path.join(inps.secondary , 'IW{0}.xml'.format(swath))) if os.path.exists(str(inps.misreg_az)): with open(inps.misreg_az, 'r') as f: misreg_az = float(f.readline()) else: misreg_az = 0.0 if os.path.exists(str(inps.misreg_rng)): with open(inps.misreg_rng, 'r') as f: misreg_rg = float(f.readline()) else: misreg_rg = 0.0 ###Output directory for coregistered SLCs outdir = os.path.join(inps.coreg,'IW{0}'.format(swath)) offdir = os.path.join(inps.coreg,'IW{0}'.format(swath)) os.makedirs(outdir, exist_ok=True) ####Indices w.r.t reference burstoffset, minBurst, maxBurst = reference.getCommonBurstLimits(secondary) secondaryBurstStart = minBurst + burstoffset secondaryBurstEnd = maxBurst relShifts = ut.getRelativeShifts(reference, secondary, minBurst, maxBurst, secondaryBurstStart) print('Shifts: ', relShifts) ####Can corporate known misregistration here apoly = Poly2D() apoly.initPoly(rangeOrder=0,azimuthOrder=0,coeffs=[[0.]]) rpoly = Poly2D() rpoly.initPoly(rangeOrder=0,azimuthOrder=0,coeffs=[[0.]]) #slvCoreg = createTOPSSwathSLCProduct() slvCoreg = ut.coregSwathSLCProduct() slvCoreg.configure() for ii in range(minBurst, maxBurst): outname = os.path.join(outdir, 'burst_%02d.slc'%(ii+1)) outnameLower = os.path.splitext(outname)[0]+'_lower.slc' outnameUpper = os.path.splitext(outname)[0]+'_upper.slc' if os.path.exists(outnameLower) and os.path.exists(outnameLower+'.vrt') and os.path.exists(outnameLower+'.xml') and \ os.path.exists(outnameUpper) and os.path.exists(outnameUpper+'.vrt') and os.path.exists(outnameUpper+'.xml'): print('burst %02d already processed, skip...'%(ii+1)) continue jj = secondaryBurstStart + ii - minBurst masBurst = reference.bursts[ii] slvBurst = secondary.bursts[jj] #####Top burst processing try: offset = relShifts[jj] except: raise Exception('Trying to access shift for secondary burst index {0}, which may not overlap with reference'.format(jj)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = {'azpoly' : apoly, 'rgpoly' : rpoly, 'rangeOff' : os.path.join(offdir, 'range_%02d.off'%(ii+1)), 'azimuthOff': os.path.join(offdir, 'azimuth_%02d.off'%(ii+1))} ###For future - should account for azimuth and range misreg here .. ignoring for now. azCarrPoly, dpoly = secondary.estimateAzimuthCarrierPolynomials(slvBurst, offset = -1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly #subband filtering from Stack import ionParam from isceobj.Constants import SPEED_OF_LIGHT rangeSamplingRate = SPEED_OF_LIGHT / (2.0 * slvBurst.rangePixelSize) ionParamObj=ionParam() ionParamObj.configure() lower_tmpfile = os.path.splitext(slvBurst.image.filename)[0]+'_lower_tmp.slc' upper_tmpfile = os.path.splitext(slvBurst.image.filename)[0]+'_upper_tmp.slc' outputfile = [lower_tmpfile, upper_tmpfile] bw = [ionParamObj.rgBandwidthSub / rangeSamplingRate, ionParamObj.rgBandwidthSub / rangeSamplingRate] bc = [-ionParamObj.rgBandwidthForSplit / 3.0 / rangeSamplingRate, ionParamObj.rgBandwidthForSplit / 3.0 / rangeSamplingRate] rgRef = ionParamObj.rgRef subband(slvBurst, 2, outputfile, bw, bc, rgRef, True) #resampling slvBurst.radarWavelength = ionParamObj.radarWavelengthLower slvBurst.image.filename = lower_tmpfile outnameSubband = outnameLower outimg = resampSecondary(masBurst, slvBurst, rdict, outnameSubband, (not inps.noflat)) slvBurst.radarWavelength = ionParamObj.radarWavelengthUpper slvBurst.image.filename = upper_tmpfile outnameSubband = outnameUpper outimg = resampSecondary(masBurst, slvBurst, rdict, outnameSubband, (not inps.noflat)) #remove original subband images os.remove(lower_tmpfile) os.remove(lower_tmpfile+'.vrt') os.remove(lower_tmpfile+'.xml') os.remove(upper_tmpfile) os.remove(upper_tmpfile+'.vrt') os.remove(upper_tmpfile+'.xml')
def geoboxToAzrgbox(frame, geobox, israw=False, isnative=False, margin=0.02, zrange=None): ''' Convert a geo bounding box - SNWE to pixel limits. ''' from isceobj.Util.Poly2D import Poly2D from isceobj.Planet.Planet import Planet from isceobj.Constants import SPEED_OF_LIGHT if zrange is None: zrange = [-500., 9000.] rgs = [] azs = [] combos = [[geobox[0] - margin, geobox[2] - margin], [geobox[0] - margin, geobox[3] + margin], [geobox[1] + margin, geobox[3] - margin], [geobox[1] + margin, geobox[2] + margin]] lookSide = frame.instrument.platform.pointingDirection planet = Planet(pname='Earth') wvl = frame.instrument.getRadarWavelength() if (isnative or israw): ####If geometry is in native doppler / raw ####You need doppler as a function of range to do ####geometry mapping correctly ###Currently doppler is saved as function of pixel number - old ROIPAC style ###Transform to function of slant range coeff = frame._dopplerVsPixel doppler = Poly2D() doppler._meanRange = frame.startingRange doppler._normRange = frame.instrument.rangePixelSize doppler.initPoly(azimuthOrder=0, rangeOrder=len(coeff) - 1, coeffs=[coeff]) else: ###Zero doppler system doppler = Poly2D() doppler.initPoly(azimuthOrder=0, rangeOrder=0, coeffs=[[0.]]) ####Do for z in zrange: for combo in combos: try: taz, rgm = frame.orbit.geo2rdr(combo + [z], side=lookSide, doppler=doppler, wvl=wvl) azs.append(taz) rgs.append(rgm) except: pass if len(azs) <= 1: raise Exception('Could not map geobbox coordinates to image') azrgbox = [np.min(azs), np.max(azs), np.min(rgs), np.max(rgs)] if israw: ####If cropping raw product, need to add an aperture length in range and azimuth ###Extra slant range at near and far range due to the uncompressed pulse deltaRg = np.abs(frame.instrument.pulseLength * SPEED_OF_LIGHT / 2.0) print('RAW data - adding range aperture (in m) : ', deltaRg) azrgbox[2] -= deltaRg azrgbox[3] += deltaRg ###Extra azimuth samples at far range elp = copy.copy(planet.ellipsoid) svmid = frame.orbit.interpolateOrbit(frame.sensingMid, method='hermite') xyz = svmid.getPosition() vxyz = svmid.getVelocity() llh = elp.xyz_to_llh(xyz) heading = frame.orbit.getENUHeading(frame.sensingMid) print('Heading: ', heading) elp.setSCH(llh[0], llh[1], heading) sch, schvel = elp.xyzdot_to_schdot(xyz, vxyz) vel = np.linalg.norm(schvel) synthAperture = np.abs(wvl * azrgbox[3] / (frame.instrument.platform.antennaLength * vel)) deltaAz = datetime.timedelta(seconds=synthAperture) print('RAW data - adding azimuth aperture (in s) : ', synthAperture) azrgbox[0] -= deltaAz azrgbox[1] += deltaAz return azrgbox
def resampleSlc(masterFrame, slaveFrame, imageSlc2, radarWavelength, coregDir, azoffname, rgoffname, azpoly=None, rgpoly=None, misreg=False): logger.info("Resampling slave SLC") imageSlc1 = masterFrame.getImage().filename inimg = isceobj.createSlcImage() inimg.load(imageSlc2 + '.xml') inimg.setAccessMode('READ') prf = slaveFrame.PRF doppler = slaveFrame._dopplerVsPixel factor = 1.0 # this should be zero for zero Doppler SLC. coeffs = [factor * 2 * np.pi * val / prf / prf for val in doppler] dpoly = Poly2D() dpoly.initPoly(rangeOrder=len(coeffs) - 1, azimuthOrder=0, coeffs=[coeffs]) rObj = stdproc.createResamp_slc() rObj.slantRangePixelSpacing = slaveFrame.getInstrument().getRangePixelSize( ) #rObj.radarWavelength = slaveFrame.getInstrument().getRadarWavelength() rObj.radarWavelength = radarWavelength rObj.dopplerPoly = dpoly # for now let's start with None polynomial. Later this should change to # the misregistration polynomial rObj.azimuthOffsetsPoly = azpoly rObj.rangeOffsetsPoly = rgpoly rObj.imageIn = inimg rngImg = isceobj.createImage() rngImg.load(rgoffname + '.xml') rngImg.setAccessMode('READ') aziImg = isceobj.createImage() aziImg.load(azoffname + '.xml') aziImg.setAccessMode('READ') width = rngImg.getWidth() length = rngImg.getLength() flatten = True rObj.flatten = flatten rObj.outputWidth = width rObj.outputLines = length rObj.residualRangeImage = rngImg rObj.residualAzimuthImage = aziImg if masterFrame is not None: rObj.startingRange = slaveFrame.startingRange rObj.referenceStartingRange = masterFrame.startingRange rObj.referenceSlantRangePixelSpacing = masterFrame.getInstrument( ).getRangePixelSize() rObj.referenceWavelength = radarWavelength # preparing the output directory for coregistered slave slc #coregDir = self.insar.coregDirname if os.path.isdir(coregDir): logger.info('Geometry directory {0} already exists.'.format(coregDir)) else: os.makedirs(coregDir) # output file name of the coregistered slave slc img = slaveFrame.getImage() coregFilename = os.path.join(coregDir, os.path.basename(img.filename)) imgOut = isceobj.createSlcImage() imgOut.setWidth(width) imgOut.filename = coregFilename imgOut.setAccessMode('write') rObj.resamp_slc(imageOut=imgOut) imgOut.renderHdr() return coregFilename
def runCoarseResamp(self): ''' Create coregistered overlap slaves. ''' if not self.doESD: return swathList = self._insar.getValidSwathList(self.swaths) for swath in swathList: if self._insar.numberOfCommonBursts[swath - 1] < 2: print('Skipping coarse resamp for swath IW{0}'.format(swath)) continue ####Load slave metadata master = self._insar.loadProduct( os.path.join(self._insar.masterSlcProduct, 'IW{0}.xml'.format(swath))) slave = self._insar.loadProduct( os.path.join(self._insar.slaveSlcProduct, 'IW{0}.xml'.format(swath))) masterTop = self._insar.loadProduct( os.path.join(self._insar.masterSlcOverlapProduct, 'top_IW{0}.xml'.format(swath))) masterBottom = self._insar.loadProduct( os.path.join(self._insar.masterSlcOverlapProduct, 'bottom_IW{0}.xml'.format(swath))) dt = slave.bursts[0].azimuthTimeInterval dr = slave.bursts[0].rangePixelSize ###Output directory for coregistered SLCs outdir = os.path.join(self._insar.coarseCoregDirname, self._insar.overlapsSubDirname, 'IW{0}'.format(swath)) if not os.path.isdir(outdir): os.makedirs(outdir) ###Directory with offsets offdir = os.path.join(self._insar.coarseOffsetsDirname, self._insar.overlapsSubDirname, 'IW{0}'.format(swath)) ####Indices w.r.t master minBurst, maxBurst = self._insar.commonMasterBurstLimits(swath - 1) slaveBurstStart, slaveBurstEnd = self._insar.commonSlaveBurstLimits( swath - 1) relShifts = getRelativeShifts(master, slave, minBurst, maxBurst, slaveBurstStart) maxBurst = maxBurst - 1 ###For overlaps print('Shifts for swath IW-{0}: {1}'.format(swath, relShifts)) ####Can corporate known misregistration here apoly = Poly2D() apoly.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.]]) rpoly = Poly2D() rpoly.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.]]) topCoreg = createTOPSSwathSLCProduct() topCoreg.configure() botCoreg = createTOPSSwathSLCProduct() botCoreg.configure() for ii in range(minBurst, maxBurst): jj = slaveBurstStart + ii - minBurst topBurst = masterTop.bursts[ii - minBurst] botBurst = masterBottom.bursts[ii - minBurst] slvBurst = slave.bursts[jj] #####Top burst processing try: offset = relShifts[jj] except: raise Exception( 'Trying to access shift for slave burst index {0}, which may not overlap with master - IW-{1}' .format(jj, swath)) outname = os.path.join( outdir, 'burst_top_%02d_%02d.slc' % (ii + 1, ii + 2)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = { 'azpoly': apoly, 'rgpoly': rpoly, 'rangeOff': os.path.join(offdir, 'range_top_%02d_%02d.off' % (ii + 1, ii + 2)), 'azimuthOff': os.path.join(offdir, 'azimuth_top_%02d_%02d.off' % (ii + 1, ii + 2)) } ###For future - should account for azimuth and range misreg here .. ignoring for now. azCarrPoly, dpoly = slave.estimateAzimuthCarrierPolynomials( slvBurst, offset=-1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly outimg = resampSlave(topBurst, slvBurst, rdict, outname) copyBurst = copy.deepcopy(topBurst) adjustValidSampleLine(copyBurst, slvBurst) copyBurst.image.filename = outimg.filename print('After: ', copyBurst.firstValidLine, copyBurst.numValidLines) topCoreg.bursts.append(copyBurst) ####################################################### slvBurst = slave.bursts[jj + 1] outname = os.path.join( outdir, 'burst_bot_%02d_%02d.slc' % (ii + 1, ii + 2)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = { 'azpoly': apoly, 'rgpoly': rpoly, 'rangeOff': os.path.join(offdir, 'range_bot_%02d_%02d.off' % (ii + 1, ii + 2)), 'azimuthOff': os.path.join(offdir, 'azimuth_bot_%02d_%02d.off' % (ii + 1, ii + 2)) } azCarrPoly, dpoly = slave.estimateAzimuthCarrierPolynomials( slvBurst, offset=-1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly outimg = resampSlave(botBurst, slvBurst, rdict, outname) copyBurst = copy.deepcopy(botBurst) adjustValidSampleLine(copyBurst, slvBurst) copyBurst.image.filename = outimg.filename print('After: ', copyBurst.firstValidLine, copyBurst.numValidLines) botCoreg.bursts.append(copyBurst) ####################################################### topCoreg.numberOfBursts = len(topCoreg.bursts) botCoreg.numberOfBursts = len(botCoreg.bursts) self._insar.saveProduct( topCoreg, os.path.join(self._insar.coregOverlapProduct, 'top_IW{0}.xml'.format(swath))) self._insar.saveProduct( botCoreg, os.path.join(self._insar.coregOverlapProduct, 'bottom_IW{0}.xml'.format(swath)))
def main(iargs=None): '''Compute baseline. ''' inps = cmdLineParse(iargs) from isceobj.Planet.Planet import Planet from isceobj.Util.Poly2D import Poly2D import numpy as np import shelve baselineDir = os.path.dirname(inps.baselineFile) if baselineDir != '': os.makedirs(baselineDir, exist_ok=True) with shelve.open(os.path.join(inps.reference, 'data'), flag='r') as mdb: reference = mdb['frame'] with shelve.open(os.path.join(inps.secondary, 'data'), flag='r') as mdb: secondary = mdb['frame'] # check if the reference and secondary shelf are the same, i.e. it is baseline grid for the reference reference_SensingStart = reference.getSensingStart() secondary_SensingStart = secondary.getSensingStart() if reference_SensingStart == secondary_SensingStart: referenceBaseline = True else: referenceBaseline = False refElp = Planet(pname='Earth').ellipsoid dr = reference.instrument.rangePixelSize dt = 1. / reference.PRF #reference.azimuthTimeInterval mStartingRange = reference.startingRange #min([x.startingRange for x in referenceswaths]) mFarRange = reference.startingRange + dr * ( reference.numberOfSamples - 1 ) #max([x.farRange for x in referenceswaths]) mSensingStart = reference.sensingStart # min([x.sensingStart for x in referenceswaths]) mSensingStop = reference.sensingStop #max([x.sensingStop for x in referenceswaths]) mOrb = getMergedOrbit(reference) nPixels = int(np.round((mFarRange - mStartingRange) / dr)) + 1 nLines = int(np.round( (mSensingStop - mSensingStart).total_seconds() / dt)) + 1 sOrb = getMergedOrbit(secondary) rangeLimits = mFarRange - mStartingRange # To make sure that we have at least 30 points nRange = int(np.max([30, int(np.ceil(rangeLimits / 7000.))])) slantRange = mStartingRange + np.arange(nRange) * rangeLimits / (nRange - 1.0) azimuthLimits = (mSensingStop - mSensingStart).total_seconds() nAzimuth = int(np.max([30, int(np.ceil(azimuthLimits))])) azimuthTime = [ mSensingStart + datetime.timedelta(seconds=x * azimuthLimits / (nAzimuth - 1.0)) for x in range(nAzimuth) ] doppler = Poly2D() doppler.initPoly(azimuthOrder=0, rangeOrder=0, coeffs=[[0.]]) Bperp = np.zeros((nAzimuth, nRange), dtype=np.float32) Bpar = np.zeros((nAzimuth, nRange), dtype=np.float32) fid = open(inps.baselineFile, 'wb') print('Baseline file {0} dims: {1}L x {2}P'.format(inps.baselineFile, nAzimuth, nRange)) if referenceBaseline: Bperp = np.zeros((nAzimuth, nRange), dtype=np.float32) Bperp.tofile(fid) else: for ii, taz in enumerate(azimuthTime): referenceSV = mOrb.interpolate(taz, method='hermite') mxyz = np.array(referenceSV.getPosition()) mvel = np.array(referenceSV.getVelocity()) for jj, rng in enumerate(slantRange): target = mOrb.rdr2geo(taz, rng) targxyz = np.array( refElp.LLH(target[0], target[1], target[2]).ecef().tolist()) slvTime, slvrng = sOrb.geo2rdr(target, doppler=doppler, wvl=0) secondarySV = sOrb.interpolateOrbit(slvTime, method='hermite') sxyz = np.array(secondarySV.getPosition()) aa = np.linalg.norm(sxyz - mxyz) costheta = (rng * rng + aa * aa - slvrng * slvrng) / (2. * rng * aa) Bpar[ii, jj] = aa * costheta perp = aa * np.sqrt(1 - costheta * costheta) direction = np.sign( np.dot(np.cross(targxyz - mxyz, sxyz - mxyz), mvel)) Bperp[ii, jj] = direction * perp Bperp.tofile(fid) fid.close() ####Write XML img = isceobj.createImage() img.setFilename(inps.baselineFile) img.bands = 1 img.scheme = 'BIP' img.dataType = 'FLOAT' img.setWidth(nRange) img.setAccessMode('READ') img.setLength(nAzimuth) img.renderHdr() img.renderVRT() ###Create oversampled VRT file cmd = 'gdal_translate -of VRT -ot Float32 -r bilinear -outsize {xsize} {ysize} {infile}.vrt {infile}.full.vrt'.format( xsize=nPixels, ysize=nLines, infile=inps.baselineFile) status = os.system(cmd) if status: raise Exception('cmd: {0} Failed'.format(cmd))
def main(iargs=None): inps = cmdLineParse(iargs) os.makedirs(inps.output, exist_ok=True) pairDirs = glob.glob(os.path.join(inps.input, '*')) polyInfo = getPolyInfo(pairDirs[0]) tbase, dateList, dateDict = date_list(pairDirs) A, B, Laz, Lrg = design_matrix(pairDirs) A1 = np.linalg.pinv(A) A1 = np.array(A1, np.float32) zero = np.array([0.], np.float32) Saz = np.dot(A1, Laz) Saz = np.dot(A1, Laz) Srg = np.dot(A1, Lrg) residual_az = Laz - np.dot(A, Saz) residual_rg = Lrg - np.dot(A, Srg) RMSE_az = np.sqrt(np.sum(residual_az**2) / len(residual_az)) RMSE_rg = np.sqrt(np.sum(residual_rg**2) / len(residual_rg)) Saz = np.vstack((np.zeros((1, Saz.shape[1]), dtype=np.float32), Saz)) Srg = np.vstack((np.zeros((1, Srg.shape[1]), dtype=np.float32), Srg)) print('') print('Rank of design matrix: ' + str(np.linalg.matrix_rank(A))) if np.linalg.matrix_rank(A) == len(dateList) - 1: print('Design matrix is full rank.') else: print('Design matrix is rank deficient. Network is disconnected.') print('Using a fully connected network is recommended.') print('RMSE in azimuth : ' + str(RMSE_az) + ' pixels') print('RMSE in range : ' + str(RMSE_rg) + ' pixels') print('') print('Estimated offsets with respect to the stack reference date') print('') offset_dict = {} for i in range(len(dateList)): print(dateList[i]) offset_dict[dateList[i]] = Saz[i] azpoly = Poly2D() rgpoly = Poly2D() azCoefs = np.reshape(Saz[i, :], polyInfo['shapeOfAzCoefs']).tolist() rgCoefs = np.reshape(Srg[i, :], polyInfo['shapeOfRgCoefs']).tolist() azpoly.initPoly(rangeOrder=polyInfo['azrgOrder'], azimuthOrder=polyInfo['azazOrder'], coeffs=azCoefs) rgpoly.initPoly(rangeOrder=polyInfo['rgrgOrder'], azimuthOrder=polyInfo['rgazOrder'], coeffs=rgCoefs) os.makedirs(os.path.join(inps.output, dateList[i]), exist_ok=True) odb = shelve.open(os.path.join(inps.output, dateList[i] + '/misreg')) odb['azpoly'] = azpoly odb['rgpoly'] = rgpoly odb.close() #with open(os.path.join(inps.output,dateList[i]+'.txt'), 'w') as f: # f.write(str(Saz[i])) print('')
def runTopoGPU(info, demImage, dop=None, nativedop=False, legendre=False): from isceobj import Constants as CN from isceobj.Planet.Planet import Planet from isceobj.Util.Poly2D import Poly2D from iscesys import DateTimeUtil as DTU from zerodop.GPUtopozero.GPUtopozero import PyTopozero ## TODO GPU does not support shadow and layover and local inc file generation full = False os.makedirs(info.outdir, exist_ok=True) # define variables to be used later on r0 = info.rangeFirstSample + ( (info.numberRangeLooks - 1) / 2) * info.slantRangePixelSpacing tbef = info.sensingStart + datetime.timedelta(seconds=( (info.numberAzimuthLooks - 1) / 2) / info.prf) pegHdg = np.radians(info.orbit.getENUHeading(tbef)) width = info.width // info.numberRangeLooks length = info.length // info.numberAzimuthLooks dr = info.slantRangePixelSpacing * info.numberRangeLooks # output file names latFilename = info.latFilename lonFilename = info.lonFilename losFilename = info.losFilename heightFilename = info.heightFilename incFilename = info.incFilename maskFilename = info.maskFilename # orbit interpolator if legendre: omethod = 2 # LEGENDRE INTERPOLATION else: omethod = 0 # HERMITE INTERPOLATION # tracking doppler specifications if nativedop and (dop is not None): try: coeffs = dop._coeffs except: coeffs = dop polyDoppler = Poly2D() polyDoppler.setWidth(width) polyDoppler.setLength(length) polyDoppler.initPoly(rangeOrder=len(coeffs) - 1, azimuthOrder=0, coeffs=[coeffs]) else: print('Zero doppler') polyDoppler = Poly2D(name='stripmapStack_dopplerPoly') polyDoppler.setWidth(width) polyDoppler.setLength(length) polyDoppler.setNormRange(1.0) polyDoppler.setNormAzimuth(1.0) polyDoppler.setMeanRange(0.0) polyDoppler.setMeanAzimuth(0.0) polyDoppler.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.0]]) polyDoppler.createPoly2D() # dem demImage.setCaster('read', 'FLOAT') demImage.createImage() # slant range file slantRangeImage = Poly2D() slantRangeImage.setWidth(width) slantRangeImage.setLength(length) slantRangeImage.setNormRange(1.0) slantRangeImage.setNormAzimuth(1.0) slantRangeImage.setMeanRange(0.0) slantRangeImage.setMeanAzimuth(0.0) slantRangeImage.initPoly(rangeOrder=1, azimuthOrder=0, coeffs=[[r0, dr]]) slantRangeImage.createPoly2D() # lat file latImage = isceobj.createImage() accessMode = 'write' dataType = 'DOUBLE' latImage.initImage(latFilename, accessMode, width, dataType) latImage.createImage() # lon file lonImage = isceobj.createImage() lonImage.initImage(lonFilename, accessMode, width, dataType) lonImage.createImage() # LOS file losImage = isceobj.createImage() dataType = 'FLOAT' bands = 2 scheme = 'BIL' losImage.initImage(losFilename, accessMode, width, dataType, bands=bands, scheme=scheme) losImage.setCaster('write', 'DOUBLE') losImage.createImage() # height file heightImage = isceobj.createImage() dataType = 'DOUBLE' heightImage.initImage(heightFilename, accessMode, width, dataType) heightImage.createImage() # add inc and mask file if requested if full: incImage = isceobj.createImage() dataType = 'FLOAT' incImage.initImage(incFilename, accessMode, width, dataType, bands=bands, scheme=scheme) incImage.createImage() incImagePtr = incImage.getImagePointer() maskImage = isceobj.createImage() dataType = 'BYTE' bands = 1 maskImage.initImage(maskFilename, accessMode, width, dataType, bands=bands, scheme=scheme) maskImage.createImage() maskImagePtr = maskImage.getImagePointer() else: incImagePtr = 0 maskImagePtr = 0 # initalize planet elp = Planet(pname='Earth').ellipsoid # initialize topo object and fill with parameters 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(info.slantRangePixelSpacing) topo.set_r0(r0) topo.set_pegHdg(pegHdg) topo.set_prf(info.prf) topo.set_t0(DTU.seconds_since_midnight(tbef)) topo.set_wvl(info.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(incImagePtr) topo.set_maskAccessor(maskImagePtr) topo.set_numIter(25) topo.set_idemWidth(demImage.getWidth()) topo.set_idemLength(demImage.getLength()) topo.set_ilrl(info.lookSide) topo.set_extraIter(10) topo.set_length(length) topo.set_width(width) topo.set_nRngLooks(info.numberRangeLooks) topo.set_nAzLooks(info.numberAzimuthLooks) topo.set_demMethod(5) # BIQUINTIC METHOD topo.set_orbitMethod(omethod) # Need to simplify orbit stuff later nvecs = len(info.orbit.stateVectors.list) 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 info.orbit.stateVectors.list: 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 # run topo topo.runTopo() # close the written files and add description etc # lat file latImage.addDescription('Pixel-by-pixel latitude in degrees.') latImage.finalizeImage() latImage.renderHdr() # lon file lonImage.addDescription('Pixel-by-pixel longitude in degrees.') lonImage.finalizeImage() lonImage.renderHdr() # height file heightImage.addDescription('Pixel-by-pixel height in meters.') heightImage.finalizeImage() heightImage.renderHdr() # los file 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() # dem/ height file demImage.finalizeImage() # adding in additional files if requested if full: descr = '''Two channel angle file. Channel 1: Angle between ray to target and the vertical at the sensor Channel 2: Local incidence angle accounting for DEM slope at target''' incImage.addDescription(descr) incImage.finalizeImage() incImage.renderHdr() descr = 'Radar shadow-layover mask. 1 - Radar Shadow. 2 - Radar Layover. 3 - Both.' maskImage.addDescription(descr) maskImage.finalizeImage() maskImage.renderHdr() if slantRangeImage: try: slantRangeImage.finalizeImage() except: pass
def resampleSlc(self, referenceFrame, secondaryFrame, imageSlc2, radarWavelength, coregDir, azoffname, rgoffname, azpoly=None, rgpoly=None, misreg=False): logger.info("Resampling secondary SLC") imageSlc1 = referenceFrame.getImage().filename inimg = isceobj.createSlcImage() inimg.load(imageSlc2 + '.xml') inimg.setAccessMode('READ') prf = secondaryFrame.PRF doppler = secondaryFrame._dopplerVsPixel factor = 1.0 # this should be zero for zero Doppler SLC. coeffs = [factor * 2 * np.pi * val / prf / prf for val in doppler] dpoly = Poly2D() dpoly.initPoly(rangeOrder=len(coeffs) - 1, azimuthOrder=0, coeffs=[coeffs]) rObj = stdproc.createResamp_slc() rObj.slantRangePixelSpacing = secondaryFrame.getInstrument( ).getRangePixelSize() #rObj.radarWavelength = secondaryFrame.getInstrument().getRadarWavelength() rObj.radarWavelength = radarWavelength rObj.dopplerPoly = dpoly # for now let's start with None polynomial. Later this should change to # the misregistration polynomial rObj.azimuthOffsetsPoly = azpoly rObj.rangeOffsetsPoly = rgpoly rObj.imageIn = inimg rngImg = isceobj.createImage() rngImg.load(rgoffname + '.xml') rngImg.setAccessMode('READ') aziImg = isceobj.createImage() aziImg.load(azoffname + '.xml') aziImg.setAccessMode('READ') width = rngImg.getWidth() length = rngImg.getLength() # Modified by V. Brancato on 10.14.2019 (if Rubbersheeting in range is turned on, flatten the interferogram during cross-correlation) if not self.doRubbersheetingRange: print( 'Rubber sheeting in range is turned off, flattening the interferogram during resampling' ) flatten = True print(flatten) else: print( 'Rubber sheeting in range is turned on, flattening the interferogram during interferogram formation' ) flatten = False print(flatten) # end of Modification rObj.flatten = flatten rObj.outputWidth = width rObj.outputLines = length rObj.residualRangeImage = rngImg rObj.residualAzimuthImage = aziImg if referenceFrame is not None: rObj.startingRange = secondaryFrame.startingRange rObj.referenceStartingRange = referenceFrame.startingRange rObj.referenceSlantRangePixelSpacing = referenceFrame.getInstrument( ).getRangePixelSize() rObj.referenceWavelength = radarWavelength # preparing the output directory for coregistered secondary slc #coregDir = self.insar.coregDirname os.makedirs(coregDir, exist_ok=True) # output file name of the coregistered secondary slc img = secondaryFrame.getImage() coregFilename = os.path.join(coregDir, os.path.basename(img.filename)) imgOut = isceobj.createSlcImage() imgOut.setWidth(width) imgOut.filename = coregFilename imgOut.setAccessMode('write') rObj.resamp_slc(imageOut=imgOut) imgOut.renderHdr() return coregFilename
def runResampleSlc(self, kind='coarse'): ''' Kind can either be coarse, refined or fine. ''' if kind not in ['coarse', 'refined', 'fine']: raise Exception('Unknown operation type {0} in runResampleSlc'.format(kind)) if kind == 'fine': if not (self.doRubbersheetingRange | self.doRubbersheetingAzimuth): # Modified by V. Brancato 10.10.2019 print('Rubber sheeting not requested, skipping resampling ....') return logger.info("Resampling secondary SLC") secondaryFrame = self._insar.loadProduct( self._insar.secondarySlcCropProduct) referenceFrame = self._insar.loadProduct( self._insar.referenceSlcCropProduct) inimg = isceobj.createSlcImage() inimg.load(secondaryFrame.getImage().filename + '.xml') inimg.setAccessMode('READ') prf = secondaryFrame.PRF doppler = secondaryFrame._dopplerVsPixel coeffs = [2*np.pi*val/prf for val in doppler] dpoly = Poly2D() dpoly.initPoly(rangeOrder=len(coeffs)-1, azimuthOrder=0, coeffs=[coeffs]) rObj = stdproc.createResamp_slc() rObj.slantRangePixelSpacing = secondaryFrame.getInstrument().getRangePixelSize() rObj.radarWavelength = secondaryFrame.getInstrument().getRadarWavelength() rObj.dopplerPoly = dpoly # for now let's start with None polynomial. Later this should change to # the misregistration polynomial misregFile = os.path.join(self.insar.misregDirname, self.insar.misregFilename) if ((kind in ['refined','fine']) and os.path.exists(misregFile+'_az.xml')): azpoly = self._insar.loadProduct(misregFile + '_az.xml') rgpoly = self._insar.loadProduct(misregFile + '_rg.xml') else: print(misregFile , " does not exist.") azpoly = None rgpoly = None rObj.azimuthOffsetsPoly = azpoly rObj.rangeOffsetsPoly = rgpoly rObj.imageIn = inimg #Since the app is based on geometry module we expect pixel-by-pixel offset #field offsetsDir = self.insar.offsetsDirname # Modified by V. Brancato 10.10.2019 #rgname = os.path.join(offsetsDir, self.insar.rangeOffsetFilename) if kind in ['coarse', 'refined']: azname = os.path.join(offsetsDir, self.insar.azimuthOffsetFilename) rgname = os.path.join(offsetsDir, self.insar.rangeOffsetFilename) flatten = True else: azname = os.path.join(offsetsDir, self.insar.azimuthRubbersheetFilename) if self.doRubbersheetingRange: print('Rubbersheeting in range is turned on, taking the cross-correlation offsets') print('Setting Flattening to False') rgname = os.path.join(offsetsDir, self.insar.rangeRubbersheetFilename) flatten=False else: print('Rubbersheeting in range is turned off, taking range geometric offsets') rgname = os.path.join(offsetsDir, self.insar.rangeOffsetFilename) flatten=True rngImg = isceobj.createImage() rngImg.load(rgname + '.xml') rngImg.setAccessMode('READ') aziImg = isceobj.createImage() aziImg.load(azname + '.xml') aziImg.setAccessMode('READ') width = rngImg.getWidth() length = rngImg.getLength() # Modified by V. Brancato 10.10.2019 #flatten = True rObj.flatten = flatten rObj.outputWidth = width rObj.outputLines = length rObj.residualRangeImage = rngImg rObj.residualAzimuthImage = aziImg if referenceFrame is not None: rObj.startingRange = secondaryFrame.startingRange rObj.referenceStartingRange = referenceFrame.startingRange rObj.referenceSlantRangePixelSpacing = referenceFrame.getInstrument().getRangePixelSize() rObj.referenceWavelength = referenceFrame.getInstrument().getRadarWavelength() # preparing the output directory for coregistered secondary slc coregDir = self.insar.coregDirname os.makedirs(coregDir, exist_ok=True) # output file name of the coregistered secondary slc img = secondaryFrame.getImage() if kind == 'coarse': coregFilename = os.path.join(coregDir , self._insar.coarseCoregFilename) elif kind == 'refined': coregFilename = os.path.join(coregDir, self._insar.refinedCoregFilename) elif kind == 'fine': coregFilename = os.path.join(coregDir, self._insar.fineCoregFilename) else: print('Exception: Should not have gotten to this stage') imgOut = isceobj.createSlcImage() imgOut.setWidth(width) imgOut.filename = coregFilename imgOut.setAccessMode('write') rObj.resamp_slc(imageOut=imgOut) imgOut.renderHdr() return
def estimateAzimuthCarrierPolynomials(self, burst, offset=0.0, xstep=500, ystep=50, azorder=5, rgorder=3, plot=False): ''' Estimate a polynomial that represents the carrier on a given burst. To be used with resampling. ''' from isceobj.Util.Poly2D import Poly2D ####TOPS steering component of the azimuth carrier x = np.arange(0, burst.numberOfSamples, xstep, dtype=np.int) y = np.arange(0, burst.numberOfLines, ystep, dtype=np.int) xx, yy = np.meshgrid(x, y) data = self.computeAzimuthCarrier(burst, offset=offset, position=(yy, xx)) ###Compute the doppler component of the azimuth carrier dop = burst.doppler dpoly = Poly2D() dpoly._meanRange = (dop._mean - burst.startingRange) / burst.rangePixelSize dpoly._normRange = dop._norm / burst.rangePixelSize coeffs = [ 2 * np.pi * val * burst.azimuthTimeInterval for val in dop._coeffs ] zcoeffs = [0. for val in coeffs] dpoly.initPoly(rangeOrder=dop._order, azimuthOrder=0) dpoly.setCoeffs([coeffs]) ####Need to account for 1-indexing in Fortran code poly = Poly2D() poly.initPoly(rangeOrder=rgorder, azimuthOrder=azorder) poly.polyfit(xx.flatten() + 1, yy.flatten() + 1, data.flatten()) #, maxOrder=True) poly.createPoly2D() # Cpointer created ###Run some diagnostics to raise warning fit = poly(yy + 1, xx + 1) diff = data - fit maxdiff = np.max(np.abs(diff)) print('Misfit radians - Max: {0} , Min : {1} '.format( np.max(diff), np.min(diff))) if (maxdiff > 0.01): print( 'Warning: The azimuth carrier polynomial may not be accurate enough' ) if plot: ####For debugging only import matplotlib.pyplot as plt plt.figure('Original') plt.imshow(data) plt.colorbar() plt.figure('Fit') plt.imshow(fit) plt.colorbar() plt.figure('diff') plt.imshow(diff) plt.colorbar() plt.show() return poly, dpoly
frame = mdb['frame'] lookSide = frame.instrument.platform.pointingDirection planet = Planet(pname='Earth') wvl = frame.instrument.getRadarWavelength() zrange = [-500., 9000.] if inps.isnative: ####If geometry is in native doppler / raw ####You need doppler as a function of range to do ####geometry mapping correctly ###Currently doppler is saved as function of pixel number - old ROIPAC style ###Transform to function of slant range coeff = frame._dopplerVsPixel doppler = Poly2D() doppler._meanRange = frame.startingRange doppler._normRange = frame.instrument.rangePixelSize doppler.initPoly(azimuthOrder=0, rangeOrder=len(coeff)-1, coeffs=[coeff]) else: ###Zero doppler system doppler = Poly2D() doppler.initPoly(azimuthOrder=0, rangeOrder=0, coeffs=[[0.]]) llh = [] for z in zrange: for taz in [frame.sensingStart, frame.sensingMid, frame.sensingStop]: for rng in [frame.startingRange, frame.getFarRange()]: pt = frame.orbit.rdr2geo(taz, rng, doppler=doppler, height=z,
def runTopo(self): from zerodop.topozero import createTopozero from isceobj.Planet.Planet import Planet logger.info("Running topo") #IU.copyAttributes(demImage, objDem) objDem = self.insar.demImage.clone() info = self.insar.masterFrame slc = self.insar.formSLC1 intImage = slc.slcImage planet = info.getInstrument().getPlatform().getPlanet() topo = createTopozero() topo.slantRangePixelSpacing = 0.5 * SPEED_OF_LIGHT / info.rangeSamplingRate topo.prf = info.PRF topo.radarWavelength = info.radarWavelegth topo.orbit = info.orbit topo.width = intImage.getWidth() topo.length = intImage.getLength() topo.wireInputPort(name='dem', object=objDem) topo.wireInputPort(name='planet', object=planet) topo.numberRangeLooks = 1 topo.numberAzimuthLooks = 1 topo.lookSide = info.getInstrument().getPlatform().pointingDirection topo.sensingStart = slc.slcSensingStart topo.rangeFirstSample = slc.startingRange topo.demInterpolationMethod='BIQUINTIC' topo.latFilename = self.insar.latFilename topo.lonFilename = self.insar.lonFilename topo.losFilename = self.insar.losFilename topo.heightFilename = self.insar.heightFilename # topo.incFilename = os.path.join(info.outdir, 'inc.rdr') # topo.maskFilename = os.path.join(info.outdir, 'mask.rdr') ####Doppler adjustment dop = info._dopplerVsPixel[::-1] xx = np.linspace(0, (topo.width-1), num=len(dop)+ 1) x = (topo.rangeFirstSample - info.startingRange)/topo.slantRangePixelSpacing + xx * topo.numberRangeLooks v = np.polyval(dop, x) p = np.polyfit(xx, v, len(dop)-1)[::-1] doppler = Poly2D() doppler.setWidth(topo.width) doppler.setLength(topo.length) doppler.initPoly(rangeOrder = len(dop)-1, azimuthOrder=0, coeffs=[list(p)]) topo.polyDoppler = doppler topo.topo() # Record the inputs and outputs from isceobj.Catalog import recordInputsAndOutputs recordInputsAndOutputs(self._insar.procDoc, topo, "runTopo", logger, "runTopo") self._insar.setTopo(topo) return topo
def main(iargs=None): ''' Create coregistered overlap secondarys. ''' inps = cmdLineParse(iargs) referenceSwathList = ut.getSwathList(inps.reference) secondarySwathList = ut.getSwathList(inps.secondary) swathList = list(sorted(set(referenceSwathList + secondarySwathList))) for swath in swathList: ####Load secondary metadata reference = ut.loadProduct( os.path.join(inps.reference, 'IW{0}.xml'.format(swath))) secondary = ut.loadProduct( os.path.join(inps.secondary, 'IW{0}.xml'.format(swath))) if inps.overlap: referenceTop = ut.loadProduct( os.path.join(inps.reference, inps.overlapDir, 'IW{0}_top.xml'.format(swath))) referenceBottom = ut.loadProduct( os.path.join(inps.reference, inps.overlapDir, 'IW{0}_bottom.xml'.format(swath))) dt = secondary.bursts[0].azimuthTimeInterval dr = secondary.bursts[0].rangePixelSize if os.path.exists(str(inps.misreg_az)): with open(inps.misreg_az, 'r') as f: misreg_az = float(f.readline()) else: misreg_az = 0.0 if os.path.exists(str(inps.misreg_rng)): with open(inps.misreg_rng, 'r') as f: misreg_rg = float(f.readline()) else: misreg_rg = 0.0 ###Output directory for coregistered SLCs if not inps.overlap: outdir = os.path.join(inps.coreg, 'IW{0}'.format(swath)) offdir = os.path.join(inps.coreg, 'IW{0}'.format(swath)) else: outdir = os.path.join(inps.coreg, inps.overlapDir, 'IW{0}'.format(swath)) offdir = os.path.join(inps.coreg, inps.overlapDir, 'IW{0}'.format(swath)) os.makedirs(outdir, exist_ok=True) ####Indices w.r.t reference burstoffset, minBurst, maxBurst = reference.getCommonBurstLimits( secondary) secondaryBurstStart = minBurst + burstoffset secondaryBurstEnd = maxBurst relShifts = ut.getRelativeShifts(reference, secondary, minBurst, maxBurst, secondaryBurstStart) print('Shifts: ', relShifts) if inps.overlap: maxBurst = maxBurst - 1 ###For overlaps ####Can corporate known misregistration here apoly = Poly2D() apoly.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.]]) rpoly = Poly2D() rpoly.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.]]) #topCoreg = createTOPSSwathSLCProduct() topCoreg = ut.coregSwathSLCProduct() topCoreg.configure() if inps.overlap: botCoreg = ut.coregSwathSLCProduct() botCoreg.configure() for ii in range(minBurst, maxBurst): jj = secondaryBurstStart + ii - minBurst if inps.overlap: botBurst = referenceBottom.bursts[ii] topBurst = referenceTop.bursts[ii] else: topBurst = reference.bursts[ii] secBurst = secondary.bursts[jj] #####Top burst processing try: offset = relShifts[jj] except: raise Exception( 'Trying to access shift for secondary burst index {0}, which may not overlap with reference' .format(jj)) if inps.overlap: outname = os.path.join( outdir, 'burst_top_%02d_%02d.slc' % (ii + 1, ii + 2)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = { 'azpoly': apoly, 'rgpoly': rpoly, 'rangeOff': os.path.join(offdir, 'range_top_%02d_%02d.off' % (ii + 1, ii + 2)), 'azimuthOff': os.path.join( offdir, 'azimuth_top_%02d_%02d.off' % (ii + 1, ii + 2)) } ###For future - should account for azimuth and range misreg here .. ignoring for now. azCarrPoly, dpoly = secondary.estimateAzimuthCarrierPolynomials( secBurst, offset=-1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly outimg = resampSecondary(topBurst, secBurst, rdict, outname, (not inps.noflat)) copyBurst = copy.deepcopy(topBurst) ut.adjustValidSampleLine(copyBurst) copyBurst.image.filename = outimg.filename print('After: ', copyBurst.firstValidLine, copyBurst.numValidLines) topCoreg.bursts.append(copyBurst) ####################################################### secBurst = secondary.bursts[jj + 1] outname = os.path.join( outdir, 'burst_bot_%02d_%02d.slc' % (ii + 1, ii + 2)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = { 'azpoly': apoly, 'rgpoly': rpoly, 'rangeOff': os.path.join(offdir, 'range_bot_%02d_%02d.off' % (ii + 1, ii + 2)), 'azimuthOff': os.path.join( offdir, 'azimuth_bot_%02d_%02d.off' % (ii + 1, ii + 2)) } azCarrPoly, dpoly = secondary.estimateAzimuthCarrierPolynomials( secBurst, offset=-1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly outimg = resampSecondary(botBurst, secBurst, rdict, outname, (not inps.noflat)) copyBurst = copy.deepcopy(botBurst) ut.adjustValidSampleLine(copyBurst) copyBurst.image.filename = outimg.filename print('After: ', copyBurst.firstValidLine, copyBurst.numValidLines) botCoreg.bursts.append(copyBurst) ####################################################### else: outname = os.path.join(outdir, 'burst_%02d.slc' % (ii + 1)) ####Setup initial polynomials ### If no misregs are given, these are zero ### If provided, can be used for resampling without running to geo2rdr again for fast results rdict = { 'azpoly': apoly, 'rgpoly': rpoly, 'rangeOff': os.path.join(offdir, f'range{suffix}_{ii+1:02d}.off'), 'azimuthOff': os.path.join(offdir, f'azimuth{suffix}_{ii+1:02d}.off') } ###For future - should account for azimuth and range misreg here .. ignoring for now. azCarrPoly, dpoly = secondary.estimateAzimuthCarrierPolynomials( secBurst, offset=-1.0 * offset) rdict['carrPoly'] = azCarrPoly rdict['doppPoly'] = dpoly outimg = resampSecondary(topBurst, secBurst, rdict, outname, (not inps.noflat)) minAz, maxAz, minRg, maxRg = ut.getValidLines( secBurst, rdict, outname, misreg_az=misreg_az - offset, misreg_rng=misreg_rg) copyBurst = copy.deepcopy(topBurst) ut.adjustValidSampleLine_V2(copyBurst, secBurst, minAz=minAz, maxAz=maxAz, minRng=minRg, maxRng=maxRg) copyBurst.image.filename = outimg.filename print('After: ', copyBurst.firstValidLine, copyBurst.numValidLines) topCoreg.bursts.append(copyBurst) ####################################################### topCoreg.numberOfBursts = len(topCoreg.bursts) topCoreg.source = ut.asBaseClass(secondary) if inps.overlap: botCoreg.numberOfBursts = len(botCoreg.bursts) topCoreg.reference = ut.asBaseClass(referenceTop) botCoreg.reference = ut.asBaseClass(referenceBottom) botCoreg.source = ut.asBaseClass(secondary) ut.saveProduct(topCoreg, outdir + '_top.xml') ut.saveProduct(botCoreg, outdir + '_bottom.xml') else: topCoreg.reference = reference ut.saveProduct(topCoreg, outdir + '.xml')
def resampSecondaryGPU(reference, secondary, rdict, outname): ''' Resample burst by burst with GPU ''' # import the GPU module import zerodop.GPUresampslc # get Poly2D objects from rdict and convert them into PyPoly2d objects azpoly = convertPoly2D(rdict['azpoly']) rgpoly = convertPoly2D(rdict['rgpoly']) azcarrpoly = convertPoly2D(rdict['carrPoly']) dpoly = convertPoly2D(rdict['doppPoly']) rngImg = isceobj.createImage() rngImg.load(rdict['rangeOff'] + '.xml') rngImg.setCaster('read', 'FLOAT') rngImg.createImage() aziImg = isceobj.createImage() aziImg.load(rdict['azimuthOff'] + '.xml') aziImg.setCaster('read', 'FLOAT') aziImg.createImage() inimg = isceobj.createSlcImage() inimg.load(secondary.image.filename + '.xml') inimg.setAccessMode('READ') inimg.createImage() # create a GPU resample processor rObj = zerodop.GPUresampslc.createResampSlc() # set parameters rObj.slr = secondary.rangePixelSize rObj.wvl = secondary.radarWavelength # set polynomials rObj.azCarrier = azcarrpoly rObj.dopplerPoly = dpoly rObj.azOffsetsPoly = azpoly rObj.rgOffsetsPoly = rgpoly # need to create an empty rgCarrier poly rgCarrier = Poly2D() rgCarrier.initPoly(rangeOrder=0, azimuthOrder=0, coeffs=[[0.]]) rgCarrier = convertPoly2D(rgCarrier) rObj.rgCarrier = rgCarrier # input secondary image rObj.slcInAccessor = inimg.getImagePointer() rObj.inWidth = inimg.getWidth() rObj.inLength = inimg.getLength() ####Setting reference values rObj.r0 = secondary.startingRange rObj.refr0 = reference.rangePixelSize rObj.refslr = reference.startingRange rObj.refwvl = reference.radarWavelength # set output image width = reference.numberOfSamples length = reference.numberOfLines imgOut = isceobj.createSlcImage() imgOut.setWidth(width) imgOut.filename = outname imgOut.setAccessMode('write') imgOut.createImage() rObj.slcOutAccessor = imgOut.getImagePointer() rObj.outWidth = width rObj.outLength = length rObj.residRgAccessor = rngImg.getImagePointer() rObj.residAzAccessor = aziImg.getImagePointer() # need to specify data type, only complex is currently supported rObj.isComplex = (inimg.dataType == 'CFLOAT') # run resampling rObj.resamp_slc() # finalize images inimg.finalizeImage() imgOut.finalizeImage() rngImg.finalizeImage() aziImg.finalizeImage() imgOut.renderHdr() return imgOut