Python中脉冲激光光谱转脉冲时长的IDTFT结果异常求助
IDTFT转换脉冲激光光谱数据异常问题排查
我尝试通过Python脚本自动将脉冲激光光谱数据转换为脉冲时长,采用了逆离散时间傅里叶变换(IDTFT)方法,但转换得到的数据不符合预期。以下是实现代码及生成的频域、时域结果图:
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 逆离散时间傅里叶变换 def IDTFT(N,intensity,frequency,time): inverse = np.zeros(len(time),dtype=np.clongdouble) for t in range(len(time)): for k in range(N): inverse[t] += (1/N)*intensity[k]*np.exp((1j*2*np.pi*frequency[k]*time[t])/N) return inverse # 加载数据 df = pd.read_csv(r'C:\Users\lukas\Downloads\Data.txt',sep='\t') # 提取数据 intensity = df['Intensity'] wavelength = df['Wavelength'] frequency = 299792458/(wavelength*1e-9) time = np.arange(0,2024e-15,1e-15) # 绘制频域图 plt.figure(0) plt.grid() plt.plot(frequency,intensity,'o') plt.show()
频域图(x轴单位:Hz):
# 执行转换 inverse = IDTFT(len(wavelength),intensity,frequency,time) # 绘制时域图 plt.figure(1) plt.grid() plt.plot(time,inverse,'o') plt.show()
时域图(x轴单位:s):
问题排查与修正方案
核心公式误用
你混淆了IDTFT和逆傅里叶变换(IFT)的适用场景:IDTFT针对离散频率的周期信号,而你的光谱是连续频率采样的非周期信号,应该用IFT。你代码里的公式错误地给频率项除以了N,正确的离散IFT近似应该是对每个频率点的强度乘以exp(1j*2*np.pi*frequency[k]*time[t])后求和,再乘以频率间隔(模拟积分的离散步长)。频率轴未排序
从频域图可见频率点是无序的,这会导致相位叠加混乱,必须先对频率和对应强度按频率从小到大排序。时间轴设置不合理
根据傅里叶变换不确定性原理,时间窗口长度应满足 $T \geq 1/\Delta f$($\Delta f$为频率分辨率),你需要先计算频率的平均间隔,再确定匹配的时间轴范围,同时采用中心对称的时间轴更符合脉冲信号的分布特性。复数结果处理错误
时域变换结果是复数,直接绘制整个复数无物理意义,应该取模(代表脉冲强度)或者实部(实值光谱对应的时域实信号)。
修正后的代码示例
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 针对离散采样连续频率的逆傅里叶变换 def inverse_fourier_transform(freqs, intensities, times): df = freqs[1] - freqs[0] # 计算频率间隔(已排序前提) time_domain = np.zeros(len(times), dtype=np.complex128) for i, t in enumerate(times): time_domain[i] = np.sum(intensities * np.exp(1j * 2 * np.pi * freqs * t)) * df return time_domain # 加载并排序数据 df = pd.read_csv(r'C:\Users\lukas\Downloads\Data.txt', sep='\t') df_sorted = df.sort_values(by='Wavelength') intensity = df_sorted['Intensity'].values wavelength = df_sorted['Wavelength'].values frequency = 299792458 / (wavelength * 1e-9) # 计算合理的时间轴 df_avg = np.diff(frequency).mean() max_time = 1 / df_avg time = np.arange(-max_time/2, max_time/2, 1e-15) # 绘制频域图 plt.figure(0) plt.grid() plt.plot(frequency, intensity, 'o') plt.xlabel('频率 (Hz)') plt.ylabel('强度') plt.show() # 执行转换并绘制时域图 time_domain = inverse_fourier_transform(frequency, intensity, time) plt.figure(1) plt.grid() plt.plot(time, np.abs(time_domain), 'o') plt.xlabel('时间 (s)') plt.ylabel('脉冲强度') plt.show()
内容的提问来源于stack exchange,提问作者Schnudrich
相关产品推荐
相关产品推荐

