enhanced merging for ALOS-2 ionospheric correction
parent
9794a75f55
commit
d22bf1048f
|
@ -44,7 +44,8 @@ def runIonFilt(self):
|
||||||
###################################
|
###################################
|
||||||
#SET PARAMETERS HERE
|
#SET PARAMETERS HERE
|
||||||
#THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
|
#THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
|
||||||
corThresholdAdj = 0.85
|
corThresholdAdj = 0.97
|
||||||
|
corOrderAdj = 20
|
||||||
###################################
|
###################################
|
||||||
|
|
||||||
print('\ncomputing ionosphere')
|
print('\ncomputing ionosphere')
|
||||||
|
@ -75,11 +76,16 @@ def runIonFilt(self):
|
||||||
upperUnw[area[0]:area[1], area[2]:area[3]] = 0
|
upperUnw[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
cor[area[0]:area[1], area[2]:area[3]] = 0
|
cor[area[0]:area[1], area[2]:area[3]] = 0
|
||||||
|
|
||||||
|
#remove possible wired values in coherence
|
||||||
|
cor[np.nonzero(cor<0)] = 0.0
|
||||||
|
cor[np.nonzero(cor>1)] = 0.0
|
||||||
|
|
||||||
#compute ionosphere
|
#compute ionosphere
|
||||||
fl = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[0]
|
fl = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[0]
|
||||||
fu = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[1]
|
fu = SPEED_OF_LIGHT / self._insar.subbandRadarWavelength[1]
|
||||||
adjFlag = 1
|
adjFlag = 1
|
||||||
ionos = computeIonosphere(lowerUnw, upperUnw, cor, fl, fu, adjFlag, corThresholdAdj, 0)
|
cor[np.nonzero(cor<corThresholdAdj)] = 0.0
|
||||||
|
ionos = computeIonosphere(lowerUnw, upperUnw, cor**corOrderAdj, fl, fu, adjFlag, 0)
|
||||||
|
|
||||||
#dump ionosphere
|
#dump ionosphere
|
||||||
ionfile = 'ion'+ml2+'.ion'
|
ionfile = 'ion'+ml2+'.ion'
|
||||||
|
@ -108,13 +114,36 @@ def runIonFilt(self):
|
||||||
size_max = self.filteringWinsizeMaxIon
|
size_max = self.filteringWinsizeMaxIon
|
||||||
size_min = self.filteringWinsizeMinIon
|
size_min = self.filteringWinsizeMinIon
|
||||||
|
|
||||||
|
if size_min >= size_max:
|
||||||
|
print('\n\nWARNING: minimum window size for filtering ionosphere phase {} >= maximum window size {}'.format(size_min, size_max))
|
||||||
|
print(' resetting maximum window size to {}\n\n'.format(size_min+5))
|
||||||
|
size_max = size_min + 5
|
||||||
|
|
||||||
#THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
|
#THESE SHOULD BE GOOD ENOUGH, NO NEED TO SET IN setup(self)
|
||||||
corThresholdIon = 0.85
|
#corThresholdFit = 0.85
|
||||||
|
|
||||||
|
#Now changed to use lower band coherence. crl, 23-apr-2020.
|
||||||
|
useDiffCoherence = False
|
||||||
|
if useDiffCoherence:
|
||||||
|
#parameters for using diff coherence
|
||||||
|
corfile = 'diff'+ml2+'.cor'
|
||||||
|
corThresholdFit = 0.95
|
||||||
|
# 1 is not good for low coherence case, changed to 20
|
||||||
|
#corOrderFit = 1
|
||||||
|
corOrderFit = 20
|
||||||
|
corOrderFilt = 20
|
||||||
|
else:
|
||||||
|
#parameters for using lower/upper band coherence
|
||||||
|
corfile = subbandPrefix[0]+ml2+'.cor'
|
||||||
|
corThresholdFit = 0.4
|
||||||
|
corOrderFit = 10
|
||||||
|
corOrderFilt = 10
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
print('\nfiltering ionosphere')
|
print('\nfiltering ionosphere')
|
||||||
ionfile = 'ion'+ml2+'.ion'
|
ionfile = 'ion'+ml2+'.ion'
|
||||||
corfile = 'diff'+ml2+'.cor'
|
#corfile = 'diff'+ml2+'.cor'
|
||||||
ionfiltfile = 'filt_ion'+ml2+'.ion'
|
ionfiltfile = 'filt_ion'+ml2+'.ion'
|
||||||
|
|
||||||
img = isceobj.createImage()
|
img = isceobj.createImage()
|
||||||
|
@ -145,14 +174,17 @@ def runIonFilt(self):
|
||||||
# cor[np.nonzero(wbd!=0)] = 0.00001
|
# cor[np.nonzero(wbd!=0)] = 0.00001
|
||||||
|
|
||||||
if fit:
|
if fit:
|
||||||
ion_fit = weight_fitting(ion, cor, width, length, 1, 1, 1, 1, 2, corThresholdIon)
|
import copy
|
||||||
|
wgt = copy.deepcopy(cor)
|
||||||
|
wgt[np.nonzero(wgt<corThresholdFit)] = 0.0
|
||||||
|
ion_fit = weight_fitting(ion, wgt**corOrderFit, width, length, 1, 1, 1, 1, 2)
|
||||||
ion -= ion_fit * (ion!=0)
|
ion -= ion_fit * (ion!=0)
|
||||||
|
|
||||||
#minimize the effect of low coherence pixels
|
#minimize the effect of low coherence pixels
|
||||||
#cor[np.nonzero( (cor<0.85)*(cor!=0) )] = 0.00001
|
#cor[np.nonzero( (cor<0.85)*(cor!=0) )] = 0.00001
|
||||||
#filt = adaptive_gaussian(ion, cor, size_max, size_min)
|
#filt = adaptive_gaussian(ion, cor, size_max, size_min)
|
||||||
#cor**14 should be a good weight to use. 22-APR-2018
|
#cor**14 should be a good weight to use. 22-APR-2018
|
||||||
filt = adaptive_gaussian(ion, cor**14, size_max, size_min)
|
filt = adaptive_gaussian(ion, cor**corOrderFilt, size_max, size_min)
|
||||||
|
|
||||||
if fit:
|
if fit:
|
||||||
filt += ion_fit * (filt!=0)
|
filt += ion_fit * (filt!=0)
|
||||||
|
@ -282,19 +314,18 @@ def runIonFilt(self):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def computeIonosphere(lowerUnw, upperUnw, cor, fl, fu, adjFlag, corThresholdAdj, dispersive):
|
def computeIonosphere(lowerUnw, upperUnw, wgt, fl, fu, adjFlag, dispersive):
|
||||||
'''
|
'''
|
||||||
This routine computes ionosphere and remove the relative phase unwrapping errors
|
This routine computes ionosphere and remove the relative phase unwrapping errors
|
||||||
|
|
||||||
lowerUnw: lower band unwrapped interferogram
|
lowerUnw: lower band unwrapped interferogram
|
||||||
upperUnw: upper band unwrapped interferogram
|
upperUnw: upper band unwrapped interferogram
|
||||||
cor: coherence
|
wgt: weight
|
||||||
fl: lower band center frequency
|
fl: lower band center frequency
|
||||||
fu: upper band center frequency
|
fu: upper band center frequency
|
||||||
adjFlag: method for removing relative phase unwrapping errors
|
adjFlag: method for removing relative phase unwrapping errors
|
||||||
0: mean value
|
0: mean value
|
||||||
1: polynomial
|
1: polynomial
|
||||||
corThresholdAdj: coherence threshold of samples used in removing relative phase unwrapping errors
|
|
||||||
dispersive: compute dispersive or non-dispersive
|
dispersive: compute dispersive or non-dispersive
|
||||||
0: dispersive
|
0: dispersive
|
||||||
1: non-dispersive
|
1: non-dispersive
|
||||||
|
@ -324,14 +355,14 @@ def computeIonosphere(lowerUnw, upperUnw, cor, fl, fu, adjFlag, corThresholdAdj,
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
#adjust phase using mean value
|
#adjust phase using mean value
|
||||||
if adjFlag == 0:
|
if adjFlag == 0:
|
||||||
flag = (lowerUnw!=0)*(cor>=corThresholdAdj)
|
flag = (lowerUnw!=0)*(wgt!=0)
|
||||||
index = np.nonzero(flag!=0)
|
index = np.nonzero(flag!=0)
|
||||||
mv = np.mean((lowerUnw - upperUnw)[index], dtype=np.float64)
|
mv = np.mean((lowerUnw - upperUnw)[index], dtype=np.float64)
|
||||||
print('mean value of phase difference: {}'.format(mv))
|
print('mean value of phase difference: {}'.format(mv))
|
||||||
diff = mv
|
diff = mv
|
||||||
#adjust phase using a surface
|
#adjust phase using a surface
|
||||||
else:
|
else:
|
||||||
diff = weight_fitting(lowerUnw - upperUnw, cor, width, length, 1, 1, 1, 1, 2, corThresholdAdj)
|
diff = weight_fitting(lowerUnw - upperUnw, wgt, width, length, 1, 1, 1, 1, 2)
|
||||||
|
|
||||||
flag2 = (lowerUnw!=0)
|
flag2 = (lowerUnw!=0)
|
||||||
index2 = np.nonzero(flag2)
|
index2 = np.nonzero(flag2)
|
||||||
|
@ -435,10 +466,10 @@ def cal_surface(x, y, c, order):
|
||||||
return z
|
return z
|
||||||
|
|
||||||
|
|
||||||
def weight_fitting(ionos, cor, width, length, nrli, nali, nrlo, nalo, order, coth):
|
def weight_fitting(ionos, weight, width, length, nrli, nali, nrlo, nalo, order):
|
||||||
'''
|
'''
|
||||||
ionos: input ionospheric phase
|
ionos: input ionospheric phase
|
||||||
cor: coherence of the interferogram
|
weight: weight
|
||||||
width: file width
|
width: file width
|
||||||
length: file length
|
length: file length
|
||||||
nrli: number of range looks of the input interferograms
|
nrli: number of range looks of the input interferograms
|
||||||
|
@ -446,7 +477,6 @@ def weight_fitting(ionos, cor, width, length, nrli, nali, nrlo, nalo, order, cot
|
||||||
nrlo: number of range looks of the output ionosphere phase
|
nrlo: number of range looks of the output ionosphere phase
|
||||||
nalo: number of azimuth looks of the ioutput ionosphere phase
|
nalo: number of azimuth looks of the ioutput ionosphere phase
|
||||||
order: the order of the polynomial for fitting ionosphere phase estimates
|
order: the order of the polynomial for fitting ionosphere phase estimates
|
||||||
coth: coherence threshhold for ionosphere phase estimation
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import create_multi_index2
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_multi_index2
|
||||||
|
@ -460,11 +490,8 @@ def weight_fitting(ionos, cor, width, length, nrli, nali, nrlo, nalo, order, cot
|
||||||
rgindex = create_multi_index2(widtho, nrli, nrlo)
|
rgindex = create_multi_index2(widtho, nrli, nrlo)
|
||||||
azindex = create_multi_index2(lengtho, nali, nalo)
|
azindex = create_multi_index2(lengtho, nali, nalo)
|
||||||
|
|
||||||
#convert coherence to weight
|
|
||||||
cor = cor**2/(1.009-cor**2)
|
|
||||||
|
|
||||||
#look for data to use
|
#look for data to use
|
||||||
flag = (cor>coth)*(ionos!=0)
|
flag = (weight!=0)*(ionos!=0)
|
||||||
point_index = np.nonzero(flag)
|
point_index = np.nonzero(flag)
|
||||||
m = point_index[0].shape[0]
|
m = point_index[0].shape[0]
|
||||||
|
|
||||||
|
@ -475,7 +502,7 @@ def weight_fitting(ionos, cor, width, length, nrli, nali, nrlo, nalo, order, cot
|
||||||
x = x0[point_index].reshape(m, 1)
|
x = x0[point_index].reshape(m, 1)
|
||||||
y = y0[point_index].reshape(m, 1)
|
y = y0[point_index].reshape(m, 1)
|
||||||
z = ionos[point_index].reshape(m, 1)
|
z = ionos[point_index].reshape(m, 1)
|
||||||
w = cor[point_index].reshape(m, 1)
|
w = weight[point_index].reshape(m, 1)
|
||||||
|
|
||||||
#convert to higher precision type before use
|
#convert to higher precision type before use
|
||||||
x=np.asfarray(x,np.float64)
|
x=np.asfarray(x,np.float64)
|
||||||
|
|
|
@ -378,33 +378,94 @@ def swathMosaic(frame, inputFiles, outputfile, rangeOffsets, azimuthOffsets, num
|
||||||
|
|
||||||
|
|
||||||
#get difference
|
#get difference
|
||||||
corth = 0.87
|
dataDiff = data1 * np.conj(data2)
|
||||||
if filt:
|
cor = cal_coherence_1(dataDiff, win=5)
|
||||||
corth = 0.90
|
index = np.nonzero(np.logical_and(cor>0.85, dataDiff!=0))
|
||||||
diffMean0 = 0.0
|
|
||||||
for k in range(5):
|
DEBUG=False
|
||||||
dataDiff = data1 * np.conj(data2)
|
if DEBUG:
|
||||||
cor = cal_coherence_1(dataDiff, win=3)
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
index = np.nonzero(np.logical_and(cor>corth, dataDiff!=0))
|
(length7, width7)=dataDiff.shape
|
||||||
|
filename = 'diff_ori_s{}-s{}.int'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber)
|
||||||
|
dataDiff.astype(np.complex64).tofile(filename)
|
||||||
|
create_xml(filename, width7, length7, 'int')
|
||||||
|
filename = 'cor_ori_s{}-s{}.cor'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber)
|
||||||
|
cor.astype(np.float32).tofile(filename)
|
||||||
|
create_xml(filename, width7, length7, 'float')
|
||||||
|
|
||||||
|
print('\ncompute phase difference between subswaths {} and {}'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber))
|
||||||
|
print('number of pixels with coherence > 0.85: {}'.format(index[0].size))
|
||||||
|
|
||||||
|
#if already filtered the subswath overlap interferograms (MAI), do not filtered differential interferograms
|
||||||
|
if (filt == False) and (index[0].size < 4000):
|
||||||
|
#coherence too low, filter subswath overlap differential interferogram
|
||||||
|
diffMean0 = 0.0
|
||||||
|
breakFlag = False
|
||||||
|
for (filterStrength, filterWinSize) in zip([3.0, 9.0], [64, 128]):
|
||||||
|
dataDiff = data1 * np.conj(data2)
|
||||||
|
dataDiff /= (np.absolute(dataDiff)+(dataDiff==0))
|
||||||
|
dataDiff = filterInterferogram(dataDiff, filterStrength, filterWinSize, 1)
|
||||||
|
cor = cal_coherence_1(dataDiff, win=7)
|
||||||
|
|
||||||
|
DEBUG=False
|
||||||
|
if DEBUG:
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
(length7, width7)=dataDiff.shape
|
||||||
|
filename = 'diff_filt_s{}-s{}_strength_{}_winsize_{}.int'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, filterStrength, filterWinSize)
|
||||||
|
dataDiff.astype(np.complex64).tofile(filename)
|
||||||
|
create_xml(filename, width7, length7, 'int')
|
||||||
|
filename = 'cor_filt_s{}-s{}_strength_{}_winsize_{}.cor'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, filterStrength, filterWinSize)
|
||||||
|
cor.astype(np.float32).tofile(filename)
|
||||||
|
create_xml(filename, width7, length7, 'float')
|
||||||
|
|
||||||
|
for corth in [0.99999, 0.9999]:
|
||||||
|
index = np.nonzero(np.logical_and(cor>corth, dataDiff!=0))
|
||||||
|
if index[0].size > 30000:
|
||||||
|
breakFlag = True
|
||||||
|
break
|
||||||
|
if breakFlag:
|
||||||
|
break
|
||||||
|
|
||||||
if index[0].size < 100:
|
if index[0].size < 100:
|
||||||
diffMean0 = 0.0
|
diffMean0 = 0.0
|
||||||
print('\n\nWARNING: too few high coherence pixels for swath phase difference estimation between swath {} and {}'.format(i-1, i))
|
print('\n\nWARNING: too few high coherence pixels for swath phase difference estimation')
|
||||||
print(' : first swath swath number: 0\n\n')
|
print(' number of high coherence pixels: {}\n\n'.format(index[0].size))
|
||||||
break
|
else:
|
||||||
angle = np.mean(np.angle(dataDiff[index]), dtype=np.float64)
|
print('filtered coherence threshold used: {}, number of pixels used: {}'.format(corth, index[0].size))
|
||||||
diffMean0 += angle
|
angle = np.mean(np.angle(dataDiff[index]), dtype=np.float64)
|
||||||
data2 *= np.exp(np.complex64(1j) * angle)
|
diffMean0 += angle
|
||||||
print('phase offset: %15.12f rad after loop: %3d'%(diffMean0, k))
|
data2 *= np.exp(np.complex64(1j) * angle)
|
||||||
|
print('phase offset: %15.12f rad with filter strength: %f, window size: %3d'%(diffMean0, filterStrength, filterWinSize))
|
||||||
|
else:
|
||||||
|
diffMean0 = 0.0
|
||||||
|
for k in range(30):
|
||||||
|
dataDiff = data1 * np.conj(data2)
|
||||||
|
cor = cal_coherence_1(dataDiff, win=5)
|
||||||
|
if filt:
|
||||||
|
index = np.nonzero(np.logical_and(cor>0.95, dataDiff!=0))
|
||||||
|
else:
|
||||||
|
index = np.nonzero(np.logical_and(cor>0.85, dataDiff!=0))
|
||||||
|
if index[0].size < 100:
|
||||||
|
diffMean0 = 0.0
|
||||||
|
print('\n\nWARNING: too few high coherence pixels for swath phase difference estimation')
|
||||||
|
print(' number of high coherence pixels: {}\n\n'.format(index[0].size))
|
||||||
|
break
|
||||||
|
angle = np.mean(np.angle(dataDiff[index]), dtype=np.float64)
|
||||||
|
diffMean0 += angle
|
||||||
|
data2 *= np.exp(np.complex64(1j) * angle)
|
||||||
|
print('phase offset: %15.12f rad after loop: %3d'%(diffMean0, k))
|
||||||
|
|
||||||
|
DEBUG=False
|
||||||
|
if DEBUG and (k==0):
|
||||||
|
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
||||||
|
(length7, width7)=dataDiff.shape
|
||||||
|
filename = 'diff_ori_s{}-s{}_loop_{}.int'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, k)
|
||||||
|
dataDiff.astype(np.complex64).tofile(filename)
|
||||||
|
create_xml(filename, width7, length7, 'int')
|
||||||
|
filename = 'cor_ori_s{}-s{}_loop_{}.cor'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, k)
|
||||||
|
cor.astype(np.float32).tofile(filename)
|
||||||
|
create_xml(filename, width7, length7, 'float')
|
||||||
|
|
||||||
DEBUG=False
|
|
||||||
if DEBUG and (k==0):
|
|
||||||
from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
|
|
||||||
(lengthxx, widthxx)=dataDiff.shape
|
|
||||||
filtnamePrefix = 'subswath{}_subswath{}_loop{}'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, k)
|
|
||||||
cor.astype(np.float32).tofile(filtnamePrefix+'.cor')
|
|
||||||
create_xml(filtnamePrefix+'.cor', widthxx, lengthxx, 'float')
|
|
||||||
dataDiff.astype(np.complex64).tofile(filtnamePrefix+'.int')
|
|
||||||
create_xml(filtnamePrefix+'.int', widthxx, lengthxx, 'int')
|
|
||||||
|
|
||||||
diffMean.append(diffMean0)
|
diffMean.append(diffMean0)
|
||||||
print('phase offset: subswath{} - subswath{}: {}'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, diffMean0))
|
print('phase offset: subswath{} - subswath{}: {}'.format(frame.swaths[i-1].swathNumber, frame.swaths[i].swathNumber, diffMean0))
|
||||||
|
|
Loading…
Reference in New Issue