Skip to content
Power_calibration_v2.py 4.92 KiB
Newer Older
Nicolas Nunez Barreto's avatar
Nicolas Nunez Barreto committed
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 LaserPowerCalibration_v2(EnvExperiment):
    """V2 - Binary search - 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("Target_PD_Value", NumberValue(0.2, min=0.01, max=0.5), "Calibration_parameters")

        self.setattr_argument("Max_amplitude", NumberValue(0.25, min=0.01, max=0.5), "Calibration_parameters")
        self.setattr_argument("Min_amplitude", NumberValue(0.01, min=0.01, max=0.5), "Calibration_parameters")

        self.setattr_argument("tolerance", NumberValue(0.005, max=0.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
                                       )
                             )        


    @rpc
    def create_datasets(self):
        #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("Current_PD_UV", np.array([0.05]), broadcast=True, archive=False)
        self.set_dataset("Calibration_freqs", self.Calibration_freqs.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", "v2_powercalibration",
                        "${python} -m pyLIAF.artiq.applets.plot_xy "
                        "Experiment_amps "
                        "--x Calibration_freqs")


    @rpc(flags={"async"})
    def Binary_Search(self, pd_value, initial_amplitude, final_amplitude, current_freq):
        mid_amplitude = round(0.5*(initial_amplitude+final_amplitude), 4)
        print(f'mid_amplitude: {mid_amplitude}')
        if abs(initial_amplitude - mid_amplitude) < 0.00001 or abs(final_amplitude - mid_amplitude) < 0.00001:
            print('toco un borde jejox')            
            return mid_amplitude
        #else:
        if mid_amplitude > self.Max_amplitude or mid_amplitude < self.Min_amplitude:
            raise
        self.change_frequency(current_freq, mid_amplitude)   
        self.measure_PD()
        measured_PD = self.get_dataset("Current_PD_UV")[0]
        if np.abs(measured_PD - pd_value) > 0.0005:
            if measured_PD > pd_value:        
                return self.Binary_Search(pd_value, initial_amplitude, mid_amplitude, current_freq) 
            elif measured_PD < pd_value:
                return self.Binary_Search(pd_value, mid_amplitude, final_amplitude, current_freq)                 
            else:
                print('no se, fijate, paso algo')
                return 0
        else:
            return mid_amplitude


    @rpc(flags={"async"})
    def measure_PD(self):
        value = rp.ReadVoltage()
        print(np.abs(value))
        self.mutate_dataset(f"Current_PD_UV", 0, np.abs(value))
        

    @kernel
    def init_kernel(self):
        self.core.reset()
        delay(1*ms)
        self.core.break_realtime()
        self.laserUV.initialize_channel()

        delay(100*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)
        delay(10*ms)

       
    def run(self):
        self.create_datasets()
        self.create_applets()
        self.init_kernel()

        i = 0

        initial_amplitude = self.Min_amplitude
        final_amplitude = self.Max_amplitude

        initial_PD = self.Target_PD_Value
        
        

        for freq in self.Calibration_freqs.sequence:
            self.change_frequency(freq, initial_amplitude)
            calibrated_amplitude = self.Binary_Search(initial_PD, initial_amplitude, final_amplitude, freq)
            print(f'Done freq {freq}')
            self.mutate_dataset("Experiment_amps", i, calibrated_amplitude)
            #initial_amplitude = calibrated_amplitude-0.1
            #final_amplitude = calibrated_amplitude+0.1
            i = i + 1