Skip to content
Power_calibration_inversed.py 8.03 KiB
Newer Older
import numpy as np
from time import sleep
from artiq.experiment import *
from pyLIAF.artiq.controllers import UrukulCh
from pyLIAF.RedPitaya import Read_analog as rp
from scipy import interpolate

class InvLaserPowerCalibration(EnvExperiment):
    """INVERSED UV Laser power calibration with photodiode and a red pitaya """

    def build(self):
        self.setattr_device("ccb")
        self.setattr_device("scheduler")
        self.setattr_device("core")

        self.laserUV = UrukulCh(self, ch=2, freq=110.0, amp=0.3, name="UV") #corresponde a 0.7 Vpp


        self.setattr_argument("Do_calibration", BooleanValue(False), "Calibration_parameters")
        self.setattr_argument("Calibration_PD_Value", NumberValue(0.2, min=0.01, max=0.5, ndecimals=5), "Calibration_parameters")


        self.setattr_argument("Calibration_freqs", Scannable(
                                        default=CenterScan(110*MHz, 10*MHz, 0.1*MHz),
                                        unit="MHz",
                                        scale=MHz,
                                        global_min = 1*MHz,
                                        global_max = 400*MHz
                                       )
                             )        

        self.setattr_argument("Calibration_amps", Scannable(
                                        default=CenterScan(0.2, 0.1, 0.01),
                                        global_min = 0,
                                        global_max = 0.3
                                       )
                             )        


