import pyvisa
from enum import Enum




class Channel(Enum):
    Channel1 = 1
    Channel2 = 2
    Channel3 = 3
    Channel4 = 4
    Channel5 = 5
    Channel6 = 6
    Channel7 = 7
    Channel8 = 8

class State(Enum):
    OFF = 0
    ON = 1

class MarkerOutState(Enum):
    OFF = "OFF"
    ON = "ON"

class VoltageUnit(Enum):
    VPP = "VPP"
    VRMS = "VRMS"
    DBM = "DBM"

class Value(Enum):
    PRESENT = ""
    MAXIMUM = "MAXimum"
    MINIMUM = "MINimum"

class Shape1(Enum):
    Sine = "SINusoid"
    Square = "SQUare"
    Pulse = "PULSe"
    Ramp = "RAMP"
    PR_Noise = "PRNoise"
    DC = "DC"
    Sinc = "SINC"
    Gaussian = "GAUSsian"
    Lorentz = "LORentz"
    Exp_Rise = "ERISe"
    Exp_Dec = "EDECay"
    Haversine = "HAVersine"
    Arbitrary = "ARBB"
    EFILe = "EFILe"
    Double_Pulse = "DOUBLEPULse"

class ModulatingSource(Enum):
    Int = "INTernal"
    Ext = "External"

class ModulatingInput(Enum):
    Mod1 = "MODIN1"
    Mod2 = "MODIN2"
    Mod3 = "MODIN3"
    Mod4 = "MODIN4"

class ModulatingShape(Enum): 
    Sine = "SIN"
    Square = "SQU"
    Triangle = "TRI"
    Pos_Ramp = "RAMP"
    Neg_Ramp = "NRAM"
    Noise = "PRN"
    Arbitrary = "ARBB"
    EFILe = "EFILe"

class SweepMode(Enum):
    Repeated = "SWE"
    Triggered = "CW"

class TriggerMode(Enum):
    Manual = "MAN"
    Auto = "AUTO"

class SweepShape(Enum):
    Linear = "LIN"
    Logarithmic = "LOG"
    Upstair = "UPS"
    Arbitrary = "ARBB"
    User = "User"

class BurstMode(Enum): 
    One_cycle = "TONECycle"
    Triggered = "TRIGgered"
    Infinite = "TCONTinuous"
    Gated = "GATEd"

class Ncycles(Enum):
    Number = 0
    Infinity = "INF"
    Min = "MINimum"
    Max = "MAXimum"

class WaitState(Enum):
    First_sample = "FIRST"
    Last_sample = "LAST"

class NoiseState(Enum):
    ON = "NOISe"
    OFF = "NONe"

class Polarity(Enum):
    Normal = "NORM"
    Inverted = "INV"

class Trigger(Enum):
    Trigger1 = "IN1"
    Trigger2 = "IN2"
    Trigger3 = "IN3"
    Trigger4 = "IN4"

class ChannelOptimization(Enum):
    Low_Noise = "LOWN"
    High_Linearity = "HLIN"

class ClockSource(Enum):
    Internal = "INT"
    External = "EXT"
    Reference = "REF"

class ExtClockFrequency(Enum):
    Low = 64
    Medium = 32
    Fast = 16
    Max = 8

class SyncClockOutFrequency(Enum):
    MHz_500 = "1"
    MHz_250 = "2"
    MHz_125 = "3"
    MHz_62_5 = "4"
    MHz_31_25 = "5"
    MHz_15_625 = "6"
    MHz_7_8125 = "7"
    MHz_3_90625 = "8"

class APP(Enum):
    TrueArb = "TA"
    PatternGenerator = "DPG"

class BufferTarget(Enum):
    Carrier = "CAR"
    Modulation = "MOD"
    Sweep = "SWE"

class Memory(Enum):
    Memory0 = 0
    Memory1 = 1
    Memory2 = 2
    Memory3 = 3
    Memory4 = 4

class ArbitraryWaveformSource(Enum):
    List = 0
    File = 1

class TriggerSource(Enum):
    Timer = "TIM"
    External = "EXT"
    Button = "MAN"

class Slope(Enum): 
    Positive = "RISing"
    Negative = "FALLing"
    Both = "BOTH"

class Impedance(Enum):
    High = "1KOhm"
    Normal = "50Ohm"

class Speed(Enum):
    Slow = "SLOW"
    Fast = "FAST"











