import sys
sys.path.insert(0, './lib')
sys.path.insert(0, '..') #append parent directory


from interface import *
from help import *
from measurements import *
import configparser
import quick

# Create the grids
#create the information grid
style = {'description_width': 'initial'}
sample,smu_map = information_box_new()


###end of sampling information#######################################

# move checkboxes outside of the tabs
transfer_check,integration_transfer,transfer_gates = header('Transfer Curve',"MEDium")
output_check,integration_output,output_gates = header('Output Curve',"SHORt")
gatediode_check,integration_gatediode,_=header('Gatediode',"MEDium")

checkboxes = widgets.HBox([transfer_check,output_check,gatediode_check])
display(checkboxes)

#transfer
Vds_transfer_widgets,Vds_transfer = secondary('VDS',0.05,0.95,1,1e-2)
Vtg_transfer_widgets,Vtg_transfer = primary('VTG',-5,0.01,5,1e-3)
Vbg_transfer_widgets,Vbg_transfer = synchronous('VBG',-15,0.1,15,1e-3)
plot_transfer_widgets,plot_transfer = plot_config(1)
transfer_box = widgets.VBox([integration_transfer,transfer_gates,Vds_transfer_widgets,Vtg_transfer_widgets,Vbg_transfer_widgets,plot_transfer_widgets])


#output
Vds_output_widgets,Vds_output = primary('VDS',0,0.01,5,1e-2)
Vtg_output_widgets,Vtg_output = secondary('VTG',-5,2,5,1e-3)
Vbg_output_widgets,Vbg_output = additional_secondary('VBG',-15,5,15,1e-3)
plot_output_widgets,plot_output = plot_config(2)

output_box = widgets.VBox([integration_output,output_gates,Vds_output_widgets,Vtg_output_widgets,Vbg_output_widgets,plot_output_widgets])
#GateDiodde
terminal = widgets.Dropdown(
    options = ['VTG','VBG'],
    description = 'Selected Gate:',
    value ='VTG',
    style=  {'description_width': 'initial'}
)
Vg_gatediode_widgets,Vg_gatediode=primary('VG',-5,0.05,5,1e-3)
plot_gatediode_widgets,plot_gatediode = plot_config(3)
gatediode_box = widgets.VBox([integration_gatediode,terminal,Vg_gatediode_widgets,plot_gatediode_widgets])

#the tab widget
children = [transfer_box,output_box,gatediode_box]
titles = ["Transfer","Output","Gatediode"]
tab = widgets.Tab()
tab.children = children
tab.titles = titles

display(tab)

button = widgets.Button(description ='Start Measurement')
quick_button = widgets.Button(description = 'Quick Measurement')
output = widgets.Output()

export_ini_button = widgets.Button(description = 'Export as ini')
import_ini_button = widgets.Button(description='Import from ini')

all_widgets =[transfer_gates,output_gates,button,transfer_check,integration_transfer,output_check,integration_output,gatediode_check,integration_gatediode,terminal,export_ini_button,import_ini_button,quick_button]

add_widgets_to_list(sample,all_widgets)
add_widgets_to_list(smu_map,all_widgets)
add_widgets_to_list(Vds_transfer,all_widgets)
add_widgets_to_list(Vtg_transfer,all_widgets)
add_widgets_to_list(Vbg_transfer,all_widgets)
add_widgets_to_list(Vds_output,all_widgets)
add_widgets_to_list(Vtg_output,all_widgets)
add_widgets_to_list(Vbg_output,all_widgets)
add_widgets_to_list(Vg_gatediode,all_widgets)

line = widgets.HBox([button,quick_button,import_ini_button,export_ini_button])
display(line,output)
device = hp4155a.HP4155a('GPIB0::17::INSTR')

