-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapod.py
executable file
·175 lines (166 loc) · 5.95 KB
/
apod.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
####### Apodisations ##########
import numpy as np
def _shifted_apod(N, func, *arg, maxi=0.5, **kw):
"""
generic wrapper which allows to shift any apodisation function
maxi is the location of the maximum point,
ranges from 0 (max at the beginning )
to 0.5 - default (max at the center)
"""
if maxi<0.0 or maxi>0.5:
raise ValueError("maxi should be within [0...0.5]")
size = N
if maxi != 0.5: # if maxi 0.5 -> same size, if 0 -> double size
size = int( size*2*(1-maxi) )
start = size - N
else:
start = 0
# print(start, size)
e = func(size, *arg, **kw)
if start != 0:
e = e[start:]
return e
#-------------------------------------------------------------------------------
def kaiser(N, beta, maxi=0.5):
"""
apply a Kaiser apodisation
beta is a positive number
maxi is the location of the maximum point,
ranges from 0 (max at the beginning )
to 0.5 - default (max at the center)
Kaiser is a versatile general apodisation method.
with maxi = 0.5 (default - means the function is centered) it approximates classical functions:
useful for modulus spectra
beta Window shape
---- ------------
0 Rectangular
5 Similar to a Hamming
6 Similar to a Hanning
8.6 Similar to a Blackman
with maxi<0.5 it allows to generate an apodisation very close to gaussenh()
shaping precisely the maximum and the curvature indepently
for instance for a dataset of 10kHz spectral width and 64k points
kaiser(maxi=0.15, beta=15) and gaussenh(0.5, enhancement=1) are similar
can also be sued to simulate the Kilgour apodisation
"""
return _shifted_apod(N, np.kaiser, beta, maxi=maxi)
#-------------------------------------------------------------------------------
def hamming(N, maxi=0.5):
"""
apply a Hamming apodisation
maxi is the location of the maximum point,
ranges from 0 (max at the beginning )
to 0.5 - default (max at the center)
"""
return _shifted_apod(N, np.hamming, maxi=maxi)
#-------------------------------------------------------------------------------
def hanning(N, maxi=0.5):
"""
apply a Hanning apodisation
maxi is the location of the maximum point,
ranges from 0 (max at the beginning )
to 0.5 - default (max at the center)
"""
return _shifted_apod(N, np.hanning, maxi=maxi)
#-------------------------------------------------------------------------------
def apod_gm(N, gb, specwidth):
"""
apply an gaussian apodisation, gb is in Hz
WARNING : different from common definition of gaussian enhancement
if this is what you need, check the plugin gaussenh()
"""
sw = specwidth
size = N
e = np.exp(-(gb*np.arange(size)/sw)**2)
return e
def gaussenh(N, width, specwidth, enhancement=2.0):
"""
apply an gaussian enhancement, width is in Hz
enhancement is the strength of the effect
multiplies by gauss(width) * exp(-enhancement*width)
"""
sw = specwidth
size = N
baseax = width*np.arange(size)/sw # t/Tau
e = np.exp(enhancement*baseax)
e *= np.exp(-(baseax)**2)
e *= 1.0/np.max(e) # normalize
return e
#-------------------------------------------------------------------------------
def apod_tm(N, tm1, tm2 ):
"""
apply a trapezoide apodisation, lb is in Hz
WARNING : different from common definition of apodisation
This commands applies a trapezoid filter function to the data-
set. The function raises from 0.0 to 1.0 from the first point to
point tm1. The function then stays to 1.0 until point tm2, from which
it goes down to 0.0 at the last point.
if tm2 = -1 nothing is done
"""
size = N
ftm1 = tm1
ftm2 = size-tm2
e = np.ones(size)
e[0:ftm1] = np.linspace(0, 1, ftm1)
if tm2 != -1:
e[tm2:] = np.linspace(1, 0, ftm2)
return e
#-------------------------------------------------------------------------------
def apod_em(N, lb, specwidth):
"""
apply an exponential apodisation, lb is in Hz
WARNING : different from common definition of apodisation
"""
sw = specwidth
size = N
e = np.exp(-lb*np.arange(size)/sw)
return e
#-------------------------------------------------------------------------------
def apod_sq_sin(N, maxi=0.0):
"""
apply a squared sinebell apodisation
maxi ranges from 0 to 0.5
"""
import math as m
if maxi<0.0 or maxi>0.5:
raise ValueError("maxi should be within [0...0.5]")
# compute shape parameters
size = N
s = 2*(1-maxi)
zz = m.pi/((size-1)*s)
yy = m.pi*(s-1)/s #yy has the dimension of a phase
# then draw buffer
e = np.sin( zz*np.arange(size)+yy)**2
return e
#-------------------------------------------------------------------------------
def _apod_sin(N, maxi=0.0):
"""
apply a sinebell apodisation
maxi is the location of the maximum point,
ranges from 0 (max at the beginning == a cosine func)
to 0.5 (max at the center == a sine func)
"""
import math as m
if maxi<0.0 or maxi>0.5:
raise ValueError("maxi should be within [0...0.5]")
# compute shape parameters
size = N
s = 2*(1-maxi)
zz = m.pi/((size-1)*s)
yy = m.pi*(s-1)/s #yy has the dimension of a phase
# then draw buffer
e = np.sin( zz*np.arange(size)+yy)
return e
def apod_sin(N, maxi=0.0):
"""
apply a sinebell apodisation
maxi is the location of the maximum point,
ranges from 0 (max at the beginning == a cosine func)
to 0.5 (max at the center == a sine func)
"""
import math as m
size = N
def lsin(M):
return np.sin(np.linspace(0,np.pi,M))
e = _shifted_apod(N, lsin, maxi=maxi)
return e