class AFG7000():
    def __init__(self, instrument: pyvisa.resources.tcpip.TCPIPInstrument, error_control=True):
        """This class can be used to send instruction to any AWG5000 by Active TRechnologies.
            ARGS: instrument: TCP/IP address of the instrument;
                error_control: set this flag to true to manage possible exceptions thrown by query or write. The code will be slower"""
        self.instrument = instrument
        self.error_control= error_control

    def Close(self):
        self.instrument.close()
    
    def ErrorQuery(self):
        try: return self.instrument.query(f"SYST:ERR?")
        except Exception as e: print(f"Was not able to receive error message from intrument because of the following error: {e}")
    
    #Write and query methods with exception management
    def CheckWrite(self, string: str):
        if self.error_control:
            try:
                self.instrument.write(string)
            except Exception as e: raise Exception(e)
            else:
                error: str = self.ErrorQuery()
                if not error.startswith("0"): raise Exception(error)
        else: self.instrument.write(string)

    def CheckQuery(self, string: str):
        if self.error_control:
            try:
                result: str = self.instrument.query(string)
            except Exception as e: raise Exception(e)
            else:
                error: str = self.ErrorQuery()
                if not error.startswith("0"): raise Exception(error)
                else: return result
        else: return self.instrument.query(string)

    


    #ACTION STATUS
    def AFGStart(self):
        self.CheckWrite("AFGControl:START")
    
    def AFGStop(self):
        self.CheckWrite("AFGControl:STOP")
    
    def GetAFGStatus(self):
        return self.CheckQuery("AFGControl:STATus?")

    def SendTrigger(self):
        self.CheckWrite("*TRG")
    
    def ReleaseTrigger(self):
        self.CheckWrite("ABORt")
    
    def GetOutputState(self, channel: Channel):
        return self.CheckQuery(f"OUTPut{channel.value}:STATe?")
    
    def SetOutputState(self, channel: Channel, state: State): 
        self.CheckWrite(f"OUTPut{channel.value}:STATe {state.value}")

    def Initialize(self, reset: bool = False, ID_query: bool = True):
        try:
            self.instrument.timeout = 180000
            self.CheckWrite("*CLS")
            if ID_query == True:
                ID = self.CheckQuery("*IDN?")
                possible_IDs = ["ACTIVE TECHNOLOGIES,AWG7202,", "ACTIVE TECHNOLOGIES,AWG7202D,", "ACTIVE TECHNOLOGIES,AWG7172,", "ACTIVE TECHNOLOGIES,AWG7172D,",
                                "ACTIVE TECHNOLOGIES,AWG7102,", "ACTIVE TECHNOLOGIES,AWG7102D,", "ACTIVE TECHNOLOGIES,AWG7204,", "ACTIVE TECHNOLOGIES,AWG7204D,",
                                "ACTIVE TECHNOLOGIES,AWG7174,", "ACTIVE TECHNOLOGIES,AWG7174D,", "ACTIVE TECHNOLOGIES,AWG7104,", "ACTIVE TECHNOLOGIES,AWG7104D,",
                                "ACTIVE TECHNOLOGIES,AWG7204S,", "ACTIVE TECHNOLOGIES,AWG7204DS,", "ACTIVE TECHNOLOGIES,AWG7174S,", "ACTIVE TECHNOLOGIES,AWG7172DS,",
                                "ACTIVE TECHNOLOGIES,BAWG7202,", "ACTIVE TECHNOLOGIES,BAWG7202D,", "ACTIVE TECHNOLOGIES,BAWG7204,", "ACTIVE TECHNOLOGIES,BAWG7204D,"]
                for i in range(len(possible_IDs)):
                    if ID.startswith(possible_IDs[i]):
                        self.model = possible_IDs[i]
                        if i in [0, 1, 2, 3, 4, 5, 16, 17]:
                            self.number_of_channels = 2
                            self.channels = [Channel.Channel1, Channel.Channel2]
                            self.number_of_markers = 2
                        else:
                            self.number_of_channels = 4
                            self.channels = [Channel.Channel1, Channel.Channel2, Channel.Channel3, Channel.Channel4]
                            self.number_of_markers = 4
                        if reset == True: self.Reset()
                        break
                    elif i == 19: raise Exception("Initialization failed: instrument ID not found")
            else:
                self.number_of_channels = 2
                self.channels = [Channel.Channel1, Channel.Channel2]
                self.number_of_markers = 2
        except Exception as e:
            self.Close()
            raise Exception(e)


    #BASIC
    #Carrier
    def GetVoltageUnit(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:UNIT?")
    
    def SetVoltageUnit(self, channel: Channel, unit: VoltageUnit):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:UNIT {unit.value}")
    
    def GetVoltageAmplitude(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:AMPLitude? {minmax.value}")
    
    def SetVoltageAmplitude(self, channel: Channel, amplitude: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:AMPLitude {amplitude}")
    
    def GetVoltageHigh(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:HIGH? {minmax.value}")
    
    def SetVoltageHigh(self, channel: Channel, voltage_high: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:HIGH {voltage_high}")
    
    def GetVoltageLow(self, channel: Channel, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:LOW? {minmax.value}")

    def SetVoltageLow(self, channel: Channel, voltage_low: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:LOW {voltage_low}")
    
    def GetVoltageOffset(self, channel: Channel, minmax: Value):  
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:OFFSet? {minmax.value}")
    
    def SetVoltageOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:OFFSet {offset}")
    
    def GetFrequency(self, channel: Channel, minmax: Value):  
        return self.CheckQuery(f"SOURce{channel.value}:FREQuency? {minmax.value}")

    def SetFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:FREQuency {frequency}")
    
    def GetVoltagePhase(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:PHASe? {minmax.value}")

    def SetVoltagePhase(self, channel: Channel, phase: float):
        self.CheckWrite(f"SOURce{channel.value}:PHASe {phase}")
    
    def GetFunctionShape(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FUNCtion:SHAPe?")
    
    def SetFunctionShape(self, channel: Channel, shape: Shape1):
        self.CheckWrite(f"SOURce{channel.value}:FUNCtion:SHAPe {shape.value}")
    
    def GetFunctionEFILe(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FUNCtion:EFILe?")
    
    def SetFunctionEFILe(self, channel:int, file: str): #file: Absolute or relative path
        self.CheckWrite(f"SOURce{channel.value}:FUNCtion:EFILe \"{file}\"")
    
    def GetRampSymmetry(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:FUNCTion:RAMP:SYMMetry? {minmax.value}")
    
    def SetRampSymmetry(self, channel: Channel, symmetry: float):
        self.CheckWrite(f"SOURce{channel.value}:FUNCtion:RAMP:SYMMetry {symmetry}")

    def GetPulseDutyCycle(self, channel: Channel, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:PULSe:DCYCle? {minmax.value}")
    
    def SetPulseDutyCycle(self, channel: Channel, dc: float):
        self.CheckWrite(f"SOURce{channel.value}:PULSe:DCYCle {dc}")

    def GetPulsePeriod(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:PULSe:PERiod? {minmax.value}")

    def SetPulsePeriod(self, channel: Channel, period: float):
        self.CheckWrite(f"SOURce{channel.value}:PULSe:PERiod {period}")
    
    def GetPulseLeading(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:PULSe:TRANsition:LEADing? {minmax.value}")

    def SetPulseLeading(self, channel: Channel, leading: float):
        self.CheckWrite(f"SOURce{channel.value}:PULSe:TRANsition:LEADing {leading}")

    def GetPulseTrailing(self, channel: Channel, minmax: Value):  
        return self.CheckQuery(f"SOURce{channel.value}:PULSe:TRANsition:TRAiling? {minmax.value}")

    def SetPulseTrailing(self, channel: Channel, trailing: float):
        self.CheckWrite(f"SOURce{channel.value}:PULSe:TRANsition:TRAiling {trailing}")

    def GetPulseWidth(self, channel: Channel, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:PULSe:WIDTh? {minmax.value}")

    def SetPulseWidth(self, channel: Channel, width: float):
        self.CheckWrite(f"SOURce{channel.value}:PULSe:WIDT {width}")

    def GetDoublePulseAmplitude(self, channel: Channel, pulse: int, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:AMPLitude? {minmax.value}")

    def SetDoublePulseAmplitude(self, channel: Channel, pulse: int, amplitude: float):
        self.CheckWrite(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:AMPLitude {amplitude}")

    def GetDoublePulseDelay(self, channel: Channel, pulse: int, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:DELay? {minmax.value}")

    def SetDoublePulseDelay(self, channel: Channel, pulse: int, delay: float):
        self.CheckWrite(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:DELay {delay}")

    def GetDoublePulseLeading(self, channel: Channel, pulse: int, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:TRANsition:LEADing? {minmax.value}")

    def SetDoublePulseLeading(self, channel: Channel, pulse: int, leading: float):
        self.CheckWrite(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:TRANsition:LEADing {leading}")

    def GetDoublePulseTrailing(self, channel: Channel, pulse: int, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:TRANsition:TRAiling? {minmax.value}")

    def SetDoublePulseTrailing(self, channel: Channel, pulse: int, trailing: float):
        self.CheckWrite(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:TRANsition:TRAiling {trailing}")

    def GetDoublePulseWidth(self, channel: Channel, pulse: int, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:WIDTh? {minmax.value}")
        
    def SetDoublePulseWidth(self, channel: Channel, pulse: int, width: float):
        self.CheckWrite(f"SOURce{channel.value}:DOUBLEPULSe:PULSe{pulse}:WIDTh {width}")

    #General Modulation
    def GetModulatingPeriod(self, channel: Channel, minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:MODulation:PERiod? {minmax.value}")
    
    def SetModulatingPeriod(self, channel: Channel, period: float):
        self.CheckWrite(f"SOURce{channel.value}:MODulation:PERiod {period}")

    def GetModulatingSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:MODulation:SOURCe?")
    
    def SetModulatingSource(self, channel: Channel, source: ModulatingSource):
        self.CheckWrite(f"SOURce{channel.value}:MODulation:SOURCe {source.value}")

    def GetExternalModulatingInput(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:MODulation:SOURce:EXTModulin?")
    
    def SetExternalModulatingInput(self, channel: Channel, input: ModulatingInput):
        self.CheckWrite(f"SOURce{channel.value}:MODulation:SOURce:EXTModulin {input.value}")

    #Frequency Modulation
    def GetFMState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FM:STATe?")
    
    def SetFMState(self, channel: Channel, state: State): 
        self.CheckWrite(f"SOURce{channel.value}:FM:STATe {state.value}")

    def GetFMSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FM:SOURce?")
    
    def SetFMSource(self, channel: Channel, source: ModulatingSource): 
        self.CheckWrite(f"SOURce{channel.value}:FM:SOURce {source.value}")

    def GetFMDeviation(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:FM:DEViation?  {minmax.value}")

    def SetFMDeviation(self, channel: Channel, deviation: float):
        self.CheckWrite(f"SOURce{channel.value}:FM:DEViation {deviation}")

    def GetFMInternalFrequency(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:FM:INTernal:FREQuency? {minmax.value}")
    
    def SetFMInternalFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:FM:INTernal:FREQuency {frequency}")

    def GetFMInternalFunctionEFILe(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FM:INTernal:FUNCtion:EFILe?")
    
    def SetFMInternalFunctionEFILe(self, channel: Channel, file: str):  #file must be the absolute or relative path
        self.CheckWrite(f"SOURce{channel.value}:FM:INTernal:FUNCtion:EFILe \"{file}\"")

    def GetFMInternalFunction(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FM:INTernal:FUNCtion?")

    def SetFMInternalFunction(self, channel: Channel, function: ModulatingShape):   
        self.CheckWrite(f"SOURce{channel.value}:FM:INTernal:FUNCtion {function.value}")

    #Amplitude Modulation
    def GetAMState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:AM:STATe?")
    
    def SetAMState(self, channel: Channel, state: State): 
        self.CheckWrite(f"SOURce{channel.value}:AM:STATe {state.value}")

    def GetAMSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:AM:SOURce?")
    
    def SetAMSource(self, channel: Channel, source: ModulatingSource):   
        self.CheckWrite(f"SOURce{channel.value}:AM:SOURce {source.value}")

    def GetAMDepth(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:AM:DEPTh?")
    
    def SetAMDepth(self, channel: Channel, depth: float):
        self.CheckWrite(f"SOURce{channel.value}:AM:DEPTh {depth}")

    def GetAMInternalFrequency(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:AM:INTernal:FREQuency? {minmax.value}")
    
    def SetAMInternalFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:AM:INTernal:FREQuency {frequency}")

    def GetAMInternalFunctionEFILe(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:AM:INTernal:FUNCtion:EFILe?")
    
    def SetAMInternalFunctionEFILe(self, channel: Channel, file: str): #file is the absolute or relative path
        self.CheckWrite(f"SOURce{channel.value}:AM:INTernal:FUNCtion:EFILe \"{file}\"")

    def GetAMInternalFunction(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:AM:INTernal:FUNCtion?")

    def SetAMInternalFunction(self, channel: Channel, function: ModulatingShape):   
        self.CheckWrite(f"SOURce{channel.value}:AM:INTernal:FUNCtion {function.value}")

    #Phase modulation
    def GetPMState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PM:STATe?")
    
    def SetPMState(self, channel: Channel, state: State): 
        self.CheckWrite(f"SOURce{channel.value}:PM:STATe {state.value}")

    def GetPMSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PM:SOURce?")
    
    def SetPMSource(self, channel: Channel, source: ModulatingSource):   
        self.CheckWrite(f"SOURce{channel.value}:PM:SOURce {source.value}")

    def GetPMDeviation(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:PM:DEViation?  {minmax.value}")

    def SetPMDeviation(self, channel: Channel, deviation: float):
        self.CheckWrite(f"SOURce{channel.value}:PM:DEViation {deviation}")

    def GetPMInternalFrequency(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:PM:INTernal:FREQuency? {minmax.value}")
    
    def SetPMInternalFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:PM:INTernal:FREQuency {frequency}")

    def GetPMInternalFunctionEFILe(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PM:INTernal:FUNCtion:EFILe?")
    
    def SetPMInternalFunctionEFILe(self, channel: Channel, file: str):  #file must be the absolute or relative path
        self.CheckWrite(f"SOURce{channel.value}:PM:INTernal:FUNCtion:EFILe \"{file}\"")

    def GetPMInternalFunction(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PM:INTernal:FUNCtion?")

    def SetPMInternalFunction(self, channel: Channel, function: ModulatingShape):   
        self.CheckWrite(f"SOURce{channel.value}:PM:INTernal:FUNCtion {function.value}")

    #Frequency Shift Keying Modulation
    def GetFSKState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FSKey:STATe?")
    
    def SetFSKState(self, channel: Channel, state: State):    
        self.CheckWrite(f"SOURce{channel.value}:FSKey:STATe {state.value}")

    def GetFSKSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FSKey:SOURce?")
    
    def SetFSKSource(self, channel: Channel, source: ModulatingSource):  
        self.CheckWrite(f"SOURce{channel.value}:FSKey:SOURce {source.value}")
    
    def GetFSKHopFrequency(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:FSKey:FREQuency? {minmax.value}")
    
    def SetFSKHopFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:FSKey:FREQuency {frequency}")
    
    def GetFSKInternalRate(self, channel:int,  minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:FSKey:INTernal:RATE? {minmax.value}")
    
    def SetFSKInternalRate(self, channel:int, internal_rate: float):
        return self.CheckWrite(f"SOURce{channel.value}:FSKey:INTernal:RATE {internal_rate}")
    
    #Phase Shift Keying
    def GetPSKState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PSKey:STATe?")
    
    def SetPSKState(self, channel: Channel, state: State):    
        self.CheckWrite(f"SOURce{channel.value}:PSKey:STATe {state.value}")

    def GetPSKSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PSKey:SOURce?")
    
    def SetPSKSource(self, channel: Channel, source: ModulatingSource):  
        self.CheckWrite(f"SOURce{channel.value}:PSKey:SOURce {source.value}")
    
    def GetPSKFrequency(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:PSKey:FREQuency? {minmax.value}")
    
    def SetPSKFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:PSKey:FREQuency {frequency}")
    
    def GetPSKPhase(self, channel:int,  minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:PSKey:PHASe? {minmax.value}")
    
    def SetPSKPhase(self, channel:int, phase: float):
        return self.CheckWrite(f"SOURce{channel.value}:PSKey:PHASe {phase}")
    
    #Pulse Width Modulation
    def GetPWMState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PWM:STATe?")
    
    def SetPWMState(self, channel: Channel, state: State):    
        self.CheckWrite(f"SOURce{channel.value}:PWM:STATe {state.value}")

    def GetPWMSource(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PWM:SOURce?")
    
    def SetPWMSource(self, channel: Channel, source: ModulatingSource):  
        self.CheckWrite(f"SOURce{channel.value}:PWM:SOURce {source.value}")

    def GetPWMInternalFrequency(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:PWM:INTernal:FREQuency? {minmax.value}")
    
    def SetPWMInternalFrequency(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:PWM:INTernal:FREQuency {frequency}")

    def GetPWMDeviation(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:PWM:DCYCle? {minmax.value}")

    def SetPWMDeviation(self, channel: Channel, deviation: float):
        self.CheckWrite(f"SOURce{channel.value}:PWM:DCYCle {deviation}")

    def GetPWMInternalFunctionEFILe(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PWM:INTernal:FUNCtion:EFILe?")
    
    def SetPWMInternalFunctionEFILe(self, channel: Channel, file: str): #file must be the absolute or relative path
        self.CheckWrite(f"SOURce{channel.value}:PWM:INTernal:FUNCtion:EFILe \"{file}\"")

    def GetPWMInternalFunction(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:PWM:INTernal:FUNCtion?")

    def SetPWMInternalFunction(self, channel: Channel, function: ModulatingShape): 
        self.CheckWrite(f"SOURce{channel.value}:PWM:INTernal:FUNCtion {function.value}")

    #Sweep
    def GetSweepState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:FREQuency:MODE?")
    
    def SetSweepState(self, channel: Channel, state: SweepMode):  
        self.CheckWrite(f"SOURce{channel.value}:FREQuency:MODE {state.value}")

    def GetSweepStartFrequency(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:FREQuencySTARt? {minmax.value}")
    
    def SetSweepStartFrequency(self, channel: Channel, start_frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:FREQuencySTARt {start_frequency}")

    def GetSweepStopFrequency(self, channel: Channel, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:FREQuencySTOP? {minmax.value}")
    
    def SetSweepStopFrequency(self, channel: Channel, stop_frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:FREQuencySTOP {stop_frequency}")

    def GetSweepRiseTime(self, channel: Channel, minmax: Value):  
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:TIME? {minmax.value}")
    
    def SetSweepRiseTime(self, channel: Channel, rise_time: float):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:TIME {rise_time}")

    def GetSweepHoldTime(self, channel: Channel, minmax: Value):  
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:HTIMe? {minmax.value}")
    
    def SetSweepHoldTime(self, channel: Channel, hold_time: float):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:HTIMe {hold_time}")

    def GetSweepReturnTime(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:RTIMe? {minmax.value}")
    
    def SetSweepReturnTime(self, channel: Channel, return_time: float):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:RTIMe {return_time}")

    def GetSweepStepNumber(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:NSTEP? {minmax.value}")
    
    def SetSweepStepNumber(self, channel: Channel, step_number: float):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:NSTEP {step_number}")

    def GetSweepTriggerMode(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:MODE?")
    
    def SetSweepTriggerMode(self, channel: Channel, manauto: TriggerMode):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:MODE {manauto.value}")

    def GetSweepShape(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:SPACing?")
    
    def SetSweepShape(self, channel: Channel, shape: SweepShape):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:SPACing {shape.value}")

    def GetSweepInternalFunctionEFILe(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:SPACing:EFILe?")

    def SetSweepInternalFunctionEFILe(self, channel: Channel, file: str):   #file must be the absolute or relative path
        self.CheckWrite(f"SOURce{channel.value}:SWEep:SPACing:EFILe \"{file}\"")

    def GetSweepFrequencyArbMode(self, channel: Channel, minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:FREQuency? {minmax.value}")

    def SetSweepFrequencyArbMode(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:FREQuency {frequency}")

    def GetSweepPeriodArbMode(self, channel: Channel, minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:SWEep:PERiod? {minmax.value}")

    def SetSweepPeriodArbMode(self, channel: Channel, frequency: float):
        self.CheckWrite(f"SOURce{channel.value}:SWEep:PERiod {frequency}")

    #Burst
    def GetBurstState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:BURSt:STATe?")
    
    def SetBurstState(self, channel: Channel, state: State):  
        self.CheckWrite(f"SOURce{channel.value}:BURSt:STATe {state.value}")
    
    def GetBurstMode(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:BURSt:MODE?")
    
    def SetBurstMode(self, channel: Channel, mode: BurstMode):    
        self.CheckWrite(f"SOURce{channel.value}:BURSt:MODE {mode.value}")
    
    def GetBurstNCycles(self, channel: Channel, minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:BURSt:NCYCles? {minmax.value}")
    
    def SetBurstNCycles(self, channel: Channel, ncycles: Ncycles, burst_count: int):
        if ncycles == Ncycles.Number: self.CheckWrite(f"SOURce{channel.value}:BURSt:NCYCles {burst_count}")
        else: self.CheckWrite(f"SOURce{channel.value}:BURSt:NCYCles {ncycles.value}")
    
    def GetBurstTDelay(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:BURSt:TDELay?")
    
    def SetBurstTDelay(self, channel: Channel, delay: float):
        self.CheckWrite(f"SOURce{channel.value}:BURSt:TDELay {delay}")
    
    def GetBurstWaitState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:BURSt:WAIT:STATe?")
    
    def SetBurstWaitState(self, channel: Channel, first_last: WaitState):  
        self.CheckWrite(f"SOURce{channel.value}:BURSt:WAIT:STATe {first_last.value}")
    
    def GetBurstDuration(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:BURSt:DURation?")
    
    def SetBurstDuration(self, channel: Channel, duration: float):
        self.CheckWrite(f"SOURce{channel.value}:BURSt:DURation {duration}")

    #Channel Settings
    def GetInitialDelay(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:INITDELay? {minmax.value}")
    
    def SetInitialDelay(self, channel: Channel, initial_delay: float):
        self.CheckWrite(f"SOURce{channel.value}:INITDELay {initial_delay}")
    
    def GetOutputPolarity(self, channel: Channel):
        return self.CheckQuery(f"OUTPut{channel.value}:POLarity?")
    
    def SetOutputPolarity(self, channel: Channel, polarity: Polarity):
        self.CheckWrite(f"OUTPut{channel.value}:POLarity {polarity.value}")
    
    def GetLoadImpedance(self, channel: Channel, minmax: Value):  
        return self.CheckQuery(f"OUTPut{channel.value}:IMPedance? {minmax.value}")
    
    def SetLoadImpedance(self, channel: Channel, impedance: float):
        self.CheckWrite(f"OUTPut{channel.value}:IMPedance {impedance}")
    
    def GetVocm(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:VOCM? {minmax.value}")
    
    def SetVocm(self, channel: Channel, Vocm: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:VOCM {Vocm}")
    
    def GetBaselineOffset(self, channel: Channel, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:BASELINE:OFFSET? {minmax.value}")
    
    def SetBaselineOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:BASELINE:OFFSET {offset}")
    
    def GetInternalNoiseAmplitude(self, channel: Channel, minmax: Value): 
        return self.CheckQuery(f"SOURce{channel.value}:POWer:LEVel:IMMediate:AMPLitude? {minmax.value}")
    
    def SetInternalNoiseAmplitude(self, channel: Channel, noise_amplitude: float):
        self.CheckWrite(f"SOURce{channel.value}:POWer:LEVel:IMMediate:AMPLitude {noise_amplitude}")
    
    def GetInternalNoiseState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COMBine:FEED?")
    
    def SetInternalNoiseState(self, channel: Channel, noise_state: NoiseState):
        self.CheckWrite(f"SOURce{channel.value}:COMBine:FEED {noise_state.value}")
    
    def GetVoltageHighLimit(self, channel: Channel, minmax: Value):   
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:LIMit:HIGH? {minmax.value}")
    
    def SetVoltageHighLimit(self, channel: Channel, Vhlim: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:LIMit:HIGH {Vhlim}")
    
    def GetVoltageLowLimit(self, channel: Channel, minmax: Value):    
        return self.CheckQuery(f"SOURce{channel.value}:VOLTage:LIMit:LOW? {minmax.value}")
    
    def SetVoltageLowLimit(self, channel: Channel, Vllim: float):
        self.CheckWrite(f"SOURce{channel.value}:VOLTage:LIMit:LOW {Vllim}")

    def GetLinkedTrigger(self, channel: Channel):
        return self.CheckQuery(f"OUTPut{channel.value}:TRIGger:LINk?")
    
    def SetLinkedTrigger(self, channel: Channel, trigger: Trigger):
        self.CheckWrite(f"OUTPut{channel.value}:TRIGger:LINk {trigger.value}")

    def GetChannelOptimization(self, channel: Channel):
        return self.CheckQuery(f"OUTPut{channel.value}:OPTimization?")
    
    def SetChannelOptimization(self, channel: Channel, optimization: ChannelOptimization):
        self.CheckWrite(f"OUTPut{channel.value}:OPTimization {optimization.value}")

    def GetFlatnessCompensation(self, channel: Channel):
        return self.CheckQuery(f"OUTPut{channel.value}:FLATComp?")

    def SetFlatnessCompensation(self, channel: Channel, compensation: State):
        self.CheckWrite(f"OUTPut{channel.value}:FLATComp {compensation.value}")

    #Clock Settings
    def GetRefClockSource(self):
        return self.CheckQuery(f"SOURce:ROSCillator:SOURce?")
    
    def SetRefClockSource(self, source: ClockSource): 
        self.CheckWrite(f"SOURce:ROSCillator:SOURce {source.value}")
    
    def GetRefClkFrequency(self, minmax: Value): 
        return self.CheckQuery(f"SOURce:ROSCillator:FREQuency? {minmax.value}")
    
    def SetRefClkFrequency(self, frequency: float):
        self.CheckWrite(f"SOURce:ROSCillator:FREQuency {frequency}")
    
    def GetExtClkFrequency(self):
        return self.CheckQuery(f"EXTSampclock:VALue?")
    
    def SetExtClkFrequency(self, frequency: ExtClockFrequency):
        self.CheckWrite(f"EXTSampclock:DIVisor  {frequency.value}")

    def GetSynchClockOutState(self):
        return self.CheckQuery(f"SYNCclockout:STATe?")
    
    def SetSynchClockOutState(self, state: State): 
        self.CheckWrite(f"SYNCclockout:STATe {state.value}")

    def GetSynchClockOutFrequency(self):
        return self.CheckQuery(f"SYNCclockout:SELector?")
    
    def SetSynchClockOutFrequency(self, frequency: SyncClockOutFrequency): 
        self.CheckWrite(f"SYNCclockout:SELector {frequency.value}")

    #Trigger in
    def GetTriggerInSource(self): 
        return self.CheckQuery(f"TRIGger:SOURce?")
    
    def SetTriggerInSource(self, source: TriggerSource):
        self.CheckWrite(f"TRIGger:SOURce {source.value}")
    
    def GetTriggerInInterval(self, minmax: Value): 
        return self.CheckQuery(f"TRIGger:TIMer? {minmax.value}")
    
    def SetTriggerInInterval(self, interval: float):
        self.CheckWrite(f"TRIGger:TIMer {interval}")
    
    def GetTriggerInSlope(self):
        return self.CheckQuery(f"TRIGger:SLOPe?")
    
    def SetTriggerInSlope(self, slope: Slope):
        self.CheckWrite(f"TRIGger:SLOPe {slope.value}")
    
    def GetTriggerInThreshold(self, minmax: Value): 
        return self.CheckQuery(f"TRIGger:SEQuence:THREshold? {minmax.value}")
    
    def SetTriggerInThreshold(self, threshold: float): 
        self.CheckWrite(f"TRIGger:SEQuence:THREshold {threshold}")
    
    def GetTriggerInImpedance(self): 
        return self.CheckQuery(f"TRIGger:IMPedance?")
    
    def SetTriggerInImpedance(self, impedance: Impedance):
        self.CheckWrite(f"TRIGger:IMPedance {impedance.value}")
    
    def GetExternalTriggerInMode(self): #Instrument answers "FASE" instead of "FAST"
        return self.CheckQuery(f"TRIGger:MODe?")
    
    def SetExternalTriggerInMode(self, speed: Speed):
        self.CheckWrite(f"TRIGger:MODe {speed.value}")
    
    def GetExternalTriggerInFastDelay(self, minmax: Value):   
        return self.CheckQuery(f"TRIGger:FAST:DELay? {minmax.value}")
    
    def SetExternalTriggerInFastDelay(self, delay: float):
        self.CheckWrite(f"TRIGger:FAST:DELay {delay}")
    

    #Marker
    def GetMarkerOutState(self, marker: int):
        return self.CheckQuery(f"TRIGger{marker}:OUTPut:STATe?")
    
    def SetMarkerOutState(self, marker: int, state: MarkerOutState):   
        self.CheckWrite(f"TRIGger{marker}:OUTPut:STATe {state.value}")
    
    def GetMarkerOutVoltageHigh(self, marker: int, minmax: Value):
        return self.CheckQuery(f"TRIGger{marker}:OUTPut1:AMPLitude? {minmax.value}")
    
    def SetMarkerOutVoltageHigh(self, marker: int, voltage_high: float):
        self.CheckWrite(f"TRIGger{marker}:OUTPut1:AMPLitude {voltage_high}")
    
    def GetMarkerOutVoltageLow(self, marker: int, minmax: Value):
        return self.CheckQuery(f"TRIGger{marker}:OUTPut2:AMPLitude? {minmax.value}")
    
    def SetMarkerOutVoltageLow(self, marker: int, voltage_low: float):
        self.CheckWrite(f"TRIGger{marker}:OUTPut2:AMPLitude {voltage_low}")
    
    def GetMarkerWidthMode(self, marker: int):
        return self.CheckQuery(f"TRIGger{marker}:OUTPut:WIDTh:MODe?")
    
    def SetMarkerWidthMode(self, marker: int, manauto: TriggerMode):
        self.CheckWrite(f"TRIGger{marker}:OUTPut:WIDTh:MODe {manauto.value}")
    
    def GetMarkerWidthSecond(self, marker: int, minmax: Value):   
        return self.CheckQuery(f"TRIGger{marker}:OUTPut:WIDTh? {minmax.value}")
    
    def SetMarkerWidthSecond(self, marker: int, width: float):
        self.CheckWrite(f"TRIGger{marker}:OUTPut:WIDTh {width}")
    
    def GetMarkerWidthPercentage(self, marker: int, minmax: Value):   
        return self.CheckQuery(f"TRIGger{marker}:OUTPut:WIDTh:PERCent? {minmax.value}")
    
    def SetMarkerWidthPercentage(self, marker: int, percentage: float):
        self.CheckWrite(f"TRIGger{marker}:OUTPut:WIDTh:PERCent {percentage}")
    
    def GetMarkerOutContinuousSkew(self, marker: int, minmax: Value):   
        return self.CheckQuery(f"TRIGger{marker}:OUTPut:DELay? {minmax.value}")
    
    def SetMarkerOutContinuousSkew(self, marker: int, skew: float):
        self.CheckWrite(f"TRIGger{marker}:OUTPut:DELay {skew}")
    
    def GetMarkerOutTriggeredSkew(self, marker: int, minmax: Value):  
        return self.CheckQuery(f"MARKer:TRIGgered:SKEW{marker}? {minmax.value}")
    
    def SetMarkerOutTriggeredSkew(self, marker: int, skew: float):
        self.CheckWrite(f"MARKer:TRIGgered:SKEW{marker} {skew}")

    #Coupling
    def GetCoupleState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:STATe?")
    
    def SetCoupleState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:STATe {state.value}")

    def GetCoupleAmplitudeState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:AMPLitude:STATe?")

    def SetCoupleAmplitudeState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:AMPLitude:STATe {state.value}")

    def GetCoupleAmplitudeRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:AMPLitude:RATio? {minmax.value}")
    
    def SetCoupleAmplitudeRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:AMPLitude:RATio {ratio}")

    def GetCoupleAmplitudeOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:AMPLitude:OFFSet? {minmax.value}")
    
    def SetCoupleAmplitudeOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:AMPLitude:OFFSet {offset}")

    def GetCoupleOffsetState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:OFFSet:STATe?")
    
    def SetCoupleOffsetState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:OFFSet:STATe {state.value}")

    def GetCoupleOffsetRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:OFFSet:RATio? {minmax.value}")
    
    def SetCoupleOffsetRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:OFFSet:RATio {ratio}")

    def GetCoupleOffsetOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:OFFSet:OFFSet? {minmax.value}")
    
    def SetCoupleOffsetOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:OFFSet:OFFSet {offset}")
    
    def GetCoupleFrequencyState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:FREQuency:STATe?")
    
    def SetCoupleFrequencyState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:FREQuency:STATe {state.value}")

    def GetCoupleFrequencyRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:FREQuency:RATio? {minmax.value}")
    
    def SetCoupleFrequencyRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:FREQuency:RATio {ratio}")

    def GetCoupleFrequencyOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:FREQuency:OFFSet? {minmax.value}")
    
    def SetCoupleFrequencyOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:FREQuency:OFFSet {offset}")

    def GetCouplePhaseState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:PHASe:STATe?")
    
    def SetCouplePhaseState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:PHASe:STATe {state.value}")

    def GetCouplePhaseRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:PHASe:RATio? {minmax.value}")
    
    def SetCouplePhaseRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:PHASe:RATio {ratio}")

    def GetCouplePhaseOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:PHASe:OFFSet? {minmax.value}")
    
    def SetCouplePhaseOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:PHASe:OFFSet {offset}")

    def GetCoupleDutyCycleState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DCYCle:STATe?")
    
    def SetCoupleDutyCycleState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DCYCle:STATe {state.value}")

    def GetCoupleDutyCycleRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DCYCle:RATio? {minmax.value}")
    
    def SetCoupleDutyCycleRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DCYCle:RATio {ratio}")

    def GetCoupleDutyCycleOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DCYCle:OFFSet? {minmax.value}")
    
    def SetCoupleDutyCycleOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DCYCle:OFFSet {offset}")

    def GetCoupleLeadingState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:LEADing:STATe?")
    
    def SetCoupleLeadingState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:LEADing:STATe {state.value}")

    def GetCoupleLeadingRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:LEADing:RATio? {minmax.value}")
    
    def SetCoupleLeadingRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:LEADing:RATio {ratio}")

    def GetCoupleLeadingOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:LEADing:OFFSet? {minmax.value}")
    
    def SetCoupleLeadingOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:LEADing:OFFSet {offset}")

    def GetCoupleTrailingState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:TRAiling:STATe?")
    
    def SetCoupleTrailingState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:TRAiling:STATe {state.value}")

    def GetCoupleTrailingRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:TRAiling:RATio? {minmax.value}")
    
    def SetCoupleTrailingRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:TRAiling:RATio {ratio}")

    def GetCoupleTrailingOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:TRAiling:OFFSet? {minmax.value}")
    
    def SetCoupleTrailingOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:TRAiling:OFFSet {offset}")

    def GetCoupleSymmetryState(self, channel: Channel):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:SYMMetry:STATe?")
    
    def SetCoupleSymmetryState(self, channel: Channel, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:SYMMetry:STATe {state.value}")

    def GetCoupleSymmetryRatio(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:SYMMetry:RATio? {minmax.value}")
    
    def SetCoupleSymmetryRatio(self, channel: Channel, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:SYMMetry:RATio {ratio}")

    def GetCoupleSymmetryOffset(self, channel: Channel,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:SYMMetry:OFFSet? {minmax.value}")
    
    def SetCoupleSymmetryOffset(self, channel: Channel, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:SYMMetry:OFFSet {offset}")

    def GetCoupleDoublePulseAmplitudeState(self, channel: Channel, pulse: int):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:AMPLitude:STATe?")
    
    def SetCoupleDoublePulseAmplitudeState(self, channel: Channel, pulse: int, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:AMPLitude:STATe {state.value}")
    
    def GetCoupleDoublePulseAmplitudeRatio(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:AMPLitude:RATio? {minmax.value}")
    
    def SetCoupleDoublePulseAmplitudeRatio(self, channel: Channel, pulse: int, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:AMPLitude:RATio {ratio}")

    def GetCoupleDoublePulseAmplitudeOffset(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:AMPLitude:OFFSet? {minmax.value}")
    
    def SetCoupleDoublePulseAmplitudeOffset(self, channel: Channel, pulse: int, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:AMPLitude:OFFSet {offset}")

    def GetCoupleDoublePulseLeadingState(self, channel: Channel, pulse: int):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:LEADing:STATe?")
    
    def SetCoupleDoublePulseLeadingState(self, channel: Channel, pulse: int, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:LEADing:STATe {state.value}")
    
    def GetCoupleDoublePulseLeadingRatio(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:LEADing:RATio? {minmax.value}")
    
    def SetCoupleDoublePulseLeadingRatio(self, channel: Channel, pulse: int, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:LEADing:RATio {ratio}")

    def GetCoupleDoublePulseLeadingOffset(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:LEADing:OFFSet? {minmax.value}")
    
    def SetCoupleDoublePulseLeadingOffset(self, channel: Channel, pulse: int, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:LEADing:OFFSet {offset}")

    def GetCoupleDoublePulseTrailingState(self, channel: Channel, pulse: int):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:TRAiling:STATe?")
    
    def SetCoupleDoublePulseTrailingState(self, channel: Channel, pulse: int, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:TRAiling:STATe {state.value}")
    
    def GetCoupleDoublePulseTrailingRatio(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:TRAiling:RATio? {minmax.value}")
    
    def SetCoupleDoublePulseTrailingRatio(self, channel: Channel, pulse: int, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:TRAiling:RATio {ratio}")

    def GetCoupleDoublePulseTrailingOffset(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:TRAiling:OFFSet? {minmax.value}")
    
    def SetCoupleDoublePulseTrailingOffset(self, channel: Channel, pulse: int, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:TRAiling:OFFSet {offset}")

    def GetCoupleDoublePulseWidthState(self, channel: Channel, pulse: int):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:WIDTh:STATe?")
    
    def SetCoupleDoublePulseWidthState(self, channel: Channel, pulse: int, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:WIDTh:STATe {state.value}")
    
    def GetCoupleDoublePulseWidthRatio(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:WIDTh:RATio? {minmax.value}")
    
    def SetCoupleDoublePulseWidthRatio(self, channel: Channel, pulse: int, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:WIDTh:RATio {ratio}")

    def GetCoupleDoublePulseWidthOffset(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:WIDTh:OFFSet? {minmax.value}")
    
    def SetCoupleDoublePulseWidthOffset(self, channel: Channel, pulse: int, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:WIDTh:OFFSet {offset}")

    def GetCoupleDoublePulseDelayState(self, channel: Channel, pulse: int):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:DELay:STATe?")
    
    def SetCoupleDoublePulseDelayState(self, channel: Channel, pulse: int, state: State):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:DELay:STATe {state.value}")
    
    def GetCoupleDoublePulseDelayRatio(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:DELay:RATio? {minmax.value}")
    
    def SetCoupleDoublePulseDelayRatio(self, channel: Channel, pulse: int, ratio: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:DELay:RATio {ratio}")

    def GetCoupleDoublePulseDelayOffset(self, channel: Channel, pulse: int,  minmax: Value):
        return self.CheckQuery(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:DELay:OFFSet? {minmax.value}")
    
    def SetCoupleDoublePulseDelayOffset(self, channel: Channel, pulse: int, offset: float):
        self.CheckWrite(f"SOURce{channel.value}:COUPLE:DOUBLEPULSe:PULSe{pulse}:DELay:OFFSet {offset}")


    #UTILITY
    def Reset(self):
        self.CheckWrite("*RST")

    def AFGCopyChannels(self, channel: Channel):
        self.CheckWrite(f"AFGControl:COPY {channel.value}")

    def AFGAppSwitch(self, app: APP):
        self.CheckWrite(f"AFGControl:APPSwitch {app.value}")
    #note: to launch the SPG application you need the AWG-506X-PAT license option.

    def Date(self): return self.CheckQuery("DATE?")
    def Time(self): return self.CheckQuery("TIME?")

    #Beeper
    def GetSystemBeeperState(self):
        return self.CheckQuery(f"SYSTem:BEEPer:STATe?")
    
    def SetSystemBeeperState(self, state: State):
        self.CheckWrite(f"SYSTem:BEEPer:STATe {state.value}")
    
    def SystemBeeper(self):
        self.CheckWrite("SYSTem:BEEPer")

    #Arbitrary Waveform Transfer
    def ArbitraryTransferData(self, channel: Channel, waveform: list, buffer_target: BufferTarget):
        byteSamples = bytearray(2 * len(waveform))
        for i in range(len(waveform)):
            byteSamples[2 * i] = waveform[i] % 256
            byteSamples[2 * i + 1] = waveform[i] // 256
        command: str = f"TRACE{channel.value}:DATA {buffer_target.value}, "
        if self.error_control:
            try:
                self.instrument.write_binary_values(command, byteSamples, datatype='B', is_big_endian=True)
            except Exception as e: raise Exception(e)
            else:
                error: str = self.ErrorQuery()
                if not error.startswith("0"): raise Exception(error)
        else: self.instrument.write_binary_values(command, byteSamples, datatype='B', is_big_endian=True)
        
    def ArbitraryTransferFile(self, channel: Channel, buffer_target: BufferTarget, file: str):
        self.CheckWrite(f"TRACe{channel.value}:RECall \"{file}\",{buffer_target.value}")

    def GetArbitraryPoints(self, channel: Channel, minmax: Value, buffer_target: BufferTarget):
        return self.CheckQuery(f"TRACe{channel.value}:POINts? {minmax.value},{buffer_target.value}")

    def SaveArbitraryIntoFile(self, channel: Channel, buffer_target: BufferTarget, file: str):
        self.CheckWrite(f"TRACe{channel.value}:SAVE \"{file}\",{buffer_target.value}")

    #Memory device settings
    def CopySettingsFromFileToSetupMemory(self, file_from_currrent_directory: str, configuration_name: str):
        self.CheckWrite(f"MMEMory:LOAD:STATe \"{file_from_currrent_directory}.zip\",{configuration_name}")
    
    def CopySettingsFromSetupMemoryToFile(self, configuration_name: str, file_in_currrent_directory: str):
        self.CheckWrite(f"MMEMory:STORe:STATe {configuration_name},\"{file_in_currrent_directory}.zip\"")

    def DeleteMemory(self, memory: Memory):
        self.CheckWrite(f"MEMory:STATe:DELete {memory.value}")

    def LoadSettingsFromFile(self, configuration_file: str):
        self.CheckWrite(f"MEMory:RECall \"{configuration_file}\"")

    def LoadSettingsFromSetupMemory(self, memory: int):
        self.CheckWrite(f"*RCL {memory.value}")

    def MemoryStateValid(self, memory: Memory):
        self.CheckQuery(f"MEMory:STATe:VALid? {memory.value}")
    
    def SaveSettingsToFile(self, configuration_name: str):
        self.CheckWrite(f"MEMory:SAVE \"{configuration_name}\"")

    def SaveSettingsToSetupMemory(self, memory: Memory):
        self.CheckWrite(f"*SAV {memory.value}")


    #MULTIINSTRUMENT
    def Capture(self):
        self.CheckWrite(f"MIM:CAPTure")
    
    def Release(self):
        self.CheckWrite(f"MIM:RELease")

    def IsSlave(self):
        return self.CheckQuery(f"MIM:SLAve?")

    def GetMultiInstrumentID(self):
        return self.CheckQuery("MIM:ID?")
    
    def IsForwardPresent(self):
        return self.CheckQuery("MIM:FORWard?")
    
    def IsCaptured(self):
        return self.CheckQuery("MIM:CAPTured?")

    def GetCapturedDevices(self):
        return self.CheckQuery("MIM:NUMber?")
    
    #CONFIGURE
    def ConfigureStandardWaveform(self, channel: Channel, amplitude: float, unit: VoltageUnit, offset: float, frequency: float, phase: float, shape: Shape1, file: str):
        self.SetFunctionShape(channel, shape)
        if shape == Shape1.EFILe.value: self.SetFunctionEFILe(channel, file)
        self.SetVoltageUnit(channel, unit)
        self.SetVoltageAmplitude(channel, amplitude)
        self.SetVoltageOffset(channel, offset)
        if shape != Shape1.PR_Noise.name and shape != Shape1.DC.name: self.SetFrequency(channel, frequency)
        self.SetVoltagePhase(channel, phase)

    def ConfigurePulseWaveform(self, channel: Channel, duty_cycle: float, frequency: float, enable_set_period: bool, period: float, width: float, leading: float, trailing: float):
        self.SetFunctionShape(channel, Shape1.Pulse)
        if enable_set_period:
            self.SetPulsePeriod(channel, period)
            self.SetPulseWidth(channel, width)
        else:
            self.SetFrequency(channel, frequency)
            self.SetPulseDutyCycle(channel, duty_cycle)
        self.SetPulseLeading(channel, leading)
        self.SetPulseTrailing(channel, trailing)
    
    def ConfigureNoise(self, channel: Channel, amplitude: float, offset: float):
        self.SetVoltageAmplitude(channel, amplitude)
        self.SetVoltageOffset(channel, offset)

    def ConfigureArbitraryWaveform(self, channel: Channel, source: ArbitraryWaveformSource, buffer_target: BufferTarget, waveform: list, file: str):
        try:
            if source == ArbitraryWaveformSource.File: self.ArbitraryTransferFile(channel, buffer_target, file)
            else: self.ArbitraryTransferData(channel, waveform, buffer_target)
        except Exception as e: raise Exception(e)

    def ConfigureAmplitudeModulation(self, channel: Channel, AMshape: ModulatingShape, AMfreuqency: float, modulation_depth: float,
                                     source: ModulatingSource, state: State, file: str, modulating_input: ModulatingInput):
        try:
            self.SetAMState(channel, state)
            if state.value:
                self.SetAMSource(channel, source)
                self.SetAMDepth(channel, modulation_depth)
                if source == ModulatingSource.Int:
                    self.SetAMInternalFunction(channel, AMshape)
                    self.SetAMInternalFrequency(channel, AMfreuqency)
                else: self.SetExternalModulatingInput(channel, modulating_input)
                if AMshape == ModulatingShape.EFILe:
                    self.SetAMInternalFunctionEFILe(channel, file)
        except Exception as e: raise Exception(e)
    
    def ConfigureFrequencyModulation(self, channel: Channel, shape: ModulatingShape, freuqency: float, deviation: float, source: ModulatingSource,
                                     state: State, file: str, modulating_input: ModulatingInput):
        try:
            self.SetFMState(channel, state)
            if state.value:
                self.SetFMSource(channel, source)
                self.SetFMDeviation(channel, deviation)
                if source == ModulatingSource.Int:
                    self.SetFMInternalFunction(channel, shape)
                    self.SetFMInternalFrequency(channel, freuqency)
                else: self.SetExternalModulatingInput(channel, modulating_input)
                if shape == ModulatingShape.EFILe:
                    self.SetFMInternalFunctionEFILe(channel, file)
        except Exception as e: raise Exception(e)
    
    def ConfigurePhaseModulation(self, channel: Channel, shape: ModulatingShape, freuqency: float, deviation: float, source: ModulatingSource,
                                 modulating_input: ModulatingInput, state: State, file: str):
        try:
            self.SetPMState(channel, state)
            if state == State.ON:
                self.SetPMSource(channel, source)
                self.SetPMDeviation(channel, deviation)
                if source == ModulatingSource.Int:
                    self.SetPMInternalFunction(channel, shape)
                    self.SetPMInternalFrequency(channel, freuqency)
                else: self.SetExternalModulatingInput(channel, modulating_input)
                if shape == ModulatingShape.EFILe:
                    self.SetPMInternalFunctionEFILe(channel, file)
        except Exception as e: raise Exception(e)
    
    def ConfigureFSKModulation(self, channel: Channel, source: ModulatingSource, internal_rate: float, hop_frequency: float, state: State, modulating_input: ModulatingInput):
        try:
            self.SetFSKState(channel, state)
            if state.value:
                self.SetFSKSource(channel, source)
                if source == ModulatingSource.Int: self.SetFSKInternalRate(channel, internal_rate)
                else: self.SetExternalModulatingInput(channel, modulating_input)
                self.SetFSKHopFrequency(channel, hop_frequency)
        except Exception as e: raise Exception(e)
    
    def ConfigurePSKModulation(self, channel: Channel, source: ModulatingSource, internal_rate: float, phase: float, state: State, modulating_input: ModulatingInput):
        try:
            self.SetPSKState(channel, state)
            if state.value:
                self.SetPSKSource(channel, source)
                if source == ModulatingSource.Int: self.SetPSKFrequency(channel, internal_rate)
                else: self.SetExternalModulatingInput(channel, modulating_input)
                self.SetPSKPhase(channel, phase)
        except Exception as e: raise Exception(e)
    
    def ConfigurePulseWidthModulation(self, channel: Channel, state: State, source: ModulatingSource, shape: ModulatingShape, frequency: float,
                                      deviation: float, file: str, modulating_input: ModulatingInput):
        try:
            self.SetPWMState(channel, state)
            self.SetPWMSource(channel, source)
            if source == ModulatingSource.Int:
                self.SetPWMInternalFunction(channel, shape)
                self.SetAMInternalFrequency(channel, frequency)
            else: self.SetExternalModulatingInput(channel, modulating_input)
            self.SetPWMDeviation(channel, deviation)
            if shape == ModulatingShape.EFILe: self.SetPWMInternalFunctionEFILe(channel, file)
        except Exception as e: raise Exception(e)
    
    def ConfigureSweep(self, channel: Channel, state: SweepMode, startfrequency: float, stopfrequency: float, risetime: float, holdtime: float,
                       returntime: float, shape: SweepShape, trigger: SweepMode, stepnumber: int, file: str, arbitrary_frequency: float):
        try:
            self.SetSweepState(channel, state)
            if state == State.ON:
                self.SetSweepStartFrequency(channel, startfrequency)
                self.SetSweepStopFrequency(channel, stopfrequency)
                if shape not in [SweepShape.Arbitrary, SweepShape.User]:
                    self.SetSweepRiseTime(channel, risetime)
                    self.SetSweepHoldTime(channel, holdtime)
                    self.SetSweepReturnTime(channel, returntime)
                self.SetSweepShape(channel, shape)
                if shape == SweepShape.Upstair: self.SetSweepStepNumber(channel, stepnumber)
                elif shape == SweepShape.User: self.SetSweepInternalFunctionEFILe(channel, file)
                elif shape == SweepShape.Arbitrary: self.SetSweepFrequencyArbMode(channel, arbitrary_frequency)
                self.SetSweepTriggerMode(channel, trigger)
        except Exception as e: raise Exception(e)
    
    def ConfigureBurst(self, channel: Channel, state: State, mode: BurstMode, ncycles: Ncycles, burst_count: int, delay: float, wait_state_if_exp_or_arb: WaitState,
                       duration_if_noise: float):
        try:
            self.SetBurstState(channel, state)
            if state == State.ON:
                self.SetBurstMode(channel, mode)
                if mode == BurstMode.Gated: self.SetBurstNCycles(channel, ncycles, burst_count)
                self.SetBurstTDelay(channel, delay)
                shape = self.GetFunctionShape(channel)
                if "PRN" in shape: self.SetBurstDuration(channel, duration_if_noise)
                elif "EFILe" in shape or shape.startswith("ER") or shape.startswith("ED"): self.SetBurstWaitState(channel, wait_state_if_exp_or_arb)
        except Exception as e: raise Exception(e)
    
    def ConfigureChannelSettings(self, channel: Channel, delay: float, impedance: float, Vocm: float, baseline_offset: float, Vhigh: float, Vlow: float, noise_state: NoiseState,
                                 noise_amplitude: float, polarity_out: Polarity, optimization: ChannelOptimization, flatness_compensation: State, linked_trigger: Trigger):
        try:
            self.SetInitialDelay(channel, delay)
            self.SetLoadImpedance(channel, impedance)
            name = self.CheckQuery("*IDN?")
            if "D" in name: self.SetVocm(channel, Vocm)
            else: self.SetBaselineOffset(channel, baseline_offset)
            self.SetInternalNoiseState(channel, noise_state)
            if noise_state == State.ON: self.SetInternalNoiseAmplitude(channel, noise_amplitude)
            self.SetOutputPolarity(channel, polarity_out)
            self.SetVoltageHighLimit(channel, Vhigh)
            self.SetVoltageLowLimit(channel, Vlow)
            self.SetChannelOptimization(channel, optimization)
            self.SetFlatnessCompensation(channel, flatness_compensation)
            self.SetLinkedTrigger(channel, linked_trigger)
        except Exception as e: raise Exception(e)

    def ConfigureMarkerOut(self, state: State, marker: int, vhigh: float, vlow: float, skew: float, skew_for_triggered_modes: float, manauto: TriggerMode,
                           width: float):
        try:
            self.SetMarkerOutState(marker, state)
            if(state == State.ON):
                self.SetMarkerOutVoltageHigh(marker, vhigh)
                self.SetMarkerOutVoltageLow(marker, vlow)
                self.SetMarkerOutContinuousSkew(marker, skew)
                self.SetMarkerOutTriggeredSkew(marker, skew_for_triggered_modes)
                self.SetMarkerWidthMode(marker, manauto)
                self.SetMarkerWidthSecond(marker, width)
        except Exception as e: raise Exception(e)

    def ConfigureTriggerIn(self, source: TriggerSource, interval: float, slope: Slope, speed: Speed, threshold: float, fast_delay: float, impedance: Impedance):
        try:
            self.SetTriggerInSource(source)
            self.SetTriggerInThreshold(threshold)
            self.SetTriggerInSlope(slope)
            self.SetTriggerInInterval(interval)
            self.SetTriggerInImpedance(impedance)
            self.SetExternalTriggerInMode(speed)
            self.SetExternalTriggerInFastDelay(fast_delay)
        except Exception as e: raise Exception(e)

    def ConfigureRefernceClock(self, source: ClockSource, frequency: float, ext_frequency: ExtClockFrequency, clock_out_state: State, clock_out_frequency: SyncClockOutFrequency):
        try:
            self.SetRefClockSource(source)
            if source == ClockSource.Reference: self.SetRefClkFrequency(frequency)
            elif source == ClockSource.External: self.SetExtClkFrequency(ext_frequency)
            self.SetSynchClockOutState(clock_out_state)
            if clock_out_state == State.ON: self.SetSynchClockOutFrequency(clock_out_frequency)
        except Exception as e: raise Exception(e)

    def ConfigureDoublePulseWaveform(self, channel: Channel, frequency: float, offset: float, phase: float, amplitude1: float, amplitude2: float, width1: float, width2: float,
                                     delay1: float, delay2: float, leading1: float, leading2: float, trailing1: float, trailing2: float):
        try:
            self.SetFunctionShape(channel, Shape1.Double_Pulse)
            self.SetVoltageOffset(channel, offset)
            self.SetFrequency(channel, frequency)
            self.SetVoltagePhase(channel, phase)
            self.SetDoublePulseWidth(channel, 1, width1)
            self.SetDoublePulseAmplitude(channel, 1, amplitude1)
            self.SetDoublePulseLeading(channel, 1, leading1)
            self.SetDoublePulseTrailing(channel, 1, trailing1)
            self.SetDoublePulseDelay(channel, 1, delay1)
            self.SetDoublePulseWidth(channel, 2, width2)
            self.SetDoublePulseAmplitude(channel, 2, amplitude2)
            self.SetDoublePulseLeading(channel, 2, leading2)
            self.SetDoublePulseTrailing(channel, 2, trailing2)
            self.SetDoublePulseDelay(channel, 2, delay2)
        except Exception as e: raise Exception(e)

    def ConfigureChannelCouplingStandardWaveform(self, channel: Channel, couple_channel: State, couple_amplitude: State, couple_frequency: State, couple_offset: State, couple_phase: State,
                                                 amplitude_ratio: float, frequency_ratio: float, offset_ratio: float, phase_ratio: float,
                                                 amplitude_offset: float, frequency_offset: float, offset_offset: float, phase_offset: float):
        try:
            self.SetCoupleState(channel, couple_channel)
            self.SetCoupleAmplitudeState(channel, couple_amplitude)
            self.SetCoupleFrequencyState(channel, couple_frequency)
            self.SetCoupleOffsetState(channel, couple_offset)
            self.SetCouplePhaseState(channel, couple_phase)
            self.SetCoupleAmplitudeRatio(channel, amplitude_ratio)
            self.SetCoupleFrequencyRatio(channel, frequency_ratio)
            self.SetCoupleOffsetRatio(channel, offset_ratio)
            self.SetCouplePhaseRatio(channel, phase_ratio)
            self.SetCoupleAmplitudeOffset(channel, amplitude_offset)
            self.SetCoupleFrequencyOffset(channel, frequency_offset)
            self.SetCoupleOffsetOffset(channel, offset_offset)
            self.SetCouplePhaseOffset(channel, phase_offset)
        except Exception as e: raise Exception(e)
        #Note: Vcom is only available for differential models; baseline offset is available only for single-ended models

    def ConfigureChannelCouplingRamp(self, channel: Channel, couple_symmetry: State, symmetry_ratio: float, symmetry_offset: float):
        try:
            self.SetCoupleSymmetryState(channel, couple_symmetry)
            self.SetCoupleSymmetryRatio(channel, symmetry_ratio)
            self.SetCoupleSymmetryOffset(channel, symmetry_offset)
        except Exception as e: raise Exception(e)

    def ConfigureChannelCouplingPulse(self, channel: Channel, couple_leading: State, couple_trailing: State, couple_dc: State,
                                      leading_ratio: float, trailing_ratio: float, dc_ratio: float,
                                      leading_offset: float, trailing_offset: float, dc_offset: float):
        try:
            self.SetCoupleLeadingState(channel, couple_leading)
            self.SetCoupleTrailingState(channel, couple_trailing)
            self.SetCoupleDutyCycleState(channel, couple_dc)
            self.SetCoupleLeadingRatio(channel, leading_ratio)
            self.SetCoupleTrailingRatio(channel, trailing_ratio)
            self.SetCoupleDutyCycleRatio(channel, dc_ratio)
            self.SetCoupleLeadingOffset(channel, leading_offset)
            self.SetCoupleTrailingOffset(channel, trailing_offset)
            self.SetCoupleDutyCycleOffset(channel, dc_offset)
        except Exception as e: raise Exception(e)

    def ConfigureChannelCouplingNoiseOrDC(self, channel: Channel, offset: State, offset_ratio: float, offset_offset: float):
        try:
            self.SetCoupleOffsetState(channel, offset)
            self.SetCoupleOffsetRatio(channel, offset_ratio)
            self.SetCoupleOffsetOffset(channel, offset_offset)
        except Exception as e: raise Exception(e)