def _get_curve(self):
"""
No transfer_function correction
:return:
"""
iq_data = self._get_filtered_iq_data() # get iq data (from scope)
if not self.running_state in ["running_single", "running_continuous"]:
self.pyrpl.scopes.free(self.scope) # free scope if not continuous
if self.baseband:
# In baseband, where the 2 real inputs are stored in the real and
# imaginary part of iq_data, we need to make 2 different FFTs. Of
# course, we could do it naively by calling twice fft, however,
# this is not optimal:
# x = rand(10000)
# y = rand(10000)
# %timeit fftpack.fft(x) # --> 74.3 us (143 us with numpy)
# %timeit fftpack.fft(x + 1j*y) # --> 163 us (182 us with numpy)
# A convenient option described in Oppenheim/Schafer p.
# 333-334 consists in taking the right combinations of
# negative/positive/real/imaginary part of the complex fft,
# however, an optimized function for real FFT is already provided:
# %timeit fftpack.rfft(x) # --> 63 us (72.7 us with numpy)
# --> In fact, we will use numpy.rfft insead of
# scipy.fftpack.rfft because the output
# format is directly a complex array, and thus, easier to handle.
fft1 = np.fft.fftpack.rfft(np.real(iq_data),
self.data_length*self.PADDING_FACTOR)
fft2 = np.fft.fftpack.rfft(np.imag(iq_data),
self.data_length*self.PADDING_FACTOR)
cross_spectrum = np.conjugate(fft1)*fft2
res = np.array([abs(fft1)**2,
abs(fft2)**2,
np.real(cross_spectrum),
np.imag(cross_spectrum)])
# at some point, we need to cache the tf for performance
self._last_curve_raw = res # for debugging purpose
return res/abs(self.transfer_function(self.frequencies))**2
else:
# Realize the complex fft of iq data
res = scipy.fftpack.fftshift(scipy.fftpack.fft(iq_data,
self.data_length*self.PADDING_FACTOR))
# at some point we need to cache the tf for performance
self._last_curve_raw = np.abs(res)**2 # for debugging purpose
return self._last_curve_raw/abs(self.transfer_function(
self.frequencies))**2
#/ abs(self.transfer_function(
#self.frequencies))**2
# [self.useful_index()]
评论列表
文章目录