def on_start_clicked(b):
    with output:
        clear_output()
        #disable all widgets
        disable_widgets(all_widgets)

        #additional code to check smu configuration fast without modifing a lot of code
        try:
            check_configuration(smu_map)
        except Exception as e:
            error_box(e)
            enable_widgets(all_widgets)
            return

        Setup(device) #setup the device

        #for all measurements the same (copy the interface with values for parameter setting)
        map = smu_map.copy()
        for key,value in map.items():
            map[key]= value.value

        sample_copy = sample.copy()
        for key,value in sample_copy.items():
            sample_copy[key]=value.value

        smu_s = device.smu_dict()
        smu_s.update(vname ='VS',iname = 'IS',mode = 'COMM',func='CONS') #Source smu is always grounded
        
        if transfer_check.value == True:
            plot = plot_transfer.copy()
            for key,value in plot.items():
                plot[key] = value.value

            points = number_of_points(Vds_transfer)

            var2=device.var2_dict() #Vds_output is always used in tranfer curve with the same config
            var2.update(
                start=Vds_transfer['start'].value,
                step=Vds_transfer['step'].value,
                points=points,
                comp=Vds_transfer['comp'].value,
                pcomp=Vds_transfer['pcomp'].value,
                stop = Vds_transfer['stop'].value #not important for setting VAR2 only parameters in file
            )

            # also drain smu is the same
            smu_d = device.smu_dict()
            smu_d.update(vname='VDS',iname='ID',mode = 'V',func = 'VAR2')
            match transfer_gates.value:
                case 'VTG' if check_values(Vtg_transfer,'primary') and check_values(Vds_transfer,'secondary'):
                    smu_t = device.smu_dict()
                    smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1')
                    smu_b = device.smu_dict()
                    smu_b.update(vname = 'VBG',iname='IBG',mode = 'COMM',func = 'CONS')
                   
                    var1 = device.var1_dict()
                    var1.update(
                        mode=Vtg_transfer['hyst'].value,
                        start=Vtg_transfer['start'].value,
                        stop=Vtg_transfer['stop'].value,
                        step=Vtg_transfer['step'].value,
                        comp =Vtg_transfer['comp'].value,
                        pcomp=Vtg_transfer['pcomp'].value
                    )
                    #define the final dict
                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_transfer.value,
                    }
                    #measure (later)
                    Transfer_VTG(device,meas_dict)
            
                case 'VBG' if check_values(Vbg_transfer,'primary') and check_values(Vds_transfer,'secondary'):
                    smu_t = device.smu_dict()
                    smu_t.update(vname = 'VTG',iname='ITG',mode = 'COMM',func='CONS')
                    smu_b = device.smu_dict()
                    smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VAR1')

                    var1 = device.var1_dict()
                    var1.update(
                        mode=Vbg_transfer['hyst'].value,
                        start=Vbg_transfer['start'].value,
                        stop=Vbg_transfer['stop'].value,
                        step=Vbg_transfer['step'].value,
                        comp =Vbg_transfer['comp'].value,
                        pcomp=Vbg_transfer['pcomp'].value
                    )

                    #define the final dict
                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_transfer.value,
                    }
                    #measure (later)
                    Transfer_VBG(device,meas_dict)
                  
                    
                case 'BOTH' if check_values(Vbg_transfer,'synchronous') and check_values(Vds_transfer,'secondary') and check_values(Vtg_transfer,'primary'):
                    smu_t = device.smu_dict()
                    smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1')  
                    smu_b = device.smu_dict()
                    smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VARD')

                    var1 = device.var1_dict()
                    var1.update(
                        mode=Vtg_transfer['hyst'].value,
                        start=Vtg_transfer['start'].value,
                        stop=Vtg_transfer['stop'].value,
                        step=Vtg_transfer['step'].value,
                        comp =Vtg_transfer['comp'].value,
                        pcomp=Vtg_transfer['pcomp'].value   
                     )

                    #calculate parameters for VARD
                    ratio,offset = calculate_line(Vtg_transfer,Vbg_transfer)
                    
                    # update VBG step
                    Vbg_transfer["step"].value = Decimal(str(ratio)) * Decimal(str(Vtg_transfer["step"].value))


                    vard = device.vard_dict()
                    vard.update(
                        offset = offset,
                        ratio = ratio,
                        comp = Vbg_transfer["comp"].value,
                        pcomp = Vbg_transfer["pcomp"].value,
                        start = Vbg_transfer["start"].value,
                        step = Vbg_transfer['step'].value,
                        stop = Vbg_transfer['stop'].value,
                    )

                    #define the final dict
                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_transfer.value,
                        "VARD":vard
                    }

                    #measure (later)
                    Transfer_BOTH(device,meas_dict)
                case _ :
                    information_box("Transfer Measurement skipped due to invalid parameters")
            
        if output_check.value == True:
            smu_d = device.smu_dict()
            smu_d.update(vname='VDS',iname='ID',mode = 'V',func = 'VAR1')
            
            var1 = device.var1_dict()
            var1.update(
                mode=Vds_output['hyst'].value,
                start=Vds_output['start'].value,
                stop=Vds_output['stop'].value,
                step=Vds_output['step'].value,
                comp =Vds_output['comp'].value,
                pcomp=Vds_output['pcomp'].value
            )
            
            plot = plot_output.copy()
            for key,value in plot.items():
                plot[key] = value.value
            
            match output_gates.value:
                case 'VTG' if check_values(Vds_output,'primary') and check_values(Vtg_output,'secondary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR2')
    
                    smu_b= device.smu_dict()
                    smu_b.update(vname='VBG',iname='IBG',mode = 'COMM',func='CONS')

                    points = number_of_points(Vtg_output)

                    var2=device.var2_dict()
                    var2.update(
                        start=Vtg_output['start'].value,
                        step=Vtg_output['step'].value,
                        points=points,
                        comp=Vtg_output['comp'].value,
                        pcomp=Vtg_output['pcomp'].value,
                        stop = Vtg_output['stop'].value
                    )

                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_output.value,
                    }

                    #measure later
                    Output_VTG(device,meas_dict)
                    
                case 'VBG' if check_values(Vds_output,'primary') and check_values(Vbg_output,'secondary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'COMM',func='CONS')
                    
                    smu_b= device.smu_dict()
                    smu_b.update(vname='VBG',iname='IBG',mode = 'V',func = 'VAR2')

                    points = number_of_points(Vbg_output)

                    var2=device.var2_dict()
                    var2.update(
                        start=Vbg_output['start'].value,
                        step=Vbg_output['step'].value,
                        points=points,
                        comp=Vbg_output['comp'].value,
                        pcomp=Vbg_output['pcomp'].value,
                        stop = Vbg_output['stop'].value
                    )

                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_output.value,
                    }

                    #measure later
                    Output_VBG(device,meas_dict)

                    
                case 'BOTH' if check_values(Vds_output,'primary') and check_values(Vtg_output,'secondary') and check_values(Vbg_output,'secondary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR2')
                    
                    smu_b= device.smu_dict()
                    smu_b.update(vname='VBG',iname='IBG',mode = 'V',func = 'CONS')

                    points = number_of_points(Vtg_output)

                    var2=device.var2_dict()
                    var2.update(
                        start=Vtg_output['start'].value,
                        step=Vtg_output['step'].value,
                        points=points,
                        comp=Vtg_output['comp'].value,
                        pcomp=Vtg_output['pcomp'].value,
                        stop = Vtg_output['stop'].value
                    )

                    points_VBG = number_of_points(Vbg_output)
                    values_VBG = np.linspace(Vbg_output["start"].value,Vbg_output["stop"].value,num = points_VBG,endpoint= True)

                    #there is not such unit we create it with a loop
                    var3 = {
                        "start":Vbg_output['start'].value,
                        "step":Vbg_output['step'].value,
                        "points":points_VBG,
                        "comp":Vbg_output['comp'].value,
                        "stop" : Vbg_output['stop'].value,
                        "values" : values_VBG   
                    }
                    meas_dict = {
                        "SAMPLE":sample_copy, 
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "VAR3":var3,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_output.value,
                    }

                    #measure later
                    Output_BOTH(device,meas_dict)
                    
                case _ :
                    information_box("Output Measurement skipped due to invalid parameters")
                    

        if gatediode_check.value == True:
            #drain is disabled
            device.smu_disable(map['D'])

            # VAR1 is set with the same interface
            var1 = device.var1_dict()
            var1.update(
                mode=Vg_gatediode['hyst'].value,
                start=Vg_gatediode['start'].value,
                stop=Vg_gatediode['stop'].value,
                step=Vg_gatediode['step'].value,
                comp =Vg_gatediode['comp'].value,
                pcomp=Vg_gatediode['pcomp'].value
            )
            
            plot = plot_gatediode.copy()
            for key,value in plot.items():
                plot[key] = value.value        
                
            match terminal.value:
                case 'VTG' if check_values(Vg_gatediode,'primary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR1')

                    meas_dict = {
                        "SAMPLE":sample_copy, 
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_gatediode.value,
                    }
                    #measure later
                    Gatediode_VTG(device,meas_dict)

                case 'VBG' if check_values(Vg_gatediode,'primary'):
                    smu_b=device.smu_dict()
                    smu_b.update(vname ='VBG',iname = 'IBG',mode = 'V',func='VAR1')

                    meas_dict = {
                        "SAMPLE":sample_copy, 
                        "MAP" : map,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_gatediode.value,
                    }
                    #measure later
                    Gatediode_VBG(device,meas_dict)
                
                case _ :
                    information_box("Gatediode Measurement skipped due to invalid parameters")
        
        information_box("Measurement finished!")
        enable_widgets(all_widgets)


