我的信号频谱PSD看起来像:
PSD的频率范围是np.linspace(0,2,500)。我想将此光谱转换为600s的时间序列。代码如下所示:
def spectrumToSeries(timeSeries,frequency,psdLoad):
'''
Function that gicen a PSD converts into a time series
'''
#
#Obtian interval frequency
df=frequency[2]-frequency[1]
#Obtian the spectrum amplitudes
amplitude=np.sqrt(2*np.array(psdLoad)*df)
#Pre allocation of matrices
epsilon=np.zeros((len(amplitude)))
randomSeries=np.zeros((len(amplitude)))
#Create time series from spectrum
#Generate random phases between [-2pi,2pi]
epsilon=-np.pi + 2*np.pi*np.random.randn(1,len(amplitude))
#Inverse Fourier
randomSeries=len(timeSeries)*np.real(np.fft.ifft(amplitude*np.exp(epsilon*1j*2*np.pi))));
return randomSeries
然而,我的最终结果如下:
timeSeries = spectrumToSeries(thrustBladed,param.frequency,analyticalThrustPSD[iwind])
x轴表示时间序列的点数。但是,时间序列应该是600s。有帮助吗?谢谢
答案 0 :(得分:0)
你的功能结果" spectrumToSeries"与您在np.fft.ifft中提供的数组长度相同。因为ifft函数返回与输入长度相同的数组。 所以,因为你的初始psdLoad数组有500个元素,"幅度"数组也是500个元素,而randomSeries也是一个,这是你的函数的结果。
我没有真正得到你功能的不同输入。什么是第一个称为timeSeries的参数?它是一个600个元素的空矩阵,等待函数的结果吗?
我正在尝试自己计算PSD的时间序列,所以我很乐意看到你的功能给出了好的结果!
我认为如果你想让你的时间序列为600个元素,你需要有一个"频率"和一个" psdLoad" 600个元素的数组。所以我试图用我的数据集来适应我的psdLoad函数(psdLoad = f(频率))。然后我可以将我的数组的大小设置为我想要的时间序列的长度,并计算ifft ......
我自己的数据是1Hz的记录,超过一天,所以86400个元素的数组。我必须使用PSD方法对其应用滤镜。所以我计算我的PSD,长度为129个元素,一旦我过滤了它,我想最终得到我的过滤时间序列。
这是我的代码:
######################################################################"
## Computation of spectrum values : PSD & frequency ##
######################################################################"
psd_ampl0, freq = mlab.psd(Up13_7april, NFFT=256, Fs=1, detrend=mlab.detrend_linear, window=mlab.window_hanning, noverlap=0.5, sides='onesided')
################################################"
## Computation of the time series from the PSD ##
################################################"
def PSDToSeries(lenTimeSeries,freq,psdLoad):
'''
Function that gicen a PSD converts into a time series
'''
#
#Obtian interval frequency
df=freq[2]-freq[1]
print('df = ', df)
#Obtian the spectrum amplitudes
amplitude=(2*psdLoad*df)**0.5
#Pre allocation of matrices
epsilon=np.zeros((len(amplitude)))
randomSeries=np.zeros((len(amplitude)))
#Create time series from spectrum
#Generate random phases between [-2pi,2pi]
epsilon=-np.pi + 2*np.pi*np.random.randn(1,len(amplitude))
#Inverse Fourier
randomSeries=lenTimeSeries*np.real(np.fft.ifft(amplitude*np.exp(epsilon*1j*2*np.pi)));
return randomSeries
#-------------------------------------------------------------------------
#########################################################"
## Fitting a function on the PSD to add it more points ##
#########################################################"
#def fitting_function(freq,a,b,c,d,e,f):
#return a*(freq**5)+b*(freq**4)+c*(freq**3)+d*(freq**2)+e*freq+f
def fitting_function(freq,a,b,c):
return a*np.exp(freq*b)
# Look for the best fitting parameters of the choosen fitting function #
param_opt, pcov = optim.curve_fit(fitting_function,freq[1:],psd_ampl0[1:])
print('The best fitting parameters are : ',param_opt)
# Definition of the new PSD and frequency arrays extended to 86400 elements #
freq_extend = np.linspace(min(freq),max(freq), 86400)
psd_extend = fitting_function(freq_extend,param_opt[0], param_opt[1], param_opt[2])
#print(psd_allonge)
ts_length = Up13_7april.shape[0] #Length of the timeSeries I want to compute
print('ts_length = ', ts_length)
tsFromPSD = PSDToSeries(ts_length, freq_allonge, psd_allonge)
print('shape tsFromPSD : ', tsFromPSD.shape)
##################"
## Plot section ##
##################"
plt.figure(1)
plt.plot(freq[1:] ,psd_ampl0[1:],marker=',', ls='-',color='SkyBlue', label='original PSD')
plt.plot(freq_allonge, psd_allonge, marker=',', ls='-',color='DarkGreen', label='PSD rallonge')
plt.xlabel('Frequency [Hz]')
plt.ylabel('PSD of raw velocity module [(m/s)²/Hz]')
plt.grid(True)
plt.legend()
plt.figure(2)
plt.plot_date(time7april,Up13_7april, xdate=True, ydate=False, marker=',', ls='-', c='Grey', label='Original Signal')
plt.plot_date(time7april, tsFromPSD[0],xdate=True, ydate=False, marker=',', ls='-', label='After inverse PSD')
plt.suptitle('Original and Corrected time series for the 7th of April')
plt.grid(True)
plt.legend()
plt.show()
阵列Up13_7april,是我的初始时间序列,在这段代码中,我只是试图计算PSD,然后回到时间系列来比较原始信号和最后一个。结果如下:
[抱歉无法发布任何图片,因为我是stackoverflow的新手]
所以我的过程是找到一个适合PSD的功能。我使用名为" optimize.curve_fit"的Python scipy函数。它只是为您提供最佳参数,以使您提供的功能适合您的数据。 一旦我有参数,我就会创建86400个元素的新PSD和频率数组。最后我使用你的" PSDToSeries"函数来计算timeSeries。
我对结果非常满意......我想我只需要找到更适合我的PSD:
[抱歉无法发布任何图片,因为我是stackoverflow的新手]
有什么想法吗?