742 lines
26 KiB
Python
Executable File
742 lines
26 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
# Copyright 2014 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
|
|
import xml.etree.ElementTree as ElementTree
|
|
import datetime
|
|
import isceobj
|
|
from isceobj.Util import Poly1D, Poly2D
|
|
from isceobj.Scene.Frame import Frame
|
|
from isceobj.Sensor.Sensor import Sensor
|
|
from isceobj.Planet.Planet import Planet
|
|
from isceobj.Orbit.Orbit import StateVector, Orbit
|
|
from isceobj.Orbit.OrbitExtender import OrbitExtender
|
|
from isceobj.Planet.AstronomicalHandbook import Const
|
|
from iscesys.Component.Component import Component
|
|
from iscesys.DateTimeUtil.DateTimeUtil import DateTimeUtil as DTUtil
|
|
from GRDProduct import GRDProduct
|
|
import os
|
|
import glob
|
|
import json
|
|
import numpy as np
|
|
import shelve
|
|
import re
|
|
import matplotlib.pyplot as plt
|
|
|
|
sep = "\n"
|
|
tab = " "
|
|
lookMap = { 'RIGHT' : -1,
|
|
'LEFT' : 1}
|
|
|
|
|
|
class Radarsat2_GRD(Component):
|
|
"""
|
|
A Class representing RadarSAT 2 data
|
|
"""
|
|
def __init__(self):
|
|
Component.__init__(self)
|
|
self.xml = None
|
|
self.tiff = None
|
|
self.orbitFile = None
|
|
self.auxFile = None
|
|
self.orbitDir = None
|
|
self.auxDir = None
|
|
self.lutSigmaXml = None
|
|
self.productXml = None
|
|
self.noiseXml = None
|
|
self.noiseCorrectionApplied = False
|
|
self.noiseLUT = None
|
|
#self.manifest = None
|
|
#self.IPFversion = None
|
|
self.slantRangeFile = None
|
|
self._xml_root=None
|
|
self.output= None
|
|
self.lutSigma = None
|
|
self.product = GRDProduct()
|
|
self.product.configure()
|
|
|
|
|
|
def parse(self):
|
|
|
|
try:
|
|
with open(self.xml, 'r') as fid:
|
|
xmlstring = fid.read()
|
|
xmlstr = re.sub('\\sxmlns="[^"]+"', '', xmlstring, count=1)
|
|
except:
|
|
raise Exception('Could not read xml file {0}'.format(self.xml))
|
|
|
|
self._xml_root = ElementTree.fromstring(xmlstr)
|
|
|
|
self.populateMetadata()
|
|
self.populateBbox()
|
|
|
|
####Tru and locate an orbit file
|
|
if self.orbitFile is None:
|
|
if self.orbitDir is not None:
|
|
self.orbitFile = self.findOrbitFile()
|
|
|
|
|
|
####Read in the orbits
|
|
if self.orbitFile:
|
|
orb = self.extractPreciseOrbit()
|
|
else:
|
|
orb = self.getOrbitFromXML()
|
|
|
|
self.product.orbit.setOrbitSource('Header')
|
|
for sv in orb:
|
|
self.product.orbit.addStateVector(sv)
|
|
|
|
####Read in the gcps
|
|
if self.readGCPsFromXML:
|
|
gcps = self.readGCPsFromXML()
|
|
|
|
|
|
########
|
|
self.extractlutSigma()
|
|
#self.extractNoiseLUT()
|
|
self.extractgr2sr()
|
|
|
|
|
|
def getxmlattr(self, path, key):
|
|
try:
|
|
res = self._xml_root.find(path).attrib[key]
|
|
except:
|
|
raise Exception('Cannot find attribute %s at %s'%(key, path))
|
|
|
|
return res
|
|
|
|
def getxmlvalue(self, path):
|
|
try:
|
|
res = self._xml_root.find(path).text
|
|
except:
|
|
raise Exception('Tag= %s not found'%(path))
|
|
|
|
if res is None:
|
|
raise Exception('Tag = %s not found'%(path))
|
|
|
|
return res
|
|
|
|
def getxmlelement(self, path):
|
|
try:
|
|
res = self._xml_root.find(path)
|
|
except:
|
|
raise Exception('Cannot find path %s'%(path))
|
|
|
|
if res is None:
|
|
raise Exception('Cannot find path %s'%(path))
|
|
|
|
return res
|
|
|
|
def convertToDateTime(self, string):
|
|
dt = datetime.datetime.strptime(string,"%Y-%m-%dT%H:%M:%S.%fZ")
|
|
return dt
|
|
|
|
def getFrame(self):
|
|
return self.frame
|
|
|
|
|
|
def populateMetadata(self):
|
|
"""
|
|
Create metadata objects from the metadata files
|
|
"""
|
|
####Set each parameter one - by - one
|
|
|
|
mission = self.getxmlvalue('sourceAttributes/satellite')
|
|
swath = self.getxmlvalue('sourceAttributes/radarParameters/beams')
|
|
polarization = self.getxmlvalue('sourceAttributes/radarParameters/polarizations')
|
|
orig_prf = float(self.getxmlvalue('sourceAttributes/radarParameters/pulseRepetitionFrequency'))
|
|
#orbitnumber = int(self.getxmlvalue('adsHeader/absoluteOrbitNumber'))
|
|
frequency = float(self.getxmlvalue('sourceAttributes/radarParameters/radarCenterFrequency'))
|
|
#passDirection = self.getxmlvalue('sourceAttributes/orbitAndAttitude/orbitInformation/passDirection')
|
|
|
|
groundRangePixelSize = float(self.getxmlvalue('imageAttributes/rasterAttributes/sampledPixelSpacing'))
|
|
azimuthPixelSize = float(self.getxmlvalue('imageAttributes/rasterAttributes/sampledLineSpacing'))
|
|
rank = self.getxmlvalue('sourceAttributes/radarParameters/rank')
|
|
##################################
|
|
|
|
orb = self.getOrbitFromXML()
|
|
self.product.orbit.setOrbitSource('Header')
|
|
|
|
gcps = self.readGCPsFromXML()
|
|
#print('gcps=',gcps)
|
|
|
|
azt = np.zeros((len(gcps),3), dtype=np.float)
|
|
nvalid = 0
|
|
for ind,gcp in enumerate(gcps):
|
|
try:
|
|
tt,rr = orb.geo2rdr(gcp[2:])
|
|
aztime = tt.hour * 3600 + tt.minute * 60 + tt.second + 1e-6 * tt.microsecond
|
|
azt[nvalid,:] = [gcp[0], gcp[1], aztime] #line, pixel, time
|
|
nvalid += 1
|
|
#print('nvalid=',nvalid)
|
|
#print('aztime=',aztime)
|
|
#print('azt=',azt)
|
|
|
|
except:
|
|
pass
|
|
|
|
###Fit linear polynomial
|
|
pp = np.polyfit(azt[:nvalid,0], azt[::-1,2],1)
|
|
azimuthTimeInterval = abs(pp[0])
|
|
print('azimuthTimeInterval=',azimuthTimeInterval)
|
|
#print("Offset should be close to sensing start: ", datetime.timedelta(seconds=pp[0]))
|
|
#gcp = [line, pixel, lat, lon, hgt]
|
|
####################################
|
|
|
|
lines = int(self.getxmlvalue('imageAttributes/rasterAttributes/numberOfLines'))
|
|
print('startlines=',lines)
|
|
samples = int(self.getxmlvalue('imageAttributes/rasterAttributes/numberOfSamplesPerLine'))
|
|
totalProcessedAzimuthBandwidth = self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/totalProcessedAzimuthBandwidth')
|
|
prf = totalProcessedAzimuthBandwidth # effective PRF can be double original, suggested by Piyush
|
|
#slantRangeTime = float(self.getxmlvalue('imageAnnotation/imageInformation/slantRangeTime'))
|
|
|
|
startingSlantRange = float(self.getxmlvalue('imageGenerationParameters/slantRangeToGroundRange/slantRangeTimeToFirstRangeSample')) * (Const.c/2)
|
|
incidenceAngle = (float(self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/incidenceAngleNearRange')) + float(self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/incidenceAngleFarRange')))/2.0
|
|
|
|
|
|
|
|
lineFlip = self.getxmlvalue('imageAttributes/rasterAttributes/lineTimeOrdering').upper() == 'DECREASING'
|
|
|
|
print('lineFlip',lineFlip)
|
|
|
|
if lineFlip:
|
|
sensingStop = self.convertToDateTime(self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/zeroDopplerTimeFirstLine'))
|
|
sensingStart = self.convertToDateTime(self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/zeroDopplerTimeLastLine'))
|
|
else:
|
|
sensingStart = self.convertToDateTime(self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/zeroDopplerTimeFirstLine'))
|
|
sensingStop = self.convertToDateTime(self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/zeroDopplerTimeLastLine'))
|
|
|
|
|
|
|
|
####Radarsat 2 me be right looking or left looking
|
|
#lookSide = -1
|
|
lookSide = lookMap[self.getxmlvalue('sourceAttributes/radarParameters/antennaPointing').upper()]
|
|
print('lookSide=',lookSide)
|
|
###Read ascending node for phase calibration
|
|
|
|
###Noise correction
|
|
#correctionApplied = self.getxmlvalue('imageGenerationParameters/sarProcessingInformation/radiometricSmoothingPerformed').upper() == 'TRUE'
|
|
correctionApplied = False
|
|
print('correctionApplied=',correctionApplied)
|
|
|
|
#Populate Frame
|
|
self.product.numberOfSamples = samples
|
|
self.product.numberOfLines = lines
|
|
self.product.startingGroundRange = 0.0
|
|
self.product.startingSlantRange = startingSlantRange
|
|
#self.product.trackNumber = ((orbitnumber-73)%175) + 1
|
|
#self.product.orbitNumber = orbitnumber
|
|
self.product.frameNumber = 1
|
|
self.product.polarization = polarization
|
|
self.product.prf = prf
|
|
self.product.azimuthTimeInterval = azimuthTimeInterval
|
|
|
|
#self.product.passDirection = passDirection
|
|
self.product.radarWavelength = Const.c / frequency
|
|
self.product.groundRangePixelSize = groundRangePixelSize
|
|
#self.product.ascendingNodeTime = ascTime
|
|
#self.product.slantRangeTime = slantRangeTime
|
|
self.product.sensingStart = sensingStart
|
|
self.product.sensingStop = sensingStop
|
|
self.noiseCorrectionApplied = correctionApplied
|
|
|
|
def populateBbox(self, margin=0.1):
|
|
'''
|
|
Populate the bounding box from metadata.
|
|
'''
|
|
|
|
glist = (self.getxmlelement('imageAttributes/geographicInformation/geolocationGrid'))
|
|
lat = []
|
|
lon = []
|
|
for child in glist.getchildren():
|
|
for grandchild in child.getchildren():
|
|
string = ElementTree.tostring(grandchild, encoding = 'unicode', method = 'xml')
|
|
string = string.split("<")[1]
|
|
string = string.split(">")[0]
|
|
if string == 'geodeticCoordinate':
|
|
lat.append( float(grandchild.find('latitude').text))
|
|
lon.append( float(grandchild.find('longitude').text))
|
|
self.product.bbox = [min(lat) - margin, max(lat) + margin, min(lon) - margin, max(lon) + margin]
|
|
print('coordinate=',self.product.bbox)
|
|
|
|
return
|
|
|
|
#################################
|
|
|
|
def getOrbitFromXML(self):
|
|
'''
|
|
Populate orbit.
|
|
'''
|
|
|
|
orb = Orbit()
|
|
orb.configure()
|
|
|
|
for node in self._xml_root.find('sourceAttributes/orbitAndAttitude/orbitInformation'):
|
|
if node.tag == 'stateVector':
|
|
sv = StateVector()
|
|
sv.configure()
|
|
for z in node.getchildren():
|
|
if z.tag == 'timeStamp':
|
|
timeStamp = self.convertToDateTime(z.text)
|
|
elif z.tag == 'xPosition':
|
|
xPosition = float(z.text)
|
|
elif z.tag == 'yPosition':
|
|
yPosition = float(z.text)
|
|
elif z.tag == 'zPosition':
|
|
zPosition = float(z.text)
|
|
elif z.tag == 'xVelocity':
|
|
xVelocity = float(z.text)
|
|
elif z.tag == 'yVelocity':
|
|
yVelocity = float(z.text)
|
|
elif z.tag == 'zVelocity':
|
|
zVelocity = float(z.text)
|
|
|
|
sv.setTime(timeStamp)
|
|
sv.setPosition([xPosition, yPosition, zPosition])
|
|
sv.setVelocity([xVelocity, yVelocity, zVelocity])
|
|
orb.addStateVector(sv)
|
|
|
|
|
|
orbExt = OrbitExtender(planet=Planet(pname='Earth'))
|
|
orbExt.configure()
|
|
newOrb = orbExt.extendOrbit(orb)
|
|
|
|
return newOrb
|
|
|
|
self.product.orbit.setOrbitSource('Header')
|
|
for sv in newOrb:
|
|
self.product.orbit.addStateVector(sv)
|
|
|
|
|
|
def readGCPsFromXML(self):
|
|
'''
|
|
Populate GCPS
|
|
'''
|
|
gcps = []
|
|
|
|
for node in self._xml_root.find('imageAttributes/geographicInformation/geolocationGrid'):
|
|
if not node.tag == 'imageTiePoint':
|
|
continue
|
|
|
|
for z in node.getchildren():
|
|
if z.tag == 'imageCoordinate':
|
|
for zz in z.getchildren():
|
|
if zz.tag == 'line':
|
|
line = float(zz.text)
|
|
elif zz.tag == 'pixel':
|
|
pixel = float(zz.text)
|
|
|
|
if z.tag == 'geodeticCoordinate':
|
|
for zz in z.getchildren():
|
|
if zz.tag == 'latitude':
|
|
lat = float(zz.text)
|
|
elif zz.tag == 'longitude':
|
|
lon = float(zz.text)
|
|
elif zz.tag == 'height':
|
|
hgt = float(zz.text)
|
|
|
|
pt = [line, pixel, lat, lon, hgt]
|
|
gcps.append(pt)
|
|
|
|
return gcps
|
|
#######################################
|
|
|
|
def extractlutSigma(self, iargs=None):
|
|
'''
|
|
Extract Sigma nought look up table from calibration file.
|
|
'''
|
|
|
|
from scipy.interpolate import RectBivariateSpline
|
|
from scipy.interpolate import interp1d
|
|
from scipy.interpolate import Rbf, InterpolatedUnivariateSpline
|
|
|
|
if self.lutSigmaXml is None:
|
|
raise Exception('No calibration file provided')
|
|
|
|
try:
|
|
with open(self.lutSigmaXml, 'r') as fid:
|
|
xmlstr = fid.read()
|
|
|
|
except:
|
|
raise Exception('Could not read calibration file: {0}'.format(self.lutSigmaXml))
|
|
_xml_root = ElementTree.fromstring(xmlstr)
|
|
#print(_xml_root)
|
|
node = _xml_root.find('gains').text
|
|
node = node.split(' ')
|
|
node = [float(x) for x in node]
|
|
#data = None
|
|
|
|
|
|
#nump = len(node) #this is the length of gains
|
|
#numps = list(range(nump))
|
|
sigmadata = np.asarray(node)
|
|
self.lutSigma = sigmadata
|
|
#self.lutSigma = interp1d(numps, sigmadata, kind='cubic')
|
|
#self.lutSigma = InterpolatedUnivariateSpline(numps, sigmadata)
|
|
|
|
if False:
|
|
import matplotlib.pyplot as plt
|
|
plt.figure()
|
|
plt.imshow(data)
|
|
plt.colorbar()
|
|
plt.show()
|
|
|
|
return
|
|
#====================================
|
|
|
|
def extractgr2sr(self):
|
|
'''
|
|
Extract Slant Range to Ground Range polynomial
|
|
'''
|
|
from scipy.interpolate import interp1d
|
|
|
|
node = self._xml_root.find('imageGenerationParameters')
|
|
#num = int(node.attrib['count'])
|
|
|
|
lines = []
|
|
data = []
|
|
|
|
for child in node.getchildren():
|
|
for child in node.getchildren():
|
|
string = ElementTree.tostring(child, encoding = 'unicode', method = 'xml')
|
|
string = string.split("<")[1]
|
|
string = string.split(">")[0]
|
|
if string == 'slantRangeToGroundRange':
|
|
|
|
t0 = self.convertToDateTime(child.find('zeroDopplerAzimuthTime').text)
|
|
lines.append( (t0-self.product.sensingStart).total_seconds()/self.product.azimuthTimeInterval)
|
|
|
|
pp = [float(x) for x in child.find('groundToSlantRangeCoefficients').text.split()]
|
|
meangr = float( child.find('groundRangeOrigin').text)
|
|
if meangr !=0 :
|
|
raise Exception('Ground range image does not start at zero coordinate')
|
|
|
|
data.append(pp[::-1])
|
|
#print('lines123=',lines)
|
|
#print('data0=',data)
|
|
###If polynomial starts beyond first line
|
|
if lines[0] > 0:
|
|
lines.insert(0, 0.)
|
|
pp = data[0]
|
|
data.insert(0,pp)
|
|
#print('data1=',data)
|
|
####If polynomial ends before last line
|
|
if lines[-1] < (self.product.numberOfLines-1):
|
|
lines.append(self.product.numberOfLines-1.0)
|
|
pp = data[-1]
|
|
data.append(pp)
|
|
#print('data2=',data)
|
|
|
|
lines = np.array(lines)
|
|
data = np.array(data)
|
|
#print('lines=',lines)
|
|
#print('data=',data)
|
|
LUT = []
|
|
|
|
for ii in range(data.shape[1]):
|
|
col = data[:,ii]
|
|
#print('col=',col)
|
|
LUT.append(interp1d(lines, col, bounds_error=False, assume_sorted=True))
|
|
|
|
self.gr2srLUT = LUT
|
|
#print('lines=',len(self.gr2srLUT))
|
|
#print('data=',data)
|
|
if False:
|
|
import matplotlib.pyplot as plt
|
|
plt.figure()
|
|
plt.imshow(data)
|
|
plt.colorbar()
|
|
plt.show()
|
|
|
|
return
|
|
|
|
def extractImage(self, parse=False, removeNoise=False, verbose=True):
|
|
"""
|
|
Use gdal python bindings to extract image
|
|
"""
|
|
try:
|
|
from osgeo import gdal
|
|
except ImportError:
|
|
raise Exception('GDAL python bindings not found. Need this for RSAT2/ TandemX / Sentinel1A.')
|
|
|
|
from scipy.interpolate import interp2d
|
|
|
|
if parse:
|
|
self.parse()
|
|
|
|
print('Extracting normalized image ....')
|
|
|
|
src = gdal.Open(self.tiff.strip(), gdal.GA_ReadOnly)
|
|
band = src.GetRasterBand(1)
|
|
|
|
if self.product.numberOfSamples != src.RasterXSize:
|
|
raise Exception('Width in metadata and image dont match')
|
|
|
|
if self.product.numberOfLines != src.RasterYSize:
|
|
raise Exception('Length in metadata and image dont match')
|
|
|
|
|
|
noiseFactor = 0.0
|
|
if (not removeNoise) and self.noiseCorrectionApplied:
|
|
print('User asked for data without noise corrections, but product appears to be corrected. Adding back noise from LUT ....')
|
|
noiseFactor = 1.0
|
|
elif removeNoise and (not self.noiseCorrectionApplied):
|
|
print('User asked for data with noise corrections, but the products appears to not be corrected. Applying noise corrections from LUT ....')
|
|
noiseFactor = -1.0
|
|
elif (not removeNoise) and (not self.noiseCorrectionApplied):
|
|
print('User asked for data without noise corrections. The product contains uncorrected data ... unpacking ....')
|
|
else:
|
|
print('User asked for noise corrected data and the product appears to be noise corrected .... unpacking ....')
|
|
|
|
###Write original GRD to file
|
|
fid = open(self.output, 'wb')
|
|
lineFlip = self.getxmlvalue('imageAttributes/rasterAttributes/lineTimeOrdering').upper() == 'DECREASING'
|
|
pixFlip = self.getxmlvalue('imageAttributes/rasterAttributes/pixelTimeOrdering').upper() == 'DECREASING'
|
|
|
|
lines = int(self.getxmlvalue('imageAttributes/rasterAttributes/numberOfLines'))
|
|
pix = np.arange(self.product.numberOfSamples)
|
|
lin =np.arange(self.product.numberOfLines)
|
|
|
|
for ii in range(self.product.numberOfLines//lines + 1):
|
|
ymin = int(ii*lines)
|
|
ymax = int(np.clip(ymin+lines,0, self.product.numberOfLines))
|
|
print('ymin=',ymin)
|
|
print('ymax=',ymax)
|
|
if ymax == ymin:
|
|
break
|
|
|
|
lin = np.arange(ymin,ymax)
|
|
####Read in one line of data
|
|
data = 1.0 * band.ReadAsArray(0, ymin, self.product.numberOfSamples, ymax-ymin)
|
|
#lut = self.lutSigma(lin,pix,grid=True)
|
|
lut = self.lutSigma
|
|
if noiseFactor != 0.0:
|
|
noise = self.noiseLUT(lin,pix)
|
|
#noise = self.noiseLUT(lin,pix,grid=True)
|
|
|
|
else:
|
|
noise = 0.0
|
|
|
|
#outdata = data
|
|
outdata = data*data/(lut*lut) + noiseFactor * noise/(lut*lut)
|
|
#outdata = 10 * np.log10(outdata)
|
|
|
|
if lineFlip:
|
|
if verbose:
|
|
print('Vertically Flipping data')
|
|
outdata = np.flipud(outdata)
|
|
|
|
if pixFlip:
|
|
if verbose:
|
|
print('Horizontally Flipping data')
|
|
outdata = np.fliplr(outdata)
|
|
|
|
outdata.astype(np.float32).tofile(fid)
|
|
fid.close()
|
|
|
|
####Render ISCE XML
|
|
L1cImage = isceobj.createImage()
|
|
L1cImage.setByteOrder('l')
|
|
L1cImage.dataType = 'FLOAT'
|
|
L1cImage.setFilename(self.output)
|
|
L1cImage.setAccessMode('read')
|
|
L1cImage.setWidth(self.product.numberOfSamples)
|
|
L1cImage.setLength(self.product.numberOfLines)
|
|
L1cImage.renderHdr()
|
|
L1cImage.renderVRT()
|
|
|
|
|
|
band = None
|
|
src = None
|
|
|
|
self.extractSlantRange()
|
|
|
|
return
|
|
|
|
def extractSlantRange(self):
|
|
'''
|
|
Extract pixel-by-pixel slant range file for GRD files.
|
|
'''
|
|
|
|
if self.slantRangeFile is None:
|
|
return
|
|
|
|
print('Extracing slant range ....')
|
|
|
|
|
|
###Write original L1c to file
|
|
fid = open(self.slantRangeFile, 'wb')
|
|
pix = np.arange(self.product.numberOfSamples) * self.product.groundRangePixelSize
|
|
lin = np.arange(self.product.numberOfLines)
|
|
|
|
polys = np.zeros((self.product.numberOfLines, len(self.gr2srLUT)))
|
|
|
|
for ii, intp in enumerate(self.gr2srLUT):
|
|
polys[:,ii] = intp(lin)
|
|
|
|
|
|
for ii in range(self.product.numberOfLines):
|
|
pp = polys[ii,:]
|
|
outdata = np.polyval(pp, pix)
|
|
outdata.tofile(fid)
|
|
|
|
fid.close()
|
|
|
|
####Render ISCE XML
|
|
L1cImage = isceobj.createImage()
|
|
L1cImage.setByteOrder('l')
|
|
L1cImage.dataType = 'DOUBLE'
|
|
L1cImage.setFilename(self.slantRangeFile)
|
|
L1cImage.setAccessMode('read')
|
|
L1cImage.setWidth(self.product.numberOfSamples)
|
|
L1cImage.setLength(self.product.numberOfLines)
|
|
L1cImage.renderHdr()
|
|
L1cImage.renderVRT()
|
|
self.product.slantRangeimage = L1cImage
|
|
|
|
|
|
def createParser():
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser( description = 'Radarsar parser' )
|
|
|
|
parser.add_argument('-d', '--dirname', dest='dirname', type=str,
|
|
default=None, help='SAFE format directory. (Recommended)')
|
|
|
|
parser.add_argument('-o', '--outdir', dest='outdir', type=str,
|
|
required=True, help='Output L1c prefix.')
|
|
|
|
parser.add_argument('--orbitdir', dest='orbitdir', type=str,
|
|
default=None, help = 'Directory with all the orbits')
|
|
|
|
parser.add_argument('--auxdir', dest='auxdir', type=str,
|
|
default=None, help = 'Directory with all the aux products')
|
|
|
|
parser.add_argument('--denoise', dest='denoise', action='store_true',
|
|
default=False, help = 'Add noise back if removed')
|
|
|
|
return parser
|
|
|
|
def cmdLineParse(iargs=None):
|
|
'''
|
|
Command Line Parser.
|
|
'''
|
|
import fnmatch
|
|
import glob
|
|
|
|
parser = createParser()
|
|
inps = parser.parse_args(args=iargs)
|
|
print('inpssss=',inps.dirname)
|
|
if inps.dirname is None:
|
|
raise Exception('File is not provided')
|
|
|
|
####First find HH Product path
|
|
swathid = 'product.xml'
|
|
swathid1 = 'imagery_HH.'
|
|
swathid2 = 'lutSigma.xml'
|
|
inps.data = {}
|
|
#Find XML file
|
|
patt = os.path.join('RS2_*', swathid)
|
|
match = glob.glob(patt)
|
|
if len(match) == 0:
|
|
raise Exception('Target file {0} not found'.format(patt))
|
|
inps.data['xml'] = match[0]
|
|
|
|
#Find TIFF file
|
|
patt = os.path.join('RS2_*', swathid1+'*')
|
|
match = glob.glob(patt)
|
|
if len(match) == 0 :
|
|
raise Exception('Target file {0} not found'.format(patt))
|
|
inps.data['tiff'] = match[0]
|
|
|
|
#Find Calibration file
|
|
patt = os.path.join('RS2_*', swathid2)
|
|
match = glob.glob(patt)
|
|
if len(match) == 0 :
|
|
raise Exception('Target file {0} not found'.format(patt))
|
|
inps.data['calibration'] = match[0]
|
|
|
|
return inps
|
|
|
|
def main(iargs=None):
|
|
inps = cmdLineParse(iargs)
|
|
|
|
rangeDone = False
|
|
|
|
obj = Radarsat2_GRD()
|
|
obj.configure()
|
|
obj.xml = inps.data['xml']
|
|
obj.tiff = inps.data['tiff']
|
|
obj.lutSigmaXml = inps.data['calibration']
|
|
|
|
if not os.path.isdir(inps.outdir):
|
|
os.mkdir(inps.outdir)
|
|
else:
|
|
print('Output directory {0} already exists.'.format(inps.outdir))
|
|
|
|
obj.output = os.path.join(inps.outdir, 'Sigma0_' + 'HH' + '.img')
|
|
|
|
if not rangeDone:
|
|
obj.slantRangeFile = os.path.join(inps.outdir, 'slantRange.img')
|
|
rangeDone = True
|
|
|
|
obj.parse()
|
|
obj.extractImage(removeNoise=inps.denoise)
|
|
|
|
dbname = os.path.join(inps.outdir, 'metadata')
|
|
with shelve.open(dbname) as db:
|
|
db['HH'] = obj.product
|
|
|
|
|
|
if __name__ == '__main__':
|
|
'''
|
|
Main driver.
|
|
'''
|
|
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|