ISCE_INSAR/components/isceobj/Sensor/SICD_RGZERO.py

248 lines
8.5 KiB
Python

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Author: Piyush Agram
# Copyright 2010, by the California Institute of Technology. ALL RIGHTS
# RESERVED. United States Government Sponsorship acknowledged. Any commercial
# use must be negotiated with the Office of Technology Transfer at the
# California Institute of Technology.
#
# This software may be subject to U.S. export control laws. By accepting this
# software, the user agrees to comply with all applicable U.S. export laws and
# regulations. User has the responsibility to obtain export licenses, or other
# export authority as may be required before exporting such information to
# foreign countries or providing access to foreign persons.
#
# NASA Jet Propulsion Laboratory
# California Institute of Technology
# (C) 2010 All Rights Reserved
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import datetime
import isceobj
from isceobj.Orbit.Orbit import StateVector
from isceobj.Planet.AstronomicalHandbook import Const
from isceobj.Planet.Planet import Planet
from isceobj.Scene.Frame import Frame
from iscesys.DateTimeUtil.DateTimeUtil import DateTimeUtil as DTUtil
from iscesys.Component.Component import Component
from isceobj.Sensor.Sensor import Sensor
SICD = Component.Parameter(
'sicd',
public_name='SICD',
default=None,
type=str,
mandatory=True,
intent='input',
doc='SICD input file')
class SICD_RGZERO(Sensor):
"""
A class to parse SICD RGZERO metadata
"""
parameter_list = (SICD,) + Sensor.parameter_list
logging_name = "isce.sensor.SICD_RGZERO"
family_name = "sicd_rgzero"
def __init__(self):
super(SICD_RGZERO,self).__init__()
self._sicdmeta = None
return None
def getFrame(self):
return self.frame
def parse(self):
try:
import sarpy.io.complex as cf
except ImportError:
raise Exception('You need to install sarpy from NGA - https://github.com/ngageoint/sarpy to work with SICD data')
self._sicdmeta = cf.open(self.sicd).sicdmeta
self.populateMetadata()
def _populatePlatform(self):
mdict = self._sicdmeta
platform = self.frame.getInstrument().getPlatform()
platform.setMission(mdict.CollectionInfo.CollectorName)
platform.setPlanet(Planet(pname="Earth"))
side = mdict.SCPCOA.SideOfTrack
if side.startswith('R'):
side = -1
else:
side = 1
platform.setPointingDirection(side)
if mdict.CollectionInfo.RadarMode.ModeType.upper() != 'STRIPMAP':
raise Exception('SICD ModeType should be STRIPMAP')
if mdict.CollectionInfo.CollectType.upper() != 'MONOSTATIC':
raise Exception('SICD ModeType should be MONOSTATIC')
def _populateInstrument(self, mdict=None):
if mdict is None:
mdict = self._sicdmeta
instrument = self.frame.getInstrument()
###Ensure that data is actually SICD RGZERO
if (mdict.Grid.Type != 'RGZERO'):
raise Exception('Input data must be SICD RGZERO')
if (mdict.Grid.ImagePlane != 'SLANT'):
raise Exception('Input data must be SICD RGZERO in Slant Range plane')
rangePixelSize = mdict.Grid.Row.SS
azimuthPixelSize = mdict.Grid.Col.SS
fs = Const.c/(2*rangePixelSize)
fc = mdict.RMA.INCA.FreqZero
prf = mdict.Timeline.IPP.Set.IPPPoly[1] * mdict.ImageFormation.RcvChanProc.PRFScaleFactor
instrument.setRadarWavelength(Const.c/fc)
instrument.setPulseRepetitionFrequency(prf)
instrument.setRangePixelSize(rangePixelSize)
instrument.setPulseLength(mdict.RadarCollection.Waveform.WFParameters[0].TxPulseLength)
instrument.setChirpSlope(mdict.RadarCollection.Waveform.WFParameters[0].TxRFBandwidth / mdict.RadarCollection.Waveform.WFParameters[0].TxPulseLength )
instrument.setRangeSamplingRate(fs)
instrument.setInPhaseValue(0.)
instrument.setQuadratureValue(0.)
instrument.platform.setAntennaLength(2.2 * azimuthPixelSize)
def _populateFrame(self, mdict=None):
if mdict is None:
mdict = self._sicdmeta
startRange = mdict.RMA.INCA.R_CA_SCP - (mdict.ImageData.SCPPixel.Row * mdict.Grid.Row.SS)
####Compute the UTC times
zd_t_scp = mdict.RMA.INCA.TimeCAPoly[0]
ss_zd_s = 1 /self.frame.PRF
sensingStart = mdict.Timeline.CollectStart + datetime.timedelta(seconds = (zd_t_scp - mdict.ImageData.SCPPixel.Col * ss_zd_s))
sensingStop = sensingStart + datetime.timedelta(seconds = (mdict.ImageData.NumCols-1) / self.frame.PRF)
sensingMid = sensingStart + 0.5 * (sensingStop - sensingStart)
self.frame.setStartingRange(startRange)
if mdict.SCPCOA.ARPVel.Z > 0:
self.frame.setPassDirection('ASCENDING')
else:
self.frame.setPassDirection('DESCENDING')
self.frame.setOrbitNumber(9999)
self.frame.setProcessingFacility(mdict.ImageCreation.Site)
self.frame.setProcessingSoftwareVersion(mdict.ImageCreation.Application)
pol = mdict.ImageFormation.TxRcvPolarizationProc
self.frame.setPolarization(pol[0] + pol[2])
self.frame.setNumberOfLines(mdict.ImageData.NumCols)
self.frame.setNumberOfSamples(mdict.ImageData.NumRows)
self.frame.setSensingStart(sensingStart)
self.frame.setSensingMid(sensingMid)
self.frame.setSensingStop(sensingStop)
rangePixelSize = self.frame.getInstrument().getRangePixelSize()
farRange = startRange + self.frame.getNumberOfSamples()*rangePixelSize
self.frame.setFarRange(farRange)
def _populateOrbit(self, mdict=None):
import numpy.polynomial.polynomial as poly
if mdict is None:
mdict = self._sicdmeta
raw_start_time = mdict.Timeline.CollectStart
tmin = self.frame.sensingStart - datetime.timedelta(seconds=5)
tmax = self.frame.sensingStop + datetime.timedelta(seconds=5)
orbit = self.frame.getOrbit()
orbit.setReferenceFrame('ECEF')
orbit.setOrbitSource('Header')
posX = mdict.Position.ARPPoly.X
posY = mdict.Position.ARPPoly.Y
posZ = mdict.Position.ARPPoly.Z
velX = poly.polyder(posX)
velY = poly.polyder(posY)
velZ = poly.polyder(posZ)
tinp = tmin
while tinp <= tmax:
deltaT = (tinp - raw_start_time).total_seconds()
vec = StateVector()
vec.setTime(tinp)
vec.setPosition([poly.polyval(deltaT, posX),
poly.polyval(deltaT, posY),
poly.polyval(deltaT, posZ)])
vec.setVelocity([poly.polyval(deltaT, velX),
poly.polyval(deltaT, velY),
poly.polyval(deltaT, velZ)])
orbit.addStateVector(vec)
tinp = tinp + datetime.timedelta(seconds=1)
def populateImage(self):
import sarpy.io.complex as cf
img = cf.open(self.sicd)
data = img.read_chip()
data.T.tofile(self.output)
rawImage = isceobj.createSlcImage()
rawImage.setByteOrder('l')
rawImage.setFilename(self.output)
rawImage.setAccessMode('read')
rawImage.setWidth(self.frame.getNumberOfSamples())
rawImage.setXmax(self.frame.getNumberOfSamples())
rawImage.setXmin(0)
self.getFrame().setImage(rawImage)
#rawImage.renderHdr()
def _populateExtras(self):
"""
Populate some extra fields.
"""
from sarpy.geometry.point_projection import coa_projection_set
import numpy as np
mdict = self._sicdmeta
###Imagesize
rows = np.linspace(0., mdict.ImageData.NumRows*1.0, num=3)
rdot = []
for grow in rows:
pt = coa_projection_set(mdict,[grow,0])
rdot.append( pt[1][0])
self.frame._dopplerVsPixel = list(np.polyfit(rows, rdot, 2)[::-1])
def extractImage(self):
"""Extract the raw image data"""
self.parse()
self._populateExtras()
self.populateImage()
def extractDoppler(self):
"""
Return the doppler centroid as defined in the HDF5 file.
"""
dopp = self.frame._dopplerVsPixel
quadratic = {}
quadratic['a'] = dopp[0]
quadratic['b'] = dopp[1]
quadratic['c'] = dopp[2]
return quadratic