-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdefine_LUTs.py
More file actions
80 lines (71 loc) · 3.33 KB
/
Copy pathdefine_LUTs.py
File metadata and controls
80 lines (71 loc) · 3.33 KB
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
import numpy as np
class roach_LUT(object):
def __init__(self):
self.test_comb = np.linspace(-150.01213e6, 150.021234e6, 80)
self.test_comb = np.roll(self.test_comb, - np.argmin(np.abs(self.test_comb)) - 1)
self.dac_samp_freq = 512.0e6
self.fpga_samp_freq = 256.0e6
self.test_freq = np.array([-50.0125]) * 1.0e6
self.LUTbuffer_len = 2**21
self.dac_freq_res = self.dac_samp_freq/self.LUTbuffer_len
self.fft_len = 1024
def fft_bin_index(self, freqs, fft_len, samp_freq):
# returns the fft bin index for a given frequency, fft length, and sample frequency
return np.round((freqs/samp_freq)*fft_len).astype('int')
def freq_comb(self, freqs, samp_freq, resolution,phase = np.array([0.]*1000), random_phase = True, DAC_LUT = True, amplitudes = np.array([1.]*1000)):
# Generates a frequency comb for the DAC or DDS look-up-tables. DAC_LUT = True for the DAC LUT. Returns I and Q
freqs = np.round(freqs/self.dac_freq_res)*self.dac_freq_res
amp_full_scale = (2**15 - 1)
np.random.seed()
if DAC_LUT:
fft_len = self.LUTbuffer_len
bins = self.fft_bin_index(freqs, fft_len, samp_freq)
#print "dac bins =", bins
phase = np.random.uniform(0., 2.*np.pi, len(bins))
self.spec = np.zeros(fft_len,dtype='complex')
amps = np.array([1.]*len(bins))
self.spec[bins] = amps*np.exp(1j*(phase))
wave = np.fft.ifft(self.spec)
waveMax = np.max(np.abs(wave))
I = (wave.real/waveMax)*(amp_full_scale)
Q = (wave.imag/waveMax)*(amp_full_scale)
else:
fft_len = (self.LUTbuffer_len/self.fft_len)
bins = self.fft_bin_index(freqs, fft_len, samp_freq)
#print "dds bins =", bins
self.dds_spec = np.zeros(fft_len,dtype='complex')
amps = np.array([1.]*len(bins))
self.dds_spec[bins] = amps*np.exp(1j*(phase))
wave = np.fft.ifft(self.dds_spec)
waveMax = np.max(np.abs(wave))
I = (wave.real/waveMax)*(amp_full_scale)
Q = (wave.imag/waveMax)*(amp_full_scale)
return I, Q
def select_bins(self, freqs):
bins = self.fft_bin_index(freqs, self.fft_len, self.dac_samp_freq)
bin_freqs = bins*self.dac_samp_freq/self.fft_len
bins[ bins < 0 ] += 1024
for i in range(len(freqs)):
if (freqs[i] < 0) and (freqs[i]+ 512.0e6 >= 511.75e6):
bins[i] = 1023
print bins
self.freq_residuals = np.round((freqs - bin_freqs)/self.dac_freq_res)*self.dac_freq_res
return
def define_DDS_LUT(self,freqs):
self.select_bins(freqs)
I_dds, Q_dds = np.array([0.]*(self.LUTbuffer_len)), np.array([0.]*(self.LUTbuffer_len))
for m in range(len(self.freq_residuals)):
I, Q = self.freq_comb(np.array([self.freq_residuals[m]]), self.fpga_samp_freq/(self.fft_len/2.), self.dac_freq_res, random_phase = False, DAC_LUT = False)
I_dds[m::1024] = I
Q_dds[m::1024] = Q
return I_dds, Q_dds
def make_luts(self, freqs):
self.I_dac, self.Q_dac = self.freq_comb(freqs, self.dac_samp_freq, self.dac_freq_res, amplitudes = np.array([1.]*1000), random_phase = True)
self.I_dds, self.Q_dds = self.define_DDS_LUT(freqs)
return
def main(self):
self.make_luts(self.test_comb)
return
if __name__=='__main__':
LUT = roach_LUT()
LUT.main()