Skip to content
copia_seguridad.py 10.8 KiB
Newer Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Sep  4 13:51:16 2024

@author: liaf-ankylosaurus-admin
"""

import numpy as np
from artiq.experiment import *
from time import sleep
PORT = 60000
PASS = b'Secr3t Pa55W0rd'
from multiprocessing.connection import Client

class InOut(EnvExperiment):
    """
    Copia seguridad v3
    """
    def build(self):
        self.setattr_device("core")
        self.setattr_device("ccb")
        self.ttl0 = self.get_device("ttl0")
        self.ttl4 = self.get_device("ttl4")
        self.ttl6 = self.get_device("ttl6")
        
        self.setattr_argument(f"t_med",
                             NumberValue(300*ms, unit='ms', scale=ms, min=0.1*ms, max=1000*ms),
                            "Experiment params")
        
        self.setattr_argument("t_exp",
                             NumberValue(200*s, unit='s', scale=s, min=1*s, max=3000*s),
                            "Experiment params")
        
        self.setattr_argument("N_ions_objective",
                             NumberValue(1, min=1, max=15, ndecimals=0, step=1), 
                            "Experiment params")
        
        self.setattr_argument("waiting_time",
                             NumberValue(60*s, unit='s',min=15*s, max=300*s), 
                            "Experiment params")
        
        self.setattr_argument("tseg",
                                  NumberValue(2*s,unit='s',scale=s,min=1*s, max=3*s),
                              "Scan params")
        
        self.setattr_argument("Calibration",
                                  BooleanValue(1==0),
                              "Calibration params")
        
        self.setattr_argument("fluo per ion",
                                  NumberValue(1, min=1, max=10000, ndecimals=0, step=1),
                              "Calibration params")

        self.setattr_argument("Read_with",
                                  EnumerationValue(["PMT", "Camera"]),
                              "Experiment params")
        


        
    @rpc
    def initialize_tca_com(self):
        address = ('localhost', PORT)
        self.conn = Client(address, authkey=PASS)
        sleep(0.1)


    @rpc
    def blinkRF(self,cmd='turnOnOffRF'):
        self.conn.send(f'{cmd} blink')
        rta = self.conn.recv()
        
        
    @rpc(flags={"async"})
    def create_datasets(self): 
        self.set_dataset('time', [], broadcast=True, archive=True)
        self.set_dataset('counts', [], broadcast=True, archive=True)
        self.set_dataset("N_ions", [], broadcast=False, archive=True)
        self.set_dataset("fluo", [], broadcast=False, archive=True)
        #self.set_dataset('Cuentas_transitorio', [0], broadcast=True, archive=True)

        
    @rpc(flags={"async"})
    def create_applets(self):

        self.ccb.issue("create_applet", "test_IR_espectro_fixeddelays",
                        "${python} -m pyLIAF.artiq.applets.plot_xy "
                        "counts "#Tiene que estar el espacio!!!
                        "--x time") #Aca habria que definir bien el vector que se use en el eje x

        self.ccb.issue("create_applet", "test_histogram_realtime",
                        "${python} -m pyLIAF.artiq.applets.histogram "
                        "counts "
                        "--update-delay 0.2")
        
        self.ccb.issue("create_applet", "test_histogram_realtime_indefinite",
                        "${python} -m pyLIAF.artiq.applets.realtime "
                        "400 "
                        "counts_indefinite")
        
        self.ccb.issue("create_applet", "test_N_ions",
                        "${python} -m pyLIAF.artiq.applets.plot_xy "
                        "N_ions "
                        "--x time")

    
    @kernel
    def ShutterClose(self):#Que controle el prendido de los dos Shutters #Abre
        self.core.break_realtime()
        self.ttl6.on()
        print("Cerrado")
    
    @kernel
    def ShutterOpen(self):#Que controle el apagado de los dos Shutters #Cierra
        self.core.break_realtime()
        self.ttl6.off()
        print("Abierto")
    
#    @rpc
#    def Varianza(self,sig)  -> TList(TFloat):
#        ruido=np.std(sig)
#        print(ruido)
#        return [ruido]
    
    @rpc
    def listas(self,sig,ruido):
        self.paso=[]
        self.pasom=[]
        self.med=[]
        self.medmax=[]
        self.N=[]
        self.fluo=[]
        self.atrapados=[]
        self.desviacion=[]
        for i in range(int(3/self.t_med)):
            self.med=self.med+[sig[i]]
            self.medmax=self.medmax+[sig[i]+ruido]
            self.N=self.N+[0]
                
    @rpc
    def func(self,i,s,mu,b,c,ruido)  -> TList(TInt64):
        recon_dev = self.Recon(i,s,self.t_med,self.tseg,mu,b,c,ruido,self.paso,self.pasom,self.med,self.medmax,self.N,self.fluo,self.atrapados,self.desviacion)
        return recon_dev

    @rpc
    def read_counts(self,t_med)  -> TList(TInt64):
        if self.Read_with=="Camera":
            self.conn.send('rois_count True')
            cuentas=self.conn.recv()
            #self.mutate_dataset("Cuentas_transitorio",0,cuentas)
        else:
            print(1)
            print(t_med)
            cuentas=self.ttl0.gate_rising(t_med)
            cuentas=self.ttl0.count(cuentas)
            print(cuentas)
            #self.mutate_dataset("Cuentas_transitorio",0,cuentas)
        #return [cuentas[0]]
        return [int(cuentas[0])]

    @rpc
    def Recon(self, i,s,med_ss,tseg,mu,b,c,ruido,paso,pasom,med,medmax,N,fluo,atrapados,desviacion)  -> TList(TInt64):
        """
        Funcion que reconoce iones
        i: iteracion
        s: vector de mediciones
        """
        med_s=1/med_ss
        med.append(np.mean(s[b:i-1]))
        medmax.append(med[-1]+ruido)
        if abs(s[i]-med[-2])>ruido: #Supera la cota
            if (s[i]-med[-2])>0: #Supera por arriba
                z=1
            else:
                z=-1
            if c>(tseg*med_s): #Supera el criterio
                fluo.append(np.mean(s[b:i-int(tseg*med_s+1)]))
                if len(fluo)>1:
                    a=abs(fluo[-1]-fluo[-2])
                    print(a)
                    A=[]
                    for k in range(len(mu)):
                        A.append(abs(a-mu[k]))
                    atrapados.append(np.argmin(A)+1)
                    desviacion.append(min(A))
                if z==1:
                    paso.append(i)
                else:
                    pasom.append(i)
                for k in range(int(tseg*med_s+1)): #Fortaleciendo med
                    med[-1-k]=s[i-k]
                    medmax[-1-k]=s[i-k]+ruido
                if z==1:
                    if len(paso)>1 and (paso[-1]-paso[-2])<(tseg*med_s): #Limpieza y ruido adaptativo, cuando aumenta N
                        paso.pop(-2)
                        N[-1]=N[-2]
                else:
                    if len(pasom)>1 and (pasom[-1]-pasom[-2])<(tseg*med_s) and z==-1: #Limpieza
                        pasom.pop(-2)
                        N[-1]=N[-2]
                b=i-1
                c=0
                if len(fluo)==1:  #Cantidad de iones
                    N.append(1)
                else:
                    N.append(N[-1]+z*atrapados[-1])
                for k in range(len(N)):
                    if (b+k-int(tseg*med_s+1))==(len(N)):
                        break
                    else:
                        N[b+k-int(tseg*med_s+1)]=N[-1]
            else:
                med[-1]=med[-2]
                medmax[-1]=medmax[-2]
                c=c+1
                N.append(N[-1])
        else: #Cae dentro de la cota
            c=0
            N.append(N[-1])
        print(N[-1])
        return [b,c,0,N[-1]]

    @kernel
    def run(self): 
        #Preparamos las variables y los graficos
        self.initialize_tca_com()
        self.create_datasets()
        self.create_applets()
        #Se prenden los "canales" a usar
        self.core.reset()
        self.ttl4.output()
        self.ttl0.input()
        self.ttl4.on()
        self.ttl6.output()
        self.ShutterOpen()
        self.blinkRF()
        delay(20*ms)
      
        
        if self.Calibration==True:
            #mu=calib
            mu=[500*i for i in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]
        else:
            #mu=self.load_calibration()
            mu=[700*i for i in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]
        
            self.core.break_realtime()
            delay(10*ms)
            sig=[]
            b=0
            c=0
            d=0 #Cantidad buscada? Si-No
            e=0 #Tiempo con cantidad buscada
            for i in range(int(3/self.t_med)):
                rta = self.read_counts(self.t_med)
                print("2")
                #rta=self.get_dataset("Cuentas_transitorio")
                #rta = 
                #rta = self.Cuentas_transitorio
                print("3")
                sig=sig+rta
                self.append_to_dataset("counts",rta[0])
                self.append_to_dataset("time",self.t_exp*i/int(self.t_exp/self.t_med))
                self.core.break_realtime()
            ruido=500#.5*mu[0]
            self.listas(sig,ruido)         
            self.core.break_realtime()
            delay(20*ms)
            
            for i in range(int(3/self.t_med),int(self.t_exp/self.t_med)):
                rta = self.read_counts(self.t_med)
                #rta=self.get_dataset("Cuentas_transitorio")
                sig=sig+rta
                self.append_to_dataset("counts",rta[0])
                self.append_to_dataset("time",self.t_exp*i/int(self.t_exp/self.t_med))

                recon_dev=self.func(i,sig,mu,b,c,ruido)

                b,c,fl,n=recon_dev[0],recon_dev[1],recon_dev[2],recon_dev[3]
                #self.append_to_dataset("fluo",fl)
                self.append_to_dataset("N_ions",n)
                
                #Chequeo cantidad de iones
                if d==0:
                    if n==self.N_ions_objective:
                        d=1
                        e=0
                        self.ShutterClose()
                    elif n>self.N_ions_objective:
                        self.blinkRF()
                        self.mutate_dataset("N_ions",-1,0)
                        c=0
                        b=i
                        print("Cantidad de iones superada, reiniciando")
                elif d==1 and e<self.waiting_time*self.t_med:
                    if n==self.N_ions_objective:
                        e=e+1
                    else:
                        d=0
                        print("Abriendo shutters")
                        self.ShutterOpen()
                elif d==1 and e==self.waiting_time/self.t_med:
                    print("Cantidad de iones alcanzada")
                    break
                
                self.core.break_realtime()
            
        start_time=now_mu()  # Record the start timeself.core.break_realtime()
        self.core.break_realtime()