Commit c361ab42 authored by Nicolas Nunez Barreto's avatar Nicolas Nunez Barreto

agrego meds de modos

parent 023ded66
This source diff could not be displayed because it is too large. You can view the blob instead.
# -*- coding: utf-8 -*-
"""
CYthon Impel,entation
"""
# https://cython.readthedocs.io/en/latest/src/tutorial/cython_tutorial.html
def optimal_param(float frequency_obj):
cdef long frequency_sample = 250_000_000
cdef float frequency = 0
cdef float delta = frequency_obj
cdef int n, N, k
cdef int n_o, N_o, k_o
# cdef int n_2, N_2, k_2
cdef bint next_break
n_o, N_o, k_o = 0,0,0
# n_2, N_2, k_2 = 0,0,0
for n in range(10,1024):
next_break = False
for k in range(1,1000):
if next_break:
break
if frequency_sample*1024/(n*k) < frequency_obj:
next_break = True
N = int(round(n*k*frequency_obj/frequency_sample))
if N<1 or n/N<10:
continue
frequency = frequency_sample*N/(n*k)
if abs(frequency-frequency_obj) < delta :
delta = abs(frequency-frequency_obj)
n_o, N_o, k_o = n, N, k
frequency = frequency_sample*N_o/(n_o*k_o)
return frequency, n_o, N_o, k_o
def optimal_param3(float frequency_obj):
cdef long frequency_sample = 250_000_000
cdef float frequency = 0
cdef float delta = frequency_obj
cdef int n, N, k
cdef int n_o, N_o, k_o
# cdef int n_2, N_2, k_2
cdef bint next_break
n_o, N_o, k_o = 0,0,0
# n_2, N_2, k_2 = 0,0,0
for n in range(10,1005):
next_break = False
for k in range(1,1000):
if next_break:
break
if frequency_sample*1024/(n*k) < frequency_obj:
next_break = True
N = int(round(n*k*frequency_obj/frequency_sample))
if N<1 or n/N<10:
continue
frequency = frequency_sample*N/(n*k)
if abs(frequency-frequency_obj) < delta :
delta = abs(frequency-frequency_obj)
n_o, N_o, k_o = n, N, k
frequency = frequency_sample*N_o/(n_o*k_o)
return frequency, n_o, N_o, k_o
def optimal_param2(float frequency_obj):
cdef long frequency_sample = 250_000_000
cdef float frequency = 0
cdef float delta = frequency_obj
cdef int n, N, k
cdef int n_o, N_o, k_o
cdef int n_2, N_2, k_2
cdef int n_3, N_3, k_3
cdef float frequency1 = 0
cdef float frequency2 = 0
cdef float frequency3 = 0
cdef bint next_break
n_o, N_o, k_o = 0,0,0
n_2, N_2, k_2 = 0,0,0
n_3, N_3, k_3 = 0,0,0
for n in range(10,1024):
next_break = False
for k in range(1,1000):
if next_break:
break
if frequency_sample*1024/(n*k) < frequency_obj:
next_break = True
# print(n,k, int(round(n*k*frequency_obj/frequency_sample)) )
N = int(round(n*k*frequency_obj/frequency_sample))
if N<1 or n/N<10:
continue
frequency = frequency_sample*N/(n*k)
if abs(frequency-frequency_obj) <= delta :
delta = abs(frequency-frequency_obj)
n_3, N_3, k_3, frequency3 = n_2, N_2, k_2, frequency2
n_2, N_2, k_2, frequency2 = n_o, N_o, k_o, frequency1
n_o, N_o, k_o, frequency1 = n, N, k, frequency
#frequency = frequency_sample*N_o/(n_o*k_o)
return frequency1, n_o, N_o, k_o, frequency2, n_2, N_2, k_2, frequency3, n_3, N_3, k_3
#%% Version con tolerancia que devuelve vectores largos
from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free
def optimal_param_tol(float frequency_obj, float tolerance):
cdef long frequency_sample = 250_000_000
cdef double frequency = 0
cdef int n, N, k
cdef bint next_break
# cdef int i
# # allocate number * sizeof(double) bytes of memory
# cdef double *my_array = <double *> malloc(
# number * sizeof(double))
# if not my_array:
# raise MemoryError()
# try:
# ran = random.normalvariate
# for i in range(number):
# my_array[i] = ran(0, 1)
# # ... let's just assume we do some more heavy C calculations here to make up
# # for the work that it takes to pack the C double values into Python float
# # objects below, right after throwing away the existing objects above.
# return [x for x in my_array[:number]]
# finally:
# # return the previously allocated memory to the system
# free(my_array)
cdef int* n_o
cdef int* N_o
cdef int* k_o
cdef double* frequencies
cdef int* mem_tmp
cdef double* mem_tmp2
n_o = <int*> PyMem_Malloc( 1000 * sizeof(int) )
if not n_o:
raise MemoryError("mem for n_o could not be allocated")
N_o = <int*> PyMem_Malloc( 1000 * sizeof(int) )
if not N_o:
raise MemoryError("mem for N_o could not be allocated")
k_o = <int*> PyMem_Malloc( 1000 * sizeof(int) )
if not k_o:
raise MemoryError("mem for k_o could not be allocated")
frequencies = <double*> PyMem_Malloc( 1000 * sizeof(double) )
if not frequencies:
raise MemoryError("mem for frequencies could not be allocated")
# cdef int[1000] n_o
# cdef int[1000] N_o
# cdef int[1000] k_o
# cdef float[1000] frequencies
cdef int i = 0
cdef int max_i = 1000
try:
# finally:
# # return the previously allocated memory to the system
# free(my_array)
for n in range(10,1024):
next_break = False
for k in range(1,1000):
if next_break:
break
if frequency_sample*1024/(n*k) < frequency_obj:
next_break = True
N = int(round(n*k*frequency_obj/frequency_sample))
if N<1 or n/N<10:
continue
frequency = frequency_sample*N/(n*k)
if abs(frequency-frequency_obj) < tolerance :
n_o[i] = n
k_o[i] = k
N_o[i] = N
frequencies[i] = frequency
i += 1
if i >- max_i:
max_i += 1000
mem_tmp = <int*> PyMem_Realloc( n_o, max_i * sizeof(int))
if not mem_tmp:
raise MemoryError()
n_o = mem_tmp
mem_tmp = <int*> PyMem_Realloc( k_o, max_i * sizeof(int))
if not mem_tmp:
raise MemoryError()
k_o = mem_tmp
mem_tmp = <int*> PyMem_Realloc( N_o, max_i * sizeof(int))
if not mem_tmp:
raise MemoryError()
N_o = mem_tmp
mem_tmp2 = <double*> PyMem_Realloc( frequencies, max_i * sizeof(double))
if not mem_tmp2:
raise MemoryError()
frequencies = mem_tmp2
#return frequencies, n_o, N_o, k_o
return [x for x in frequencies[:i]]
finally:
# return the previously allocated memory to the system
PyMem_Free(n_o)
PyMem_Free(N_o)
PyMem_Free(k_o)
PyMem_Free(frequencies)
#
#def optimal_param(float frequency_obj):
#
# cdef long frequency_sample = 250_000_000
# cdef float frequency = 0
#
# cdef float delta = frequency_obj
#
# cdef int n, N, k
# cdef int n_o, N_o, k_o
#
# cdef bint next_break
#
# n_o, N_o, k_o = 0,0,0
#
#
# for n in range(10,1024):
# next_break = False
# for k in range(1,1000):
# if next_break:
# break
#
# if frequency_sample*1024/(n*k) < frequency_obj:
# next_break = True
#
# N = int(round(n*k*frequency_obj/frequency_sample))
#
# if N<1:
# continue
#
# frequency = frequency_sample*N/(n*k)
#
# if abs(frequency-frequency_obj) < delta :
# delta = abs(frequency-frequency_obj)
# n_o, N_o, k_o = n, N, k
#
#
# return frequency, n_o, N_o, k_o
#
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize("freq_syn.pyx")
)
# -*- coding: utf-8 -*-
"""
cuentas varias
Algo de info
4 channels of DDS at 1GS/s.
Output frequency from <1 to >400 MHz / 0.25 mHz resolution (para AD9910)
maximum output power of each channel 10dBm
attenuation from 0 to -31.5 dB (digital)
RF switches, 1ns temporal resolution / 70 dB isolation
El DDS es el AD9910
Tiene modulacion de amplitud por block-ram
Entiendo que el IO update del RAM es de 4 ns en este caso
"""
from numpy import *
import matplotlib.pyplot as plt
from time import time
#%% modo bruto
sample_time = 4e-9 # 4 ns
frequency_sample = round(1/sample_time)
frequency_obj = 987654.0 # frecuencia objetivo en el orden del MHz
frequency_real = 0
k = 1 # sample_time multiplier
n = 10 # memory sample length used
N = 3 # Number of periods written in the n samples.
ratio = frequency_sample/frequency_obj
tiempos = []
for _ in range(20):
frequency_obj += random.normal(size=1)[0]
ratio = frequency_sample/frequency_obj
t0 = time()
rta = list(
[ (n*k/N , n,k,N ) for n in range(10,1024)
for N in range(1,int(n/10))
for k in range(1,100)
if abs(n*k/N-ratio)<=1 ]
)
tiempos.append( time()-t0 )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
rta
#%% modo N estimado
sample_time = 4e-9 # 4 ns
frequency_sample = round(1/sample_time)
frequency_obj = 987654.0 # frecuencia objetivo en el orden del MHz
frequency_real = 0
k = 1 # sample_time multiplier
n = 10 # memory sample length used
N = 3 # Number of periods written in the n samples.
random.seed(0)
ratio = frequency_sample/frequency_obj
def optimal_params(frequency_obj,tolerance=1):
ratio = frequency_sample/frequency_obj
rta = []
for n in range(10,1024):
for k in range(1,100):
N = int(round(n*k/ratio))
if N<1:
continue
if abs(n*k/N - ratio) < tolerance:
rta.append( ( n*k/N , n, k , N ) )
return rta
tiempos = []
for _ in range(20):
frequency_obj_tmp = frequency_obj + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_params(frequency_obj_tmp, tolerance=0.01)
tiempos.append( time()-t0 )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
# rta
#%% modo N estimado y k estimado
sample_time = 4e-9 # 4 ns
frequency_sample = round(1/sample_time)
frequency_obj = 987654.0 # frecuencia objetivo en el orden del MHz
frequency_real = 0
k = 1 # sample_time multiplier
n = 10 # memory sample length used
N = 3 # Number of periods written in the n samples.
random.seed(0)
ratio = frequency_sample/frequency_obj
def optimal_params(frequency_obj,tolerance=1):
ratio = frequency_sample/frequency_obj
rta = []
for n in range(10,1024):
for k in range(1,1000):
if n*k/1024 > ratio:
print(k)
break
N = int(round(n*k/ratio))
if N<1:
continue
if abs(n*k/N - ratio) < tolerance:
rta.append( ( n*k/N , n, k , N ) )
return rta
tiempos = []
for _ in range(20):
frequency_obj_tmp = frequency_obj + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_params(frequency_obj_tmp, tolerance=0.01)
tiempos.append( time()-t0 )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
# rta
#%% Cython import
import pyximport;
pyximport.install(reload_support=True)
from importlib import reload
# pyximport.install()
# from freq_syn import optimal_param
import freq_syn
reload(freq_syn)
optimal_param = freq_syn.optimal_param
optimal_param(999654)
frequency_obj = 987654
tiempos = []
for _ in range(20):
frequency_obj_tmp = frequency_obj + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_param(frequency_obj_tmp)
tiempos.append( time()-t0 )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
#%% PRUEBA Cython y armado de grafico de error
import pyximport;
pyximport.install(reload_support=True)
from importlib import reload
# pyximport.install()
# from freq_syn import optimal_param
import freq_syn
reload(freq_syn)
optimal_param = freq_syn.optimal_param
frequency_obj = []
frequency = []
random.seed(0)
tiempos = []
for frec in range(1_000_000-1000,1_000_000+1000):
# frequency_obj_tmp = + random.normal(size=1)[0]/100
frec = frec + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_param(frec)
tiempos.append( time()-t0 )
frequency_obj.append( frec )
frequency.append( rta[0] )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
#%%
frequency_obj, frequency = array(frequency_obj), array(frequency)
fig, ax = plt.subplots( 1,1, figsize=(10,7) , constrained_layout=True )
ax.plot(frequency_obj-1e6, abs(frequency-frequency_obj) , '-', alpha=0.3, color='C0')
ax.plot(frequency_obj-1e6, abs(frequency-frequency_obj) , 'o', alpha=0.7, color='C0')
#plt.plot(frequency_obj, frequency, '.-')
ax.semilogy()
ax.grid(b=True,linestyle='-',color='lightgray')
ax.grid(b=True,linestyle=':',color='lightgray', which='minor')
ax.set_xlabel('$\Delta$f (@1MHz ) [Hz]')
ax.set_ylabel('error [Hz]')
fig.suptitle("error de frecuencias generados con freq_syn.optimal_param()")
# fig.savefig("freq_syn.optimal_param.png")
#%% PRUEBA Cython varias freq
import pyximport;
pyximport.install(reload_support=True)
from importlib import reload
# pyximport.install()
# from freq_syn import optimal_param
import freq_syn
reload(freq_syn)
optimal_param2 = freq_syn.optimal_param2
frequency_obj = []
dat = []
random.seed(0)
tiempos = []
for frec in range(1_000_000-100,1_000_000+100):
# frequency_obj_tmp = + random.normal(size=1)[0]/100
frec = frec + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_param2(frec)
tiempos.append( time()-t0 )
frequency_obj.append( frec )
dat.append( rta )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
# dat = array(dat)
# frequency1, n_o, N_o, k_o, frequency2, n_2, N_2, k_2, frequency3, n_3, N_3, k_3
#%% Ejemplo de ordenamiento
import pyximport;
pyximport.install(reload_support=True)
from importlib import reload
# pyximport.install()
# from freq_syn import optimal_param
import freq_syn
reload(freq_syn)
optimal_param2 = freq_syn.optimal_param2
frequency_obj = []
dat = []
random.seed(0)
tiempos = []
for frec in range(1_000_000-100,1_000_000+100):
# frequency_obj_tmp = + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_param2(frec)
tiempos.append( time()-t0 )
frequency_obj.append( frec )
dat.append( rta )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
#%%
def test_fail(x):
if int(x-1) & 840 == 840:
return True
if int(x-1) & 900 == 900:
return True
barrido = []
for d in dat:
frequency1, n_o, N_o, k_o, frequency2, n_2, N_2, k_2, frequency3, n_3, N_3, k_3 = d
if not test_fail(N_o):
barrido.append( (frequency1, n_o, N_o, k_o) )
elif not test_fail(N_o)
#%% PRUEBA Cython con tolerancia
import pyximport;
pyximport.install(reload_support=True)
from importlib import reload
# pyximport.install()
# from freq_syn import optimal_param
import freq_syn
reload(freq_syn)
optimal_param_tol = freq_syn.optimal_param_tol
# frequency, n, N, k = optimal_param_tol(987654,1)
optimal_param_tol(997659,10)
frequency_obj = []
frequency = []
random.seed(0)
tiempos = []
for frec in range(1_000_000-10,1_000_000+10):
# frequency_obj_tmp = + random.normal(size=1)[0]/100
frec = frec + random.normal(size=1)[0]/100
t0 = time()
rta = optimal_param_tol(frec,1)
tiempos.append( time()-t0 )
frequency_obj.append( frec )
frequency.append( rta )
print('.', end='')
print("")
#print(f"time: {round(time()-t0,3)}")
print(f"{round(mean(tiempos),3)} +- {std(tiempos)}")
#%% Resolucion vs frecuencia
frecuencias = 1/(arange(1,10000)*4e-9)
paso = diff(frecuencias)
paso = abs(array( paso.tolist() + [paso[-1]]))
fig, ax = plt.subplots( 1,1, figsize=(10,7) , constrained_layout=True )
ax.plot(frecuencias, paso , '.-' )
ax.semilogx()
ax.semilogy()
ax.grid(b=True,linestyle='-',color='lightgray')
ax.grid(b=True,linestyle=':',color='lightgray', which='minor')
ax.set_xlabel('frecuencia [Hz]')
ax.set_ylabel('paso [Hz]')
ax.set_xlim(500e3,2e6)
#%% frecuencias fabricables
# Para cada largo temporal, calculo 10 armónicos
fig, ax = plt.subplots( 1,1, figsize=(10,7) , constrained_layout=True )
frecs = []
for steps in arange(100,1024):
frecs += [ nn/(steps*4e-9) for nn in arange(1,10) ]
frecuencias = array(unique(array(frecs).astype(int)))
paso = diff(frecuencias)
paso = abs(array( paso.tolist() + [paso[-1]]))
ax.plot(frecuencias, paso , '.', alpha=0.6 )
ax.semilogx()
ax.semilogy()
ax.grid(b=True,linestyle='-',color='lightgray')
ax.grid(b=True,linestyle=':',color='lightgray', which='minor')
ax.set_xlabel('frecuencia [Hz]')
ax.set_ylabel('paso [Hz]')
ax.set_xlim(100e3,ax.get_xlim()[1])
#ax.set_ylim(100,10000)
#%% frecuencias fabricables
# Mejoro la estrategia probando para diferentes tiempos
f_inicio = 100e3 # frecuecia de inicio
f_fin = 2e6 # frecuencia final
# step es el numero de ticks de reloj entre muestras de amplitud
# large es el largo del vector de muestras
dd = []
for large in arange(1024,10,-1):
# frecuencias
for step in arange(1,2**16-1):
armonico_final = int(floor(large*step*4e-9*f_fin))
armonico_inicio = int(ceil(large*step*4e-9*f_inicio))
# Protección para que cada armónico tenga varios puntos por periodo
armonico_final = min( armonico_final , int(large/10) )
armonico_inicio = min( armonico_inicio , int(large/10) )
dd += [ [ int(round(armonico/(step*4e-9*large))), large, step, armonico ]
for armonico in arange(armonico_inicio,armonico_final) ]
print(large)
if len(dd)>1:
_,II = unique( array(dd)[:,0] , return_index=True)
dd = array(dd)[II].tolist()
#savez('barrido_freq2.npz',dd=dd)
# Formato:
# [frec en HZ, largo vector, step en clks , nro de armonico]
#%% Graficar paso vs frec para multiples parametros
fig, ax = plt.subplots( 1,1, figsize=(10,7) , constrained_layout=True )
dd = load('../barrido_freq2.npz')['dd']
from matplotlib import cm
frecuencias = dd[:,0]
paso = diff(frecuencias)
paso = abs(array( paso.tolist() + [paso[-1]]))
#ax.plot(frecuencias, paso , '.', alpha=0.6 )
aa= ax.scatter(frecuencias, paso , c=dd[:,2] , s=2, alpha=0.8 ,
cmap='jet', norm=cm.colors.LogNorm(vmin=dd[:,2].min(), vmax=dd[:,2].max()) )
ax.semilogx()
ax.semilogy()
ax.grid(b=True,linestyle='-',color='lightgray')
ax.grid(b=True,linestyle=':',color='lightgray', which='minor')
ax.set_xlabel('frecuencia [Hz]')
ax.set_ylabel('paso [Hz]')
ax.set_xlim(100e3,ax.get_xlim()[1])
#ax.set_ylim(100,10000)
cb = plt.colorbar(aa)
cb.set_label('step')
#%% Analisis con PANDAS
import pandas as pd
dd = load('../barrido_freq2.npz')['dd']
cols = 'freq large step armonico'.split()
df = pd.DataFrame(dd, columns = cols )
fig, ax = plt.subplots( 1,1, figsize=(7,7) , constrained_layout=True )
aa = ax.matshow(df.corr())
plt.colorbar(aa)
for aa in [ax.xaxis, ax.yaxis]:
aa.set_ticks( arange(len(cols)) )
aa.set_ticklabels( cols )
#
#ax.set_xticklabels( cols )
#ax.set_yticklabels( cols )
......@@ -160,11 +160,12 @@ class AD9910RAM(EnvExperiment):
self.create_applets()
for ind,am_freq in enumerate(sequence):
# t0 = time() ; jj=0
t0 = time() #; jj=0
# print(f"{jj}: {time()-t0}") ; jj += 1
# print(f"4step time: {round(time()-t0,2)}")
parameters = get_urukul_params( am_freq )
# print(f"5step time: {round(time()-t0,2)}")
frec, num_samples, clock_step, n_harmonic = parameters
modulation = get_urukul_array(frec, num_samples, n_harmonic)
......@@ -183,6 +184,7 @@ class AD9910RAM(EnvExperiment):
# data = data + [0]*10
# self.fix = True
for ii in range(len(data)):
#print(len(data))
self.data[ii] = data[ii]
# print(self.data)
......@@ -194,20 +196,24 @@ class AD9910RAM(EnvExperiment):
try:
# print(f"6step time: {round(time()-t0,2)}")
self.run_kernel()
# print(f"7step time: {round(time()-t0,2)}")
except:
print("HUBO UNA FALLA DEL run_kernel()")
self.fix = True
data = data + [0]*10
if len(data)<1024-10:
self.fix = True
data = data + [0]*10
for ii in range(len(data)):
self.data[ii] = data[ii]
self.run_kernel()
for ii in range(len(data)):
self.data[ii] = data[ii]
self.run_kernel()
self.mutate_dataset("error_freq", ind, 1 )
sleep(self.scan_time_step)
print(f"step time: {round(time()-t0,2)}")
print("FFIIINNN")
......
from artiq.experiment import * #Imports everything from experiment library
from artiq.coredevice.ad9910 import ( #Imports RAM destination amplitude scale factor and RAM mode bidirectional ramp methods from AD9910 Source
RAM_DEST_ASF, RAM_MODE_BIDIR_RAMP, RAM_MODE_CONT_RAMPUP)
from numpy import load,sin,linspace,pi,array
import numpy as np
from time import sleep,time
# This code demonstrates use of the urukul RAM.
# It produces a 50 MHz square waveform attenuated
# import pyximport;
# # pyximport.install(reload_support=True)
# # from importlib import reload
# pyximport.install()
from freq_syn import optimal_param, optimal_param2, optimal_param3
# import freq_syn
# reload(freq_syn)
# optimal_param = freq_syn.optimal_param
def test_fail(x):
if int(x-1) & 840 == 840:
return True
if int(x-1) & 900 == 900:
return True
def get_urukul_array(frec: TInt32, num_samples: TInt32, n_harmonic: TInt32) -> list :
"""
get the array values for AM modulation in urukul for the frequency f0
params:
f0 (float): frequency to set on AM
"""
xx = linspace(0, 2*pi*n_harmonic, num=num_samples, endpoint=False)
modulation = sin(xx)
return modulation.tolist()
def convert_amp_to_data(amp):
"""
takes amp values (from 0 to 1) and returns data values (suitable for DDS load)
"""
MAX = 2**9-1
# N = 10
# if not iterable(amp):
# amp = [amp]
# return list([ int(round(val*MAX)) << 23 for val in amp ])
return list([ int(round(val*MAX)) for val in amp ])
class AD9910RAM(EnvExperiment):
'''Amplitude Modulation SCAN (V2)'''
def build(self): #this code runs on the host computer
self.setattr_device("core") #sets core device drivers as attributes
self.setattr_device("ccb")
self.u = [ self.get_device("urukul0_ch0"),
self.get_device("urukul0_ch1"),
self.get_device("urukul0_ch2"),
self.get_device("urukul0_ch3")]
self.pmt = self.get_device("ttl0")
# self.data=[0]*512 + [1000<<23]*512
self.data = [0]*1024
self.data_len = 1024
# GUI
self._channel_list = list( [ f'Ch{jj}' for jj in range(4) ] )
self.setattr_argument("channel",EnumerationValue(self._channel_list))
self.frequency = self.get_argument(f"frequency",NumberValue(100*MHz, unit='MHz', scale=MHz, min=1*MHz, max=400*MHz))
self.amplitude = self.get_argument(f"amplitude",NumberValue( 0.25, min=0.000, max=1.000))
self.depth = self.get_argument(f"AM Depth", NumberValue( 0.15, min=0.000, max=1.000))
# self.am_freq = self.get_argument(f"AM frequency",NumberValue(700*kHz, unit='kHz', scale=kHz, min=100*kHz, max=2000*kHz))
self._channel = 0
self.scan_time_step = self.get_argument(f"Scan time step" ,NumberValue(1 , min=0.01, max=60,unit="s") )
self.sorted = self.get_argument(f"sorted", BooleanValue(True))
self.setattr_argument("freqs", Scannable(
default=CenterScan(700*kHz, 20*kHz, 1*kHz),
unit="kHz",
scale=kHz,
global_min = 1,
global_max = 2*MHz
)
)
self.setattr_argument(f"t_readout",
NumberValue(300*ms, unit='ms', scale=ms, min=0.001*ms),
"Experiment params")
self.setattr_argument(f"t_trans",
NumberValue(10*us, unit='us', scale=us, min=1*us),
"Experiment params")
def run(self):
t0 = time()
self._channel = self._channel_list.index( self.channel )
print("canal:", self._channel)
# assert self._channel==3
if self.sorted:
sequence = sorted(self.freqs.sequence)
else:
sequence = self.freqs.sequence
self.create_datasets()
self.create_applets()
for ind,am_freq in enumerate(sequence):
self.mutate_dataset("real_freq", ind, am_freq)
for ind,am_freq in enumerate(sequence):
t0 = time() #; jj=0
# print(f"{jj}: {time()-t0}") ; jj += 1
parameters = optimal_param2( am_freq )
for jj in range(0,12,4):
# print(f"1step time: {round(time()-t0,2)}")
frec, num_samples, n_harmonic, clock_step = parameters[jj:jj+4]
modulation = get_urukul_array(frec, num_samples, n_harmonic)
#modulation = (array(modulation)/2 * self.depth ) + (self.amplitude-self.depth)
# print(f"2step time: {round(time()-t0,2)}")
modulation = self.amplitude*(1+0.5*(1-self.depth)*(array(modulation)-1))
data = convert_amp_to_data( modulation )
self.clock_step = clock_step
self.data_len = int(num_samples)
self.ind = ind
# print(f"3step time: {round(time()-t0,2)}")
if test_fail(num_samples):
self.fix = True
data = data + [0]*10
self.data = [0]*len(data)
for ii in range(len(data)):
self.data[ii] = data[ii]
else:
self.fix = False
self.data = [0]*len(data)
for ii in range(len(data)):
self.data[ii] = data[ii]
print(f"frec: {frec} | am_freq: {am_freq} | num_samples:{num_samples} | clock_step: {clock_step}")
try:
# print(f"4step time: {round(time()-t0,2)}")
self.run_kernel()
# print(f"5step time: {round(time()-t0,2)}")
self.mutate_dataset("set_freq", ind, am_freq)
self.mutate_dataset("real_freq", ind, frec)
break
except:
print(f"HUBO UNA FALLA DEL run_kernel() (intento {int(jj/4+1)})")
self.mutate_dataset("error_freq", ind, 1 )
if jj==8:
print(F"NO SE PUDO SINTETIZAR F_am={am_freq} Hz POR ERRORES DEL KERNEL")
self.mutate_dataset("error_freq", ind, 2 )
# print(f"6step time: {round(time()-t0,2)}")
sleep(self.scan_time_step)
print(f"step time: {round(time()-t0,2)}")
print("FFIIINNN")
@rpc
def create_datasets(self):
self.set_dataset("counts" , np.zeros( len(self.freqs.sequence) , dtype=int ), broadcast=True, archive=True)
self.set_dataset("set_freq" , np.zeros( len(self.freqs.sequence) , dtype=float), broadcast=True, archive=True)
self.set_dataset("real_freq", np.zeros( len(self.freqs.sequence) , dtype=float), broadcast=True, archive=True)
self.set_dataset("error_freq", np.zeros( len(self.freqs.sequence) , dtype=float), broadcast=True, archive=True)
@rpc(flags={"async"})
def create_applets(self):
self.ccb.issue("create_applet", "Motional_spectrum_AM",
"${python} -m pyLIAF.artiq.applets.plot_xy "
"counts "
"--x real_freq")
@kernel
def readout(self) -> TInt64:
"""Registro de cuentas emitidas"""
# delay(self.t_trans)
here = self.pmt.gate_rising(self.t_readout) # Que mida durante t_readout
# self.enfriar_ion() # ya pongo a enfriar, asi todos los retardos estan enfriando
return self.pmt.count(here) # recupero las cuentas medidas
@kernel #this code runs on the FPGA
def run_kernel(self):
if self.fix:
local_data_len = self.data_len + 10
else:
local_data_len = self.data_len
data = [0] * local_data_len
for ii in range(local_data_len):
data[ii] = self.data[ii] << 23
self.core.break_realtime()
# modulation, frec, clock_step = get_urukul_array( self.am_freq )
# modulation = (modulation/2 * self.depth )+0.9
# data = convert_amp_to_data( modulation )
# data = [0]*512 + [1000<<23]*512
# clock_step = 1
#reset core
# self.core.reset()
# Esto último hace saltar un error de de underflow
#initialise
self.u[self._channel].cpld.init()
self.core.break_realtime()
self.u[self._channel].init()
delay(1*ms)
#set ram profile 0 -----------------------------
self.u[self._channel].set_profile_ram(
start=0, end=0 + self.data_len - 1, step=self.clock_step,
profile=0, mode=RAM_MODE_CONT_RAMPUP)
self.u[self._channel].cpld.set_profile(0)
self.u[self._channel].cpld.io_update.pulse_mu(8)
delay(1*ms) # ES ESTE
#write to ram
self.u[self._channel].write_ram(data)
delay(10*ms)
self.core.break_realtime()
# --------------------------
# self.u.cpld.set_profile(0)
# self.u.cpld.io_update.pulse_mu(8)
# delay(1*ms)
#write to cfr
self.u[self._channel].set_cfr1(ram_enable=1, ram_destination=RAM_DEST_ASF, internal_profile=0)
self.u[self._channel].sw.on()
#set urukuln parameters and turn channel on
self.u[self._channel].set_frequency(self.frequency)
self.u[self._channel].cpld.io_update.pulse_mu(8)
# self.u.set_att(10*dB)
# self.core.break_realtime()
# delay(1*ms)
#self.u.sw.off()
delay(self.t_trans)
cuentas = self.readout()
#delay(1*ms)
self.mutate_dataset("counts", self.ind, cuentas )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment