Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
M
mbtrack2
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
PA
Collective Effects
mbtrack2
Commits
f8dc995f
Commit
f8dc995f
authored
4 months ago
by
lu.zhao@synchrotron-soleil.fr
Browse files
Options
Downloads
Patches
Plain Diff
add code comments to class PhaseNoiseGenerator
parent
5f29cbb1
Branches
Branches containing commit
No related tags found
1 merge request
!37
Feature feedback iq damper0
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
mbtrack2/tracking/noise.py
+45
-40
45 additions, 40 deletions
mbtrack2/tracking/noise.py
with
45 additions
and
40 deletions
mbtrack2/tracking/noise.py
+
45
−
40
View file @
f8dc995f
...
...
@@ -2,32 +2,32 @@ import numpy as np
class
PhaseNoiseGenerator
:
"""
用于生成相位噪声序列的示例类。
可以根据需求定义不同类型的噪声模型:
-
白噪声
- 1/f
噪声
-
由给定
PSD(Phase Noise Spectrum)
生成时域噪声
-
等等
Example class for generating phase noise sequences.
Different types of noise models can be defined as needed:
-
White noise
- 1/f
noise
-
Time-domain noise generated from a given
PSD
(Phase Noise Spectrum)
-
Etc.
Parameters
----------
fs : float
采样频率 (若需要离线一次性生成整条噪声序列
)
Sampling frequency (if generating the entire noise sequence offline at once
)
n_samples : int
需要一次性生成多少点的噪声 (也可不固定
)
Number of noise points to generate at once (can also be non-fixed
)
noise_amplitude : float
噪声幅度因子(可理解为标准差或用于标定噪声大小
)
Noise amplitude factor (can be understood as the standard deviation or used to calibrate noise magnitude
)
model : str
噪声模型类型,可自定义
"
white
"
,
"
1/f
"
,
"
custom_psd
"
等
Type of noise model, customizable as
"
white
"
,
"
1/f
"
,
"
custom_psd
"
, etc.
custom_psd : array-like, optional
用户自定义相位噪声谱密度(若需要
)
User-defined phase noise power spectral density (if needed
)
freq_vector : array-like, optional
对应
custom_psd
的频率坐标
Frequency coordinates corresponding to
custom_psd
Usage
-----
1.
i
nit PhaseNoiseGenerator(fs, n_samples, noise_amplitude, ...)
2.
在每一次跟踪/每一圈调用
generate_noise()
获取噪声值(或序列
)
1.
I
nit
ialize
PhaseNoiseGenerator(fs, n_samples, noise_amplitude, ...)
2.
Call
generate_noise()
during each tracking step/turn to get noise values (or sequences
)
"""
def
__init__
(
self
,
...
...
@@ -44,9 +44,9 @@ class PhaseNoiseGenerator:
self
.
custom_psd
=
custom_psd
self
.
freq_vector
=
freq_vector
#
如果要一次性离线生成,可以在这里生成整条时间序列
#
if generated_noise offline, generate it here
self
.
generated_noise
=
None
self
.
index
=
0
#
用于记录当前取到哪一个采样点
self
.
index
=
0
#
record the current sample point
if
model
==
"
white
"
:
self
.
_generate_white_noise
()
...
...
@@ -55,11 +55,11 @@ class PhaseNoiseGenerator:
elif
model
==
"
custom_psd
"
and
(
custom_psd
is
not
None
):
self
.
_generate_custom_psd_noise
()
else
:
#
默认白噪声
#
default to white noise if model is not recognized
self
.
_generate_white_noise
()
def
_generate_white_noise
(
self
):
"""
简单白噪声生成
"""
"""
wite noise generation
"""
self
.
generated_noise
=
np
.
random
.
normal
(
loc
=
0.0
,
scale
=
self
.
noise_amplitude
,
...
...
@@ -67,63 +67,68 @@ class PhaseNoiseGenerator:
)
def
_generate_1overf_noise
(
self
):
"""
1/f
噪声生成(示例:通过频域滤波实现)
"""
#
频域产生白噪声
"""
1/f
noise generation by filter in frequement domain
"""
#
white noise generation in frequency domain
white
=
np
.
fft
.
rfft
(
np
.
random
.
normal
(
0.0
,
1.0
,
self
.
n_samples
)
)
freqs
=
np
.
fft
.
rfftfreq
(
self
.
n_samples
,
1.0
/
self
.
fs
)
#
对应
~ 1/f
滤波
# ~ 1/f
filtering
H
=
1.0
/
(
freqs
+
1e-6
)
colored
=
white
*
H
#
逆变换回时域
#
transform back to time domain
out
=
np
.
fft
.
irfft
(
colored
,
n
=
self
.
n_samples
)
#
调整幅度
#
adjust amplitude to user specified level
out
=
out
/
np
.
std
(
out
)
*
self
.
noise_amplitude
self
.
generated_noise
=
out
def
_generate_custom_psd_noise
(
self
):
"""
根据用户给定的相位噪声谱密度 custom_psd 生成时域噪声(示例)。
这里假设
custom_psd
和
freq_vector
二者长度相同,
并且
freq_vector[0]
对应
DC
,
freq_vector[-1]
对应最高频。
according to the user-defined phase noise power spectral density custom_psd to generate time-domain noise (example).
Here, it is assumed that
custom_psd
and
freq_vector
are of the same length,
and
freq_vector[0]
corresponds to
DC
,
freq_vector[-1]
corresponds to the highest frequency.
"""
# 频域内生成符合 PSD 的随机相位
phase_random
=
np
.
random
.
uniform
(
0
,
2
*
np
.
pi
,
len
(
self
.
custom_psd
))
# 幅度 = sqrt(PSD * 带宽),此处带宽 ~ freq_vector 间隔(简化处理)
# generate random phase in frequency domain
phase_random
=
np
.
random
.
uniform
(
0
,
2
*
np
.
pi
,
len
(
self
.
custom_p
# amplitude = np.sqrt(self.custom_psd * df) df = bandwidth = (freq_vector[-1] - freq_vector[0]) / (len(freq_vector)-1)
df
=
(
self
.
freq_vector
[
-
1
]
-
self
.
freq_vector
[
0
])
/
(
len
(
self
.
freq_vector
)
-
1
)
amplitude
=
np
.
sqrt
(
self
.
custom_psd
*
df
)
# 简化近似
freq_domain_signal
=
amplitude
*
np
.
exp
(
1j
*
phase_random
)
# 如果需要对称频谱,可拼接负频部分
# 这里仅演示正频部分,实际需要根据具体情况做镜像
# if need to be symmetric, add negative frequency part
# here we assume the custom_psd is symmetric, so we can just mirror the positive frequency part to negative frequency part
# ...
#
逆
FFT
得到时域信号
#FFT
to time domain
time_domain_signal
=
np
.
fft
.
irfft
(
freq_domain_signal
,
n
=
self
.
n_samples
)
#
调整幅度到用户指定量级
#
ajuste amplitude to user specified level
time_domain_signal
=
time_domain_signal
/
np
.
std
(
time_domain_signal
)
*
self
.
noise_amplitude
self
.
generated_noise
=
time_domain_signal
def
generate_noise
(
self
,
size
=
1
):
"""
每次调用,返回 size 个噪声点(默认 1 个)。
如果一次性生成的序列用完了,就再次生成(或循环使用)。
return size of noise points (default 1).
if the sequence generated at once is used up, generate again (or loop).
Returns
-------
float or np.ndarray
返回相位噪声值(单位:弧度),可直接加到 cavity 或 generator 相位上。
returns phase noise value (in radians), can be directly added to cavity or generator phase.
Examples
--------
>>>
noise
=
PhaseNoiseGenerator
(
fs
=
1.0e5
,
n_samples
=
1024
,
noise_amplitude
=
1e-3
)
>>>
noise
.
generate_noise
()
"""
if
self
.
generated_noise
is
None
:
#
如果用户没有事先离线生成,就临时生成白噪声
#
if not defined, generate white noise
val
=
np
.
random
.
normal
(
0.0
,
self
.
noise_amplitude
,
size
=
size
)
return
val
if
size
>
1
else
val
[
0
]
#
如果已离线生成
#
if pre-generated noise is used up, generate again or loop
if
self
.
index
+
size
<=
self
.
n_samples
:
val
=
self
.
generated_noise
[
self
.
index
:
self
.
index
+
size
]
self
.
index
+=
size
else
:
#
若越界,重新生成或循环
#
loop back to the beginning of the generated noise sequence
self
.
index
=
0
val
=
self
.
generated_noise
[
self
.
index
:
self
.
index
+
size
]
self
.
index
+=
size
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment