Python rfft不会产生正确的阶段信息

时间:2015-11-10 22:41:08

标签: python numpy scipy signal-processing fft

所以我正在尝试编写一个代码来实现Forman相位校正,以纠正干涉图中与相位相关的不对称性。例程的前提是用你的干涉图卷积exp(-i * PhaseAngle)的傅里叶变换。这种技术自60年代就开始存在,它应该可行,但我一直遇到困难。

因此,我使用python生成一个具有正好0相角的干涉图来调试我的代码。一旦我开始工作,我生成了一个0.3弧度相位的干涉图,我的相位数组看起来不像常数0.3,我不确定是什么时候发生的。我已经尝试了numpy arctan,numpy arctan2和numpy angle都是糟糕的结果。我也试过改变我的数据并且没有帮助,所以为了清楚起见我删除了它。

为什么我没有从我的程序中获取正确的阶段信息?如果你将这段代码插入到python中,你会得到一些不稳定的阶段图。

我对我的处理功能非常有信心,并且代码的真正含义低于那些,我将这些函数称为处理干涉图。计算相位角的基本程序是:

- 将干涉图发送到少数几个点(我使用了401) - 旋转它以使零路径差(ZPD)成为第一个数据点 - 将ZPD值乘以0.5(不确定原因,但学术论文说你必须这样做) - 获取结果数据的真实(单侧)fft - 取虚数的反正切除以实数得到相位角

所以我按照上面的例程进行人工生成的0.3弧度相移干涉图,但是不能用例程重现那个相位误差。有任何想法吗?感谢您提供的任何帮助!

编辑:这个问题的很多内容归结为在应用fft之前我应该​​如何安排我的信号(具有0.3的已知,恒定,相位误差),使得我的结果的虚部是常数0.3 ?而且,我应该使用python中的哪种类型的fft来实现这个结果?我非常有信心我成功地生成了一个具有0.3的恒定相位误差的信号。

代码:

## Importer
import numpy as np
import scipy.integrate
import matplotlib.pyplot as plt
plt.style.use('ggplot')
from scipy.fftpack import dct,idct,dst,idst
import cmath
from scipy import signal
from scipy.integrate import simps
import csv

## Generate interferogram
xlist = np.arange(-0.03, 0.03,(1/15798.69))
numPhase = 200
print 'generating interferogram...'
def infGen(nu, xval):
    h = 6.626*10**-34 #J*s
    c = 3*10**8 #m/s
    kB = 1.38*10**-23 #J/K
    T = 300.0 # K    
    return 0.5*2*h*c*c*nu*nu*nu*(100.0**3)*1/(np.exp(h*c*nu*100/(kB*T))-1)*np.cos(2*np.pi*nu*xval+0.3)
interferogram = list()
intError = list()
for i in range(len(xlist)):
    xval = xlist[i]
    value, error = scipy.integrate.quad(infGen,500,4000,args = (xval),limit=150)
    interferogram.append(value)
    intError.append(error)

## Processing functions
def truncate(interferogram, centerburst):
    truncated=list()
    truncatedLength=2*numPhase+1
    for i in range(truncatedLength):
        truncated.append(interferogram[centerburst-(truncatedLength/2)+i])
    #Compute interferogram averages to normalize
    truncavg=np.average(truncated)
    #Normalize the interferograms by their averages
    for i in range(len(truncated)):
        truncated[i]=truncated[i]-truncavg
    return truncated
def rotateMertz(interferogram):
    rotated=list()
    for i in range(len(interferogram)-numPhase):
        rotated.append(interferogram[i+numPhase])
    for i in range(numPhase):
        rotated.append(interferogram[i])
    return rotated   
def getphaseangle(fftdata):
    phaseangle=list()
    for i in range(len(fftdata)):
        #phaseangle.append(np.angle(fftdata[i]))
        """if fftdata[i].imag < 0:
            phaseangle[i] = phaseangle[i]+2*np.pi
        if fftdata[i].real>0 and np.abs(fftdata[i].imag)<(10**-10) and fftdata[i].imag<0:
            phaseangle[i] = 0"""
        phaseangle.append(np.arctan(fftdata[i].imag/fftdata[i].real))
    return phaseangle
def findZPD(inf):
    # finds the index of the zpd for a given interferogram
    maxVal=max(np.abs(inf))
    x = [i for i, j in enumerate(inf) if j==maxVal]
    return x[0]

## Process Interferogram
inf = interferogram
phasedataTrunc = truncate(inf, findZPD(inf))
phasedataRot = rotateMertz(phasedataTrunc) # Rotates so ZPD is first value
phasedataRot[0] = phasedataRot[0]*0.5 # Multiply ZPD value by 0.5
phasedataFFT = np.fft.rfft(phasedataRot)
plt.figure('real part')
plt.plot(phasedataFFT.real)
plt.figure('imaginary part')
plt.plot(phasedataFFT.imag)
plt.figure('imaginary/real')
plt.plot(phasedataFFT.imag/phasedataFFT.real)
phaseAngle = getphaseangle(phasedataFFT)
plt.figure('phase angle')
plt.plot(phaseAngle)
plt.show()

0 个答案:

没有答案