1864 lines
71 KiB
Python
1864 lines
71 KiB
Python
#!/usr/bin/env python3
|
||
|
||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
# Copyright 2010 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
|
||
#
|
||
# LT1AB 重复轨道模式
|
||
#
|
||
# Author: Chenzenghui
|
||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
|
||
|
||
|
||
from xml.etree.ElementTree import ElementTree
|
||
import datetime
|
||
import isceobj
|
||
from isceobj.Util import Poly1D
|
||
from isceobj.Scene.Frame import Frame
|
||
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
|
||
import os
|
||
import numpy as np
|
||
import math
|
||
import datetime
|
||
import time
|
||
from math import sin,cos
|
||
from scipy.optimize import leastsq
|
||
import numpy as np
|
||
from isceobj.Util.Poly2D import Poly2D
|
||
|
||
|
||
|
||
sep = "\n"
|
||
tab = " "
|
||
lookMap = { 'RIGHT' : -1,
|
||
'LEFT' : 1}
|
||
|
||
TIFF = Component.Parameter(
|
||
'tiff',
|
||
public_name='TIFF',
|
||
default='',
|
||
type=str,
|
||
mandatory=True,
|
||
doc='RadarSAT2 tiff imagery file'
|
||
)
|
||
|
||
XML = Component.Parameter(
|
||
'xml',
|
||
public_name='XML',
|
||
default='',
|
||
type=str,
|
||
mandatory=True,
|
||
doc='RadarSAT2 xml metadata file'
|
||
)
|
||
|
||
ORBIT_DIRECTORY = Component.Parameter(
|
||
'orbitDirectory',
|
||
public_name = 'orbit directory',
|
||
default=None,
|
||
type=str,
|
||
mandatory=False,
|
||
doc='Directory with Radarsat2 precise orbits')
|
||
|
||
ORBIT_FILE = Component.Parameter(
|
||
'orbitFile',
|
||
public_name = 'orbit file',
|
||
default = None,
|
||
type = str,
|
||
mandatory = False,
|
||
doc = 'Precise orbit file to use')
|
||
|
||
from .Sensor import Sensor
|
||
|
||
|
||
#######################################################################################################
|
||
# 增加轨道求解模型,为了方便轨道模型的求解,这里对轨道模型进行修改
|
||
# 这里采用《Insar原理和应用 》(刘国祥著)中基于空间定位的轨道参数计算方法一章中的内容(Gabriel and Goldstein)
|
||
# 注意为了方便计算,采用基准时间的方法
|
||
######################################################
|
||
|
||
def FindInfomationFromJson(HeaderFile_dom_json, node_path_list):
|
||
"""
|
||
在Json文件中,按照指定路径解析出制定节点
|
||
"""
|
||
result_node = HeaderFile_dom_json
|
||
for nodename in node_path_list:
|
||
result_node = result_node[nodename]
|
||
return result_node
|
||
|
||
|
||
def GetVectorNorm(Vecter):
|
||
"""
|
||
得到向量的模
|
||
"""
|
||
Vecter = Vecter.reshape(-1,1)
|
||
Vecter_Norm_pow = np.matmul(Vecter.T,Vecter)
|
||
return np.sqrt(Vecter_Norm_pow)
|
||
|
||
|
||
def XYZOuterM2(A, B):
|
||
"""
|
||
外积(叉乘),日后版本换成可以任意维度的外积运算方程
|
||
args:
|
||
A:nx3
|
||
B:nx3
|
||
"""
|
||
cnt = A.shape[0]
|
||
C = np.zeros((cnt, 3))
|
||
C[:, 0] = A[:, 1] * B[:, 2] - A[:, 2] * B[:, 1]
|
||
C[:, 1] = A[:, 2] * B[:, 0] - A[:, 0] * B[:, 2]
|
||
C[:, 2] = A[:, 0] * B[:, 1] - A[:, 1] * B[:, 0]
|
||
return C
|
||
|
||
|
||
class SatelliteOrbit(object):
|
||
def __init__(self) -> None:
|
||
super().__init__()
|
||
self.starttime = 1262275200.0
|
||
self.modelName=""
|
||
|
||
def get_starttime(self):
|
||
'''
|
||
返回卫星轨道时间起算点
|
||
'''
|
||
return self.starttime
|
||
|
||
def ReconstructionSatelliteOrbit(self, GPSPoints_list):
|
||
'''
|
||
重建卫星轨道,使用多项式拟合法
|
||
args:
|
||
GPSPoints_list:GPS 卫星轨道点
|
||
return:
|
||
SatelliteOrbitModel 卫星轨道模型
|
||
'''
|
||
self.SatelliteOrbitModel = None
|
||
|
||
def SatelliteSpaceState(self, time_float):
|
||
'''
|
||
根据时间戳,返回对应时间的卫星的轨迹状态
|
||
args:
|
||
time_float:时间戳
|
||
return:
|
||
State_list:[time,Xp,Yp,Zp,Vx,Vy,Vz]
|
||
'''
|
||
return None
|
||
|
||
|
||
class SatelliteOrbitFitPoly(SatelliteOrbit):
|
||
'''
|
||
继承于SatelliteOribit类,为拟合多项式实现方法
|
||
'''
|
||
|
||
def __init__(self) -> None:
|
||
super().__init__()
|
||
self.modelName="多项式"
|
||
self.polynum=4
|
||
|
||
def ReconstructionSatelliteOrbit(self, GPSPoints_list, starttime):
|
||
if len(GPSPoints_list)==2:
|
||
self.polynum=1
|
||
self.starttime = starttime
|
||
|
||
record_count = len(GPSPoints_list)
|
||
time_arr = np.zeros((record_count, 1), dtype=np.float64) # 使用np.float64只是为了精度高些;如果32位也能满足需求,请用32位
|
||
state_arr = np.zeros((record_count, 6), dtype=np.float64)
|
||
A_arr = np.zeros((self.polynum+1, 6), dtype=np.float64) # 四次项
|
||
X=np.ones((record_count,self.polynum+1),dtype=np.float64) # 记录时间坐标
|
||
# 将点记录转换为自变量矩阵、因变量矩阵
|
||
|
||
for i in range(record_count):
|
||
GPSPoint = GPSPoints_list[i]
|
||
time_ = GPSPoint[0] - self.starttime # 为了保证精度,对时间进行缩放
|
||
X[i,:]=np.array([1,time_])
|
||
state_arr[i, :] = np.array(GPSPoint[1:],dtype=np.float64).reshape(1,6) # 空间坐标
|
||
self.model_f=[]
|
||
for i in range(6):
|
||
Y = state_arr[:, i].reshape(-1,1)
|
||
A_arr[:,i]=np.matmul(np.matmul(np.linalg.inv(np.matmul(X.T,X)),X.T),Y)[:,0]
|
||
|
||
self.A_arr=copy.deepcopy(A_arr.copy())
|
||
return self.A_arr
|
||
elif len(GPSPoints_list) > 6:
|
||
# 多项式的节点数,理论上是超过5个可以起算,这里为了精度选择10个点起算。
|
||
# 多项式 XA=Y ==> A=(X'X)^X'Y,其中 A 为待求系数,X为变量,Y为因变量
|
||
# 这里使用三次项多项式,共有6组参数。
|
||
# 声明自变量,因变量,系数矩阵
|
||
self.starttime = starttime
|
||
|
||
record_count = len(GPSPoints_list)
|
||
time_arr = np.zeros((record_count, 1), dtype=np.float64) # 使用np.float64只是为了精度高些;如果32位也能满足需求,请用32位
|
||
state_arr = np.zeros((record_count, 6), dtype=np.float64)
|
||
A_arr = np.zeros((self.polynum, 6), dtype=np.float64) # 四次项
|
||
X=np.ones((record_count,self.polynum),dtype=np.float64) # 记录时间坐标
|
||
# 将点记录转换为自变量矩阵、因变量矩阵
|
||
|
||
for i in range(record_count):
|
||
GPSPoint = GPSPoints_list[i]
|
||
time_ = GPSPoint[0] - self.starttime # 为了保证精度,对时间进行缩放
|
||
X[i,:]=np.array(list(map(lambda ii:time_**ii,range(self.polynum))))
|
||
state_arr[i, :] = np.array(GPSPoint[1:],dtype=np.float64).reshape(1,6) # 空间坐标
|
||
self.model_f=[]
|
||
for i in range(6):
|
||
Y = state_arr[:, i].reshape(-1,1)
|
||
A_arr[:,i]=np.matmul(np.matmul(np.linalg.inv(np.matmul(X.T,X)),X.T),Y)[:,0]
|
||
|
||
self.A_arr=A_arr.copy()
|
||
return self.A_arr
|
||
else:
|
||
self.A_arr = None
|
||
return None
|
||
|
||
def SatelliteSpaceState(self, time_float):
|
||
'''
|
||
逐像素求解
|
||
根据时间戳,返回对应时间的卫星的轨迹状态,会自动计算与起算时间之差
|
||
args:
|
||
time_float:时间戳
|
||
return:
|
||
State_list:[time,Xp,Yp,Zp,Vx,Vy,Vz]
|
||
'''
|
||
if self.model_f is None:
|
||
return None
|
||
|
||
result_arr=np.zeros((1,7))
|
||
|
||
time_float = time_float - self.starttime
|
||
|
||
#
|
||
px=0
|
||
py=0
|
||
pz=0
|
||
vx=0
|
||
vy=0
|
||
vz=0
|
||
for ii in range(self.polynum):
|
||
px+=self.A_arr[ii,0]*time_float**ii
|
||
py+=self.A_arr[ii,1]*time_float**ii
|
||
pz+=self.A_arr[ii,2]*time_float**ii
|
||
vx+=self.A_arr[ii,3]*time_float**ii
|
||
vy+=self.A_arr[ii,4]*time_float**ii
|
||
vz+=self.A_arr[ii,5]*time_float**ii
|
||
|
||
return [time_float,[px,py,pz,vx,vy,vz]]
|
||
|
||
def getTimeOrbitStamp(self,UTCStartTime_float):
|
||
sv=_StateVector()
|
||
temp_sv=self.SatelliteSpaceState(UTCStartTime_float)
|
||
sv.timeStamp=datetime.datetime.fromtimestamp(UTCStartTime_float)
|
||
sv.xPosition = temp_sv[1][0,0]
|
||
sv.yPosition = temp_sv[1][0,1]
|
||
sv.zPosition = temp_sv[1][0,2]
|
||
sv.xVelocity = temp_sv[1][0,3]
|
||
sv.yVelocity = temp_sv[1][0,4]
|
||
sv.zVelocity = temp_sv[1][0,5]
|
||
return sv
|
||
|
||
def getTimeOrbits(self,UTCStartTime,UTCEndTime,orbitnum=1000):
|
||
#
|
||
startTime_stamp=datetime.datetime.strptime(UTCStartTime,"%Y-%m-%dT%H:%M:%S.%f").timestamp()-1
|
||
endTime_stamp=datetime.datetime.strptime(UTCEndTime,"%Y-%m-%dT%H:%M:%S.%f").timestamp()+1
|
||
if startTime_stamp>endTime_stamp:
|
||
raise
|
||
delta_t=(endTime_stamp-startTime_stamp)/orbitnum
|
||
extractOrbits=[]
|
||
#
|
||
temptime=startTime_stamp
|
||
while temptime<endTime_stamp:
|
||
temptime=temptime+delta_t
|
||
newOrbit=self.getTimeOrbitStamp(temptime)
|
||
extractOrbits.append(newOrbit)
|
||
newOrbit=self.getTimeOrbitStamp(endTime_stamp)
|
||
extractOrbits.append(newOrbit)
|
||
return extractOrbits # 扩展的轨道节点
|
||
|
||
def ReconstructionSatelliteOrbit(stateVectors, starttime):
|
||
'''
|
||
构建卫星轨道
|
||
args:
|
||
GPSPoints_list:卫星轨道点
|
||
starttime:起算时间
|
||
'''
|
||
GPSPoint_list=[]
|
||
for sv in stateVectors:
|
||
GPSPoint=[sv.timeStamp.timestamp(),
|
||
sv.xPosition,
|
||
sv.yPosition,
|
||
sv.zPosition,
|
||
sv.xVelocity,
|
||
sv.yVelocity,
|
||
sv.zVelocity
|
||
]
|
||
GPSPoint_list.append(GPSPoint)
|
||
SatelliteOrbitModel = SatelliteOrbitFitPoly()
|
||
if SatelliteOrbitModel.ReconstructionSatelliteOrbit(GPSPoint_list, starttime=starttime) is None:
|
||
return None
|
||
|
||
|
||
|
||
print("orbit test")
|
||
distance=[]
|
||
for gpsPoint in GPSPoint_list:
|
||
temp_sv=SatelliteOrbitModel.SatelliteSpaceState(gpsPoint[0])
|
||
sv=np.array(temp_sv[1])
|
||
temp_distance=sv-gpsPoint[1:]
|
||
distance.append(temp_distance)
|
||
distance=np.array(distance)
|
||
print("orbit max:",np.max(distance))
|
||
print("orbit min:",np.min(distance))
|
||
return SatelliteOrbitModel
|
||
|
||
########
|
||
# 函数列表
|
||
########
|
||
def poly1dfunc(p,x): # 一次函数
|
||
k,b=p
|
||
return k*x+b
|
||
|
||
def poly2dfunc(p,x): # 二次函数
|
||
k1,k2,b=p
|
||
return b+k1*x+k2*x*x
|
||
|
||
def poly3dfunc(p,x):
|
||
k1,k2,k3,b=p
|
||
return b+k1*x+k2*x*x+k3*x*x*x
|
||
|
||
def poly4dfunc(p,x):
|
||
k1,k2,k3,k4,b=p
|
||
return b+k1*x+k2*x**2+k3*x**3+k4*x**4
|
||
|
||
def poly5dfunc(p,x):
|
||
k1,k2,k3,k4,k5,b=p
|
||
return b+k1*x+k2*x**2+k3*x**3+k4*x**4+k5*x**5
|
||
|
||
def poly1derror(p,x,y):
|
||
return poly1dfunc(p,x)-y
|
||
|
||
def poly2derror(p,x,y):
|
||
return poly2dfunc(p,x)-y
|
||
|
||
def poly3derror(p,x,y):
|
||
return poly3dfunc(p,x)-y
|
||
|
||
def poly4derror(p,x,y):
|
||
return poly4dfunc(p,x)-y
|
||
|
||
def poly5derror(p,x,y):
|
||
return poly5dfunc(p,x)-y
|
||
|
||
class orbitVector:
|
||
def __init__(self,UTCTimes,vx,vy,vz,px,py,pz,dateformat="%Y-%m-%dT%H:%M:%S.%fZ"):
|
||
self.UTCTime=datetime.datetime.strptime(UTCTimes,dateformat) # 字符串转UTC时间
|
||
self.time_stamp=self.UTCTime.timestamp() # 时间戳
|
||
self.vx=vx # Vx
|
||
self.vy=vy
|
||
self.vz=vz
|
||
self.px=px
|
||
self.py=py # Ys
|
||
self.pz=pz
|
||
self.orbitVector2GG() # 将坐标进行变换
|
||
self.Check()
|
||
pass
|
||
|
||
def orbitVector2GG(self):
|
||
Cx=self.py*self.vz-self.pz*self.vy
|
||
Cy=self.pz*self.vx-self.px*self.vz
|
||
Cz=self.px*self.vy-self.py*self.vx
|
||
C=(Cx**2+Cy**2+Cz**2)**0.5
|
||
self.rho=(self.px**2+self.py**2+self.pz**2)**0.5
|
||
self.I=math.acos(Cz/C)
|
||
self.omega=math.asin(self.pz/(self.rho*math.sin(self.I)))
|
||
self.Omega=math.atan(-Cx/Cy)
|
||
return [self.rho,self.I,self.omega,self.Omega]
|
||
|
||
def Check(self):
|
||
rho=self.rho
|
||
I=self.I
|
||
omega=self.omega
|
||
Omega=self.Omega
|
||
Xp=rho*(cos(omega)*cos(Omega)-sin(omega)*sin(Omega)*cos(I))
|
||
Yp=rho*(cos(omega)*sin(Omega)+sin(omega)*cos(Omega)*cos(I))
|
||
Zp=rho*sin(Omega)*sin(I)
|
||
print("计算插值:",self.UTCTime,self.px,self.py,self.pz,self.vx,self.vy,self.vz,"|",Xp-self.px,Yp-self.py,Zp-self.pz)
|
||
|
||
|
||
class SARorbit(object):
|
||
# 作为自定义轨道计算基类
|
||
# 定义几个基本方法:addvector(),createOrbit(),getTime(),getTimes()
|
||
# 注意均为UTC
|
||
def __init__(self):
|
||
self.vectors=[]
|
||
self.baseTime=None
|
||
def addvector(self,UTCTime,vx,vy,vz,px,py,pz):
|
||
neworbit_point=orbitVector(UTCTime,vx,vy,vz,px,py,pz)
|
||
self.vectors.append(neworbit_point)
|
||
if len(self.vectors)==1:
|
||
self.baseTime=neworbit_point.time_stamp-1 # 基线
|
||
else:
|
||
if self.baseTime>neworbit_point.time_stamp:
|
||
self.baseTime=neworbit_point.time_stamp-1
|
||
|
||
def createOrbit(self):
|
||
pass
|
||
|
||
def getTimeOrbit(self,UTCTime):
|
||
return None
|
||
|
||
def getTimeOrbitStamp(self,StampTime):
|
||
utcStr=datetime.datetime.fromtimestamp(StampTime).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
|
||
return self.getTimeOrbit(utcStr)
|
||
|
||
def getTimeOrbits(self,UTCStartTime,UTCEndTime,orbitnum=100):
|
||
#
|
||
startTime_stamp=datetime.datetime.strptime(UTCStartTime,"%Y-%m-%dT%H:%M:%S.%fZ").timestamp()-10
|
||
endTime_stamp=datetime.datetime.strptime(UTCEndTime,"%Y-%m-%dT%H:%M:%S.%fZ").timestamp()+10
|
||
if startTime_stamp>endTime_stamp:
|
||
raise
|
||
delta_t=(endTime_stamp-startTime_stamp)*1000/orbitnum
|
||
delta_t=int(delta_t)/1000 # 获取
|
||
extractOrbits=[]
|
||
#
|
||
temptime=startTime_stamp
|
||
while temptime<endTime_stamp:
|
||
temptime=temptime+delta_t
|
||
newOrbit=self.getTimeOrbitStamp(temptime)
|
||
extractOrbits.append(newOrbit)
|
||
newOrbit=self.getTimeOrbitStamp(endTime_stamp)
|
||
extractOrbits.append(newOrbit)
|
||
return extractOrbits # 扩展的轨道节点
|
||
pass
|
||
|
||
class polyorbit(SARorbit):
|
||
def __init__(self):
|
||
super(polyorbit,self).__init__()
|
||
|
||
def createOrbit(self):
|
||
if len(self.vectors)<8:
|
||
raise
|
||
ts,xs,ys,zs,vx,vy,vz=[],[],[],[],[],[],[]
|
||
for orbit_point in self.vectors:
|
||
ts.append(orbit_point.time_stamp-self.baseTime)
|
||
xs.append(orbit_point.px)
|
||
ys.append(orbit_point.py)
|
||
zs.append(orbit_point.pz)
|
||
vx.append(orbit_point.vx)
|
||
vy.append(orbit_point.vy)
|
||
vz.append(orbit_point.vz)
|
||
ts=np.array(ts)
|
||
xs=np.array(xs)
|
||
ys=np.array(ys)
|
||
zs=np.array(zs)
|
||
vx=np.array(vx)
|
||
vy=np.array(vy)
|
||
vz=np.array(vz)
|
||
self.p_xs=leastsq(poly5derror,[100,100,100,100,100,100],args=(ts,xs))
|
||
self.p_ys=leastsq(poly5derror,[100,100,100,100,100,100],args=(ts,ys))
|
||
self.p_zs=leastsq(poly5derror,[100,100,100,100,100,100],args=(ts,zs))
|
||
self.p_vxs=leastsq(poly5derror,[100,100,100,100,100,100],args=(ts,vx))
|
||
self.p_vy=leastsq(poly5derror,[100,100,100,100,100,100],args=(ts,vy))
|
||
self.p_vz=leastsq(poly5derror,[100,100,100,100,100,100],args=(ts,vz))
|
||
return
|
||
def getTimeOrbit(self,UTCTime):
|
||
staptime=datetime.datetime.strptime(UTCTime,"%Y-%m-%dT%H:%M:%S.%fZ").timestamp()-self.baseTime
|
||
xs=poly5dfunc(self.p_xs,staptime)
|
||
ys=poly5dfunc(self.p_ys,staptime)
|
||
zs=poly5dfunc(self.p_zs,staptime)
|
||
vx=poly5dfunc(self.p_vx,staptime)
|
||
vy=poly5dfunc(self.p_vy,staptime)
|
||
vz=poly5dfunc(self.p_vz,staptime)
|
||
utmstr=datetime.datetime.strptime(UTCTime,"%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y-%m-%d %H:%M:%S.%f")
|
||
neworbit_point=orbitVector(utmstr,vx,vy,vz,xs,ys,zs,dateformat="%Y-%m-%d %H:%M:%S.%f")
|
||
return neworbit_point
|
||
|
||
#######################################################################################################
|
||
|
||
class LT1ABLT1ABREPEAT(Sensor):
|
||
"""
|
||
A Class representing RADARSAT 2 data
|
||
"""
|
||
|
||
family='LT1ABLT1ABREPEAT'
|
||
parameter_list = (XML, TIFF, ORBIT_DIRECTORY, ORBIT_FILE ) + Sensor.parameter_list
|
||
|
||
def __init__(self, family='', name=''):
|
||
super().__init__(family if family else self.__class__.family, name=name)
|
||
self.product = _Product()
|
||
self.frame = Frame()
|
||
self.frame.configure()
|
||
|
||
|
||
def getFrame(self):
|
||
return self.frame
|
||
|
||
def parse(self):
|
||
try:
|
||
fp = open(self.xml,'r')
|
||
except IOError as strerr:
|
||
print("IOError: %s" % strerr)
|
||
return
|
||
self._xml_root = ElementTree(file=fp).getroot()
|
||
self.product.set_from_etnode(self._xml_root) # 解析meta xml
|
||
self.populateMetadata()
|
||
self.extractDoppler()
|
||
fp.close()
|
||
|
||
def populateMetadata(self):
|
||
"""
|
||
Create metadata objects from the metadata files
|
||
"""
|
||
mission = self.product.mission
|
||
swath = self.product.swath
|
||
frequency = self.product.frequency
|
||
orig_prf =self.product.orig_prf
|
||
rangePixelSize = self.product.rangePixelSize
|
||
rangeSamplingRate = Const.c/(2*rangePixelSize)
|
||
pulseLength =self.product.pulseLength
|
||
pulseBandwidth = self.product.pulseBandwidth
|
||
polarization = self.product.polarization
|
||
lookSide = self.product.lookSide
|
||
facility = self.product.facility
|
||
version = self.product.version
|
||
lines = self.product.lines
|
||
samples = self.product.samples
|
||
startingRange = self.product.startingRange
|
||
incidenceAngle = self.product.incidenceAngle
|
||
|
||
|
||
# some RS2 scenes have oversampled SLC images because processed azimuth bandwidth larger than PRF EJF 2015/08/15
|
||
azimuthPixelSize = self.product.azimuthPixelSize # ground spacing in meters
|
||
totalProcessedAzimuthBandwidth = self.product.totalProcessedAzimuthBandwidth
|
||
prf = orig_prf * np.ceil(totalProcessedAzimuthBandwidth / orig_prf) # effective PRF can be double original, suggested by Piyush
|
||
print('-------------------------------------')
|
||
print("mission",mission)
|
||
print("swath",swath)
|
||
print("frequency",frequency)
|
||
print("orig_prf",orig_prf)
|
||
print("prf",prf)
|
||
print("rangePixelSize",rangePixelSize)
|
||
print("rangeSamplingRate",rangeSamplingRate)
|
||
print("pulseLength",pulseLength)
|
||
print("pulseBandwidth",pulseBandwidth)
|
||
print("polarization",polarization)
|
||
print("lookSide",lookSide)
|
||
print("lines",lines)
|
||
print("samples",samples)
|
||
print("startingRange",startingRange)
|
||
print("incidenceAngle",incidenceAngle)
|
||
print(self.product.imageGenerationParameters.dopplerCentroid.dopplerCentroidCoefficients)
|
||
print(self.product.imageGenerationParameters.dopplerRateValues.dopplerRateValuesCoefficients)
|
||
print("effective PRF %f, original PRF %f" % (prf, orig_prf) )
|
||
print('-------------------------------------------')
|
||
|
||
|
||
#lineFlip = (self.product.imageAttributes.rasterAttributes.lineTimeOrdering.upper() == 'DECREASING')
|
||
dataStartTime = self.product.dataStartTime
|
||
dataStopTime = self.product.dataStopTime
|
||
|
||
passDirection = self.product.passDirection
|
||
|
||
|
||
####Populate platform
|
||
platform = self.frame.getInstrument().getPlatform()
|
||
platform.setPlanet(Planet(pname="Earth"))
|
||
platform.setMission(mission)
|
||
platform.setPointingDirection(lookSide)
|
||
platform.setAntennaLength(15.0)
|
||
|
||
####Populate instrument
|
||
instrument = self.frame.getInstrument()
|
||
instrument.setRadarFrequency(frequency)
|
||
instrument.setPulseRepetitionFrequency(prf)
|
||
instrument.setPulseLength(pulseLength)
|
||
instrument.setChirpSlope(pulseBandwidth/pulseLength)
|
||
instrument.setIncidenceAngle(incidenceAngle)
|
||
#self.frame.getInstrument().setRangeBias(0)
|
||
instrument.setRangePixelSize(rangePixelSize)
|
||
instrument.setRangeSamplingRate(rangeSamplingRate)
|
||
instrument.setBeamNumber(swath)
|
||
instrument.setPulseLength(pulseLength)
|
||
|
||
|
||
#Populate Frame
|
||
#self.frame.setSatelliteHeight(height)
|
||
self.frame.setSensingStart(dataStartTime)
|
||
self.frame.setSensingStop(dataStopTime)
|
||
diffTime = DTUtil.timeDeltaToSeconds(dataStopTime - dataStartTime)/2.0
|
||
sensingMid = dataStartTime + datetime.timedelta(microseconds=int(diffTime*1e6))
|
||
self.frame.setSensingMid(sensingMid)
|
||
self.frame.setPassDirection(passDirection)
|
||
self.frame.setPolarization(polarization)
|
||
self.frame.setStartingRange(startingRange)
|
||
self.frame.setFarRange(startingRange + (samples-1)*rangePixelSize)
|
||
self.frame.setNumberOfLines(lines)
|
||
self.frame.setNumberOfSamples(samples)
|
||
self.frame.setProcessingFacility("LAMP") # 处理软件
|
||
self.frame.setProcessingSoftwareVersion(version)
|
||
self.frame.setPassDirection(passDirection)
|
||
self.frame.setProcessingSystem("LT1AB") # 陆探数据
|
||
self.frame.getOrbit().setOrbitSource("LT1AB.META.XML")
|
||
|
||
|
||
print("======= 修改轨道代码部分: =================")
|
||
if (self.orbitFile is None) and (self.orbitDirectory is None):
|
||
self.extractOrbit()
|
||
|
||
|
||
elif (self.orbitDirectory is not None):
|
||
self.orbitFile = findPreciseOrbit(self.orbitDirectory, self.frame.getOrbit().getOrbitSource(), self.frame.sensingStart.year)
|
||
|
||
if self.orbitFile is not None:
|
||
self.extractPreciseOrbit(self.orbitFile, self.frame.sensingStart, self.frame.sensingStop)
|
||
|
||
|
||
# save the Doppler centroid coefficients, converting units from product.xml file
|
||
# units in the file are quadratic coefficients in Hz, Hz/sec, and Hz/(sec^2)
|
||
# ISCE expects Hz, Hz/(range sample), Hz((range sample)^2
|
||
# note that RS2 Doppler values are estimated at time dc.dopplerCentroidReferenceTime,
|
||
# so the values might need to be adjusted for ISCE usage
|
||
# added EJF 2015/08/17
|
||
dc = self.product.dopplerCentroid
|
||
poly = dc.dopplerCentroidCoefficients
|
||
# need to convert units
|
||
poly[1] = poly[1]/rangeSamplingRate
|
||
poly[2] = poly[2]/rangeSamplingRate**2
|
||
self.doppler_coeff = poly
|
||
|
||
# similarly save Doppler azimuth fm rate values, converting units
|
||
# units in the file are quadratic coefficients in Hz, Hz/sec, and Hz/(sec^2)
|
||
# Guessing that ISCE expects Hz, Hz/(range sample), Hz((range sample)^2
|
||
# note that RS2 Doppler values are estimated at time dc.dopplerRateReferenceTime,
|
||
# so the values might need to be adjusted for ISCE usage
|
||
# added EJF 2015/08/17
|
||
dr = self.product.dopplerRateValues
|
||
fmpoly = dr.dopplerRateValuesCoefficients
|
||
# need to convert units
|
||
fmpoly[1] = fmpoly[1]/rangeSamplingRate
|
||
fmpoly[2] = fmpoly[2]/rangeSamplingRate**2
|
||
self.azfmrate_coeff = fmpoly
|
||
|
||
# now calculate effective PRF from the azimuth line spacing after we have the orbit info EJF 2015/08/15
|
||
# this does not work because azimuth spacing is on ground. Instead use bandwidth ratio calculated above EJF
|
||
# SCHvelocity = self.frame.getSchVelocity()
|
||
# SCHvelocity = 7550.75 # hard code orbit velocity for now m/s
|
||
# prf = SCHvelocity/azimuthPixelSize
|
||
# instrument.setPulseRepetitionFrequency(prf)
|
||
|
||
def extractOrbit(self):
|
||
'''
|
||
Extract the orbit state vectors from the XML file.
|
||
'''
|
||
|
||
# Initialize orbit objects
|
||
# Read into temp orbit first.frame
|
||
# Radarsat 2 needs orbit extensions.
|
||
print("构建新的轨道程序代码:")
|
||
|
||
|
||
self.frame.getOrbit().setOrbitSource('Header: ' + self.frame.getOrbit().getOrbitSource())
|
||
stateVectors = self.product.OrbitModelInfo.stateVectors
|
||
|
||
|
||
tempOrbit= ReconstructionSatelliteOrbit(stateVectors,self.product.orbitstarttime.timestamp())
|
||
As_arr=tempOrbit.A_arr.tolist()
|
||
""" 构建轨道 """
|
||
self.frame.getOrbit().setsessionMode(self.product.mission)
|
||
print("卫星型号")
|
||
print(self.frame.orbit.sessionMode)
|
||
self.frame.getOrbit().setPolyParams(tempOrbit.polynum,tempOrbit.starttime,As_arr)
|
||
self.frame.getOrbit().setDoppler(self.product.dopplerRateValues.dopplerRateReferenceTime,
|
||
self.product.dopplerRateValues.dopplerRateValuesCoefficients)
|
||
""" """
|
||
newOrb=self.frame.getOrbit().getTimeOrbits(self.frame.sensingStart.strftime("%Y-%m-%dT%H:%M:%S.%f"),
|
||
self.frame.sensingStop.strftime("%Y-%m-%dT%H:%M:%S.%f"),
|
||
orbitnum=1000)
|
||
for svect in newOrb:
|
||
self.frame.getOrbit().addStateVector(svect)
|
||
|
||
print('Successfully read state vectors from product XML')
|
||
|
||
def extractPreciseOrbit(self, orbitfile, tstart, tend):
|
||
'''
|
||
Extract precise orbits for given time-period from orbit file.
|
||
'''
|
||
|
||
self.frame.getOrbit().setOrbitSource('File: ' + orbitfile)
|
||
|
||
tmin = tstart - datetime.timedelta(seconds=30.)
|
||
tmax = tstart + datetime.timedelta(seconds=30.)
|
||
|
||
fid = open(orbitfile, 'r')
|
||
for line in fid:
|
||
if not line.startswith('; Position'):
|
||
continue
|
||
else:
|
||
break
|
||
|
||
for line in fid:
|
||
if not line.startswith(';###END'):
|
||
tstamp = convertRSTimeToDateTime(line)
|
||
|
||
if (tstamp >= tmin) and (tstamp <= tmax):
|
||
sv = StateVector()
|
||
sv.configure()
|
||
sv.setTime( tstamp)
|
||
sv.setPosition( [float(x) for x in fid.readline().split()])
|
||
sv.setVelocity( [float(x) for x in fid.readline().split()])
|
||
|
||
self.frame.getOrbit().addStateVector(sv)
|
||
else:
|
||
fid.readline()
|
||
fid.readline()
|
||
|
||
dummy = fid.readline()
|
||
if not dummy.startswith(';'):
|
||
raise Exception('Expected line to start with ";". Got {0}'.format(dummy))
|
||
|
||
fid.close()
|
||
print('Successfully read {0} state vectors from {1}'.format( len(self.frame.getOrbit()._stateVectors), orbitfile))
|
||
|
||
def extractImage(self, verbose=True):
|
||
'''
|
||
Use gdal to extract the slc.
|
||
'''
|
||
|
||
try:
|
||
from osgeo import gdal
|
||
except ImportError:
|
||
raise Exception('GDAL python bindings not found. Need this for RSAT2 / TandemX / Sentinel1A.')
|
||
|
||
self.parse()
|
||
|
||
width = self.frame.getNumberOfSamples()
|
||
lgth = self.frame.getNumberOfLines()
|
||
lineFlip = False #(self.product.imageAttributes.rasterAttributes.lineTimeOrdering.upper() == 'DECREASING')
|
||
pixFlip = False #(self.product.imageAttributes.rasterAttributes.pixelTimeOrdering.upper() == 'DECREASING')
|
||
|
||
src = gdal.Open(self.tiff.strip(), gdal.GA_ReadOnly)
|
||
cJ = np.complex64(1.0j)
|
||
|
||
####Images are small enough that we can do it all in one go - Piyush
|
||
real = src.GetRasterBand(1).ReadAsArray(0,0,width,lgth)
|
||
imag = src.GetRasterBand(2).ReadAsArray(0,0,width,lgth)
|
||
|
||
if (real is None) or (imag is None):
|
||
raise Exception('Input Radarsat2 SLC seems to not be a 2 band Int16 image.')
|
||
|
||
data = real+cJ*imag
|
||
|
||
real = None
|
||
imag = None
|
||
src = None
|
||
|
||
if lineFlip:
|
||
if verbose:
|
||
print('Vertically Flipping data')
|
||
data = np.flipud(data)
|
||
|
||
if pixFlip:
|
||
if verbose:
|
||
print('Horizontally Flipping data')
|
||
data = np.fliplr(data)
|
||
|
||
data.tofile(self.output)
|
||
|
||
####
|
||
slcImage = isceobj.createSlcImage()
|
||
slcImage.setByteOrder('l')
|
||
slcImage.setFilename(self.output)
|
||
slcImage.setAccessMode('read')
|
||
slcImage.setWidth(width)
|
||
slcImage.setLength(lgth)
|
||
slcImage.setXmin(0)
|
||
slcImage.setXmax(width)
|
||
#slcImage.renderHdr()
|
||
self.frame.setImage(slcImage)
|
||
|
||
|
||
def extractDoppler(self):
|
||
'''
|
||
self.parse()
|
||
Extract doppler information as needed by mocomp
|
||
'''
|
||
ins = self.frame.getInstrument()
|
||
dc = self.product.dopplerCentroid
|
||
quadratic = {}
|
||
|
||
r0 = self.frame.startingRange
|
||
fs = ins.getRangeSamplingRate()
|
||
tNear = 2*r0/Const.c
|
||
|
||
tMid = tNear + 0.5*self.frame.getNumberOfSamples()/fs
|
||
t0 = dc.dopplerCentroidReferenceTime
|
||
poly = dc.dopplerCentroidCoefficients
|
||
|
||
fd_mid = 0.0
|
||
for kk in range(len(poly)):
|
||
fd_mid += poly[kk] * (tMid - t0)**kk
|
||
|
||
####For insarApp
|
||
quadratic['a'] = fd_mid / ins.getPulseRepetitionFrequency()
|
||
quadratic['b'] = 0.
|
||
quadratic['c'] = 0.
|
||
|
||
|
||
####For roiApp
|
||
####More accurate
|
||
|
||
|
||
coeffs = poly
|
||
dr = self.frame.getInstrument().getRangePixelSize()
|
||
rref = 0.5 * Const.c * t0
|
||
r0 = self.frame.getStartingRange()
|
||
norm = 0.5*Const.c/dr
|
||
|
||
dcoeffs = []
|
||
for ind, val in enumerate(coeffs):
|
||
dcoeffs.append( val / (norm**ind))
|
||
|
||
poly = Poly1D.Poly1D()
|
||
poly.initPoly(order=len(coeffs)-1)
|
||
poly.setMean( (rref - r0)/dr - 1.0)
|
||
poly.setCoeffs(dcoeffs)
|
||
|
||
pix = np.linspace(0, self.frame.getNumberOfSamples(), num=len(coeffs)+1)
|
||
evals = poly(pix)
|
||
fit = np.polyfit(pix,evals, len(coeffs)-1)
|
||
self.frame._dopplerVsPixel = list(fit[::-1])
|
||
self.frame._dopplerVsPixel_LT1AB = list([self.product.dopplerRateValues.dopplerRateReferenceTime]
|
||
+self.product.dopplerRateValues.dopplerRateValuesCoefficients)
|
||
|
||
|
||
print('Doppler Fit: ', fit[::-1])
|
||
|
||
|
||
# print("---- radar ------------------------------------------print")
|
||
# print("****" * 10)
|
||
# print("t0",t0)
|
||
# print('lightspeed',Const.c)
|
||
# print('rref',rref)
|
||
# print('dr',dr)
|
||
# print('dcoeff',dcoeffs)
|
||
# print('r0',r0)
|
||
# print("****" * 10)
|
||
# print('pix',pix)
|
||
# print('evals',evals)
|
||
# print('fit',fit)
|
||
# print('Doppler Fit: ', fit[::-1])
|
||
# print('---------------------------------------------------')
|
||
|
||
# """ 测试 多普勒"""
|
||
# print("======= Test LTInSAR =========")
|
||
# """ 测试 轨道情况"""
|
||
|
||
|
||
# coeff = self.frame._dopplerVsPixel_LT1AB
|
||
# doppler = Poly2D()
|
||
# doppler._meanRange = self.frame.startingRange
|
||
# doppler._normRange = self.frame.instrument.rangePixelSize
|
||
# doppler.initPoly(azimuthOrder=0, rangeOrder=len(coeff)-1, coeffs=[coeff])
|
||
|
||
# lookSide = self.frame.instrument.platform.pointingDirection
|
||
# planet = Planet(pname='Earth')
|
||
# wvl = self.frame.instrument.getRadarWavelength()
|
||
# test_lla=[47.75,130.82,159.50]
|
||
# taz, rgm = self.frame.orbit.geo2rdr(test_lla, side=lookSide, doppler=doppler, wvl=wvl)
|
||
|
||
# print("taz",taz)
|
||
# print('n11',datetime.datetime.strptime("2023-03-27T21:28:27.551796","%Y-%m-%dT%H:%M:%S.%f"))
|
||
# print("rgm",rgm)
|
||
# print('r11',4.96786423292669768E-03*Const.c/2)
|
||
|
||
# print("lon,lat,ati",test_lla)
|
||
# print("==============================================")
|
||
return quadratic
|
||
|
||
class LT1ABNamespace(object):
|
||
def __init__(self):
|
||
self.uri = ""
|
||
|
||
def elementName(self,element):
|
||
return element
|
||
|
||
def convertToDateTime(self,string):
|
||
dt = datetime.datetime.strptime(string,"%Y-%m-%dT%H:%M:%S.%f")
|
||
return dt
|
||
|
||
class _Product(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.productId = None
|
||
self.documentId = None
|
||
self.mission=None
|
||
self.swath=None
|
||
self.frequency=None
|
||
self.orig_prf=None # 原始PRF --- 参考PRF
|
||
self.rangePixelSize=None # 距离向分辨率
|
||
self.pulseLength=None
|
||
self.pulseBandwidth=None
|
||
self.polarization=None
|
||
self.lookSide=None
|
||
self.facility=None
|
||
self.version=None
|
||
self.lines=None # 行数
|
||
self.samples=None # 列数
|
||
self.startingRange=None
|
||
self.incidenceAngle=None
|
||
self.azimuthPixelSize=None
|
||
self.totalProcessedAzimuthBandwidth=None
|
||
self.prf=None
|
||
|
||
"""
|
||
入射角
|
||
"""
|
||
self.topRight_IncidenceAngle=None
|
||
self.topLeft_IncidenceAngle=None
|
||
self.bottomRight_IncidenceAngle=None
|
||
self.bottomLeft_IncidenceAngle=None
|
||
|
||
self.Near_incidenceAngle=None
|
||
self.Far_incidenceAngle=None
|
||
|
||
""" 斜距 """
|
||
self.slantRangeTimeToFirstRangeSample=None
|
||
self.startingRange=None
|
||
|
||
""" 轨道"""
|
||
self.passDirection=None
|
||
|
||
""" 成像 """
|
||
self.dataStartTime=None
|
||
self.dataStopTime=None
|
||
self.orbitstarttime=None
|
||
|
||
""" 多普勒系数 """
|
||
self.dopplerCentroid=_DopplerCentroid()
|
||
self.dopplerRateValues = _DopplerRateValues()
|
||
|
||
|
||
|
||
self.OrbitModelInfo=_OrbitInformation()
|
||
self.sourceAttributes = _SourceAttributes()
|
||
self.imageGenerationParameters = _ImageGenerationParameters()
|
||
self.imageAttributes = _ImageAttributes()
|
||
|
||
def set_from_etnode(self,node):
|
||
self.productId=node.find("productInfo").find("generationInfo").find("logicalProductID").text
|
||
self.documentId=node.find("generalHeader").find("referenceDocument").text
|
||
self.mission=node.find("generalHeader").find("mission").text
|
||
self.swath=node.find("productInfo").find("acquisitionInfo").find("imagingMode").text
|
||
self.frequency=float(node.find("processing").find("processingParameter").find("rangeCompression").find("chirps").find("referenceChirp").find("centerFrequency").text)
|
||
|
||
self.rangePixelSize=float(node.find("productInfo").find("imageDataInfo").find("imageRaster").find("columnSpacing").text)
|
||
self.pulseLength=float(node.find("processing").find("processingParameter").find("rangeCompression").find("chirps").find("referenceChirp").find("pulseLength").text)
|
||
self.pulseBandwidth=float(node.find("processing").find("processingParameter").find("rangeCompression").find("chirps").find("referenceChirp").find("pulseBandwidth").text)
|
||
self.polarization=node.find("productInfo").find("acquisitionInfo").find("polarisationMode").text
|
||
self.lookSide=lookMap[node.find("productInfo").find("acquisitionInfo").find("lookDirection").text.upper()]
|
||
self.facility=node.find("productInfo").find("generationInfo").find("level1ProcessingFacility").text
|
||
self.version="V1.1"
|
||
self.lines=int(node.find("productInfo").find("imageDataInfo").find("imageRaster").find("numberOfRows").text)
|
||
self.samples=int(node.find("productInfo").find("imageDataInfo").find("imageRaster").find("numberOfColumns").text)
|
||
sceneCorners=node.find("productInfo").find("sceneInfo").findall("sceneCornerCoord")
|
||
for sceneCorner in sceneCorners:
|
||
incidenceAngle_temp=float(sceneCorner.find("incidenceAngle").text)
|
||
if sceneCorner.attrib["name"]=="topRight":
|
||
self.topRight_IncidenceAngle=incidenceAngle_temp
|
||
elif sceneCorner.attrib["name"]=="topLeft":
|
||
self.topLeft_IncidenceAngle=incidenceAngle_temp
|
||
elif sceneCorner.attrib["name"]=="bottomRight":
|
||
self.bottomRight_IncidenceAngle=incidenceAngle_temp
|
||
elif sceneCorner.attrib["name"]=="bottomLeft":
|
||
self.bottomLeft_IncidenceAngle=incidenceAngle_temp
|
||
self.Near_incidenceAngle=self.topRight_IncidenceAngle
|
||
self.Near_incidenceAngle=self.Near_incidenceAngle if self.Near_incidenceAngle < self.topLeft_IncidenceAngle else self.topLeft_IncidenceAngle
|
||
self.Near_incidenceAngle=self.Near_incidenceAngle if self.Near_incidenceAngle < self.bottomRight_IncidenceAngle else self.bottomRight_IncidenceAngle
|
||
self.Near_incidenceAngle=self.Near_incidenceAngle if self.Near_incidenceAngle < self.bottomLeft_IncidenceAngle else self.bottomLeft_IncidenceAngle
|
||
|
||
self.Far_incidenceAngle=self.topRight_IncidenceAngle
|
||
self.Far_incidenceAngle=self.Far_incidenceAngle if self.Far_incidenceAngle > self.topLeft_IncidenceAngle else self.topLeft_IncidenceAngle
|
||
self.Far_incidenceAngle=self.Far_incidenceAngle if self.Far_incidenceAngle > self.bottomRight_IncidenceAngle else self.bottomRight_IncidenceAngle
|
||
self.Far_incidenceAngle=self.Far_incidenceAngle if self.Far_incidenceAngle > self.bottomLeft_IncidenceAngle else self.bottomLeft_IncidenceAngle
|
||
|
||
self.incidenceAngle=float((node.find("productInfo").find("sceneInfo").find("sceneCenterCoord").find("incidenceAngle").text))
|
||
|
||
""" 斜距 """
|
||
self.slantRangeTimeToFirstRangeSample=float(node.find("productInfo").find("sceneInfo").find("rangeTime").find("firstPixel").text)
|
||
self.startingRange=self.slantRangeTimeToFirstRangeSample * (Const.c/2)
|
||
|
||
self.azimuthPixelSize=float(node.find("productInfo").find("imageDataInfo").find("imageRaster").find("rowSpacing").text)
|
||
self.totalProcessedAzimuthBandwidth=float(node.find("processing").find("processingParameter").find("totalProcessedAzimuthBandwidth").text) # 方位向
|
||
self.prf=float(node.find("instrument").find("settings").find("settingRecord").find("PRF").text)
|
||
|
||
|
||
""" 成像 """
|
||
self.dataStartTime=self.convertToDateTime(node.find("productInfo").find("sceneInfo").find("start").find("timeUTC").text)
|
||
self.dataStopTime=self.convertToDateTime(node.find("productInfo").find("sceneInfo").find("stop").find("timeUTC").text)
|
||
|
||
self.orig_prf=(self.lines-1)/((self.dataStopTime-self.dataStartTime).total_seconds())
|
||
|
||
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('platform'):
|
||
self.OrbitModelInfo.set_from_etnode(z.find("orbit"))
|
||
elif z.tag == self.elementName('imageGenerationParameters'):
|
||
self.imageGenerationParameters.set_from_etnode(z)
|
||
elif z.tag == self.elementName('imageAttributes'):
|
||
self.imageAttributes.set_from_etnode(z)
|
||
|
||
""" 轨道 """
|
||
self.passDirection=node.find("productInfo").find("missionInfo").find("orbitDirection").text
|
||
self.orbitstarttime=(self.dataStopTime-self.dataStartTime)/2+self.dataStartTime
|
||
|
||
""" 多普勒系数 """
|
||
self.dopplerCentroid.set_from_etnode(node.find("processing").find("doppler").find("dopplerCentroid").find("dopplerEstimate").find("basebandDoppler"))
|
||
self.dopplerRateValues.set_from_etnode(node.find("processing").find("geometry").find("dopplerRate").find("dopplerRatePolynomial"))
|
||
|
||
|
||
def __str__(self):
|
||
retstr = "Product:"+sep+tab
|
||
retlst = ()
|
||
retstr += "productID=%s"+sep+tab
|
||
retlst += (self.productId,)
|
||
retstr += "documentIdentifier=%s"+sep
|
||
retlst += (self.documentId,)
|
||
retstr += "%s"+sep
|
||
retlst += (str(self.sourceAttributes),)
|
||
retstr += "%s"+sep
|
||
retlst += (str(self.imageGenerationParameters),)
|
||
retstr += ":Product"
|
||
return retstr % retlst
|
||
|
||
class _SourceAttributes(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.satellite = None
|
||
self.sensor = None
|
||
self.inputDatasetId = None
|
||
self.imageId = None
|
||
self.inputDatasetFacilityId = None
|
||
self.beamModeId = None
|
||
self.beamModeMnemonic = None
|
||
self.rawDataStartTime = None
|
||
self.radarParameters = _RadarParameters()
|
||
self.rawDataAttributes = _RawDataAttributes()
|
||
self.orbitAndAttitude = _OrbitAndAttitude()
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('satellite'):
|
||
self.satellite = z.text
|
||
elif z.tag == self.elementName('sensor'):
|
||
self.sensor = z.text
|
||
elif z.tag == self.elementName('inputDatasetId'):
|
||
self.inputDatasetId = z.text
|
||
elif z.tag == self.elementName('imageID'):
|
||
self.imageId = z.text
|
||
elif z.tag == self.elementName('inputDatasetFacilityId'):
|
||
self.inputDatasetFacilityId = z.text
|
||
elif z.tag == self.elementName('beamModeID'):
|
||
self.beamModeId = z.text
|
||
elif z.tag == self.elementName('beamModeMnemonic'):
|
||
self.beamModeMnemonic = z.text
|
||
elif z.tag == self.elementName('rawDataStartTime'):
|
||
self.rawDataStartTime = self.convertToDateTime(z.text)
|
||
elif z.tag == self.elementName('radarParameters'):
|
||
self.radarParameters.set_from_etnode(z)
|
||
elif z.tag == self.elementName('rawDataAttributes'):
|
||
self.rawDataAttributes.set_from_etnode(z)
|
||
elif z.tag == self.elementName('orbitAndAttitude'):
|
||
self.orbitAndAttitude.set_from_etnode(z)
|
||
|
||
def __str__(self):
|
||
retstr = "SourceAttributes:"+sep+tab
|
||
retlst = ()
|
||
retstr += "satellite=%s"+sep+tab
|
||
retlst += (self.satellite,)
|
||
retstr += "sensor=%s"+sep+tab
|
||
retlst += (self.sensor,)
|
||
retstr += "inputDatasetID=%s"+sep
|
||
retlst += (self.inputDatasetId,)
|
||
retstr += "%s"
|
||
retlst += (str(self.radarParameters),)
|
||
retstr += "%s"
|
||
retlst += (str(self.rawDataAttributes),)
|
||
retstr += "%s"
|
||
retlst += (str(self.orbitAndAttitude),)
|
||
retstr += ":SourceAttributes"
|
||
return retstr % retlst
|
||
|
||
class _RadarParameters(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.acquisitionType = None
|
||
self.beams = None
|
||
self.polarizations = None
|
||
self.pulses = None
|
||
self.rank = None
|
||
self.settableGains = []
|
||
self.radarCenterFrequency = None
|
||
self.prf = None
|
||
self.pulseLengths = []
|
||
self.pulseBandwidths = []
|
||
self.antennaPointing = None
|
||
self.adcSamplingRate = []
|
||
self.yawSteeringFlag = None
|
||
self.geodeticFlag = None
|
||
self.rawBitsPerSample = None
|
||
self.samplesPerEchoLine = None
|
||
self.referenceNoiseLevels = [_ReferenceNoiseLevel()]*3
|
||
|
||
def set_from_etnode(self,node):
|
||
i = 0
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('acquisitionType'):
|
||
self.acquisitionType = z.text
|
||
elif z.tag == self.elementName('beams'):
|
||
self.beams = z.text
|
||
elif z.tag == self.elementName('polarizations'):
|
||
self.polarizations = z.text
|
||
elif z.tag == self.elementName('pulses'):
|
||
self.pulses = z.text
|
||
elif z.tag == self.elementName('rank'):
|
||
self.rank = z.text
|
||
elif z.tag == self.elementName('settableGain'):
|
||
self.settableGains.append(z.text)
|
||
elif z.tag == self.elementName('radarCenterFrequency'):
|
||
self.radarCenterFrequency = float(z.text)
|
||
elif z.tag == self.elementName('pulseRepetitionFrequency'):
|
||
self.prf = float(z.text)
|
||
elif z.tag == self.elementName('pulseLength'):
|
||
self.pulseLengths.append(float(z.text))
|
||
elif z.tag == self.elementName('pulseBandwidth'):
|
||
self.pulseBandwidths.append(float(z.text))
|
||
elif z.tag == self.elementName('antennaPointing'):
|
||
self.antennaPointing = z.text
|
||
elif z.tag == self.elementName('adcSamplingRate'):
|
||
self.adcSamplingRate.append(float(z.text))
|
||
elif z.tag == self.elementName('yawSteeringFlag'):
|
||
self.yawSteeringFlag = z.text
|
||
elif z.tag == self.elementName('rawBitsPerSample'):
|
||
self.rawBitsPerSample = int(z.text)
|
||
elif z.tag == self.elementName('samplesPerEchoLine'):
|
||
self.samplesPerEchoLine = int(z.text)
|
||
elif z.tag == self.elementName('referenceNoiseLevels'):
|
||
self.referenceNoiseLevels[i].set_from_etnode(z)
|
||
i += 1
|
||
|
||
def __str__(self):
|
||
retstr = "RadarParameters:"+sep+tab
|
||
retlst = ()
|
||
retstr += "acquisitionType=%s"+sep+tab
|
||
retlst += (self.acquisitionType,)
|
||
retstr += "beams=%s"+sep+tab
|
||
retlst += (self.beams,)
|
||
retstr += "polarizations=%s"+sep+tab
|
||
retlst += (self.polarizations,)
|
||
retstr += "pulses=%s"+sep+tab
|
||
retlst += (self.pulses,)
|
||
retstr += "rank=%s"+sep
|
||
retlst += (self.rank,)
|
||
retstr += ":RadarParameters"+sep
|
||
return retstr % retlst
|
||
|
||
class _ReferenceNoiseLevel(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.pixelFirstNoiseValue = None
|
||
self.stepSize = None
|
||
self.numberOfNoiseLevelValues = None
|
||
self.noiseLevelValues = []
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('pixelFirstNoiseValue'):
|
||
self.pixelFirstNoiseValue = int(z.text)
|
||
elif z.tag == self.elementName('stepSize'):
|
||
self.stepSize = int(z.text)
|
||
elif z.tag == self.elementName('numberOfNoiseLevelValues'):
|
||
self.numberOfNoiseLevelValues = int(z.text)
|
||
elif z.tag == self.elementName('noiseLevelValues'):
|
||
self.noiseLevelValues = list(map(float,z.text.split()))
|
||
|
||
def __str__(self):
|
||
retstr = "ReferenceNoiseLevel:"+sep+tab
|
||
retlst = ()
|
||
retstr += "pixelFirstNoiseValue=%s"+sep+tab
|
||
retlst += (self.pixelFirstNoiseValue,)
|
||
retstr += "stepSize=%s"+sep+tab
|
||
retlst += (self.stepSize,)
|
||
retstr += "numberOfNoiseLevelValues=%s"+sep+tab
|
||
retlst += (self.numberOfNoiseLevelValues,)
|
||
retstr += "noiseLevelValues=%s"+sep+tab
|
||
retlst += (self.noiseLevelValues,)
|
||
retstr += sep+":ReferenceNoiseLevel"
|
||
return retstr % retlst
|
||
|
||
class _RawDataAttributes(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.numberOfInputDataGaps = None
|
||
self.gapSize = None
|
||
self.numberOfMissingLines = None
|
||
self.rawDataAnalysis = [_RawDataAnalysis]*4
|
||
|
||
def set_from_etnode(self,node):
|
||
pass
|
||
|
||
def __str__(self):
|
||
return ""
|
||
|
||
class _RawDataAnalysis(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
|
||
def set_from_etnode(self,node):
|
||
pass
|
||
|
||
class _OrbitAndAttitude(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.orbitInformation = _OrbitInformation()
|
||
self.attitudeInformation = _AttitudeInformation()
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('orbitInformation'):
|
||
self.orbitInformation.set_from_etnode(z)
|
||
elif z.tag == self.elementName('attitudeInformation'):
|
||
self.attitudeInformation.set_from_etnode(z)
|
||
|
||
def __str__(self):
|
||
retstr = "OrbitAndAttitude:"+sep
|
||
retlst = ()
|
||
retstr += "%s"
|
||
retlst += (str(self.orbitInformation),)
|
||
retstr += "%s"
|
||
retlst += (str(self.attitudeInformation),)
|
||
retstr += ":OrbitAndAttitude"+sep
|
||
return retstr % retlst
|
||
|
||
class _OrbitInformation(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.passDirection = None
|
||
self.orbitDataSource = None
|
||
self.orbitDataFile = None
|
||
self.stateVectors = []
|
||
|
||
|
||
|
||
|
||
def set_from_etnode(self,node): # orbit
|
||
self.orbitDataSource=node.find("orbitHeader").find("sensor").text
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('stateVec'):
|
||
sv = _StateVector()
|
||
sv.set_from_etnode(z)
|
||
self.stateVectors.append(sv)
|
||
|
||
def __str__(self):
|
||
retstr = "OrbitInformation:"+sep+tab
|
||
retlst = ()
|
||
retstr += "passDirection=%s"+sep+tab
|
||
retlst += (self.passDirection,)
|
||
retstr += "orbitDataSource=%s"+sep+tab
|
||
retlst += (self.orbitDataSource,)
|
||
retstr += "orbitDataFile=%s"+sep
|
||
retlst += (self.orbitDataFile,)
|
||
retstr += ":OrbitInformation"+sep
|
||
return retstr % retlst
|
||
|
||
|
||
class _StateVector(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.timeStamp = None
|
||
self.xPosition = None
|
||
self.yPosition = None
|
||
self.zPosition = None
|
||
self.xVelocity = None
|
||
self.yVelocity = None
|
||
self.zVelocity = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('timeUTC'):
|
||
self.timeStamp = self.convertToDateTime(z.text)
|
||
elif z.tag == self.elementName('posX'):
|
||
self.xPosition = float(z.text)
|
||
elif z.tag == self.elementName('posY'):
|
||
self.yPosition = float(z.text)
|
||
elif z.tag == self.elementName('posZ'):
|
||
self.zPosition = float(z.text)
|
||
elif z.tag == self.elementName('velX'):
|
||
self.xVelocity = float(z.text)
|
||
elif z.tag == self.elementName('velY'):
|
||
self.yVelocity = float(z.text)
|
||
elif z.tag == self.elementName('velZ'):
|
||
self.zVelocity = float(z.text)
|
||
|
||
def __str__(self):
|
||
retstr = "StateVector:"+sep+tab
|
||
retlst = ()
|
||
retstr += "timeStamp=%s"+sep+tab
|
||
retlst += (self.timeStamp,)
|
||
retstr += "xPosition=%s"+sep+tab
|
||
retlst += (self.xPosition,)
|
||
retstr += "yPosition=%s"+sep+tab
|
||
retlst += (self.yPosition,)
|
||
retstr += "zPosition=%s"+sep+tab
|
||
retlst += (self.zPosition,)
|
||
retstr += "xVelocity=%s"+sep+tab
|
||
retlst += (self.xVelocity,)
|
||
retstr += "yVelocity=%s"+sep+tab
|
||
retlst += (self.yVelocity,)
|
||
retstr += "zVelocity=%s"+sep+tab
|
||
retlst += (self.zVelocity,)
|
||
retstr += sep+":StateVector"
|
||
return retstr % retlst
|
||
|
||
class _AttitudeInformation(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.attitudeDataSource = None
|
||
self.attitudeOffsetApplied = None
|
||
self.attitudeAngles = []
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('attitudeDataSource'):
|
||
self.attitudeDataSource = z.text
|
||
elif z.tag == self.elementName('attitudeOffsetApplied'):
|
||
self.attitudeOffsetApplied = z.text
|
||
elif z.tag == self.elementName('attitudeAngles'):
|
||
aa = _AttitudeAngles()
|
||
aa.set_from_etnode(z)
|
||
self.attitudeAngles.append(aa)
|
||
|
||
def __str__(self):
|
||
retstr = "AttitudeInformation:"+sep+tab
|
||
retlst = ()
|
||
retstr += "attitudeDataSource=%s"+sep+tab
|
||
retlst += (self.attitudeDataSource,)
|
||
retstr += "attitudeOffsetApplied=%s"+sep+tab
|
||
retlst += (self.attitudeOffsetApplied,)
|
||
retstr += "%s"+sep+tab
|
||
retlst += (map(str,self.attitudeAngles),)
|
||
retstr += ":AttitudeInformation"+sep
|
||
return retstr % retlst
|
||
|
||
class _AttitudeAngles(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.timeStamp = None
|
||
self.yaw = None
|
||
self.roll = None
|
||
self.pitch = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('timeStamp'):
|
||
self.timeStamp = self.convertToDateTime(z.text)
|
||
elif z.tag == self.elementName('yaw'):
|
||
self.yaw = float(z.text)
|
||
elif z.tag == self.elementName('roll'):
|
||
self.roll = float(z.text)
|
||
elif z.tag == self.elementName('pitch'):
|
||
self.pitch = float(z.text)
|
||
|
||
def __str__(self):
|
||
retstr = "AttitudeAngles:"+sep+tab
|
||
retlst = ()
|
||
retstr += "timeStamp=%s"+sep+tab
|
||
retlst += (self.timeStamp,)
|
||
retstr += "yaw=%s"+sep+tab
|
||
retlst += (self.yaw,)
|
||
retstr += "roll=%s"+sep+tab
|
||
retlst += (self.roll,)
|
||
retstr += "pitch=%s"+sep+tab
|
||
retlst += (self.pitch,)
|
||
retstr += sep+":AttitudeAngles"
|
||
return retstr % retlst
|
||
|
||
class _ImageGenerationParameters(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.generalProcessingInformation = _GeneralProcessingInformation()
|
||
self.sarProcessingInformation = _SarProcessingInformation()
|
||
self.dopplerCentroid = _DopplerCentroid()
|
||
self.dopplerRateValues = _DopplerRateValues()
|
||
self.chirp = []
|
||
self.slantRangeToGroundRange = _SlantRangeToGroundRange()
|
||
self.payloadCharacteristicsFile = []
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('generalProcessingInformation'):
|
||
self.generalProcessingInformation.set_from_etnode(z)
|
||
elif z.tag == self.elementName('sarProcessingInformation'):
|
||
self.sarProcessingInformation.set_from_etnode(z)
|
||
elif z.tag == self.elementName('dopplerCentroid'):
|
||
self.dopplerCentroid.set_from_etnode(z)
|
||
elif z.tag == self.elementName('dopplerRateValues'):
|
||
self.dopplerRateValues.set_from_etnode(z)
|
||
elif z.tag == self.elementName('slantRangeToGroundRange'):
|
||
self.slantRangeToGroundRange.set_from_etnode(z)
|
||
|
||
def __str__(self):
|
||
retstr = "ImageGenerationParameters:"+sep
|
||
retlst = ()
|
||
retstr += "%s"
|
||
retlst += (str(self.generalProcessingInformation),)
|
||
retstr += "%s"
|
||
retlst += (str(self.sarProcessingInformation),)
|
||
retstr += "%s"
|
||
retlst += (str(self.dopplerCentroid),)
|
||
retstr += "%s"
|
||
retlst += (str(self.dopplerRateValues),)
|
||
retstr += ":ImageGenerationParameters"
|
||
return retstr % retlst
|
||
|
||
|
||
class _GeneralProcessingInformation(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.productType = None
|
||
self._processingFacility = None
|
||
self.processingTime = None
|
||
self.softwareVersion = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('productType'):
|
||
self.productType = z.text
|
||
elif z.tag == self.elementName('_processingFacility'):
|
||
self._processingFacility = z.text
|
||
elif z.tag == self.elementName('processingTime'):
|
||
self.processingTime = self.convertToDateTime(z.text)
|
||
elif z.tag == self.elementName('softwareVersion'):
|
||
self.softwareVersion = z.text
|
||
|
||
def __str__(self):
|
||
retstr = "GeneralProcessingInformation:"+sep+tab
|
||
retlst = ()
|
||
retstr += "productType=%s"+sep+tab
|
||
retlst += (self.productType,)
|
||
retstr += "_processingFacility=%s"+sep+tab
|
||
retlst += (self._processingFacility,)
|
||
retstr += "processingTime=%s"+sep+tab
|
||
retlst += (self.processingTime,)
|
||
retstr += "softwareVersion=%s"+sep
|
||
retlst += (self.softwareVersion,)
|
||
retstr += ":GeneralProcessingInformation"+sep
|
||
return retstr % retlst
|
||
|
||
class _SarProcessingInformation(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.lutApplied = None
|
||
self.elevationPatternCorrection = None
|
||
self.rangeSpreadingLossCorrection = None
|
||
self.pulseDependantGainCorrection = None
|
||
self.receiverSettableGain = None
|
||
self.rawDataCorrection = None
|
||
self.rangeReferenceFunctionSource = None
|
||
self.interPolarizationMatricesCorrection = None
|
||
self.zeroDopplerTimeFirstLine = None
|
||
self.zeroDopplerTimeLastLine = None
|
||
self.numberOfLinesProcessed = None
|
||
self.samplingWindowStartTimeFirstRawLine = None
|
||
self.samplingWindowStartTimeLastRawLine = None
|
||
self.numberOfSwstChanges = None
|
||
self.numberOfRangeLooks = None
|
||
self.rangeLookBandwidth = None
|
||
self.totalProcessedRangeBandwidth = None
|
||
self.numberOfAzimuthLooks = None
|
||
self.scalarLookWeights = None
|
||
self.azimuthLookBandwidth = None
|
||
self.totalProcessedAzimuthBandwidth = None
|
||
self.azimuthWindow = _Window('Azimuth')
|
||
self.rangeWindow = _Window('Range')
|
||
self.incidenceAngleNearRange = None
|
||
self.incidenceAngleFarRange = None
|
||
self.slantRangeNearEdge = None
|
||
self._satelliteHeight = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('lutApplied'):
|
||
self.lutApplied = z.text
|
||
elif z.tag == self.elementName('numberOfLinesProcessed'):
|
||
self.numberOfLinesProcessed = int(z.text)
|
||
elif z.tag == self.elementName('azimuthWindow'):
|
||
self.azimuthWindow.set_from_etnode(z)
|
||
elif z.tag == self.elementName('rangeWindow'):
|
||
self.rangeWindow.set_from_etnode(z)
|
||
elif z.tag == self.elementName('incidenceAngleNearRange'):
|
||
self.incidenceAngleNearRange = float(z.text)
|
||
elif z.tag == self.elementName('incidenceAngleFarRange'):
|
||
self.incidenceAngleFarRange = float(z.text)
|
||
elif z.tag == self.elementName('slantRangeNearEdge'):
|
||
self.slantRangeNearEdge = float(z.text)
|
||
elif z.tag == self.elementName('totalProcessedAzimuthBandwidth'):
|
||
self.totalProcessedAzimuthBandwidth = float(z.text)
|
||
elif z.tag == self.elementName('_satelliteHeight'):
|
||
self._satelliteHeight = float(z.text)
|
||
elif z.tag == self.elementName('zeroDopplerTimeFirstLine'):
|
||
self.zeroDopplerTimeFirstLine = self.convertToDateTime(z.text)
|
||
elif z.tag == self.elementName('zeroDopplerTimeLastLine'):
|
||
self.zeroDopplerTimeLastLine = self.convertToDateTime(z.text)
|
||
|
||
def __str__(self):
|
||
retstr = "sarProcessingInformation:"+sep+tab
|
||
retlst = ()
|
||
retstr += "lutApplied=%s"+sep+tab
|
||
retlst += (self.lutApplied,)
|
||
retstr += "numberOfLineProcessed=%s"+sep
|
||
retlst += (self.numberOfLinesProcessed,)
|
||
retstr += "%s"+sep
|
||
retlst += (str(self.azimuthWindow),)
|
||
retstr += "%s"+sep
|
||
retlst += (str(self.rangeWindow),)
|
||
retstr += ":sarProcessingInformation"+sep
|
||
return retstr % retlst
|
||
|
||
class _Window(LT1ABNamespace):
|
||
def __init__(self,type):
|
||
LT1ABNamespace.__init__(self)
|
||
self.type = type
|
||
self.windowName = None
|
||
self.windowCoefficient = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('windowName'):
|
||
self.windowName = z.text
|
||
elif z.tag == self.elementName('windowCoefficient'):
|
||
self.windowCoefficient = float(z.text)
|
||
|
||
def __str__(self):
|
||
retstr = "%sWindow:"+sep+tab
|
||
retlst = (self.type,)
|
||
retstr += "windowName=%s"+sep+tab
|
||
retlst += (self.windowName,)
|
||
retstr += "windowCoefficient=%s"+sep
|
||
retlst += (self.windowCoefficient,)
|
||
retstr += ":%sWindow"
|
||
retlst += (self.type,)
|
||
return retstr % retlst
|
||
|
||
class _DopplerCentroid(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.timeOfDopplerCentroidEstimate = None
|
||
self.dopplerAmbiguity = None
|
||
self.dopplerAmbiguityConfidence= None
|
||
self.dopplerCentroidReferenceTime = None
|
||
self.dopplerCentroidPolynomialPeriod = None
|
||
self.dopplerCentroidCoefficients = []
|
||
self.dopplerCentroidConfidence = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('timeOfDopplerCentroidEstimate'):
|
||
self.timeOfDopplerCentroidEstimate = True
|
||
elif z.tag == self.elementName('dopplerAmbiguity'):
|
||
self.dopplerAmbiguity = True
|
||
elif z.tag == self.elementName('referencePoint'):
|
||
self.dopplerCentroidReferenceTime = float(z.text)
|
||
coefficientlist=node.findall('coefficient')
|
||
for i in range(len(coefficientlist)):
|
||
self.dopplerCentroidCoefficients.append(0)
|
||
for i in range(len(coefficientlist)):
|
||
if int(coefficientlist[i].attrib["exponent"])==i:
|
||
self.dopplerCentroidCoefficients[i]=float(coefficientlist[i].text)
|
||
|
||
def __str__(self):
|
||
retstr = "DopplerCentroid:"+sep+tab
|
||
retlst = ()
|
||
retstr += "dopplerAmbiguity=%s"+sep+tab
|
||
retlst += (self.dopplerAmbiguity,)
|
||
retstr += "dopplerCentroidCoefficients=%s"+sep
|
||
retlst += (self.dopplerCentroidCoefficients,)
|
||
retstr += ":DopplerCentroid"+sep
|
||
return retstr % retlst
|
||
|
||
class _DopplerRateValues(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.dopplerRateReferenceTime = None
|
||
self.dopplerRateValuesCoefficients = []
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('referencePoint'):
|
||
self.dopplerRateReferenceTime = float(z.text)
|
||
coefficientlist=node.findall('coefficient')
|
||
for i in range(len(coefficientlist)):
|
||
self.dopplerRateValuesCoefficients.append(0)
|
||
for i in range(len(coefficientlist)):
|
||
if int(coefficientlist[i].attrib["exponent"])==i:
|
||
self.dopplerRateValuesCoefficients[i]=float(coefficientlist[i].text)
|
||
|
||
|
||
|
||
|
||
def __str__(self):
|
||
retstr = "DopplerRateValues:"+sep+tab
|
||
retlst = ()
|
||
retstr += "dopplerRateReferenceTime=%s"+sep+tab
|
||
retlst += (self.dopplerRateReferenceTime,)
|
||
retstr += "dopplerRateValuesCoefficients=%s"+sep+tab
|
||
retlst += (self.dopplerRateValuesCoefficients,)
|
||
retstr += ":DopplerRateValues"
|
||
return retstr % retlst
|
||
|
||
class _Chirp(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
|
||
class _SlantRangeToGroundRange(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.zeroDopplerAzimuthTime = None
|
||
self.slantRangeTimeToFirstRangeSample = None
|
||
self.groundRangeOrigin = None
|
||
self.groundToSlantRangeCoefficients = []
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('zeroDopplerAzimuthTime'):
|
||
self.zeroDopplerAzimuthTime = self.convertToDateTime(z.text)
|
||
elif z.tag == self.elementName('slantRangeTimeToFirstRangeSample'):
|
||
self.slantRangeTimeToFirstRangeSample = float(z.text)
|
||
|
||
class _ImageAttributes(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.productFormat = None
|
||
self.outputMediaInterleaving = None
|
||
self.rasterAttributes = _RasterAttributes()
|
||
self.geographicInformation = _GeographicInformation()
|
||
self.fullResolutionImageData = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('productFormat'):
|
||
self.productFormat = z.text
|
||
elif z.tag == self.elementName('outputMediaInterleaving'):
|
||
self.outputMediaInterleaving = z.text
|
||
elif z.tag == self.elementName('rasterAttributes'):
|
||
self.rasterAttributes.set_from_etnode(z)
|
||
elif z.tag == self.elementName('geographicInformation'):
|
||
self.geographicInformation.set_from_etnode(z)
|
||
elif z.tag == self.elementName('fullResolutionImageData'):
|
||
self.fullResolutionImageData = z.text
|
||
|
||
class _RasterAttributes(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.dataType = None
|
||
self.bitsPerSample = []
|
||
self.numberOfSamplesPerLine = None
|
||
self.numberOfLines = None
|
||
self.sampledPixelSpacing = None
|
||
self.sampledLineSpacing = None
|
||
self.lineTimeOrdering = None
|
||
self.pixelTimeOrdering = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('dataType'):
|
||
self.dataType = z.text
|
||
elif z.tag == self.elementName('bitsPerSample'):
|
||
self.bitsPerSample.append(z.text) # TODO: Make this a dictionary with keys of 'imaginary' and 'real'
|
||
elif z.tag == self.elementName('numberOfSamplesPerLine'):
|
||
self.numberOfSamplesPerLine = int(z.text)
|
||
elif z.tag == self.elementName('numberOfLines'):
|
||
self.numberOfLines = int(z.text)
|
||
elif z.tag == self.elementName('sampledPixelSpacing'):
|
||
self.sampledPixelSpacing = float(z.text)
|
||
elif z.tag == self.elementName('sampledLineSpacing'):
|
||
self.sampledLineSpacing = float(z.text)
|
||
elif z.tag == self.elementName('lineTimeOrdering'):
|
||
self.lineTimeOrdering = z.text
|
||
elif z.tag == self.elementName('pixelTimeOrdering'):
|
||
self.pixelTimeOrdering = z.text
|
||
|
||
class _GeographicInformation(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.geolocationGrid = _GeolocationGrid()
|
||
self.rationalFunctions = _RationalFunctions()
|
||
self.referenceEllipsoidParameters = _ReferenceEllipsoidParameters()
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('geolocationGrid'):
|
||
self.geolocationGrid.set_from_etnode(z)
|
||
|
||
class _GeolocationGrid(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.imageTiePoint = []
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('imageTiePoint'):
|
||
tp = _ImageTiePoint()
|
||
tp.set_from_etnode(z)
|
||
self.imageTiePoint.append(tp)
|
||
|
||
|
||
class _ImageTiePoint(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.imageCoordinates = _ImageCoordinates()
|
||
self.geodeticCoordinates = _GeodeticCoordinates()
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('imageCoordinate'):
|
||
self.imageCoordinates.set_from_etnode(z)
|
||
elif z.tag == self.elementName('geodeticCoordinate'):
|
||
self.geodeticCoordinates.set_from_etnode(z)
|
||
|
||
def __str__(self):
|
||
retstr = "ImageTiePoint:"+sep+tab
|
||
retlst = ()
|
||
retstr += "%s"
|
||
retlst += (str(self.imageCoordinates),)
|
||
retstr += "%s"
|
||
retlst += (str(self.geodeticCoordinates),)
|
||
retstr += ":ImageTiePoint"
|
||
return retstr % retlst
|
||
|
||
class _ImageCoordinates(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.line = None
|
||
self.pixel = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('line'):
|
||
self.line = float(z.text)
|
||
elif z.tag == self.elementName('pixel'):
|
||
self.pixel = float(z.text)
|
||
|
||
def __str__(self):
|
||
retstr = "ImageCoordinate:"+sep+tab
|
||
retlst = ()
|
||
retstr += "line=%s"+sep+tab
|
||
retlst += (self.line,)
|
||
retstr += "pixel=%s"+sep+tab
|
||
retlst += (self.pixel,)
|
||
retstr += ":ImageCoordinate"
|
||
return retstr % retlst
|
||
|
||
class _GeodeticCoordinates(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.latitude = None
|
||
self.longitude = None
|
||
self.height = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('latitude'):
|
||
self.latitude = float(z.text)
|
||
elif z.tag == self.elementName('longitude'):
|
||
self.longitude = float(z.text)
|
||
elif z.tag == self.elementName('height'):
|
||
self.height = float(z.text)
|
||
|
||
def __str__(self):
|
||
retstr = "GeodeticCoordinate:"+sep+tab
|
||
retlst = ()
|
||
retstr += "latitude=%s"+sep+tab
|
||
retlst += (self.latitude,)
|
||
retstr += "longitude=%s"+sep+tab
|
||
retlst += (self.longitude,)
|
||
retstr += "height=%s"+sep+tab
|
||
retlst += (self.height,)
|
||
retstr += ":GeodeticCoordinate"
|
||
return retstr % retlst
|
||
|
||
class _ReferenceEllipsoidParameters(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
self.ellipsoidName = None
|
||
self.semiMajorAxis = None
|
||
self.semiMinorAxis = None
|
||
self.geodeticTerrainHeight = None
|
||
|
||
def set_from_etnode(self,node):
|
||
for z in node.getchildren():
|
||
if z.tag == self.elementName('ellipsoidName'):
|
||
self.ellipsoidName = z.text
|
||
elif z.tag == self.elementName('semiMajorAxis'):
|
||
self.semiMajorAxis = float(z.text)
|
||
elif z.tag == self.elementName('semiMinorAxis'):
|
||
self.semiMinorAxis = float(z.text)
|
||
elif z.tag == self.elementName('geodeticTerrainHeight'):
|
||
self.geodeticTerrainHeight = float(z.text)
|
||
|
||
def __str__(self):
|
||
return ""
|
||
|
||
class _RationalFunctions(LT1ABNamespace):
|
||
def __init__(self):
|
||
LT1ABNamespace.__init__(self)
|
||
|
||
def set_from_etnode(self,node):
|
||
pass
|
||
|
||
def __str__(self):
|
||
return ""
|
||
|
||
|
||
def findPreciseOrbit(dirname, fname, year):
|
||
'''
|
||
Find precise orbit file in given folder.
|
||
'''
|
||
|
||
import glob
|
||
|
||
###First try root folder itself
|
||
res = glob.glob( os.path.join(dirname, fname.lower()))
|
||
if len(res) == 0:
|
||
|
||
res = glob.glob( os.path.join(dirname, "{0}".format(year), fname.lower()))
|
||
if len(res) == 0:
|
||
raise Exception('Orbit Dirname provided but no suitable orbit file found in {0}'.format(dirname))
|
||
|
||
|
||
if len(res) > 1:
|
||
print('More than one matching result found. Using first result.')
|
||
|
||
return res[0]
|
||
|
||
def convertRSTimeToDateTime(instr):
|
||
'''
|
||
Convert RS2 orbit time string to datetime.
|
||
'''
|
||
|
||
parts = instr.strip().split('-')
|
||
tparts = parts[-1].split(':')
|
||
secs = float(tparts[2])
|
||
intsecs = int(secs)
|
||
musecs = int((secs - intsecs)*1e6)
|
||
|
||
timestamp = datetime.datetime(int(parts[0]),1,1, int(tparts[0]), int(tparts[1]), intsecs, musecs) + datetime.timedelta(days = int(parts[1])-1)
|
||
|
||
return timestamp
|