#        self.setattr_argument("Experiment_frequencies", Scannable(
#                                        default=CenterScan(110*MHz, 10*MHz, 0.1*MHz),
#                                        unit="MHz",
#                                        scale=MHz,
#                                        global_min = 1*MHz,
#                                        global_max = 400*MHz
#                                       )
#                             )        


    @rpc
    def create_datasets(self):
        if self.Do_calibration:
            self.set_dataset("PD_UV_counts", list(np.zeros(len(self.Calibration_freqs.sequence)*len(self.Calibration_amps.sequence), dtype=int)), broadcast=True, archive=True)
        self.set_dataset("Calibration_freqs", len(self.Calibration_amps.sequence)*self.Calibration_freqs.sequence, broadcast=True, archive=True)
        self.set_dataset("Calibration_amps", self.Calibration_amps.sequence, broadcast=True, archive=True)


        self.set_dataset("Experiment_freqs", self.Calibration_freqs.sequence, broadcast=True, archive=True)
        self.set_dataset("Experiment_amps", np.zeros(len(self.Calibration_freqs.sequence), dtype=float), broadcast=True, archive=True)


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

        self.ccb.issue("create_applet", "powercalibration",
                        "${python} -m pyLIAF.artiq.applets.plot_xy "
                        "PD_UV_counts "
                        "--x Calibration_freqs")

    @rpc(flags={"async"})
    def RemoveZeros(calib, freqs):
        i, j = 0, 1
        new_calib = calib
        while i < len(calib):
            if new_calib[0] == 0:
                new_calib = new_calib[1:]
                i = i + 1
            else:            
                init_len = len(new_calib)
                final_calib = new_calib
                while j < init_len:
                    if final_calib[-1] == 0:
                        final_calib = final_calib[:-1]
                        j = j + 1
                    else:
                        if j == 1:
                            return freqs[i:], final_calib
                        else:
                            return freqs[i:-j+1], final_calib


    @rpc(flags={"async"})
    def Calibrate_amplitudes(self):
        Interpolation_functions = []

        PD_UV_counts = self.get_dataset("PD_UV_counts")

        n = len(self.Calibration_freqs.sequence)
        PD_split = np.matrix([PD_UV_counts[i * n:(i + 1) * n] for i in range((len(PD_UV_counts) + n - 1) // n )])
        PD_T = np.transpose(PD_split)

        amps = self.Calibration_amps.sequence

        for i in range(len(PD_T)):
            #PD_values = np.array(PD_T[i][0])[0]
            PD_values = np.array(PD_T[i])[0]
            f = interpolate.interp1d(PD_values, amps, kind='linear')
            Interpolation_functions.append(f)
            

        Calibration_PD_Value = self.Calibration_PD_Value

        Calibrated_Amplitudes = []
        for fi in Interpolation_functions:
            try:
                Calibrated_Amplitudes.append(float(fi(Calibration_PD_Value)))
            except:
                Calibrated_Amplitudes.append(0)
                print('no, rey')

        
        #Freqs_withoutZeros, Calibs_withoutZeros = RemoveZeros(Calibs, freqs)        

        Function_Calibs_vs_freq = interpolate.interp1d(self.Calibration_freqs.sequence, Calibrated_Amplitudes, kind='linear')    
        for freq in self.Calibration_freqs.sequence:
            calibamp = Function_Calibs_vs_freq(freq)
            print(calibamp)
            self.mutate_dataset("Experiment_amps", i, calibamp)
            i = i + 1

        print('okarda con la calibreta')


    @rpc(flags={"async"})
    def Calibrate_amplitudes_v2(self):
        Interpolation_functions = []

        PD_UV_counts = self.get_dataset("PD_UV_counts")
        n = len(self.Calibration_freqs.sequence)
        PD_split = np.matrix([PD_UV_counts[i * n:(i + 1) * n] for i in range((len(PD_UV_counts) + n - 1) // n )])
        PD_T = PD_split
        #PD_T = PD_split

        amps = self.Calibration_amps.sequence

        Calibration_PD_Value = self.Calibration_PD_Value
        Calibrated_Amplitudes = []
        for i in range(len(PD_T)):
            PD_values = np.array(PD_T[i])[0]
            print(len(PD_values))
            print(len(amps))
            j = 0
            while j < len(PD_values):
                if PD_values[j] < Calibration_PD_Value:
                    j = j + 1
                elif PD_values[j] > Calibration_PD_Value:
                    Calibrated_Amplitudes.append(amps[j])
                    break
                else:
                    Calibrated_Amplitudes.append(0)
                    print('malardo')
                    break

        i = 0
        for i in range(len(Calibrated_Amplitudes)):
            self.mutate_dataset("Experiment_amps", i, Calibrated_Amplitudes[i])
            i = i + 1

        print('okarda con la calibreta')

    @rpc(flags={"async"})
    def measure_PD(self, i):
        value = rp.ReadVoltage()
        print(value)
        if i%self.No_freqs == 0:
            sleep(0.3)
            value = rp.ReadVoltage()
            sleep(0.3)
            print(f"Corrected value: {value}")
        self.mutate_dataset(f"PD_UV_counts", i, np.abs(value))

    @kernel
    def init_kernel(self):
        self.core.reset()
        self.laserUV.initialize_channel()

        delay(10*us)

        self.laserUV.set_channel()

        self.core.wait_until_mu(now_mu())

        delay(1*ms)
        self.laserUV.on()

    @kernel
    def change_frequency(self, freq, amp):
        self.core.break_realtime()
        delay(50*ms)
        self.laserUV.set_frequency(freq, amp)

        #def GetTargetAmplitude(self, amplitudes, PD_values, i):
        #f = interpolate.interp1d(amplitudes, PD_values)
        
        #amplitudes_interpoladas = np.arange()
        
    def run(self):
        self.create_datasets()
        self.create_applets()
        self.init_kernel()

        self.No_freqs = len(self.Calibration_freqs.sequence)

        i = 0
        
        if self.Do_calibration:
            print('Usaremos mediciones nuevas')
            for freq in self.Calibration_freqs.sequence:
                print(freq)
                for amp in self.Calibration_amps.sequence:
                    self.change_frequency(freq, amp)
                    self.measure_PD(i)
                    i = i + 1
            self.Calibrate_amplitudes()
        else:
            print('Usando mediciones ya hechas')
            self.Calibrate_amplitudes_v2()