def on_quick_clicked(b):
    with output:
        clear_output()
        #disable all widgets
        disable_widgets(all_widgets)

        #additional code to check smu configuration fast without modifing a lot of code
        try:
            check_configuration(smu_map)
        except Exception as e:
            error_box(e)
            enable_widgets(all_widgets)
            return

        Setup(device) #setup the device

        #for all measurements the same (copy the interface with values for parameter setting)
        map = smu_map.copy()
        for key,value in map.items():
            map[key]= value.value

        sample_copy = sample.copy()
        for key,value in sample_copy.items():
            sample_copy[key]=value.value

        smu_s = device.smu_dict()
        smu_s.update(vname ='VS',iname = 'IS',mode = 'COMM',func='CONS') #Source smu is always grounded
        
        if transfer_check.value == True:
            plot = plot_transfer.copy()
            for key,value in plot.items():
                plot[key] = value.value

            points = number_of_points(Vds_transfer)

            var2=device.var2_dict() #Vds_output is always used in tranfer curve with the same config
            var2.update(
                start=Vds_transfer['start'].value,
                step=Vds_transfer['step'].value,
                points=points,
                comp=Vds_transfer['comp'].value,
                pcomp=Vds_transfer['pcomp'].value,
                stop = Vds_transfer['stop'].value #not important for setting VAR2 only parameters in file
            )

            # also drain smu is the same
            smu_d = device.smu_dict()
            smu_d.update(vname='VDS',iname='ID',mode = 'V',func = 'VAR2')
            match transfer_gates.value:
                case 'VTG' if check_values(Vtg_transfer,'primary') and check_values(Vds_transfer,'secondary'):
                    smu_t = device.smu_dict()
                    smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1')
                    smu_b = device.smu_dict()
                    smu_b.update(vname = 'VBG',iname='IBG',mode = 'COMM',func = 'CONS')
                   
                    var1 = device.var1_dict()
                    var1.update(
                        mode=Vtg_transfer['hyst'].value,
                        start=Vtg_transfer['start'].value,
                        stop=Vtg_transfer['stop'].value,
                        step=Vtg_transfer['step'].value,
                        comp =Vtg_transfer['comp'].value,
                        pcomp=Vtg_transfer['pcomp'].value
                    )
                    #define the final dict
                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_transfer.value,
                    }
                    #measure (later)
                    quick.Transfer_VTG(device,meas_dict)
            
                case 'VBG' if check_values(Vbg_transfer,'primary') and check_values(Vds_transfer,'secondary'):
                    smu_t = device.smu_dict()
                    smu_t.update(vname = 'VTG',iname='ITG',mode = 'COMM',func='CONS')
                    smu_b = device.smu_dict()
                    smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VAR1')

                    var1 = device.var1_dict()
                    var1.update(
                        mode=Vbg_transfer['hyst'].value,
                        start=Vbg_transfer['start'].value,
                        stop=Vbg_transfer['stop'].value,
                        step=Vbg_transfer['step'].value,
                        comp =Vbg_transfer['comp'].value,
                        pcomp=Vbg_transfer['pcomp'].value
                    )

                    #define the final dict
                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_transfer.value,
                    }
                    #measure (later)
                    quick.Transfer_VBG(device,meas_dict)
                  
                    
                case 'BOTH' if check_values(Vbg_transfer,'synchronous') and check_values(Vds_transfer,'secondary') and check_values(Vtg_transfer,'primary'):
                    smu_t = device.smu_dict()
                    smu_t.update(vname = 'VTG',iname='ITG',mode = 'V',func='VAR1')  
                    smu_b = device.smu_dict()
                    smu_b.update(vname = 'VBG',iname='IBG',mode = 'V',func = 'VARD')

                    var1 = device.var1_dict()
                    var1.update(
                        mode=Vtg_transfer['hyst'].value,
                        start=Vtg_transfer['start'].value,
                        stop=Vtg_transfer['stop'].value,
                        step=Vtg_transfer['step'].value,
                        comp =Vtg_transfer['comp'].value,
                        pcomp=Vtg_transfer['pcomp'].value   
                     )

                    #calculate parameters for VARD
                    ratio,offset = calculate_line(Vtg_transfer,Vbg_transfer)
                    
                    # update VBG step
                    Vbg_transfer["step"].value = Decimal(str(ratio)) * Decimal(str(Vtg_transfer["step"].value))


                    vard = device.vard_dict()
                    vard.update(
                        offset = offset,
                        ratio = ratio,
                        comp = Vbg_transfer["comp"].value,
                        pcomp = Vbg_transfer["pcomp"].value,
                        start = Vbg_transfer["start"].value,
                        step = Vbg_transfer['step'].value,
                        stop = Vbg_transfer['stop'].value,
                    )

                    #define the final dict
                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_transfer.value,
                        "VARD":vard
                    }

                    #measure (later)
                    quick.Transfer_BOTH(device,meas_dict)
                case _ :
                    information_box("Transfer Measurement skipped due to invalid parameters")
            
        if output_check.value == True:
            smu_d = device.smu_dict()
            smu_d.update(vname='VDS',iname='ID',mode = 'V',func = 'VAR1')
            
            var1 = device.var1_dict()
            var1.update(
                mode=Vds_output['hyst'].value,
                start=Vds_output['start'].value,
                stop=Vds_output['stop'].value,
                step=Vds_output['step'].value,
                comp =Vds_output['comp'].value,
                pcomp=Vds_output['pcomp'].value
            )
            
            plot = plot_output.copy()
            for key,value in plot.items():
                plot[key] = value.value
            
            match output_gates.value:
                case 'VTG' if check_values(Vds_output,'primary') and check_values(Vtg_output,'secondary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR2')
    
                    smu_b= device.smu_dict()
                    smu_b.update(vname='VBG',iname='IBG',mode = 'COMM',func='CONS')

                    points = number_of_points(Vtg_output)

                    var2=device.var2_dict()
                    var2.update(
                        start=Vtg_output['start'].value,
                        step=Vtg_output['step'].value,
                        points=points,
                        comp=Vtg_output['comp'].value,
                        pcomp=Vtg_output['pcomp'].value,
                        stop = Vtg_output['stop'].value
                    )

                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_output.value,
                    }

                    #measure later
                    quick.Output_VTG(device,meas_dict)
                    
                case 'VBG' if check_values(Vds_output,'primary') and check_values(Vbg_output,'secondary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'COMM',func='CONS')
                    
                    smu_b= device.smu_dict()
                    smu_b.update(vname='VBG',iname='IBG',mode = 'V',func = 'VAR2')

                    points = number_of_points(Vbg_output)

                    var2=device.var2_dict()
                    var2.update(
                        start=Vbg_output['start'].value,
                        step=Vbg_output['step'].value,
                        points=points,
                        comp=Vbg_output['comp'].value,
                        pcomp=Vbg_output['pcomp'].value,
                        stop = Vbg_output['stop'].value
                    )

                    meas_dict = {
                        "SAMPLE":sample_copy,
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_output.value,
                    }

                    #measure later
                    quick.Output_VBG(device,meas_dict)

                    
                case 'BOTH' if check_values(Vds_output,'primary') and check_values(Vtg_output,'secondary') and check_values(Vbg_output,'secondary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR2')
                    
                    smu_b= device.smu_dict()
                    smu_b.update(vname='VBG',iname='IBG',mode = 'V',func = 'CONS')

                    points = number_of_points(Vtg_output)

                    var2=device.var2_dict()
                    var2.update(
                        start=Vtg_output['start'].value,
                        step=Vtg_output['step'].value,
                        points=points,
                        comp=Vtg_output['comp'].value,
                        pcomp=Vtg_output['pcomp'].value,
                        stop = Vtg_output['stop'].value
                    )

                    points_VBG = number_of_points(Vbg_output)
                    values_VBG = np.linspace(Vbg_output["start"].value,Vbg_output["stop"].value,num = points_VBG,endpoint= True)

                    #there is not such unit we create it with a loop
                    var3 = {
                        "start":Vbg_output['start'].value,
                        "step":Vbg_output['step'].value,
                        "points":points_VBG,
                        "comp":Vbg_output['comp'].value,
                        "stop" : Vbg_output['stop'].value,
                        "values" : values_VBG   
                    }
                    meas_dict = {
                        "SAMPLE":sample_copy, 
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_D": smu_d,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "VAR2":var2,
                        "VAR3":var3,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_output.value,
                    }

                    #measure later
                    quick.Output_BOTH(device,meas_dict)
                    
                case _ :
                    information_box("Output Measurement skipped due to invalid parameters")
                    

        if gatediode_check.value == True:
            #drain is disabled
            device.smu_disable(map['D'])

            # VAR1 is set with the same interface
            var1 = device.var1_dict()
            var1.update(
                mode=Vg_gatediode['hyst'].value,
                start=Vg_gatediode['start'].value,
                stop=Vg_gatediode['stop'].value,
                step=Vg_gatediode['step'].value,
                comp =Vg_gatediode['comp'].value,
                pcomp=Vg_gatediode['pcomp'].value
            )
            
            plot = plot_gatediode.copy()
            for key,value in plot.items():
                plot[key] = value.value        
                
            match terminal.value:
                case 'VTG' if check_values(Vg_gatediode,'primary'):
                    smu_t=device.smu_dict()
                    smu_t.update(vname ='VTG',iname = 'ITG',mode = 'V',func='VAR1')

                    meas_dict = {
                        "SAMPLE":sample_copy, 
                        "MAP" : map,
                        "SMU_T":smu_t,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_gatediode.value,
                    }
                    #measure later
                    quick.Gatediode_VTG(device,meas_dict)

                case 'VBG' if check_values(Vg_gatediode,'primary'):
                    smu_b=device.smu_dict()
                    smu_b.update(vname ='VBG',iname = 'IBG',mode = 'V',func='VAR1')

                    meas_dict = {
                        "SAMPLE":sample_copy, 
                        "MAP" : map,
                        "SMU_B":smu_b,
                        "SMU_S":smu_s,
                        "VAR1":var1,
                        "PLOT": plot, # plot in the tool
                        "INTEGRATION": integration_gatediode.value,
                    }
                    #measure later
                    quick.Gatediode_VBG(device,meas_dict)
                
                case _ :
                    information_box("Gatediode Measurement skipped due to invalid parameters")
        
        information_box("Measurement finished!")
        enable_widgets(all_widgets)                      
            
def on_export_ini_clicked(b):
    with output:
        disable_widgets(all_widgets)
        config = configparser.ConfigParser()
        default_filename = 'ADU_double_gate.ini'
        try:
            file = save_as_ini(default_filename)
            with open(file,'w') as configfile:
                config.add_section('ALL VALUES ARE IN SI-UNITS!')
                config.add_section('IT IS RECOMMENDED TO CHANGE THE INI FILE FROM THE INTERFACE AND DO NOT CHANGE ANY VALUES MANUALLY')
    
                # Transfer curve
                config.add_section('Transfer')
                config.set('Transfer','Integration',integration_transfer.value)
    
                config.add_section("Vtg_transfer")
                for parameter,widget in Vtg_transfer.items():
                    config.set('Vtg_transfer',parameter,str(widget.value))
    
                config.add_section("Vbg_transfer")
                for parameter,widget in Vbg_transfer.items():
                    config.set('Vbg_transfer',parameter,str(widget.value))
    
                config.add_section('Vds_transfer')
                for parameter,widget in Vds_transfer.items():
                    config.set('Vds_transfer',parameter,str(widget.value))

                config.add_section('Plot_transfer')
                for parameter,widget in plot_transfer.items():
                    config.set('Plot_transfer',parameter,str(widget.value))
    
                #output
                config.add_section('Output')
                config.set('Output','Integration',integration_output.value)
    
                config.add_section("Vtg_output")
                for parameter,widget in Vtg_output.items():
                    config.set('Vtg_output',parameter,str(widget.value))
    
                config.add_section("Vbg_output")
                for parameter,widget in Vbg_output.items():
                    config.set('Vbg_output',parameter,str(widget.value))
                
                config.add_section('Vds_output')
                for parameter,widget in Vds_output.items():
                    config.set('Vds_output',parameter,str(widget.value))

                config.add_section('Plot_output')
                for parameter,widget in plot_output.items():
                    config.set('Plot_output',parameter,str(widget.value))

                # Gatediode
                config.add_section('Gatediode')
                config.set('Gatediode','Integration',integration_gatediode.value)
    
                config.add_section("Vg_gatediode")
                for parameter,widget in Vg_gatediode.items():
                    config.set('Vg_gatediode',parameter,str(widget.value)) 

                config.add_section('Plot_gatediode')
                for parameter,widget in plot_gatediode.items():
                    config.set('Plot_gatediode',parameter,str(widget.value))

                # add the smu configuration
                config.add_section('SMU_configuration')
                for parameter,widget in smu_map.items():
                    config.set('SMU_configuration',parameter,str(widget.value))

                # Add the sweeping gates
                config.add_section('Sweeping_gates')
                config.set('Sweeping_gates','Transfer',str(transfer_gates.value))
                config.set('Sweeping_gates','Output',str(output_gates.value))
                config.set('Sweeping_gates','Gatediode',str(terminal.value))
                
    
                config.write(configfile)
        except Exception as e:
            information_box(e)
        
        enable_widgets(all_widgets)


def on_import_ini_clicked(b):
    with output:
        disable_widgets(all_widgets)
        #load values to the interface
        config = configparser.ConfigParser()
        try:
            file = load_ini()
        except Exception as e:
            information_box(e)
            enable_widgets(all_widgets)
            return

        try:
            #read the values from each section
            config.read(file)
    
            #transfer curve
            integration_transfer.value = config.get('Transfer', "integration")
            for parameter,widget in Vtg_transfer.items():
                widget.value = config.get('Vtg_transfer',parameter)
            for parameter,widget in Vds_transfer.items():
                widget.value = config.get('Vds_transfer',parameter)
            for parameter,widget in Vbg_transfer.items():
                widget.value = config.get('Vbg_transfer',parameter)
            for parameter,widget in plot_transfer.items():
                widget.value = config.get('Plot_transfer',parameter)
            
            #output curve
            integration_output.value = config.get('Output','integration')
            for parameter,widget in Vtg_output.items():
                widget.value = config.get('Vtg_output',parameter)
            for parameter,widget in Vds_output.items():
                widget.value = config.get('Vds_output',parameter)
            for parameter,widget in Vbg_output.items():
                widget.value = config.get('Vbg_output',parameter)
    
            for parameter,widget in plot_output.items():
                widget.value = config.get('Plot_output',parameter)
        
            # gatediode
            integration_gatediode.value = config.get('Gatediode','integration')
            for parameter,widget in Vg_gatediode.items():
                widget.value = config.get('Vg_gatediode',parameter)
    
            for parameter,widget in plot_gatediode.items():
                widget.value = config.get('Plot_gatediode',parameter)
    
            # SMU map
            for parameter,widget in smu_map.items():
                widget.value = int(config.get('SMU_configuration',parameter))
            
            # sweeping gates
            transfer_gates.value = config.get('Sweeping_gates','Transfer')
            output_gates.value = config.get('Sweeping_gates','Output')
            terminal.value = config.get('Sweeping_gates','Gatediode')
    
            information_box("all parameters loaded succesfully")
        except Exception as error:
            if type(error).__name__ =='NoSectionError':
                information_box(f"{error}.Explanation: Section(header) [section] does not exist. Create a new ini file or compare it with functional ini files!")
            elif type(error).__name__=='NoOptionError':
                information_box(f'{error}.Explanation: The variable name before the equal sign is not recognized. Create a new ini file or compare it with functional ini files!')
            elif type(error).__name__ == 'TraitError':
                information_box(f'{error}.Explanation: Invalid Parameter Setting. Check if you set an invalid value!')
            elif type(error).__name__ =="DuplicateOptionError":
                information_box(f"{error}. Explaination: The section contains the setted parameter more than once!")
            else:
                information_box(f"A {type(error).__name__} has occurred. Create A new ini file")
        enable_widgets(all_widgets)

            
button.on_click(on_start_clicked)
quick_button.on_click(on_quick_clicked)
import_ini_button.on_click(on_import_ini_clicked)
export_ini_button.on_click(on_export_ini_clicked)