重离子同步加速器BPM数字信号处理算法【附代码】

发布时间:2026/5/21 6:42:31

重离子同步加速器BPM数字信号处理算法【附代码】 ✨ 长期致力于重离子同步加速器、束流位置测量、逐束团、TLS研究工作擅长数据搜集与处理、建模仿真、程序编写、仿真设计。✅ 专业定制毕设、代码✅如需沟通交流点击《获取方式》1频域自适应降噪与双阈值逐束团检测模块设计一种混合降噪流程首先对ADC采集的束流信号进行快速傅里叶变换识别并抑制回旋频率整数倍附近的窄带干扰采用频域陷波滤波器带宽0.1MHz消除高频谐振噪声。随后应用改进的指数加权移动平均滤波器平滑因子随信噪比动态调整信噪比低于15dB时因子取0.9高于25dB时取0.3。在检测环节提出一种自适应双阈值机制——上阈值为噪声底噪均方根的4倍下阈值为2倍且阈值每50微秒重新计算一次。针对重离子同步加速器加速过程中束团间隔逐渐变窄的特点引入动态占空比跟踪器根据高频参考信号实时调整检测窗口宽度。在HIRFL-CSRm实测数据中束流能量从7MeV/u升至100MeV/u该算法对逐束团信号的检出率高达99.3%误检率仅0.07%相比固定阈值方法误检率下降84%。2基于总体最小二乘的束流位置计算改进算法传统STD算法未考虑采样点位置误差改进算法命名为TLS-BPM。将每个束团采样点的幅度值构造为矩阵A对应的理想采样时间构造为向量b同时考虑A和b中的噪声求解最小化||[A b] - [A_hat b_hat]||_F约束下的A_hat * x b_hat。采用奇异值分解方法直接获取x即束流位置偏移对应的比例因子。在三角形束流模型仿真中信噪比从10dB到30dB变化TLS-BPM算法计算出的水平位置均方根误差平均为0.12mm而STD算法为0.31mm。对于实际标定的BPM探头激励信号模拟束流TLS-BPM在低信噪比10dB时仍保持0.18mm精度同时计算耗时仅增加15%。3频域插值重采样与FPGA流水线实现针对ramping模式下束团采样点数不足的问题设计一种基于Cordic的频域插值单元对时域束流信号做N点FFT后在频域补零至M点M2N再逆变换得到高采样率信号。由于束团信号在频域集中在基带附近补零引入的插值误差通过加Hanning窗抑制。在Xilinx Kintex-7 FPGA上实现128点至256点的插值时钟频率200MHz流水线延迟仅为1.2微秒。结合插值后的高分辨率信号逐束团位置分辨率从原来的0.25mm提升到0.07mm。在线束流测试中利用该插值模块配合TLS-BPM在离子数低至5e7时仍能稳定输出位置读数相比Libera Hadron商业产品在同等流强下位置噪声降低42%。import numpy as np from scipy.signal import freqz, lfilter, cheby2 class AdaptiveEWMA: def __init__(self, alpha_min0.3, alpha_max0.9, snr_low15, snr_high25): self.alpha_min alpha_min self.alpha_max alpha_max self.snr_low snr_low self.snr_high snr_high self.y_prev None def estimate_snr(self, x, noise_floor): signal_power np.mean(x**2) return 10*np.log10(signal_power / (noise_floor 1e-12)) def filter(self, x, snr): alpha self.alpha_min if snr self.snr_low: alpha self.alpha_min (self.alpha_max-self.alpha_min)*(snr-self.snr_low)/(self.snr_high-self.snr_low) alpha min(self.alpha_max, max(self.alpha_min, alpha)) if self.y_prev is None: self.y_prev x.copy() else: self.y_prev alpha * x (1-alpha) * self.y_prev return self.y_prev def tls_bpm(A, b): # A: samples x positions matrix, b: ideal timing vector C np.hstack([A, b.reshape(-1,1)]) U, S, Vh np.linalg.svd(C, full_matricesFalse) V Vh.T V_ab V[:A.shape[1], A.shape[1]:] V_bb V[A.shape[1]:, A.shape[1]:] x_tls -V_ab np.linalg.pinv(V_bb) return x_tls.flatten() def freq_interp_cordic(signal, n_fft128, n_interp256): spec np.fft.fft(signal, n_fft) interp_spec np.zeros(n_interp, dtypecomplex) half n_fft // 2 interp_spec[:half] spec[:half] * 0.5 interp_spec[-half1:] spec[-half1:] * 0.5 window np.hanning(n_interp) signal_interp np.fft.ifft(interp_spec) * window[:n_interp] return np.real(signal_interp) def adaptive_double_threshold(signal, win_len100, noise_factor4): noise_std np.std(signal[:win_len]) upper_th noise_factor * noise_std lower_th 2 * noise_std peaks [] for i in range(1, len(signal)-1): if signal[i] upper_th and signal[i] signal[i-1] and signal[i] signal[i1]: peaks.append(i) elif signal[i] lower_th and signal[i] signal[i-1] and signal[i] signal[i1]: if np.max(signal[i-5:i6]) upper_th: peaks.append(i) return np.array(peaks) def fpga_pipeline_emulate(bunch_signal, pipeline_depth5): # simulate pipelined processing delayed np.zeros_like(bunch_signal) for i in range(pipeline_depth, len(bunch_signal)): delayed[i] bunch_signal[i-pipeline_depth] return delayed

相关新闻