diff --git a/docs/changes/newsfragments/8658.breaking b/docs/changes/newsfragments/8658.breaking new file mode 100644 index 000000000000..04786d51a1cb --- /dev/null +++ b/docs/changes/newsfragments/8658.breaking @@ -0,0 +1,26 @@ +Several instrument driver parameters now return numbers or booleans instead of the raw string +from the instrument, or an integer for an on/off state. Code that compares the returned value to +a string, or to ``0``/``1`` by identity, needs updating: + +- ``Keithley2450.line_frequency`` and ``Keithley2450Sense.count`` now return ``int``, and + ``Keithley2450Sense.nplc`` and ``Keithley2450Source.delay`` return ``float``. +- ``Keithley7510Sense.user_delay`` now returns ``float``, and + ``Keithley7510Sense.average_count``, ``Keithley7510DigitizeSense.acq_rate`` and + ``Keithley7510DigitizeSense.count`` return ``int``. +- ``SR86xBuffer.count_capture_kilobytes`` now returns ``int``. +- ``RigolDG1062Burst.ncycles`` now returns ``int``, and ``RigolDG1062Burst.phase``, + ``RigolDG1062Burst.time_delay`` and ``RigolDG1062Channel.duty_cycle`` return ``float``. +- ``RigolDS1074Z.trigger_level`` and ``TektronixTPS2012.trigger_level`` now return ``float``. +- ``TektronixDPOHorizontal.record_length`` now returns ``int`` instead of ``float``, as the + record length is a number of samples. +- ``AgilentE8267C.pulse_width`` now returns ``float`` and its unit is ``s`` instead of ``ns``, + matching the value sent to and returned by the instrument. +- ``RohdeSchwarzRTO1000ScopeChannel.impedance`` and ``KeysightE4980A.range`` now return + ``float``. +- ``RohdeSchwarzZNBChannel.bandwidth`` now returns ``float``, e.g. ``10000.0`` instead of + ``10000``. +- The channel ``state`` and ``direct_output`` and the instrument ``DC_output`` of + ``TektronixAWG5014`` now return ``bool``. They accept ``True``/``False``, ``1``/``0`` and + ``"on"``/``"off"``. ``TektronixAWG5014.sequence_pos`` now returns ``int``. +- ``KeysightB1520A.ac_dc_volt_monitor`` now returns ``bool`` and also accepts ``1``/``0`` + and ``"on"``/``"off"``. diff --git a/docs/changes/newsfragments/8658.improved_driver b/docs/changes/newsfragments/8658.improved_driver new file mode 100644 index 000000000000..8a8c5a44acf5 --- /dev/null +++ b/docs/changes/newsfragments/8658.improved_driver @@ -0,0 +1,35 @@ +Most instrument driver parameters are now annotated with the type of their value, e.g. +``Parameter[float, Self]``, so static type checkers can infer the type returned by ``get`` +and accepted by ``set``. As part of this, the mock instruments no longer pass the default +``parameter_class=Parameter`` explicitly, and ``Keysight34980A.module`` is typed as a mapping +from slot number to switch matrix submodule. + +Fixed the following driver bugs found along the way: + +- ``RigolDS4000.enable_auto_scale`` always read back as ``True``, since ``bool("0")`` is + ``True``, and was set with ``True``/``False`` instead of ``1``/``0``. +- ``RohdeSchwarzRTO1000.trigger_mode`` queried the trigger source instead of the trigger mode. +- ``Keithley6500.digits`` sent a set command with a stray ``?``. +- ``MessageBuilder.pch_query`` of the Keysight B1500 sent ``PCH`` instead of ``PCH?``. +- ``LakeshoreModel325Heater.output_range`` accepted the high (25 W) range on loop 2, which is + only supported on loop 1. +- ``LakeshoreModel325Sensor.curve_index`` now accepts ``0`` (no curve), which the instrument + also reports when the selected curve does not match the input, and rejects non-integer values. +- The ``LakeshoreModel325`` curve list now includes user curve 35, so ``upload_curve(35, ...)`` + no longer raises an ``IndexError``. +- ``LakeshoreModel325Curve.get_data`` now reads all 200 points of a curve instead of 199. +- ``LakeshoreModel325Curve.set_data`` now writes curve points with 6 significant digits, the + resolution of the instrument, instead of rounding them to 3 decimals. +- ``LakeshoreModel325Sensor.curve`` now raises a ``RuntimeError`` when no curve is selected for + the sensor, instead of returning a curve 0, which the instrument does not have. +- ``RohdeSchwarzZNBChannel.bandwidth`` failed to read a non-integer bandwidth such as 1.5 Hz, + which the instrument supports. +- The ``current_compliance`` and ``power_compliance`` of the ``KeysightB1517A`` sweep could not + be set back to ``None``, which leaves the compliance out of the ``WV`` command. +- ``Keysight34980A.scan_slots`` can now be called again; it skips slots that already have a + module instead of failing to register a duplicate submodule. +- ``Keithley7510DigitizeSense.aperture`` was labelled in ``us`` although the instrument uses + seconds; its unit is now ``s``. +- ``averages``, ``points`` and ``active_trace`` of the Keysight PNA (``KeysightPNABase``) drivers + now reject non-integer values. Previously ``averages`` failed to format a float such as + ``2.5`` and the others sent it to the instrument. diff --git a/src/qcodes/instrument/sims/Agilent_E8257D.yaml b/src/qcodes/instrument/sims/Agilent_E8257D.yaml new file mode 100644 index 000000000000..af4816d6bbbc --- /dev/null +++ b/src/qcodes/instrument/sims/Agilent_E8257D.yaml @@ -0,0 +1,30 @@ +# SIMULATED INSTRUMENT FOR Agilent E8257D +# Only covers what is needed to create the driver and switch the RF output. +# The installed options are frequency option 520 (20 GHz) and the step +# attenuator (1E1). +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "Agilent Technologies, E8257D, US00000000, C.06.28" + - q: "DIAG:CPU:INFO:OPT:DET?" + r: "1E1,520,UNT" + + properties: + output_enabled: + default: "0" + getter: + q: ":OUTP?" + r: "{}" + setter: + q: "OUTP {}" + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/Agilent_E8267C.yaml b/src/qcodes/instrument/sims/Agilent_E8267C.yaml new file mode 100644 index 000000000000..c6f82f5887d6 --- /dev/null +++ b/src/qcodes/instrument/sims/Agilent_E8267C.yaml @@ -0,0 +1,41 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "Agilent Technologies, E8267C, US00000000, C.04.84" + + properties: + power: + default: 0 + getter: + q: "POW?" + r: "{}" + setter: + q: "POW {}" + + power_offset: + default: 0 + getter: + q: "POW:OFFS?" + r: "{}" + setter: + q: "POW:OFFS {}" + + pulse_width: + # *RST value according to the E8257D/67D SCPI command reference + default: "+1.00000000E-006" + getter: + q: "PULM:INT:PWID?" + r: "{}" + setter: + q: "PULM:INT:PWID {}" + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/Keithley_2450.yaml b/src/qcodes/instrument/sims/Keithley_2450.yaml index 5706ca2da002..bdea187f326f 100644 --- a/src/qcodes/instrument/sims/Keithley_2450.yaml +++ b/src/qcodes/instrument/sims/Keithley_2450.yaml @@ -67,6 +67,42 @@ devices: setter: q: "TRACe:CLEar" + sense_count: + default: 1 + getter: + q: ":SENSe:COUNt?" + r: "{}" + setter: + q: ":SENSe:COUNt {}" + specs: + type: int + + line_frequency: + default: "5.000000E+01" + getter: + q: ":SYSTem:LFRequency?" + r: "{}" + + sense_current_nplc: + default: 1 + getter: + q: ":SENSe:current:NPLCycles?" + r: "{}" + setter: + q: ":SENSe:current:NPLCycles {}" + specs: + type: float + + source_current_delay: + default: 0 + getter: + q: ":SOURce:current:DELay?" + r: "{}" + setter: + q: ":SOURce:current:DELay {}" + specs: + type: float + resources: GPIB::1::INSTR: device: device wrong_mode diff --git a/src/qcodes/instrument/sims/Keithley_6500.yaml b/src/qcodes/instrument/sims/Keithley_6500.yaml new file mode 100644 index 000000000000..c17c66a09c56 --- /dev/null +++ b/src/qcodes/instrument/sims/Keithley_6500.yaml @@ -0,0 +1,38 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "KEITHLEY INSTRUMENTS,MODEL DMM6500,04000000,1.0.0" + - q: "*LANG?" + r: "SCPI" + + properties: + data_format: + default: ASCII + getter: + q: "FORM:DATA?" + r: "{}" + setter: + q: "FORM:DATA {}" + + display_digits: + default: 6 + getter: + q: "DISP:VOLT:DC:DIG?" + r: "{}" + setter: + q: "DISP:VOLT:DC:DIG {}" + specs: + type: int + min: 4 + max: 7 + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/Keysight_E4980A.yaml b/src/qcodes/instrument/sims/Keysight_E4980A.yaml index a0e21f2a9340..b218c9e7a343 100644 --- a/src/qcodes/instrument/sims/Keysight_E4980A.yaml +++ b/src/qcodes/instrument/sims/Keysight_E4980A.yaml @@ -32,6 +32,23 @@ devices: setter: q: ":CURRent:LEVel {}" + impedance_range: + # preset value according to the E4980A/AL user's guide + default: "+1.00000E+02" + getter: + q: ":FUNCtion:IMPedance:RANGe?" + r: "{}" + setter: + q: ":FUNCtion:IMPedance:RANGe {}" + + impedance_autorange: + default: 1 + getter: + q: ":FUNCtion:IMPedance:RANGe:AUTO?" + r: "{}" + setter: + q: ":FUNCtion:IMPedance:RANGe:AUTO {}" + resources: GPIB::1::INSTR: device: device 1 diff --git a/src/qcodes/instrument/sims/Keysight_N5222B.yaml b/src/qcodes/instrument/sims/Keysight_N5222B.yaml new file mode 100644 index 000000000000..f686fe2269bf --- /dev/null +++ b/src/qcodes/instrument/sims/Keysight_N5222B.yaml @@ -0,0 +1,65 @@ +# SIMULATED INSTRUMENT FOR Keysight PNA N5222B +# Only covers what is needed to create the driver and a few parameters. +# The instrument has a single measurement "CH1_S11_1" (trace number 1). +# Commands that are only written are modelled as properties with a setter +# without a response, so that they do not leave a reply in the read buffer. +spec: "1.0" +devices: + N5222B: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "Keysight Technologies,N5222B,MY12345678,A.13.95.09" + - q: "*OPT?" + r: '""' + - q: "CALC:PAR:CAT:EXT?" + r: '"CH1_S11_1,S11"' + + properties: + + data_format: + default: "REAL,32" + setter: + q: "FORM {}" + + byte_order: + default: "NORM" + setter: + q: "FORM:BORD {}" + + selected_measurement_name: + default: "'CH1_S11_1'" + setter: + q: "CALC:PAR:SEL {}" + + active_trace: + default: 1 + getter: + q: "CALC:PAR:MNUM?" + r: "{}" + setter: + q: "CALC:PAR:MNUM {}" + + averages: + default: 1 + getter: + q: "SENS:AVER:COUN?" + r: "{}" + setter: + q: "SENS:AVER:COUN {}" + + points: + default: 201 + getter: + q: "SENS:SWE:POIN?" + r: "{}" + setter: + q: "SENS:SWE:POIN {}" + +resources: + GPIB::1::INSTR: + device: N5222B diff --git a/src/qcodes/instrument/sims/RTO_1000.yaml b/src/qcodes/instrument/sims/RTO_1000.yaml index 4ab9eb3fbf97..adfcceb2c480 100644 --- a/src/qcodes/instrument/sims/RTO_1000.yaml +++ b/src/qcodes/instrument/sims/RTO_1000.yaml @@ -25,7 +25,7 @@ devices: q: "TRIGger1:SOURce?" r: "{}" setter: - q: "TRIGger1:SOURce? {}" + q: "TRIGger1:SOURce {}" trigger level 1: default: 0 @@ -35,6 +35,14 @@ devices: setter: q: "TRIGger1:LEVel1 {}" + trigger mode: + default: AUTO + getter: + q: "TRIGger:MODE?" + r: "{}" + setter: + q: "TRIGger:MODE {}" + channel range 1: default: 5 getter: @@ -49,6 +57,15 @@ devices: setter: q: "CHANnel1:OFFSet {}" + channel impedance 1: + # *RST value according to the R&S RTO user manual + default: 50 + getter: + q: "CHANnel1:IMPedance?" + r: "{}" + setter: + q: "CHANnel1:IMPedance {}" + resources: GPIB::1::INSTR: device: device 1 diff --git a/src/qcodes/instrument/sims/Rigol_DG1062.yaml b/src/qcodes/instrument/sims/Rigol_DG1062.yaml new file mode 100644 index 000000000000..3676da725ef2 --- /dev/null +++ b/src/qcodes/instrument/sims/Rigol_DG1062.yaml @@ -0,0 +1,54 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "Rigol Technologies,DG1062Z,DG1ZA000000001,00.01.14" + - q: ":SOUR1:APPL?" + r: "\"SQU,1.000000E+03,5.000000E+00,0.000000E+00,0.000000E+00\"" + - q: ":SOUR2:APPL?" + r: "\"SIN,1.000000E+03,5.000000E+00,0.000000E+00,0.000000E+00\"" + + # query responses use the scientific notation documented in the + # DG1000Z Programming Guide + properties: + burst_ncycles_1: + default: "1.000000E+00" + getter: + q: ":SOUR1:BURS:NCYC?" + r: "{}" + setter: + q: ":SOUR1:BURS:NCYC {}" + + burst_phase_1: + default: "0.000000E+00" + getter: + q: ":SOUR1:BURS:PHAS?" + r: "{}" + setter: + q: ":SOUR1:BURS:PHAS {}" + + burst_time_delay_1: + default: "0.000000E+00" + getter: + q: ":SOUR1:BURS:TDEL?" + r: "{}" + setter: + q: ":SOUR1:BURS:TDEL {}" + + square_duty_cycle_1: + default: "5.000000E+01" + getter: + q: ":SOUR1:FUNC:SQU:DCYC?" + r: "{}" + setter: + q: ":SOUR1:FUNC:SQU:DCYC {}" + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/Rigol_DS1074Z.yaml b/src/qcodes/instrument/sims/Rigol_DS1074Z.yaml index af5cbd8e1148..c247eeb645cd 100644 --- a/src/qcodes/instrument/sims/Rigol_DS1074Z.yaml +++ b/src/qcodes/instrument/sims/Rigol_DS1074Z.yaml @@ -46,6 +46,14 @@ devices: r: "{}" setter: q: ":TRIGger:MODE {}" + trigger_edge_level: + # response format from the MSO1000Z/DS1000Z Programming Guide + default: "1.600000e-01" + getter: + q: ":TRIGger:edge:LEVel?" + r: "{}" + setter: + q: ":TRIGger:edge:LEVel {}" data_source: default: "CHAN1" getter: diff --git a/src/qcodes/instrument/sims/Rigol_DS4000.yaml b/src/qcodes/instrument/sims/Rigol_DS4000.yaml new file mode 100644 index 000000000000..9279dca6b6eb --- /dev/null +++ b/src/qcodes/instrument/sims/Rigol_DS4000.yaml @@ -0,0 +1,27 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "RIGOL TECHNOLOGIES,DS4024,DS4A000000001,00.02.03" + + properties: + enable_auto_scale: + default: 1 + getter: + q: ":SYSTem:AUToscale?" + r: "{}" + setter: + q: ":SYSTem:AUToscale {}" + specs: + type: int + valid: [0, 1] + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/Rohde_Schwarz_ZNB20.yaml b/src/qcodes/instrument/sims/Rohde_Schwarz_ZNB20.yaml new file mode 100644 index 000000000000..71c23e4fc61a --- /dev/null +++ b/src/qcodes/instrument/sims/Rohde_Schwarz_ZNB20.yaml @@ -0,0 +1,99 @@ +# SIMULATED INSTRUMENT FOR Rohde&Schwarz ZNB20 +# Only covers what is needed to create the driver with +# init_s_params=False and reset_channels=False and add a single channel. +# Commands that are only written are modelled as properties with a setter +# without a response, so that they do not leave a reply in the read buffer. +spec: "1.0" +devices: + ZNB20: + eom: + TCPIP INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "Rohde-Schwarz,ZNB20-2Port,1311601062100104,3.12" + - q: "INST:PORT:COUN?" + r: "2" + - q: "SENS1:SWE:TIME?" + r: "0.0201" + + properties: + + display_update: + default: "ON" + setter: + q: "SYST:DISP:UPD {}" + + trace_definition: + default: "" + setter: + q: "CALC1:PAR:SDEF {}" + + # the driver sends "DISP:LAY GRID;:DISP:LAY:GRID r,c", which the + # simulator splits at the ";" into two commands + display_layout: + default: "GRID" + setter: + q: "DISP:LAY {}" + + display_layout_grid: + default: "1,1" + setter: + q: ":DISP:LAY:GRID {}" + + sweep_time_auto: + default: "ON" + setter: + q: "SENS1:SWE:TIME:AUTO {}" + + trigger_source: + default: "IMM" + setter: + q: "TRIG1:SEQ:SOUR {}" + + averaging: + default: "ON" + setter: + q: "SENS1:AVER:STAT {}" + + start: + default: 100e3 + getter: + q: "SENS1:FREQ:START?" + r: "{}" + + stop: + default: 20e9 + getter: + q: "SENS1:FREQ:STOP?" + r: "{}" + + npts: + default: 201 + getter: + q: "SENS1:SWE:POIN?" + r: "{}" + + sweep_type: + default: "LIN" + getter: + q: "SENS1:SWE:TYPE?" + r: "{}" + setter: + q: "SENS1:SWE:TYPE {}" + + bandwidth: + # *RST value is 10 kHz. The value is returned as it was sent, so + # after setting 1.5 Hz the instrument returns a non-integer string. + default: "10000" + getter: + q: "SENS1:BAND?" + r: "{}" + setter: + q: "SENS1:BAND {}" + +resources: + TCPIP0::localhost::inst0::INSTR: + device: ZNB20 diff --git a/src/qcodes/instrument/sims/SR860.yaml b/src/qcodes/instrument/sims/SR860.yaml new file mode 100644 index 000000000000..bdd525a984ee --- /dev/null +++ b/src/qcodes/instrument/sims/SR860.yaml @@ -0,0 +1,26 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "Stanford_Research_Systems,SR860,000001,V1.51" + - q: "CAPTURERATEMAX?" + r: "1.25e6" + - q: "ISRC?" + r: "0" + + properties: + capture_progress: + default: 12 + getter: + q: "CAPTUREPROG?" + r: "{}" + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/Tektronix_DPO7200xx.yaml b/src/qcodes/instrument/sims/Tektronix_DPO7200xx.yaml index c41560df9f13..7dc501a5f822 100644 --- a/src/qcodes/instrument/sims/Tektronix_DPO7200xx.yaml +++ b/src/qcodes/instrument/sims/Tektronix_DPO7200xx.yaml @@ -17,6 +17,21 @@ devices: r: "s" setter: q: "HORizontal:MAIn:UNIts {}" + horizontal_mode: + default: "MANUAL" + getter: + q: "HORizontal:MODE?" + r: "{}" + setter: + q: "HORizontal:MODE {}" + record_length: + # the record length in samples () + default: "1000000" + getter: + q: "HORizontal:MODE:RECOrdlength?" + r: "{}" + setter: + q: "HORizontal:MODE:RECOrdlength {}" waveform_horizontal_units: getter: q: "WFMOutpre:XUNit?" @@ -83,6 +98,54 @@ devices: getter: q: "MEASUrement:MEAS1:MEAN?" r: "0.012" + # waveform preamble of the DATa:SOUrce waveform, using the example + # replies from the programmer manual + waveform_y_multiplier: + getter: + q: "WFMOutPRE:YMULT?" + r: "4.0000E-3" + waveform_y_offset: + # in digitizing levels + getter: + q: "WFMOutPRE:YOFF?" + r: "-50.0000E+0" + waveform_y_zero: + getter: + q: "WFMOutPRE:YZERO?" + r: "-100.0000E-3" + waveform_number_of_points: + # kept short so tests can supply matching curve data + getter: + q: "WFMOutpre:NR_Pt?" + r: "3" + waveform_encoding: + default: "ASCII" + getter: + q: "WFMOutpre:ENCdg?" + r: "{}" + setter: + q: "WFMOutpre:ENCdg {}" + waveform_binary_format: + default: "RI" + getter: + q: "WFMOutpre:BN_Fmt?" + r: "{}" + setter: + q: "WFMOutpre:BN_Fmt {}" + waveform_bytes_per_sample: + default: "1" + getter: + q: "WFMOutpre:BYT_Nr?" + r: "{}" + setter: + q: "WFMOutpre:BYT_Nr {}" + waveform_byte_order: + default: "LSB" + getter: + q: "WFMOutpre:BYT_Or?" + r: "{}" + setter: + q: "WFMOutpre:BYT_Or {}" resources: diff --git a/src/qcodes/instrument/sims/Tektronix_TPS2012.yaml b/src/qcodes/instrument/sims/Tektronix_TPS2012.yaml new file mode 100644 index 000000000000..790105db15ad --- /dev/null +++ b/src/qcodes/instrument/sims/Tektronix_TPS2012.yaml @@ -0,0 +1,41 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\n" + r: "\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "TEKTRONIX,TPS 2012,0,CF:91.1CT FV:v10.01" + + properties: + data_encoding: + default: RPBinary + getter: + q: "DATa:ENCdg?" + r: "{}" + setter: + q: "DATa:ENCdg {}" + + data_width: + default: 2 + getter: + q: "DATa:WIDTh?" + r: "{}" + setter: + q: "DATa:WIDTh {}" + + trigger_level: + # example response from the TPS2000 programmer manual + default: "1.4" + getter: + q: "TRIGger:MAIn:LEVel?" + r: "{}" + setter: + q: "TRIGger:MAIn:LEVel {}" + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument/sims/keithley_7510.yaml b/src/qcodes/instrument/sims/keithley_7510.yaml index ee31db3b93c8..39c53d28b44e 100644 --- a/src/qcodes/instrument/sims/keithley_7510.yaml +++ b/src/qcodes/instrument/sims/keithley_7510.yaml @@ -34,6 +34,52 @@ devices: setter: q: ":SENSe:voltage:NPLCycles {}" + user_delay_1_voltage: + default: 0 + getter: + q: ":SENSe:voltage:DELay:USER1?" + r: "{}" + setter: + q: ":SENSe:voltage:DELay:USER1 {}" + specs: + type: float + + average_count_voltage: + default: 10 + getter: + q: ":SENSe:voltage:AVERage:COUNt?" + r: "{}" + setter: + q: ":SENSe:voltage:AVERage:COUNt {}" + specs: + type: int + + digitize_function: + default: "\"VOLT\"" + getter: + q: ":DIGitize:FUNCtion?" + r: "{}" + setter: + q: ":DIGitize:FUNCtion {}" + + digitize_sample_rate_voltage: + default: "1.000000E+06" + getter: + q: ":SENSe:DIGitize:voltage:SRATE?" + r: "{}" + setter: + q: ":SENSe:DIGitize:voltage:SRATE {}" + + digitize_count: + default: 10000 + getter: + q: "SENSe:DIGitize:COUNt?" + r: "{}" + setter: + q: "SENSe:DIGitize:COUNt {}" + specs: + type: int + resources: "GPIB::1::INSTR": device: device 1 diff --git a/src/qcodes/instrument/sims/lakeshore_model325.yaml b/src/qcodes/instrument/sims/lakeshore_model325.yaml new file mode 100644 index 000000000000..5f1cdec7610e --- /dev/null +++ b/src/qcodes/instrument/sims/lakeshore_model325.yaml @@ -0,0 +1,55 @@ +spec: "1.0" +devices: + device 1: + eom: + GPIB INSTR: + q: "\r\n" + r: "\r\n" + error: ERROR + dialogues: + - q: "*IDN?" + r: "LSCI,MODEL325,000000,1.0" + + properties: + output_range_1: + default: 0 + getter: + q: "RANGE? 1" + r: "{}" + setter: + q: "RANGE 1, {}" + specs: + type: int + valid: [0, 1, 2] + + output_range_2: + default: 0 + getter: + q: "RANGE? 2" + r: "{}" + setter: + q: "RANGE 2, {}" + specs: + type: int + valid: [0, 1] + + curve_index_A: + # INCRV? returns the curve number in nn format + default: "02" + getter: + q: "INCRV? A" + r: "{}" + setter: + q: "INCRV A, {}" + + curve_index_B: + default: "00" + getter: + q: "INCRV? B" + r: "{}" + setter: + q: "INCRV B, {}" + +resources: + GPIB::1::INSTR: + device: device 1 diff --git a/src/qcodes/instrument_drivers/AimTTi/_AimTTi_PL_P.py b/src/qcodes/instrument_drivers/AimTTi/_AimTTi_PL_P.py index 8523e77abd1f..f30fdbdbb7c7 100644 --- a/src/qcodes/instrument_drivers/AimTTi/_AimTTi_PL_P.py +++ b/src/qcodes/instrument_drivers/AimTTi/_AimTTi_PL_P.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, ClassVar +from typing import TYPE_CHECKING, ClassVar, Self from qcodes import validators as vals from qcodes.instrument import ( @@ -50,7 +50,7 @@ def __init__( # internally. self.set_up_store_slots = [i for i in range(10)] - self.volt: Parameter = self.add_parameter( + self.volt: Parameter[float, Self] = self.add_parameter( "volt", get_cmd=self._get_voltage_value, get_parser=float, @@ -60,7 +60,7 @@ def __init__( ) """Parameter volt""" - self.volt_step_size: Parameter = self.add_parameter( + self.volt_step_size: Parameter[float, Self] = self.add_parameter( "volt_step_size", get_cmd=self._get_voltage_step_size, get_parser=float, @@ -70,7 +70,7 @@ def __init__( ) """Parameter volt_step_size""" - self.curr: Parameter = self.add_parameter( + self.curr: Parameter[float, Self] = self.add_parameter( "curr", get_cmd=self._get_current_value, get_parser=float, @@ -94,7 +94,7 @@ def __init__( ) """Set the current range of the output. Here, the integer 1 is for the Low range, and integer 2 is for the High range.""" - self.curr_step_size: Parameter = self.add_parameter( + self.curr_step_size: Parameter[float, Self] = self.add_parameter( "curr_step_size", get_cmd=self._get_current_step_size, get_parser=float, @@ -104,7 +104,7 @@ def __init__( ) """Parameter curr_step_size""" - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( "output", get_cmd=f"OP{channel}?", get_parser=float, diff --git a/src/qcodes/instrument_drivers/AlazarTech/ATS9360.py b/src/qcodes/instrument_drivers/AlazarTech/ATS9360.py index b318a06c0c0d..e40be41b346d 100644 --- a/src/qcodes/instrument_drivers/AlazarTech/ATS9360.py +++ b/src/qcodes/instrument_drivers/AlazarTech/ATS9360.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np from packaging import version @@ -277,7 +277,7 @@ def __init__( """Parameter aux_io_param""" # ----- Parameters for the acquire function ----- - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( name="mode", label="Acquisition mode", unit=None, @@ -286,7 +286,7 @@ def __init__( val_mapping={"NPT": 0x200, "TS": 0x400}, ) """Parameter mode""" - self.samples_per_record: Parameter = self.add_parameter( + self.samples_per_record: Parameter[int, Self] = self.add_parameter( name="samples_per_record", label="Samples per Record", unit=None, @@ -295,7 +295,7 @@ def __init__( vals=validators.Multiples(divisor=self.samples_divisor, min_value=256), ) """Parameter samples_per_record""" - self.records_per_buffer: Parameter = self.add_parameter( + self.records_per_buffer: Parameter[int, Self] = self.add_parameter( name="records_per_buffer", label="Records per Buffer", unit=None, @@ -304,7 +304,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter records_per_buffer""" - self.buffers_per_acquisition: Parameter = self.add_parameter( + self.buffers_per_acquisition: Parameter[int, Self] = self.add_parameter( name="buffers_per_acquisition", label="Buffers per Acquisition", unit=None, @@ -313,7 +313,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter buffers_per_acquisition""" - self.channel_selection: Parameter = self.add_parameter( + self.channel_selection: Parameter[str, Self] = self.add_parameter( name="channel_selection", label="Channel Selection", unit=None, @@ -322,7 +322,7 @@ def __init__( val_mapping={"A": 1, "B": 2, "AB": 3}, ) """Parameter channel_selection""" - self.transfer_offset: Parameter = self.add_parameter( + self.transfer_offset: Parameter[int, Self] = self.add_parameter( name="transfer_offset", label="Transfer Offset", unit="Samples", @@ -331,7 +331,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter transfer_offset""" - self.external_startcapture: Parameter = self.add_parameter( + self.external_startcapture: Parameter[str, Self] = self.add_parameter( name="external_startcapture", label="External Startcapture", unit=None, @@ -340,7 +340,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1}, ) """Parameter external_startcapture""" - self.enable_record_headers: Parameter = self.add_parameter( + self.enable_record_headers: Parameter[str, Self] = self.add_parameter( name="enable_record_headers", label="Enable Record Headers", unit=None, @@ -349,7 +349,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x8}, ) """Parameter enable_record_headers""" - self.alloc_buffers: Parameter = self.add_parameter( + self.alloc_buffers: Parameter[str, Self] = self.add_parameter( name="alloc_buffers", label="Alloc Buffers", unit=None, @@ -358,7 +358,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x20}, ) """Parameter alloc_buffers""" - self.fifo_only_streaming: Parameter = self.add_parameter( + self.fifo_only_streaming: Parameter[str, Self] = self.add_parameter( name="fifo_only_streaming", label="Fifo Only Streaming", unit=None, @@ -367,7 +367,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x800}, ) """Parameter fifo_only_streaming""" - self.interleave_samples: Parameter = self.add_parameter( + self.interleave_samples: Parameter[str, Self] = self.add_parameter( name="interleave_samples", label="Interleave Samples", unit=None, @@ -376,7 +376,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1000}, ) """Parameter interleave_samples""" - self.get_processed_data: Parameter = self.add_parameter( + self.get_processed_data: Parameter[str, Self] = self.add_parameter( name="get_processed_data", label="Get Processed Data", unit=None, @@ -385,7 +385,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x2000}, ) """Parameter get_processed_data""" - self.allocated_buffers: Parameter = self.add_parameter( + self.allocated_buffers: Parameter[int, Self] = self.add_parameter( name="allocated_buffers", label="Allocated Buffers", unit=None, @@ -394,7 +394,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter allocated_buffers""" - self.buffer_timeout: Parameter = self.add_parameter( + self.buffer_timeout: Parameter[int, Self] = self.add_parameter( name="buffer_timeout", label="Buffer Timeout", unit="ms", @@ -404,7 +404,7 @@ def __init__( ) """Parameter buffer_timeout""" - self.trigger_holdoff: Parameter = self.add_parameter( + self.trigger_holdoff: Parameter[bool, Self] = self.add_parameter( name="trigger_holdoff", label="Trigger Holdoff", docstring=f"If enabled Alazar will " diff --git a/src/qcodes/instrument_drivers/AlazarTech/ATS9373.py b/src/qcodes/instrument_drivers/AlazarTech/ATS9373.py index f593115492d2..144f4cb66b9c 100644 --- a/src/qcodes/instrument_drivers/AlazarTech/ATS9373.py +++ b/src/qcodes/instrument_drivers/AlazarTech/ATS9373.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np from packaging import version @@ -293,7 +293,7 @@ def __init__( """Parameter aux_io_param""" # ----- Parameters for the acquire function ----- - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( name="mode", label="Acquisition mode", unit=None, @@ -302,7 +302,7 @@ def __init__( val_mapping={"NPT": 0x200, "TS": 0x400}, ) """Parameter mode""" - self.samples_per_record: Parameter = self.add_parameter( + self.samples_per_record: Parameter[int, Self] = self.add_parameter( name="samples_per_record", label="Samples per Record", unit=None, @@ -311,7 +311,7 @@ def __init__( vals=validators.Multiples(divisor=self.samples_divisor, min_value=256), ) """Parameter samples_per_record""" - self.records_per_buffer: Parameter = self.add_parameter( + self.records_per_buffer: Parameter[int, Self] = self.add_parameter( name="records_per_buffer", label="Records per Buffer", unit=None, @@ -320,7 +320,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter records_per_buffer""" - self.buffers_per_acquisition: Parameter = self.add_parameter( + self.buffers_per_acquisition: Parameter[int, Self] = self.add_parameter( name="buffers_per_acquisition", label="Buffers per Acquisition", unit=None, @@ -329,7 +329,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter buffers_per_acquisition""" - self.channel_selection: Parameter = self.add_parameter( + self.channel_selection: Parameter[str, Self] = self.add_parameter( name="channel_selection", label="Channel Selection", unit=None, @@ -338,7 +338,7 @@ def __init__( val_mapping={"A": 1, "B": 2, "AB": 3}, ) """Parameter channel_selection""" - self.transfer_offset: Parameter = self.add_parameter( + self.transfer_offset: Parameter[int, Self] = self.add_parameter( name="transfer_offset", label="Transfer Offset", unit="Samples", @@ -347,7 +347,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter transfer_offset""" - self.external_startcapture: Parameter = self.add_parameter( + self.external_startcapture: Parameter[str, Self] = self.add_parameter( name="external_startcapture", label="External Startcapture", unit=None, @@ -356,7 +356,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1}, ) """Parameter external_startcapture""" - self.enable_record_headers: Parameter = self.add_parameter( + self.enable_record_headers: Parameter[str, Self] = self.add_parameter( name="enable_record_headers", label="Enable Record Headers", unit=None, @@ -365,7 +365,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x8}, ) """Parameter enable_record_headers""" - self.alloc_buffers: Parameter = self.add_parameter( + self.alloc_buffers: Parameter[str, Self] = self.add_parameter( name="alloc_buffers", label="Alloc Buffers", unit=None, @@ -374,7 +374,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x20}, ) """Parameter alloc_buffers""" - self.fifo_only_streaming: Parameter = self.add_parameter( + self.fifo_only_streaming: Parameter[str, Self] = self.add_parameter( name="fifo_only_streaming", label="Fifo Only Streaming", unit=None, @@ -383,7 +383,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x800}, ) """Parameter fifo_only_streaming""" - self.interleave_samples: Parameter = self.add_parameter( + self.interleave_samples: Parameter[str, Self] = self.add_parameter( name="interleave_samples", label="Interleave Samples", unit=None, @@ -392,7 +392,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1000}, ) """Parameter interleave_samples""" - self.get_processed_data: Parameter = self.add_parameter( + self.get_processed_data: Parameter[str, Self] = self.add_parameter( name="get_processed_data", label="Get Processed Data", unit=None, @@ -401,7 +401,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x2000}, ) """Parameter get_processed_data""" - self.allocated_buffers: Parameter = self.add_parameter( + self.allocated_buffers: Parameter[int, Self] = self.add_parameter( name="allocated_buffers", label="Allocated Buffers", unit=None, @@ -410,7 +410,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter allocated_buffers""" - self.buffer_timeout: Parameter = self.add_parameter( + self.buffer_timeout: Parameter[int, Self] = self.add_parameter( name="buffer_timeout", label="Buffer Timeout", unit="ms", @@ -420,7 +420,7 @@ def __init__( ) """Parameter buffer_timeout""" - self.trigger_holdoff: Parameter = self.add_parameter( + self.trigger_holdoff: Parameter[bool, Self] = self.add_parameter( name="trigger_holdoff", label="Trigger Holdoff", docstring=f"If enabled Alazar will " diff --git a/src/qcodes/instrument_drivers/AlazarTech/ATS9440.py b/src/qcodes/instrument_drivers/AlazarTech/ATS9440.py index 04a3337917e3..52199d23d74e 100644 --- a/src/qcodes/instrument_drivers/AlazarTech/ATS9440.py +++ b/src/qcodes/instrument_drivers/AlazarTech/ATS9440.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self from qcodes import validators @@ -257,7 +257,7 @@ def __init__( """Parameter aux_io_param""" # The above parameters are important for preparing the card. - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( name="mode", label="Acquisition mode", unit=None, @@ -266,7 +266,7 @@ def __init__( val_mapping={"NPT": 0x200, "TS": 0x400}, ) """Parameter mode""" - self.samples_per_record: Parameter = self.add_parameter( + self.samples_per_record: Parameter[int, Self] = self.add_parameter( name="samples_per_record", label="Samples per Record", unit=None, @@ -275,7 +275,7 @@ def __init__( vals=validators.Multiples(divisor=self.samples_divisor, min_value=256), ) """Parameter samples_per_record""" - self.records_per_buffer: Parameter = self.add_parameter( + self.records_per_buffer: Parameter[int, Self] = self.add_parameter( name="records_per_buffer", label="Records per Buffer", unit=None, @@ -284,7 +284,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter records_per_buffer""" - self.buffers_per_acquisition: Parameter = self.add_parameter( + self.buffers_per_acquisition: Parameter[int, Self] = self.add_parameter( name="buffers_per_acquisition", label="Buffers per Acquisition", unit=None, @@ -293,7 +293,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter buffers_per_acquisition""" - self.channel_selection: Parameter = self.add_parameter( + self.channel_selection: Parameter[str, Self] = self.add_parameter( name="channel_selection", label="Channel Selection", unit=None, @@ -314,7 +314,7 @@ def __init__( }, ) """Parameter channel_selection""" - self.transfer_offset: Parameter = self.add_parameter( + self.transfer_offset: Parameter[int, Self] = self.add_parameter( name="transfer_offset", label="Transfer Offset", unit="Samples", @@ -323,7 +323,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter transfer_offset""" - self.external_startcapture: Parameter = self.add_parameter( + self.external_startcapture: Parameter[str, Self] = self.add_parameter( name="external_startcapture", label="External Startcapture", unit=None, @@ -332,7 +332,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1}, ) """Parameter external_startcapture""" - self.enable_record_headers: Parameter = self.add_parameter( + self.enable_record_headers: Parameter[str, Self] = self.add_parameter( name="enable_record_headers", label="Enable Record Headers", unit=None, @@ -341,7 +341,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x8}, ) """Parameter enable_record_headers""" - self.alloc_buffers: Parameter = self.add_parameter( + self.alloc_buffers: Parameter[str, Self] = self.add_parameter( name="alloc_buffers", label="Alloc Buffers", unit=None, @@ -350,7 +350,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x20}, ) """Parameter alloc_buffers""" - self.fifo_only_streaming: Parameter = self.add_parameter( + self.fifo_only_streaming: Parameter[str, Self] = self.add_parameter( name="fifo_only_streaming", label="Fifo Only Streaming", unit=None, @@ -359,7 +359,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x800}, ) """Parameter fifo_only_streaming""" - self.interleave_samples: Parameter = self.add_parameter( + self.interleave_samples: Parameter[str, Self] = self.add_parameter( name="interleave_samples", label="Interleave Samples", unit=None, @@ -368,7 +368,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1000}, ) """Parameter interleave_samples""" - self.get_processed_data: Parameter = self.add_parameter( + self.get_processed_data: Parameter[str, Self] = self.add_parameter( name="get_processed_data", label="Get Processed Data", unit=None, @@ -377,7 +377,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x2000}, ) """Parameter get_processed_data""" - self.allocated_buffers: Parameter = self.add_parameter( + self.allocated_buffers: Parameter[int, Self] = self.add_parameter( name="allocated_buffers", label="Allocated Buffers", unit=None, @@ -386,7 +386,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter allocated_buffers""" - self.buffer_timeout: Parameter = self.add_parameter( + self.buffer_timeout: Parameter[int, Self] = self.add_parameter( name="buffer_timeout", label="Buffer Timeout", unit="ms", diff --git a/src/qcodes/instrument_drivers/AlazarTech/ATS9870.py b/src/qcodes/instrument_drivers/AlazarTech/ATS9870.py index f1c13168ea23..3851ebc11464 100644 --- a/src/qcodes/instrument_drivers/AlazarTech/ATS9870.py +++ b/src/qcodes/instrument_drivers/AlazarTech/ATS9870.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self from qcodes import validators @@ -266,7 +266,7 @@ def __init__( """Parameter aux_io_param""" # ----- Parameters for the acquire function ----- - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( name="mode", label="Acquisition mode", unit=None, @@ -279,7 +279,7 @@ def __init__( # samples_per_record must be a multiple of of some number (64 in the # case of ATS9870) and and has some minimum (256 in the case of ATS9870) # These values can be found in the ATS-SDK programmar's guide - self.samples_per_record: Parameter = self.add_parameter( + self.samples_per_record: Parameter[int, Self] = self.add_parameter( name="samples_per_record", label="Samples per Record", unit=None, @@ -289,7 +289,7 @@ def __init__( ) """Parameter samples_per_record""" - self.records_per_buffer: Parameter = self.add_parameter( + self.records_per_buffer: Parameter[int, Self] = self.add_parameter( name="records_per_buffer", label="Records per Buffer", unit=None, @@ -298,7 +298,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter records_per_buffer""" - self.buffers_per_acquisition: Parameter = self.add_parameter( + self.buffers_per_acquisition: Parameter[int, Self] = self.add_parameter( name="buffers_per_acquisition", label="Buffers per Acquisition", unit=None, @@ -307,7 +307,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter buffers_per_acquisition""" - self.channel_selection: Parameter = self.add_parameter( + self.channel_selection: Parameter[str, Self] = self.add_parameter( name="channel_selection", label="Channel Selection", unit=None, @@ -316,7 +316,7 @@ def __init__( val_mapping={"A": 1, "B": 2, "AB": 3}, ) """Parameter channel_selection""" - self.transfer_offset: Parameter = self.add_parameter( + self.transfer_offset: Parameter[int, Self] = self.add_parameter( name="transfer_offset", label="Transfer Offset", unit="Samples", @@ -325,7 +325,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter transfer_offset""" - self.external_startcapture: Parameter = self.add_parameter( + self.external_startcapture: Parameter[str, Self] = self.add_parameter( name="external_startcapture", label="External Startcapture", unit=None, @@ -334,7 +334,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1}, ) """Parameter external_startcapture""" - self.enable_record_headers: Parameter = self.add_parameter( + self.enable_record_headers: Parameter[str, Self] = self.add_parameter( name="enable_record_headers", label="Enable Record Headers", unit=None, @@ -343,7 +343,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x8}, ) """Parameter enable_record_headers""" - self.alloc_buffers: Parameter = self.add_parameter( + self.alloc_buffers: Parameter[str, Self] = self.add_parameter( name="alloc_buffers", label="Alloc Buffers", unit=None, @@ -352,7 +352,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x20}, ) """Parameter alloc_buffers""" - self.fifo_only_streaming: Parameter = self.add_parameter( + self.fifo_only_streaming: Parameter[str, Self] = self.add_parameter( name="fifo_only_streaming", label="Fifo Only Streaming", unit=None, @@ -361,7 +361,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x800}, ) """Parameter fifo_only_streaming""" - self.interleave_samples: Parameter = self.add_parameter( + self.interleave_samples: Parameter[str, Self] = self.add_parameter( name="interleave_samples", label="Interleave Samples", unit=None, @@ -370,7 +370,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x1000}, ) """Parameter interleave_samples""" - self.get_processed_data: Parameter = self.add_parameter( + self.get_processed_data: Parameter[str, Self] = self.add_parameter( name="get_processed_data", label="Get Processed Data", unit=None, @@ -379,7 +379,7 @@ def __init__( val_mapping={"DISABLED": 0x0, "ENABLED": 0x2000}, ) """Parameter get_processed_data""" - self.allocated_buffers: Parameter = self.add_parameter( + self.allocated_buffers: Parameter[int, Self] = self.add_parameter( name="allocated_buffers", label="Allocated Buffers", unit=None, @@ -388,7 +388,7 @@ def __init__( vals=validators.Ints(min_value=0), ) """Parameter allocated_buffers""" - self.buffer_timeout: Parameter = self.add_parameter( + self.buffer_timeout: Parameter[int, Self] = self.add_parameter( name="buffer_timeout", label="Buffer Timeout", unit="ms", diff --git a/src/qcodes/instrument_drivers/AlazarTech/ATS_acquisition_controllers.py b/src/qcodes/instrument_drivers/AlazarTech/ATS_acquisition_controllers.py index 4198df03c6c1..649d05ed0b6b 100644 --- a/src/qcodes/instrument_drivers/AlazarTech/ATS_acquisition_controllers.py +++ b/src/qcodes/instrument_drivers/AlazarTech/ATS_acquisition_controllers.py @@ -1,5 +1,5 @@ import math -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np import numpy.typing as npt @@ -46,7 +46,7 @@ def __init__( # make a call to the parent class and by extension, create the parameter # structure of this class super().__init__(name, alazar_name, **kwargs) - self.acquisition: Parameter = self.add_parameter( + self.acquisition: Parameter[float, Self] = self.add_parameter( "acquisition", get_cmd=self.do_acquisition ) """Parameter acquisition""" diff --git a/src/qcodes/instrument_drivers/CopperMountain/_M5xxx.py b/src/qcodes/instrument_drivers/CopperMountain/_M5xxx.py index 906312286088..6cb6b0c966ef 100644 --- a/src/qcodes/instrument_drivers/CopperMountain/_M5xxx.py +++ b/src/qcodes/instrument_drivers/CopperMountain/_M5xxx.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Literal +from typing import TYPE_CHECKING, Any, Literal, Self import numpy as np from numpy.typing import NDArray @@ -58,7 +58,7 @@ def __init__( self.min_points = 2 self.max_points = 200001 - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( name="output", label="Output", get_parser=int, @@ -68,7 +68,7 @@ def __init__( ) """Use to check state of RF signal output (ON/OFF) and turns the RF signal output ON/OFF""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( name="power", label="Power", get_parser=float, @@ -80,7 +80,7 @@ def __init__( ) """Sets or reads out the power level for the frequency sweep type in dBm.""" - self.if_bandwidth: Parameter = self.add_parameter( + self.if_bandwidth: Parameter[float, Self] = self.add_parameter( name="if_bandwidth", label="IF Bandwidth", get_parser=float, @@ -96,7 +96,7 @@ def __init__( ) """Sets or reads out the IF bandwidth in Hz.""" - self.averages_enabled: Parameter = self.add_parameter( + self.averages_enabled: Parameter[bool, Self] = self.add_parameter( name="averages_enabled", label="Averages Status", get_cmd="SENS1:AVER:STAT?", @@ -105,7 +105,7 @@ def __init__( ) """Turns the measurement averaging function ON/OFF on channel 1.""" - self.averages_trigger_enabled: Parameter = self.add_parameter( + self.averages_trigger_enabled: Parameter[bool, Self] = self.add_parameter( "averages_trigger_enabled", label="Trigger average status", get_cmd="TRIG:SEQ:AVER?", @@ -129,7 +129,7 @@ def __init__( """Sets or reads out the averaging factor when the averaging function is turned on.""" - self.electrical_delay: Parameter = self.add_parameter( + self.electrical_delay: Parameter[float, Self] = self.add_parameter( "electrical_delay", label="Electrical delay", get_cmd="CALC1:CORR:EDEL:TIME?", @@ -142,7 +142,7 @@ def __init__( ) """Sets or reads out the value of the electrical delay in seconds.""" - self.electrical_distance: Parameter = self.add_parameter( + self.electrical_distance: Parameter[float, Self] = self.add_parameter( "electrical_distance", label="Electrical distance", get_cmd="CALC1:CORR:EDEL:DIST?", @@ -156,7 +156,7 @@ def __init__( """Sets or reads out the value of the equivalent distance in the electrical delay function.""" - self.electrical_distance_units: Parameter = self.add_parameter( + self.electrical_distance_units: Parameter[str, Self] = self.add_parameter( "electrical_distance_units", label="Electrical distance units", get_cmd="CALC1:CORR:EDEL:DIST:UNIT?", @@ -167,7 +167,7 @@ def __init__( ) """Sets or reads out the distance units in the electrical delay function.""" - self.clock_source: Parameter = self.add_parameter( + self.clock_source: Parameter[str, Self] = self.add_parameter( name="clock_source", label="Clock source", get_cmd="SENSe1:ROSCillator:SOURce?", @@ -194,7 +194,7 @@ def __init__( """Sets or reads out an internal or external source of the 10 MHz reference frequency.""" - self.start: Parameter = self.add_parameter( + self.start: Parameter[float, Self] = self.add_parameter( name="start", label="Start Frequency", get_parser=float, @@ -208,7 +208,7 @@ def __init__( """Sets or reads out the stimulus start value of the sweep range for linear or logarithmic sweep type.""" - self.stop: Parameter = self.add_parameter( + self.stop: Parameter[float, Self] = self.add_parameter( name="stop", label="Stop Frequency", get_parser=float, @@ -222,7 +222,7 @@ def __init__( """Sets or reads out the stimulus stop value of the sweep range for linear or logarithmic sweep type.""" - self.center: Parameter = self.add_parameter( + self.center: Parameter[float, Self] = self.add_parameter( name="center", label="Center Frequency", get_parser=float, @@ -236,7 +236,7 @@ def __init__( """Sets or reads out the stimulus center value of the sweep range for linear or logarithmic sweep type.""" - self.span: Parameter = self.add_parameter( + self.span: Parameter[float, Self] = self.add_parameter( name="span", label="Frequency Span", get_parser=float, @@ -250,7 +250,7 @@ def __init__( """Sets or reads out the stimulus span value of the sweep range for linear or logarithmic sweep type.""" - self.number_of_points: Parameter = self.add_parameter( + self.number_of_points: Parameter[int, Self] = self.add_parameter( "number_of_points", label="Number of points", get_parser=int, @@ -262,7 +262,7 @@ def __init__( ) """Sets or reads out the number of measurement points.""" - self.number_of_traces: Parameter = self.add_parameter( + self.number_of_traces: Parameter[int, Self] = self.add_parameter( name="number_of_traces", label="Number of traces", get_parser=int, @@ -275,7 +275,7 @@ def __init__( ) """Sets or reads out the number of traces in the channel.""" - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( name="trigger_source", label="Trigger source", get_parser=str, @@ -286,7 +286,7 @@ def __init__( ) """Selects the trigger source""" - self.data_transfer_format: Parameter = self.add_parameter( + self.data_transfer_format: Parameter[str, Self] = self.add_parameter( name="data_transfer_format", label="Data format during transfer", get_parser=str, @@ -441,7 +441,7 @@ def _set_averages_enabled(self, averages_enabled: str) -> None: """ self.write(f"SENS1:AVER:STAT {averages_enabled}") - self.averages_trigger_enabled("ON") + self.averages_trigger_enabled(True) def _set_span(self, val: float) -> None: """Sets frequency span and updates linear trace parameters. diff --git a/src/qcodes/instrument_drivers/Galil/dmc_41x3.py b/src/qcodes/instrument_drivers/Galil/dmc_41x3.py index d211032ad5b2..154225e2c47a 100644 --- a/src/qcodes/instrument_drivers/Galil/dmc_41x3.py +++ b/src/qcodes/instrument_drivers/Galil/dmc_41x3.py @@ -4,7 +4,7 @@ Colloquially known as the "stepper motors". """ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self import numpy as np import numpy.typing as npt @@ -143,7 +143,7 @@ def __init__( min_value=-2147483648, max_value=2147483647 ) - self.coordinate_system: Parameter = self.add_parameter( + self.coordinate_system: Parameter[str, Self] = self.add_parameter( "coordinate_system", get_cmd="CA ?", get_parser=self._parse_coordinate_system_active, @@ -156,7 +156,7 @@ def __init__( ) """activates coordinate system for the motion. Two coordinate systems are possible with values 'S' and 'T'. All vector mode commands will apply to the active coordinate system.""" - self.vector_acceleration: Parameter = self.add_parameter( + self.vector_acceleration: Parameter[int, Self] = self.add_parameter( "vector_acceleration", get_cmd="VA ?", get_parser=lambda s: int(float(s)), @@ -167,7 +167,7 @@ def __init__( ) """sets and gets the defined vector's acceleration""" - self.vector_deceleration: Parameter = self.add_parameter( + self.vector_deceleration: Parameter[int, Self] = self.add_parameter( "vector_deceleration", get_cmd="VD ?", get_parser=lambda s: int(float(s)), @@ -178,7 +178,7 @@ def __init__( ) """sets and gets the defined vector's deceleration""" - self.vector_speed: Parameter = self.add_parameter( + self.vector_speed: Parameter[int, Self] = self.add_parameter( "vector_speed", get_cmd="VS ?", get_parser=lambda s: int(float(s)), @@ -271,7 +271,7 @@ def __init__( super().__init__(parent, name, **kwargs) self._axis = name - self.relative_position: Parameter = self.add_parameter( + self.relative_position: Parameter[int, Self] = self.add_parameter( "relative_position", unit="quadrature counts", get_cmd=f"MG _PR{self._axis}", @@ -282,7 +282,7 @@ def __init__( ) """sets relative position for the motor's move""" - self.speed: Parameter = self.add_parameter( + self.speed: Parameter[int, Self] = self.add_parameter( "speed", unit="counts/sec", get_cmd=f"MG _SP{self._axis}", @@ -293,7 +293,7 @@ def __init__( ) """speed for motor's motion""" - self.acceleration: Parameter = self.add_parameter( + self.acceleration: Parameter[int, Self] = self.add_parameter( "acceleration", unit="counts/sec2", get_cmd=f"MG _AC{self._axis}", @@ -304,7 +304,7 @@ def __init__( ) """acceleration for motor's motion""" - self.deceleration: Parameter = self.add_parameter( + self.deceleration: Parameter[int, Self] = self.add_parameter( "deceleration", unit="counts/sec2", get_cmd=f"MG _DC{self._axis}", @@ -315,7 +315,7 @@ def __init__( ) """deceleration for motor's motion""" - self.off_when_error_occurs: Parameter = self.add_parameter( + self.off_when_error_occurs: Parameter[str, Self] = self.add_parameter( "off_when_error_occurs", get_cmd=self._get_off_when_error_occurs, set_cmd=self._set_off_when_error_occurs, @@ -330,7 +330,7 @@ def __init__( ) """enables or disables the motor to automatically turn off when error occurs""" - self.reverse_sw_limit: Parameter = self.add_parameter( + self.reverse_sw_limit: Parameter[int, Self] = self.add_parameter( "reverse_sw_limit", unit="quadrature counts", get_cmd=f"MG _BL{self._axis}", @@ -344,7 +344,7 @@ def __init__( ) """can be used to set software reverse limit for the motor. motor motion will stop beyond this limit automatically. default value is -2147483648. this value effectively disables the reverse limit.""" - self.forward_sw_limit: Parameter = self.add_parameter( + self.forward_sw_limit: Parameter[int, Self] = self.add_parameter( "forward_sw_limit", unit="quadrature counts", get_cmd=f"MG _FL{self._axis}", @@ -483,7 +483,7 @@ def __init__( """ super().__init__(name=name, address=address, **kwargs) - self.position_format_decimals: Parameter = self.add_parameter( + self.position_format_decimals: Parameter[int, Self] = self.add_parameter( "position_format_decimals", get_cmd=None, set_cmd="PF 10.{}", @@ -501,7 +501,7 @@ def __init__( ) """gets absolute position of the motors from the set origin""" - self.wait: Parameter = self.add_parameter( + self.wait: Parameter[int, Self] = self.add_parameter( "wait", get_cmd=None, set_cmd="WT {}", diff --git a/src/qcodes/instrument_drivers/HP/HP_8133A.py b/src/qcodes/instrument_drivers/HP/HP_8133A.py index e526b385acbc..8a667d4d03ad 100644 --- a/src/qcodes/instrument_drivers/HP/HP_8133A.py +++ b/src/qcodes/instrument_drivers/HP/HP_8133A.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.validators import Numbers @@ -25,7 +25,7 @@ def __init__( ): super().__init__(name, address, **kwargs) - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", label="Frequency", unit="Hz", @@ -35,7 +35,7 @@ def __init__( vals=Numbers(min_value=31.3e6, max_value=3.5e9), ) """Parameter frequency""" - self.period: Parameter = self.add_parameter( + self.period: Parameter[float, Self] = self.add_parameter( name="period", label="Period", unit="s", @@ -45,7 +45,7 @@ def __init__( vals=Numbers(min_value=286e-12, max_value=31.949e-9), ) """Parameter period""" - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( name="phase", label="Phase", unit="deg", @@ -55,7 +55,7 @@ def __init__( vals=Numbers(min_value=-3.6e3, max_value=3.6e3), ) """Parameter phase""" - self.duty_cycle: Parameter = self.add_parameter( + self.duty_cycle: Parameter[float, Self] = self.add_parameter( name="duty_cycle", label="Duty cycle", unit="%", @@ -65,7 +65,7 @@ def __init__( vals=Numbers(min_value=0, max_value=100), ) """Parameter duty_cycle""" - self.delay: Parameter = self.add_parameter( + self.delay: Parameter[float, Self] = self.add_parameter( name="delay", label="Delay", unit="s", @@ -75,7 +75,7 @@ def __init__( vals=Numbers(min_value=-5e-9, max_value=5e-9), ) """Parameter delay""" - self.width: Parameter = self.add_parameter( + self.width: Parameter[float, Self] = self.add_parameter( name="width", label="Width", unit="s", @@ -85,7 +85,7 @@ def __init__( vals=Numbers(min_value=1e-12, max_value=10.5e-9), ) """Parameter width""" - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( name="amplitude", label="Amplitude", unit="V", @@ -95,7 +95,7 @@ def __init__( vals=Numbers(min_value=0.1, max_value=3.3), ) """Parameter amplitude""" - self.amplitude_offset: Parameter = self.add_parameter( + self.amplitude_offset: Parameter[float, Self] = self.add_parameter( name="amplitude_offset", label="Offset", unit="V", @@ -105,7 +105,7 @@ def __init__( vals=Numbers(min_value=-2.95, max_value=3.95), ) """Parameter amplitude_offset""" - self.output: Parameter = self.add_parameter( + self.output: Parameter[str, Self] = self.add_parameter( name="output", label="Output", get_cmd="OUTP?", diff --git a/src/qcodes/instrument_drivers/HP/HP_83650A.py b/src/qcodes/instrument_drivers/HP/HP_83650A.py index 7282f1107dc7..fb901db13dae 100644 --- a/src/qcodes/instrument_drivers/HP/HP_83650A.py +++ b/src/qcodes/instrument_drivers/HP/HP_83650A.py @@ -2,7 +2,7 @@ # # Written by Bruno Buijtendorp (brunobuijtendorp@gmail.com) import logging -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators as vals from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs @@ -38,7 +38,7 @@ def __init__( log.debug("Initializing instrument") super().__init__(name, address, **kwargs) - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( "frequency", label="Frequency", get_cmd="FREQ:CW?", @@ -50,7 +50,7 @@ def __init__( ) """Microwave frequency, ....""" - self.freqmode: Parameter = self.add_parameter( + self.freqmode: Parameter[str, Self] = self.add_parameter( "freqmode", label="Frequency mode", get_cmd="FREQ:MODE?", @@ -61,7 +61,7 @@ def __init__( ) """Microwave frequency mode, ....""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( "power", label="Power", get_cmd="SOUR:POW?", @@ -73,7 +73,7 @@ def __init__( ) """Microwave power, ....""" - self.rfstatus: Parameter = self.add_parameter( + self.rfstatus: Parameter[str, Self] = self.add_parameter( "rfstatus", label="RF status", get_cmd=":POW:STAT?", @@ -85,7 +85,7 @@ def __init__( ) """Status, ....""" - self.fmstatus: Parameter = self.add_parameter( + self.fmstatus: Parameter[str, Self] = self.add_parameter( "fmstatus", label="FM status", get_cmd=":FM:STAT?", @@ -97,7 +97,7 @@ def __init__( ) """FM status, ....""" - self.fmcoup: Parameter = self.add_parameter( + self.fmcoup: Parameter[str, Self] = self.add_parameter( "fmcoup", label="FM coupling", get_cmd=":FM:COUP?", @@ -108,7 +108,7 @@ def __init__( ) """FM coupling, ....""" - self.amstatus: Parameter = self.add_parameter( + self.amstatus: Parameter[str, Self] = self.add_parameter( "amstatus", label="AM status", get_cmd=":AM:STAT?", @@ -120,7 +120,7 @@ def __init__( ) """AM status, ....""" - self.pulsestatus: Parameter = self.add_parameter( + self.pulsestatus: Parameter[str, Self] = self.add_parameter( "pulsestatus", label="Pulse status", get_cmd=":PULS:STAT?", @@ -132,7 +132,7 @@ def __init__( ) """Pulse status, ....""" - self.pulsesource: Parameter = self.add_parameter( + self.pulsesource: Parameter[str, Self] = self.add_parameter( "pulsesource", label="Pulse source", get_cmd=":PULS:SOUR?", diff --git a/src/qcodes/instrument_drivers/HP/HP_8753D.py b/src/qcodes/instrument_drivers/HP/HP_8753D.py index ae6756427ab7..2d9b7d042c57 100644 --- a/src/qcodes/instrument_drivers/HP/HP_8753D.py +++ b/src/qcodes/instrument_drivers/HP/HP_8753D.py @@ -1,6 +1,6 @@ import logging from functools import partial -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self import numpy as np @@ -128,7 +128,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.start_freq: Parameter = self.add_parameter( + self.start_freq: Parameter[float, Self] = self.add_parameter( "start_freq", label="Sweep start frequency", unit="Hz", @@ -139,7 +139,7 @@ def __init__( ) """Parameter start_freq""" - self.stop_freq: Parameter = self.add_parameter( + self.stop_freq: Parameter[float, Self] = self.add_parameter( "stop_freq", label="Sweep stop frequency", unit="Hz", @@ -150,7 +150,7 @@ def __init__( ) """Parameter stop_freq""" - self.averaging: Parameter = self.add_parameter( + self.averaging: Parameter[str, Self] = self.add_parameter( "averaging", label="Averaging state", set_cmd="AVERO{}", @@ -159,7 +159,7 @@ def __init__( ) """Parameter averaging""" - self.number_of_averages: Parameter = self.add_parameter( + self.number_of_averages: Parameter[int, Self] = self.add_parameter( "number_of_averages", label="Number of averages", set_cmd="AVERFACT{}", @@ -169,7 +169,7 @@ def __init__( ) """Parameter number_of_averages""" - self.trace_points: Parameter = self.add_parameter( + self.trace_points: Parameter[int, Self] = self.add_parameter( "trace_points", label="Number of points in trace", set_cmd=partial(self.invalidate_trace, "POIN{}"), @@ -179,7 +179,7 @@ def __init__( ) """Parameter trace_points""" - self.sweep_time: Parameter = self.add_parameter( + self.sweep_time: Parameter[float, Self] = self.add_parameter( "sweep_time", label="Sweep time", set_cmd="SWET{}", @@ -190,7 +190,7 @@ def __init__( ) """Parameter sweep_time""" - self.output_power: Parameter = self.add_parameter( + self.output_power: Parameter[float, Self] = self.add_parameter( "output_power", label="Output power", unit="dBm", @@ -201,7 +201,7 @@ def __init__( ) """Parameter output_power""" - self.s_parameter: Parameter = self.add_parameter( + self.s_parameter: Parameter[str, Self] = self.add_parameter( "s_parameter", label="S-parameter", set_cmd=self._s_parameter_setter, @@ -210,7 +210,7 @@ def __init__( """Parameter s_parameter""" # DISPLAY / Y SCALE PARAMETERS - self.display_format: Parameter = self.add_parameter( + self.display_format: Parameter[str, Self] = self.add_parameter( "display_format", label="Display format", set_cmd=self._display_format_setter, @@ -219,7 +219,7 @@ def __init__( """Parameter display_format""" # TODO: update this on startup and via display format - self.display_reference: Parameter = self.add_parameter( + self.display_reference: Parameter[float, Self] = self.add_parameter( "display_reference", label="Display reference level", unit=None, # will be set by display_format @@ -230,7 +230,7 @@ def __init__( ) """Parameter display_reference""" - self.display_scale: Parameter = self.add_parameter( + self.display_scale: Parameter[float, Self] = self.add_parameter( "display_scale", label="Display scale", unit=None, # will be set by display_format diff --git a/src/qcodes/instrument_drivers/Keithley/Keithley_2000.py b/src/qcodes/instrument_drivers/Keithley/Keithley_2000.py index 3ce69db89fad..fe4dd779bf67 100644 --- a/src/qcodes/instrument_drivers/Keithley/Keithley_2000.py +++ b/src/qcodes/instrument_drivers/Keithley/Keithley_2000.py @@ -1,5 +1,5 @@ from functools import partial -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.validators import Bool, Enum, Ints, MultiType, Numbers @@ -69,7 +69,7 @@ def __init__( "frequency": '"FREQ"', } - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", get_cmd="SENS:FUNC?", set_cmd="SENS:FUNC {}", @@ -78,7 +78,7 @@ def __init__( """Parameter mode""" # Mode specific parameters - self.nplc: Parameter = self.add_parameter( + self.nplc: Parameter[float, Self] = self.add_parameter( "nplc", get_cmd=partial(self._get_mode_param, "NPLC", float), set_cmd=partial(self._set_mode_param, "NPLC"), @@ -88,7 +88,7 @@ def __init__( # TODO: validator, this one is more difficult since different modes # require different validation ranges - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd=partial(self._get_mode_param, "RANG", float), set_cmd=partial(self._set_mode_param, "RANG"), @@ -96,7 +96,7 @@ def __init__( ) """Parameter range""" - self.auto_range_enabled: Parameter = self.add_parameter( + self.auto_range_enabled: Parameter[bool, Self] = self.add_parameter( "auto_range_enabled", get_cmd=partial(self._get_mode_param, "RANG:AUTO", _parse_output_bool), set_cmd=partial(self._set_mode_param, "RANG:AUTO"), @@ -104,7 +104,7 @@ def __init__( ) """Parameter auto_range_enabled""" - self.digits: Parameter = self.add_parameter( + self.digits: Parameter[int, Self] = self.add_parameter( "digits", get_cmd=partial(self._get_mode_param, "DIG", int), set_cmd=partial(self._set_mode_param, "DIG"), @@ -112,7 +112,7 @@ def __init__( ) """Parameter digits""" - self.averaging_type: Parameter = self.add_parameter( + self.averaging_type: Parameter[str, Self] = self.add_parameter( "averaging_type", get_cmd=partial(self._get_mode_param, "AVER:TCON", _parse_output_string), set_cmd=partial(self._set_mode_param, "AVER:TCON"), @@ -120,7 +120,7 @@ def __init__( ) """Parameter averaging_type""" - self.averaging_count: Parameter = self.add_parameter( + self.averaging_count: Parameter[int, Self] = self.add_parameter( "averaging_count", get_cmd=partial(self._get_mode_param, "AVER:COUN", int), set_cmd=partial(self._set_mode_param, "AVER:COUN"), @@ -128,7 +128,7 @@ def __init__( ) """Parameter averaging_count""" - self.averaging_enabled: Parameter = self.add_parameter( + self.averaging_enabled: Parameter[bool, Self] = self.add_parameter( "averaging_enabled", get_cmd=partial(self._get_mode_param, "AVER:STAT", _parse_output_bool), set_cmd=partial(self._set_mode_param, "AVER:STAT"), @@ -137,7 +137,7 @@ def __init__( """Parameter averaging_enabled""" # Global parameters - self.display_enabled: Parameter = self.add_parameter( + self.display_enabled: Parameter[bool, Self] = self.add_parameter( "display_enabled", get_cmd="DISP:ENAB?", get_parser=_parse_output_bool, @@ -147,7 +147,7 @@ def __init__( ) """Parameter display_enabled""" - self.trigger_continuous: Parameter = self.add_parameter( + self.trigger_continuous: Parameter[bool, Self] = self.add_parameter( "trigger_continuous", get_cmd="INIT:CONT?", get_parser=_parse_output_bool, @@ -169,7 +169,7 @@ def __init__( ) """Parameter trigger_count""" - self.trigger_delay: Parameter = self.add_parameter( + self.trigger_delay: Parameter[float, Self] = self.add_parameter( "trigger_delay", get_cmd="TRIG:DEL?", get_parser=float, @@ -179,7 +179,7 @@ def __init__( ) """Parameter trigger_delay""" - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( "trigger_source", get_cmd="TRIG:SOUR?", set_cmd="TRIG:SOUR {}", @@ -193,7 +193,7 @@ def __init__( ) """Parameter trigger_source""" - self.trigger_timer: Parameter = self.add_parameter( + self.trigger_timer: Parameter[float, Self] = self.add_parameter( "trigger_timer", get_cmd="TRIG:TIM?", get_parser=float, @@ -203,7 +203,7 @@ def __init__( ) """Parameter trigger_timer""" - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( "amplitude", unit="arb.unit", get_cmd=self._read_next_value ) """Parameter amplitude""" @@ -234,10 +234,15 @@ def _read_next_value(self) -> float: return float(self.ask("SENSE:DATA:FRESH?")) - def _get_mode_param( - self, parameter: str, parser: "Callable[[str], Any]" - ) -> float | str | bool: - """Read the current Keithley mode and ask for a parameter""" + def _get_mode_param[T](self, parameter: str, parser: "Callable[[str], T]") -> T: + """Read the current Keithley mode and ask for a parameter. + + Args: + parameter: The parameter to query in the current mode. + parser: A function that parses the response. It determines the + return type. + + """ mode = _parse_output_string(self._mode_map[self.mode()]) cmd = f"{mode}:{parameter}?" diff --git a/src/qcodes/instrument_drivers/Keithley/Keithley_2400.py b/src/qcodes/instrument_drivers/Keithley/Keithley_2400.py index a3956ad0f130..e2378599e94e 100644 --- a/src/qcodes/instrument_drivers/Keithley/Keithley_2400.py +++ b/src/qcodes/instrument_drivers/Keithley/Keithley_2400.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.parameters import create_on_off_val_mapping @@ -25,7 +25,7 @@ def __init__( ): super().__init__(name, address, **kwargs) - self.rangev: Parameter = self.add_parameter( + self.rangev: Parameter[float, Self] = self.add_parameter( "rangev", get_cmd="SENS:VOLT:RANG?", get_parser=float, @@ -34,7 +34,7 @@ def __init__( ) """Parameter rangev""" - self.rangei: Parameter = self.add_parameter( + self.rangei: Parameter[float, Self] = self.add_parameter( "rangei", get_cmd="SENS:CURR:RANG?", get_parser=float, @@ -43,7 +43,7 @@ def __init__( ) """Parameter rangei""" - self.compliancev: Parameter = self.add_parameter( + self.compliancev: Parameter[float, Self] = self.add_parameter( "compliancev", get_cmd="SENS:VOLT:PROT?", get_parser=float, @@ -52,7 +52,7 @@ def __init__( ) """Parameter compliancev""" - self.compliancei: Parameter = self.add_parameter( + self.compliancei: Parameter[float, Self] = self.add_parameter( "compliancei", get_cmd="SENS:CURR:PROT?", get_parser=float, @@ -61,7 +61,7 @@ def __init__( ) """Parameter compliancei""" - self.volt: Parameter = self.add_parameter( + self.volt: Parameter[float, Self] = self.add_parameter( "volt", get_cmd=self._get_read_output_protected, get_parser=self._volt_parser, @@ -77,7 +77,7 @@ def __init__( ) """Sets voltage in 'VOLT' mode. Get returns measured voltage if sensing 'VOLT' otherwise it returns setpoint value. Note that it is an error to read voltage with output off""" - self.curr: Parameter = self.add_parameter( + self.curr: Parameter[float, Self] = self.add_parameter( "curr", get_cmd=self._get_read_output_protected, get_parser=self._curr_parser, @@ -93,7 +93,7 @@ def __init__( ) """Sets current in 'CURR' mode. Get returns measured current if sensing 'CURR' otherwise it returns setpoint value. Note that it is an error to read current with output off""" - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", vals=Enum("VOLT", "CURR"), get_cmd=":SOUR:FUNC?", @@ -102,7 +102,7 @@ def __init__( ) """Parameter mode""" - self.sense: Parameter = self.add_parameter( + self.sense: Parameter[str, Self] = self.add_parameter( "sense", vals=Strings(), get_cmd=":SENS:FUNC?", @@ -111,7 +111,7 @@ def __init__( ) """Parameter sense""" - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( "output", set_cmd=":OUTP:STAT {}", get_cmd=":OUTP:STAT?", @@ -119,7 +119,7 @@ def __init__( ) """Parameter output""" - self.nplcv: Parameter = self.add_parameter( + self.nplcv: Parameter[float, Self] = self.add_parameter( "nplcv", get_cmd="SENS:VOLT:NPLC?", get_parser=float, @@ -128,7 +128,7 @@ def __init__( ) """Parameter nplcv""" - self.nplci: Parameter = self.add_parameter( + self.nplci: Parameter[float, Self] = self.add_parameter( "nplci", get_cmd="SENS:CURR:NPLC?", get_parser=float, @@ -137,7 +137,7 @@ def __init__( ) """Parameter nplci""" - self.resistance: Parameter = self.add_parameter( + self.resistance: Parameter[float, Self] = self.add_parameter( "resistance", get_cmd=self._get_read_output_protected, get_parser=self._resistance_parser, diff --git a/src/qcodes/instrument_drivers/Keithley/Keithley_2450.py b/src/qcodes/instrument_drivers/Keithley/Keithley_2450.py index 792739d9ff56..e26a86205fa6 100644 --- a/src/qcodes/instrument_drivers/Keithley/Keithley_2450.py +++ b/src/qcodes/instrument_drivers/Keithley/Keithley_2450.py @@ -96,7 +96,7 @@ def __init__( f"{self.buffer_name} size to {self._size}." ) - self.size: Parameter = self.add_parameter( + self.size: Parameter[int, Self] = self.add_parameter( "size", get_cmd=f":TRACe:POINts? '{self.buffer_name}'", set_cmd=f":TRACe:POINts {{}}, '{self.buffer_name}'", @@ -105,7 +105,7 @@ def __init__( ) """The number of readings a buffer can store.""" - self.number_of_readings: Parameter = self.add_parameter( + self.number_of_readings: Parameter[int, Self] = self.add_parameter( "number_of_readings", get_cmd=f":TRACe:ACTual? '{self.buffer_name}'", get_parser=int, @@ -247,7 +247,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N self.function = self.parent.sense_function - self.four_wire_measurement: Parameter = self.add_parameter( + self.four_wire_measurement: Parameter[bool, Self] = self.add_parameter( "four_wire_measurement", set_cmd=f":SENSe:{self._proper_function}:RSENse {{}}", get_cmd=f":SENSe:{self._proper_function}:RSENse?", @@ -255,7 +255,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter four_wire_measurement""" - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", set_cmd=f":SENSe:{self._proper_function}:RANGe {{}}", get_cmd=f":SENSe:{self._proper_function}:RANGe?", @@ -265,7 +265,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter range""" - self.auto_range: Parameter = self.add_parameter( + self.auto_range: Parameter[bool, Self] = self.add_parameter( "auto_range", set_cmd=f":SENSe:{self._proper_function}:RANGe:AUTO {{}}", get_cmd=f":SENSe:{self._proper_function}:RANGe:AUTO?", @@ -291,20 +291,21 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter sweep""" - self.nplc: Parameter = self.add_parameter( + self.nplc: Parameter[float, Self] = self.add_parameter( "nplc", get_cmd=f":SENSe:{self._proper_function}:NPLCycles?", set_cmd=f":SENSe:{self._proper_function}:NPLCycles {{}}", + get_parser=float, vals=Numbers(0.001, 10), ) """Parameter nplc""" - self.user_number: Parameter = self.add_parameter( + self.user_number: Parameter[int, Self] = self.add_parameter( "user_number", get_cmd=None, set_cmd=None, vals=Ints(1, 5) ) """Parameter user_number""" - self.user_delay: Parameter = self.add_parameter( + self.user_delay: Parameter[float, Self] = self.add_parameter( "user_delay", get_cmd=self._get_user_delay, set_cmd=self._set_user_delay, @@ -313,7 +314,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter user_delay""" - self.auto_zero_enabled: Parameter = self.add_parameter( + self.auto_zero_enabled: Parameter[bool, Self] = self.add_parameter( "auto_zero_enabled", get_cmd=f":SENSe:{self._proper_function}:AZERo?", set_cmd=f":SENSe:{self._proper_function}:AZERo {{}}", @@ -324,10 +325,11 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """This command enables or disables automatic updates to the internal reference measurements (autozero) of the instrument.""" - self.count: Parameter = self.add_parameter( + self.count: Parameter[int, Self] = self.add_parameter( "count", get_cmd=":SENSe:COUNt?", set_cmd=":SENSe:COUNt {}", + get_parser=int, docstring="The number of measurements to make when a measurement " "is requested.", ) @@ -409,7 +411,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N self.function = self.parent.source_function self._sweep_arguments: _SweepDict | None = None - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", set_cmd=f":SOUR:{self._proper_function}:RANGe {{}}", get_cmd=f":SOUR:{self._proper_function}:RANGe?", @@ -419,7 +421,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter range""" - self.auto_range: Parameter = self.add_parameter( + self.auto_range: Parameter[bool, Self] = self.add_parameter( "auto_range", set_cmd=f":SOURce:{self._proper_function}:RANGe:AUTO {{}}", get_cmd=f":SOURce:{self._proper_function}:RANGe:AUTO?", @@ -428,7 +430,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N """Parameter auto_range""" limit_cmd = {"current": "VLIM", "voltage": "ILIM"}[self._proper_function] - self.limit: Parameter = self.add_parameter( + self.limit: Parameter[float, Self] = self.add_parameter( "limit", set_cmd=f"SOUR:{self._proper_function}:{limit_cmd} {{}}", get_cmd=f"SOUR:{self._proper_function}:{limit_cmd}?", @@ -437,7 +439,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter limit""" - self.limit_tripped: Parameter = self.add_parameter( + self.limit_tripped: Parameter[bool, Self] = self.add_parameter( "limit_tripped", get_cmd=f":SOUR:{self._proper_function}:{limit_cmd}:TRIPped?", val_mapping={True: 1, False: 0}, @@ -462,20 +464,21 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter sweep_axis""" - self.delay: Parameter = self.add_parameter( + self.delay: Parameter[float, Self] = self.add_parameter( "delay", get_cmd=f":SOURce:{self._proper_function}:DELay?", set_cmd=f":SOURce:{self._proper_function}:DELay {{}}", + get_parser=float, vals=Numbers(0, 1e4), ) """Parameter delay""" - self.user_number: Parameter = self.add_parameter( + self.user_number: Parameter[int, Self] = self.add_parameter( "user_number", get_cmd=None, set_cmd=None, vals=Ints(1, 5) ) """Parameter user_number""" - self.user_delay: Parameter = self.add_parameter( + self.user_delay: Parameter[float, Self] = self.add_parameter( "user_delay", get_cmd=self._get_user_delay, set_cmd=self._set_user_delay, @@ -483,7 +486,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter user_delay""" - self.auto_delay: Parameter = self.add_parameter( + self.auto_delay: Parameter[bool, Self] = self.add_parameter( "auto_delay", get_cmd=f":SOURce:{self._proper_function}:DELay:AUTO?", set_cmd=f":SOURce:{self._proper_function}:DELay:AUTO {{}}", @@ -491,7 +494,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """Parameter auto_delay""" - self.read_back_enabled: Parameter = self.add_parameter( + self.read_back_enabled: Parameter[bool, Self] = self.add_parameter( "read_back_enabled", get_cmd=f":SOURce:{self._proper_function}:READ:BACK?", set_cmd=f":SOURce:{self._proper_function}:READ:BACK {{}}", @@ -502,7 +505,7 @@ def __init__(self, parent: "Keithley2450", name: str, proper_function: str) -> N ) """This command determines if the instrument records the measured source value or the configured source value when making a measurement.""" - self.block_during_ramp: Parameter = self.add_parameter( + self.block_during_ramp: Parameter[bool, Self] = self.add_parameter( "block_during_ramp", initial_value=False, get_cmd=None, @@ -610,7 +613,7 @@ def __init__( ) return - self.source_function: Parameter = self.add_parameter( + self.source_function: Parameter[str, Self] = self.add_parameter( "source_function", set_cmd=self._set_source_function, get_cmd=":SOUR:FUNC?", @@ -621,7 +624,7 @@ def __init__( ) """Parameter source_function""" - self.sense_function: Parameter = self.add_parameter( + self.sense_function: Parameter[str, Self] = self.add_parameter( "sense_function", set_cmd=self._set_sense_function, get_cmd=":SENS:FUNC?", @@ -632,7 +635,7 @@ def __init__( ) """Parameter sense_function""" - self.terminals: Parameter = self.add_parameter( + self.terminals: Parameter[str, Self] = self.add_parameter( "terminals", set_cmd="ROUTe:TERMinals {}", get_cmd="ROUTe:TERMinals?", @@ -640,7 +643,7 @@ def __init__( ) """Parameter terminals""" - self.output_enabled: Parameter = self.add_parameter( + self.output_enabled: Parameter[bool, Self] = self.add_parameter( "output_enabled", set_cmd=":OUTP {}", get_cmd=":OUTP?", @@ -648,9 +651,12 @@ def __init__( ) """Parameter output_enabled""" - self.line_frequency: Parameter = self.add_parameter( + self.line_frequency: Parameter[int, Self] = self.add_parameter( "line_frequency", get_cmd=":SYSTem:LFRequency?", + # the manual does not document the response format, so accept + # both integer and exponent notation + get_parser=lambda s: int(float(s)), unit="Hz", docstring="returns the power line frequency setting that is used " "for NPLC calculations", diff --git a/src/qcodes/instrument_drivers/Keithley/Keithley_3706A.py b/src/qcodes/instrument_drivers/Keithley/Keithley_3706A.py index 842d4734960f..4e7db35fbcb3 100644 --- a/src/qcodes/instrument_drivers/Keithley/Keithley_3706A.py +++ b/src/qcodes/instrument_drivers/Keithley/Keithley_3706A.py @@ -3,7 +3,7 @@ import textwrap import warnings from time import sleep -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self import qcodes.validators as vals from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs @@ -51,7 +51,7 @@ def __init__( self.use_forbidden_channels_cache: bool = use_forbidden_channels_cache self._forbidden_channels_cache: str = "" - self.channel_connect_rule: Parameter = self.add_parameter( + self.channel_connect_rule: Parameter[str, Self] = self.add_parameter( "channel_connect_rule", get_cmd=self._get_channel_connect_rule, set_cmd=self._set_channel_connect_rule, @@ -89,7 +89,7 @@ def __init__( If it is off, channels open and close simultaneously. """ - self.gpib_enabled: Parameter = self.add_parameter( + self.gpib_enabled: Parameter[bool, Self] = self.add_parameter( "gpib_enabled", get_cmd=self._get_gpib_status, set_cmd=self._set_gpib_status, @@ -98,7 +98,7 @@ def __init__( ) """Enables or disables GPIB connection.""" - self.gpib_address: Parameter = self.add_parameter( + self.gpib_address: Parameter[int, Self] = self.add_parameter( "gpib_address", get_cmd=self._get_gpib_address, get_parser=int, @@ -108,7 +108,7 @@ def __init__( ) """Sets and gets the GPIB address.""" - self.lan_enabled: Parameter = self.add_parameter( + self.lan_enabled: Parameter[bool, Self] = self.add_parameter( "lan_enabled", get_cmd=self._get_lan_status, set_cmd=self._set_lan_status, diff --git a/src/qcodes/instrument_drivers/Keithley/Keithley_6500.py b/src/qcodes/instrument_drivers/Keithley/Keithley_6500.py index f8b30ac5c477..7e9a3bad4e9a 100644 --- a/src/qcodes/instrument_drivers/Keithley/Keithley_6500.py +++ b/src/qcodes/instrument_drivers/Keithley/Keithley_6500.py @@ -1,5 +1,5 @@ from functools import partial -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.validators import Bool, Enum, Ints, MultiType, Numbers @@ -97,7 +97,7 @@ def __init__( "frequency": "FREQ", } - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", get_cmd="SENS:FUNC?", set_cmd="SENS:FUNC '{}'", @@ -105,7 +105,7 @@ def __init__( ) """Parameter mode""" - self.nplc: Parameter = self.add_parameter( + self.nplc: Parameter[float, Self] = self.add_parameter( "nplc", get_cmd=partial(self._get_mode_param, "NPLC", float), set_cmd=partial(self._set_mode_param, "NPLC"), @@ -115,7 +115,7 @@ def __init__( # TODO: validator, this one is more difficult since different modes # require different validation ranges. - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd=partial(self._get_mode_param, "RANG", float), set_cmd=partial(self._set_mode_param, "RANG"), @@ -123,7 +123,7 @@ def __init__( ) """Parameter range""" - self.auto_range_enabled: Parameter = self.add_parameter( + self.auto_range_enabled: Parameter[bool, Self] = self.add_parameter( "auto_range_enabled", get_cmd=partial(self._get_mode_param, "RANG:AUTO", _parse_output_bool), set_cmd=partial(self._set_mode_param, "RANG:AUTO"), @@ -131,16 +131,16 @@ def __init__( ) """Parameter auto_range_enabled""" - self.digits: Parameter = self.add_parameter( + self.digits: Parameter[int, Self] = self.add_parameter( "digits", get_cmd="DISP:VOLT:DC:DIG?", get_parser=int, - set_cmd="DISP:VOLT:DC:DIG? {}", + set_cmd="DISP:VOLT:DC:DIG {}", vals=Ints(min_value=4, max_value=7), ) """Parameter digits""" - self.averaging_type: Parameter = self.add_parameter( + self.averaging_type: Parameter[str, Self] = self.add_parameter( "averaging_type", get_cmd=partial(self._get_mode_param, "AVER:TCON", _parse_output_string), set_cmd=partial(self._set_mode_param, "AVER:TCON"), @@ -148,7 +148,7 @@ def __init__( ) """Parameter averaging_type""" - self.averaging_count: Parameter = self.add_parameter( + self.averaging_count: Parameter[int, Self] = self.add_parameter( "averaging_count", get_cmd=partial(self._get_mode_param, "AVER:COUN", int), set_cmd=partial(self._set_mode_param, "AVER:COUN"), @@ -156,7 +156,7 @@ def __init__( ) """Parameter averaging_count""" - self.averaging_enabled: Parameter = self.add_parameter( + self.averaging_enabled: Parameter[bool, Self] = self.add_parameter( "averaging_enabled", get_cmd=partial(self._get_mode_param, "AVER:STAT", _parse_output_bool), set_cmd=partial(self._set_mode_param, "AVER:STAT"), @@ -165,7 +165,7 @@ def __init__( """Parameter averaging_enabled""" # Global parameters - self.display_backlight: Parameter = self.add_parameter( + self.display_backlight: Parameter[str, Self] = self.add_parameter( "display_backlight", docstring="Control the brightness of the display " "backligt. Off turns the display off and" @@ -229,7 +229,7 @@ def __init__( # Control interval between scans; the default value from the instrument is 0, # hence 0 is included in the validator's range of this parameter. - self.trigger_timer: Parameter = self.add_parameter( + self.trigger_timer: Parameter[float, Self] = self.add_parameter( "trigger_timer", get_parser=float, get_cmd="ROUT:SCAN:INT?", @@ -239,7 +239,7 @@ def __init__( ) """Parameter trigger_timer""" - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( "amplitude", get_cmd=self._read_next_value, set_cmd=False, unit="a.u." ) """Parameter amplitude""" diff --git a/src/qcodes/instrument_drivers/Keithley/Keithley_7510.py b/src/qcodes/instrument_drivers/Keithley/Keithley_7510.py index f0d313f52b4e..3be951318c60 100644 --- a/src/qcodes/instrument_drivers/Keithley/Keithley_7510.py +++ b/src/qcodes/instrument_drivers/Keithley/Keithley_7510.py @@ -130,7 +130,7 @@ def __init__( f"{self.short_name} size to {self._size}." ) - self.size: Parameter = self.add_parameter( + self.size: Parameter[int, Self] = self.add_parameter( "size", get_cmd=f":TRACe:POINts? '{self.short_name}'", set_cmd=f":TRACe:POINts {{}}, '{self.short_name}'", @@ -139,7 +139,7 @@ def __init__( ) """The number of readings a buffer can store.""" - self.number_of_readings: Parameter = self.add_parameter( + self.number_of_readings: Parameter[int, Self] = self.add_parameter( "number_of_readings", get_cmd=f":TRACe:ACTual? '{self.short_name}'", get_parser=int, @@ -147,7 +147,7 @@ def __init__( ) """Get the number of readings in the reading buffer.""" - self.last_index: Parameter = self.add_parameter( + self.last_index: Parameter[int, Self] = self.add_parameter( "last_index", get_cmd=f":TRACe:ACTual:END? '{self.short_name}'", get_parser=int, @@ -155,7 +155,7 @@ def __init__( ) """Get the last index of readings in the reading buffer.""" - self.first_index: Parameter = self.add_parameter( + self.first_index: Parameter[int, Self] = self.add_parameter( "first_index", get_cmd=f":TRACe:ACTual:STARt? '{self.short_name}'", get_parser=int, @@ -208,7 +208,7 @@ def __init__( ) """Parameter setpoints_stop""" - self.n_pts: Parameter = self.add_parameter( + self.n_pts: Parameter[int, Self] = self.add_parameter( "n_pts", label="total n for the setpoints", get_cmd=self._get_n_pts ) """Parameter n_pts""" @@ -245,7 +245,7 @@ def __init__( ) """Parameter t_stop""" - self.fill_mode: Parameter = self.add_parameter( + self.fill_mode: Parameter[str, Self] = self.add_parameter( "fill_mode", get_cmd=f":TRACe:FILL:MODE? '{self.short_name}'", set_cmd=f":TRACe:FILL:MODE {{}}, '{self.short_name}'", @@ -495,7 +495,7 @@ def __init__( "return the last reading.", ) - self.auto_range: Parameter = self.add_parameter( + self.auto_range: Parameter[bool, Self] = self.add_parameter( "auto_range", get_cmd=f":SENSe:{self._proper_function}:RANGe:AUTO?", set_cmd=f":SENSe:{self._proper_function}:RANGe:AUTO {{}}", @@ -505,7 +505,7 @@ def __init__( ) """Determine if the measurement range is set manually or automatically for the selected measure function.""" - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd=f":SENSe:{self._proper_function}:RANGe?", set_cmd=f":SENSe:{self._proper_function}:RANGe {{}}", @@ -516,7 +516,7 @@ def __init__( ) """Determine the positive full-scale measure range.""" - self.nplc: Parameter = self.add_parameter( + self.nplc: Parameter[float, Self] = self.add_parameter( "nplc", get_cmd=f":SENSe:{self._proper_function}:NPLCycles?", set_cmd=f":SENSe:{self._proper_function}:NPLCycles {{}}", @@ -527,7 +527,7 @@ def __init__( ) """Set the time that the input signal is measured for the selected function.(NPLC = number of power line cycles)""" - self.auto_delay: Parameter = self.add_parameter( + self.auto_delay: Parameter[bool, Self] = self.add_parameter( "auto_delay", get_cmd=f":SENSe:{self._proper_function}:DELay:AUTO?", set_cmd=f":SENSe:{self._proper_function}:DELay:AUTO {{}}", @@ -537,7 +537,7 @@ def __init__( ) """Enable or disable the automatic delay that occurs before each measurement.""" - self.user_number: Parameter = self.add_parameter( + self.user_number: Parameter[int, Self] = self.add_parameter( "user_number", get_cmd=None, set_cmd=None, @@ -546,7 +546,7 @@ def __init__( ) """Set the user number for user-defined delay.""" - self.user_delay: Parameter = self.add_parameter( + self.user_delay: Parameter[float, Self] = self.add_parameter( "user_delay", get_cmd=self._get_user_delay, set_cmd=self._set_user_delay, @@ -556,7 +556,7 @@ def __init__( ) """Set a user-defined delay that you can use in the trigger model.""" - self.auto_zero: Parameter = self.add_parameter( + self.auto_zero: Parameter[bool, Self] = self.add_parameter( "auto_zero", get_cmd=f":SENSe:{self._proper_function}:AZERo?", set_cmd=f":SENSe:{self._proper_function}:AZERo {{}}", @@ -574,7 +574,7 @@ def __init__( ) """Cause the instrument to refresh the reference and zero measurements once""" - self.average: Parameter = self.add_parameter( + self.average: Parameter[bool, Self] = self.add_parameter( "average", get_cmd=f":SENSe:{self._proper_function}:AVERage?", set_cmd=f":SENSe:{self._proper_function}:AVERage {{}}", @@ -584,17 +584,18 @@ def __init__( ) """Enable or disable the averaging filter for measurements of the selected function.""" - self.average_count: Parameter = self.add_parameter( + self.average_count: Parameter[int, Self] = self.add_parameter( "average_count", get_cmd=f":SENSe:{self._proper_function}:AVERage:COUNt?", set_cmd=f":SENSe:{self._proper_function}:AVERage:COUNt {{}}", + get_parser=int, vals=Numbers(1, 100), docstring="Set the number of measurements that are averaged when " "filtering is enabled.", ) """Set the number of measurements that are averaged when filtering is enabled.""" - self.average_type: Parameter = self.add_parameter( + self.average_type: Parameter[str, Self] = self.add_parameter( "average_type", get_cmd=f":SENSe:{self._proper_function}:AVERage:TCONtrol?", set_cmd=f":SENSe:{self._proper_function}:AVERage:TCONtrol {{}}", @@ -605,9 +606,9 @@ def __init__( ) """Set the type of averaging filter that is used for the selected measure function when the measurement filter is enabled.""" - def _get_user_delay(self) -> str: + def _get_user_delay(self) -> float: get_cmd = f":SENSe:{self._proper_function}:DELay:USER{self.user_number()}?" - return self.ask(get_cmd) + return float(self.ask(get_cmd)) def _set_user_delay(self, value: float) -> None: set_cmd = ( @@ -662,7 +663,7 @@ def __init__(self, parent: "Keithley7510", name: str, proper_function: str) -> N "return the last reading.", ) - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd=f":SENSe:DIGitize:{self._proper_function}:RANGe?", set_cmd=f":SENSe:DIGitize:{self._proper_function}:RANGe {{}}", @@ -673,7 +674,7 @@ def __init__(self, parent: "Keithley7510", name: str, proper_function: str) -> N ) """Determine the positive full-scale measure range.""" - self.input_impedance: Parameter = self.add_parameter( + self.input_impedance: Parameter[str, Self] = self.add_parameter( "input_impedance", get_cmd=":SENSe:DIGitize:VOLTage:INPutimpedance?", set_cmd=":SENSe:DIGitize:VOLTage:INPutimpedance {}", @@ -683,29 +684,33 @@ def __init__(self, parent: "Keithley7510", name: str, proper_function: str) -> N ) """Determine when the 10 MΩ input divider is enabled. 'MOHM10' means 10 MΩ for all ranges.""" - self.acq_rate: Parameter = self.add_parameter( + self.acq_rate: Parameter[int, Self] = self.add_parameter( "acq_rate", get_cmd=f":SENSe:DIGitize:{self._proper_function}:SRATE?", set_cmd=f":SENSe:DIGitize:{self._proper_function}:SRATE {{}}", + # the manual does not document the response format, so accept + # both integer and exponent notation + get_parser=lambda s: int(float(s)), vals=Ints(1000, 1000000), docstring="Define the precise acquisition rate at which the " "digitizing measurements are made.", ) """Define the precise acquisition rate at which the digitizing measurements are made.""" - self.aperture: Parameter = self.add_parameter( + self.aperture: Parameter[str, Self] = self.add_parameter( "aperture", get_cmd=f":SENSe:DIGitize:{self._proper_function}:APERture?", set_cmd=f":SENSe:DIGitize:{self._proper_function}:APERture {{}}", - unit="us", + unit="s", docstring="Determine the aperture setting.", ) """Determine the aperture setting.""" - self.count: Parameter = self.add_parameter( + self.count: Parameter[int, Self] = self.add_parameter( "count", get_cmd="SENSe:DIGitize:COUNt?", set_cmd="SENSe:DIGitize:COUNt {}", + get_parser=int, vals=Ints(1, 55000000), docstring="Set the number of measurements to digitize when a " "measurement is requested", @@ -741,7 +746,7 @@ def __init__( """ super().__init__(name, address, **kwargs) - self.sense_function: Parameter = self.add_parameter( + self.sense_function: Parameter[str, Self] = self.add_parameter( "sense_function", set_cmd=":SENSe:FUNCtion {}", get_cmd=":SENSe:FUNCtion?", @@ -753,7 +758,7 @@ def __init__( ) """Add sense functions listed in the function modes.""" - self.digi_sense_function: Parameter = self.add_parameter( + self.digi_sense_function: Parameter[str, Self] = self.add_parameter( "digi_sense_function", set_cmd=":DIGitize:FUNCtion {}", get_cmd=":DIGitize:FUNCtion?", @@ -773,7 +778,7 @@ def __init__( ) """Name of the reading buffer in use.""" - self.trigger_block_list: Parameter = self.add_parameter( + self.trigger_block_list: Parameter[str, Self] = self.add_parameter( "trigger_block_list", get_cmd=":TRIGger:BLOCk:LIST?", docstring="Return the settings for all trigger model blocks.", @@ -787,7 +792,7 @@ def __init__( ) """Clear the trigger event on the external in line.""" - self.trigger_in_ext_edge: Parameter = self.add_parameter( + self.trigger_in_ext_edge: Parameter[str, Self] = self.add_parameter( "trigger_in_ext_edge", get_cmd=":TRIGger:EXTernal:IN:EDGE?", set_cmd=":TRIGger:EXTernal:IN:EDGE {}", @@ -797,14 +802,14 @@ def __init__( ) """Type of edge that is detected as an input on the external trigger in line""" - self.overrun_status: Parameter = self.add_parameter( + self.overrun_status: Parameter[str, Self] = self.add_parameter( "overrun_status", get_cmd=":TRIGger:EXTernal:IN:OVERrun?", docstring="Return the event detector overrun status.", ) """Return the event detector overrun status.""" - self.digitize_trigger: Parameter = self.add_parameter( + self.digitize_trigger: Parameter[str, Self] = self.add_parameter( "digitize_trigger", get_cmd=":TRIGger:DIGitize:STIMulus?", set_cmd=":TRIGger:DIGitize:STIMulus {}", @@ -814,7 +819,7 @@ def __init__( ) """Set the instrument to digitize a measurement the next time it detects the specified trigger event.""" - self.system_errors: Parameter = self.add_parameter( + self.system_errors: Parameter[str, Self] = self.add_parameter( "system_errors", get_cmd=":SYSTem:ERRor?", docstring="Return the oldest unread error message from the event " diff --git a/src/qcodes/instrument_drivers/Keithley/_Keithley_2600.py b/src/qcodes/instrument_drivers/Keithley/_Keithley_2600.py index a6fb362e9fae..8ca91a9824bc 100644 --- a/src/qcodes/instrument_drivers/Keithley/_Keithley_2600.py +++ b/src/qcodes/instrument_drivers/Keithley/_Keithley_2600.py @@ -687,7 +687,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Parameter curr""" - self.res: Parameter = self.add_parameter( + self.res: Parameter[float, Self] = self.add_parameter( "res", get_cmd=f"{channel}.measure.r()", get_parser=float, @@ -697,7 +697,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Parameter res""" - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", get_cmd=f"{channel}.source.func", get_parser=float, @@ -708,7 +708,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Selects the output source type. Can be either voltage or current.""" - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( "output", get_cmd=f"{channel}.source.output", get_parser=float, @@ -717,7 +717,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Parameter output""" - self.linefreq: Parameter = self.add_parameter( + self.linefreq: Parameter[float, Self] = self.add_parameter( "linefreq", label="Line frequency", get_cmd="localnode.linefreq", @@ -727,7 +727,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Parameter linefreq""" - self.nplc: Parameter = self.add_parameter( + self.nplc: Parameter[float, Self] = self.add_parameter( "nplc", label="Number of power line cycles", set_cmd=f"{channel}.measure.nplc={{}}", @@ -753,7 +753,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: # volt range # needs get after set (WilliamHPNielsen): why? - self.sourcerange_v: Parameter = self.add_parameter( + self.sourcerange_v: Parameter[float, Self] = self.add_parameter( "sourcerange_v", label="voltage source range", get_cmd=f"{channel}.source.rangev", @@ -767,7 +767,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """The range used when sourcing voltage This affects the range and the precision of the source.""" - self.source_autorange_v_enabled: Parameter = self.add_parameter( + self.source_autorange_v_enabled: Parameter[bool, Self] = self.add_parameter( "source_autorange_v_enabled", label="voltage source autorange", get_cmd=f"{channel}.source.autorangev", @@ -778,7 +778,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Set autorange on/off for source voltage.""" - self.measurerange_v: Parameter = self.add_parameter( + self.measurerange_v: Parameter[float, Self] = self.add_parameter( "measurerange_v", label="voltage measure range", get_cmd=f"{channel}.measure.rangev", @@ -798,7 +798,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: Note that if you both measure and source current this will have no effect, set `sourcerange_v` instead """ - self.measure_autorange_v_enabled: Parameter = self.add_parameter( + self.measure_autorange_v_enabled: Parameter[bool, Self] = self.add_parameter( "measure_autorange_v_enabled", label="voltage measure autorange", get_cmd=f"{channel}.measure.autorangev", @@ -810,7 +810,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: """Set autorange on/off for measure voltage.""" # current range # needs get after set - self.sourcerange_i: Parameter = self.add_parameter( + self.sourcerange_i: Parameter[float, Self] = self.add_parameter( "sourcerange_i", label="current source range", get_cmd=f"{channel}.source.rangei", @@ -824,7 +824,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """The range used when sourcing current This affects the range and the precision of the source.""" - self.source_autorange_i_enabled: Parameter = self.add_parameter( + self.source_autorange_i_enabled: Parameter[bool, Self] = self.add_parameter( "source_autorange_i_enabled", label="current source autorange", get_cmd=f"{channel}.source.autorangei", @@ -835,7 +835,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Set autorange on/off for source current.""" - self.measurerange_i: Parameter = self.add_parameter( + self.measurerange_i: Parameter[float, Self] = self.add_parameter( "measurerange_i", label="current measure range", get_cmd=f"{channel}.measure.rangei", @@ -854,7 +854,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: The range to perform current measurements in. This affects the range and the precision of the measurement. Note that if you both measure and source current this will have no effect, set `sourcerange_i` instead""" - self.measure_autorange_i_enabled: Parameter = self.add_parameter( + self.measure_autorange_i_enabled: Parameter[bool, Self] = self.add_parameter( "measure_autorange_i_enabled", label="current autorange", get_cmd=f"{channel}.measure.autorangei", @@ -865,7 +865,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Set autorange on/off for measure current.""" # Compliance limit - self.limitv: Parameter = self.add_parameter( + self.limitv: Parameter[float, Self] = self.add_parameter( "limitv", get_cmd=f"{channel}.source.limitv", get_parser=float, @@ -880,7 +880,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Voltage limit e.g. the maximum voltage allowed in current mode. If exceeded the current will be clipped.""" # Compliance limit - self.limiti: Parameter = self.add_parameter( + self.limiti: Parameter[float, Self] = self.add_parameter( "limiti", get_cmd=f"{channel}.source.limiti", get_parser=float, @@ -996,7 +996,7 @@ def __init__(self, parent: Keithley2600, name: str, channel: str) -> None: ) """Parameter timetrace""" - self.timetrace_mode: Parameter = self.add_parameter( + self.timetrace_mode: Parameter[str, Self] = self.add_parameter( "timetrace_mode", initial_value="current", get_cmd=None, @@ -1353,7 +1353,7 @@ def __init__( self.channels.append(channel) # display - self.display_settext: Parameter = self.add_parameter( + self.display_settext: Parameter[str, Self] = self.add_parameter( "display_settext", set_cmd=self._display_settext, vals=vals.Strings() ) """Parameter display_settext""" diff --git a/src/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py b/src/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py index 891e6716a2a5..60ff7edc82d2 100644 --- a/src/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py +++ b/src/qcodes/instrument_drivers/Keysight/KeysightAgilent_33XXX.py @@ -1,6 +1,6 @@ import logging from functools import partial -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators as vals from qcodes.instrument import ( @@ -74,7 +74,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: self.model = self._parent.model - self.function_type: Parameter = self.add_parameter( + self.function_type: Parameter[str, Self] = self.add_parameter( "function_type", label=f"Channel {channum} function type", set_cmd=f"SOURce{channum}:FUNCtion {{}}", @@ -86,7 +86,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter function_type""" - self.frequency_mode: Parameter = self.add_parameter( + self.frequency_mode: Parameter[str, Self] = self.add_parameter( "frequency_mode", label=f"Channel {channum} frequency mode", set_cmd=f"SOURce{channum}:FREQuency:MODE {{}}", @@ -97,7 +97,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: """Parameter frequency_mode""" max_freq = self._parent._max_freqs[self.model] - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( "frequency", label=f"Channel {channum} frequency", set_cmd=f"SOURce{channum}:FREQuency {{}}", @@ -109,7 +109,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter frequency""" - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( "phase", label=f"Channel {channum} phase", set_cmd=f"SOURce{channum}:PHASe {{}}", @@ -120,7 +120,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter phase""" - self.amplitude_unit: Parameter = self.add_parameter( + self.amplitude_unit: Parameter[str, Self] = self.add_parameter( "amplitude_unit", label=f"Channel {channum} amplitude unit", set_cmd=f"SOURce{channum}:VOLTage:UNIT {{}}", @@ -130,7 +130,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter amplitude_unit""" - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( "amplitude", label=f"Channel {channum} amplitude", set_cmd=f"SOURce{channum}:VOLTage {{}}", @@ -140,7 +140,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter amplitude""" - self.offset: Parameter = self.add_parameter( + self.offset: Parameter[float, Self] = self.add_parameter( "offset", label=f"Channel {channum} voltage offset", set_cmd=f"SOURce{channum}:VOLTage:OFFSet {{}}", @@ -150,7 +150,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter offset""" - self.output: Parameter = self.add_parameter( + self.output: Parameter[str, Self] = self.add_parameter( "output", label=f"Channel {channum} output state", set_cmd=f"OUTPut{channum} {{}}", @@ -159,7 +159,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter output""" - self.ramp_symmetry: Parameter = self.add_parameter( + self.ramp_symmetry: Parameter[float, Self] = self.add_parameter( "ramp_symmetry", label=f"Channel {channum} ramp symmetry", set_cmd=f"SOURce{channum}:FUNCtion:RAMP:SYMMetry {{}}", @@ -170,7 +170,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter ramp_symmetry""" - self.pulse_width: Parameter = self.add_parameter( + self.pulse_width: Parameter[float, Self] = self.add_parameter( "pulse_width", label=f"Channel {channum} pulse width", set_cmd=f"SOURce{channum}:FUNCtion:PULSE:WIDTh {{}}", @@ -192,7 +192,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: """Sets the transition times for the leading and trailing edges of the pulse.""" # TRIGGER MENU - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( "trigger_source", label=f"Channel {channum} trigger source", set_cmd=f"TRIGger{channum}:SOURce {{}}", @@ -202,7 +202,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter trigger_source""" - self.trigger_slope: Parameter = self.add_parameter( + self.trigger_slope: Parameter[str, Self] = self.add_parameter( "trigger_slope", label=f"Channel {channum} trigger slope", set_cmd=f"TRIGger{channum}:SLOPe {{}}", @@ -224,7 +224,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter trigger_count""" - self.trigger_delay: Parameter = self.add_parameter( + self.trigger_delay: Parameter[float, Self] = self.add_parameter( "trigger_delay", label=f"Channel {channum} trigger delay", set_cmd=f"TRIGger{channum}:DELay {{}}", @@ -235,7 +235,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter trigger_delay""" - self.trigger_timer: Parameter = self.add_parameter( + self.trigger_timer: Parameter[float, Self] = self.add_parameter( "trigger_timer", label=f"Channel {channum} trigger timer", set_cmd=f"TRIGger{channum}:TIMer {{}}", @@ -248,7 +248,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: # TODO: trigger level doesn't work remotely. Why? # output menu - self.output_polarity: Parameter = self.add_parameter( + self.output_polarity: Parameter[str, Self] = self.add_parameter( "output_polarity", label=f"Channel {channum} output polarity", set_cmd=f"OUTPut{channum}:POLarity {{}}", @@ -258,7 +258,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter output_polarity""" # BURST MENU - self.burst_state: Parameter = self.add_parameter( + self.burst_state: Parameter[str, Self] = self.add_parameter( "burst_state", label=f"Channel {channum} burst state", set_cmd=f"SOURce{channum}:BURSt:STATe {{}}", @@ -268,7 +268,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter burst_state""" - self.burst_mode: Parameter = self.add_parameter( + self.burst_mode: Parameter[str, Self] = self.add_parameter( "burst_mode", label=f"Channel {channum} burst mode", set_cmd=f"SOURce{channum}:BURSt:MODE {{}}", @@ -289,7 +289,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter burst_ncycles""" - self.burst_phase: Parameter = self.add_parameter( + self.burst_phase: Parameter[float, Self] = self.add_parameter( "burst_phase", label=f"Channel {channum} burst start phase", set_cmd=f"SOURce{channum}:BURSt:PHASe {{}}", @@ -300,7 +300,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter burst_phase""" - self.burst_polarity: Parameter = self.add_parameter( + self.burst_polarity: Parameter[str, Self] = self.add_parameter( "burst_polarity", label=f"Channel {channum} burst gated polarity", set_cmd=f"SOURce{channum}:BURSt:GATE:POLarity {{}}", @@ -309,7 +309,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Parameter burst_polarity""" - self.burst_int_period: Parameter = self.add_parameter( + self.burst_int_period: Parameter[float, Self] = self.add_parameter( "burst_int_period", label=f"Channel {channum} burst internal period", set_cmd=f"SOURce{channum}:BURSt:INTernal:PERiod {{}}", @@ -336,7 +336,7 @@ def val_parser(parser: type, inputstring: str) -> float | int: ) """Sets expected output termination. Should equal the load impedance attached to the output.""" - self.auto_range: Parameter = self.add_parameter( + self.auto_range: Parameter[str, Self] = self.add_parameter( "auto_range", label=f"Channel {channum} range mode", set_cmd=f"SOURce{channum}:VOLTage:RANGe:AUTO {{}}", @@ -405,7 +405,7 @@ def __init__( ): super().__init__(parent, name, **kwargs) - self.output: Parameter = self.add_parameter( + self.output: Parameter[str, Self] = self.add_parameter( "output", label="Sync output state", set_cmd="OUTPut:SYNC {}", @@ -416,7 +416,7 @@ def __init__( """Parameter output""" if parent.num_channels == 2: - self.source: Parameter = self.add_parameter( + self.source: Parameter[int, Self] = self.add_parameter( "source", label="Source of sync function", set_cmd="OUTPut:SYNC:SOURce {}", diff --git a/src/qcodes/instrument_drivers/Keysight/Keysight_N6705B.py b/src/qcodes/instrument_drivers/Keysight/Keysight_N6705B.py index 6e6cf298c6df..7533fa94a216 100644 --- a/src/qcodes/instrument_drivers/Keysight/Keysight_N6705B.py +++ b/src/qcodes/instrument_drivers/Keysight/Keysight_N6705B.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import ( Instrument, @@ -27,7 +27,7 @@ def __init__( super().__init__(parent, name, **kwargs) - self.source_voltage: Parameter = self.add_parameter( + self.source_voltage: Parameter[float, Self] = self.add_parameter( "source_voltage", label=f"Channel {chan} Voltage", get_cmd=f"SOURCE:VOLT? (@{chan})", @@ -37,7 +37,7 @@ def __init__( ) """Parameter source_voltage""" - self.source_current: Parameter = self.add_parameter( + self.source_current: Parameter[float, Self] = self.add_parameter( "source_current", label=f"Channel {chan} Current", get_cmd=f"SOURCE:CURR? (@{chan})", @@ -47,7 +47,7 @@ def __init__( ) """Parameter source_current""" - self.voltage_limit: Parameter = self.add_parameter( + self.voltage_limit: Parameter[float, Self] = self.add_parameter( "voltage_limit", get_cmd=f"SOUR:VOLT:PROT? (@{chan})", get_parser=float, @@ -57,7 +57,7 @@ def __init__( ) """Parameter voltage_limit""" - self.voltage: Parameter = self.add_parameter( + self.voltage: Parameter[float, Self] = self.add_parameter( "voltage", get_cmd=f"MEAS:VOLT? (@{chan})", get_parser=float, @@ -66,7 +66,7 @@ def __init__( ) """Parameter voltage""" - self.current: Parameter = self.add_parameter( + self.current: Parameter[float, Self] = self.add_parameter( "current", get_cmd=f"MEAS:CURR? (@{chan})", get_parser=float, @@ -75,7 +75,7 @@ def __init__( ) """Parameter current""" - self.enable: Parameter = self.add_parameter( + self.enable: Parameter[str, Self] = self.add_parameter( "enable", get_cmd=f"OUTP:STAT? (@{chan})", set_cmd=f"OUTP:STAT {{:d}}, (@{chan})", @@ -83,7 +83,7 @@ def __init__( ) """Parameter enable""" - self.source_mode: Parameter = self.add_parameter( + self.source_mode: Parameter[str, Self] = self.add_parameter( "source_mode", get_cmd=f":OUTP:PMOD? (@{chan})", set_cmd=f":OUTP:PMOD {{:s}}, (@{chan})", diff --git a/src/qcodes/instrument_drivers/Keysight/Keysight_N9030B.py b/src/qcodes/instrument_drivers/Keysight/Keysight_N9030B.py index a5f17ac885f4..5cbada875779 100644 --- a/src/qcodes/instrument_drivers/Keysight/Keysight_N9030B.py +++ b/src/qcodes/instrument_drivers/Keysight/Keysight_N9030B.py @@ -200,7 +200,7 @@ def __init__( docstring="Preamplifier selection", ) """Preamplifier selection""" - self.preamp_enabled: Parameter = self.add_parameter( + self.preamp_enabled: Parameter[bool, Self] = self.add_parameter( name="preamp_enabled", get_cmd=":SENS:POW:GAIN:STAT?", set_cmd=":SENS:POW:GAIN:STAT {}", @@ -210,7 +210,7 @@ def __init__( """Preamplifier state""" # Resolution parameters - self.res_bw: Parameter = self.add_parameter( + self.res_bw: Parameter[float, Self] = self.add_parameter( name="res_bw", unit="Hz", get_cmd=":SENS:BAND:RES?", @@ -220,7 +220,7 @@ def __init__( docstring="Resolution Bandwidth", ) """Resolution Bandwidth""" - self.video_bw: Parameter = self.add_parameter( + self.video_bw: Parameter[float, Self] = self.add_parameter( name="video_bw", unit="Hz", get_cmd=":SENS:BAND:VID?", @@ -230,7 +230,7 @@ def __init__( docstring="Video Filter Bandwidth", ) """Video Filter Bandwidth""" - self.res_bw_type: Parameter = self.add_parameter( + self.res_bw_type: Parameter[str, Self] = self.add_parameter( name="res_bw_type", get_cmd=":SENS:BAND:TYPE?", set_cmd=":SENS:BAND:TYPE {}", @@ -267,7 +267,7 @@ def __init__( """ # Input parameters - self.detector: Parameter = self.add_parameter( + self.detector: Parameter[str, Self] = self.add_parameter( name="detector", get_cmd=":SENS:DET:TRAC?", set_cmd=":SENS:DET:TRAC {}", @@ -275,7 +275,7 @@ def __init__( docstring="Detector type", ) """Detector type""" - self.average_type: Parameter = self.add_parameter( + self.average_type: Parameter[str, Self] = self.add_parameter( name="average_type", get_cmd=":SENS:AVER:TYPE?", set_cmd=":SENS:AVER:TYPE {}", @@ -342,7 +342,7 @@ def __init__( for in the Marker Noise function.""" # Sweep Parameters - self.sweep_time: Parameter = self.add_parameter( + self.sweep_time: Parameter[float, Self] = self.add_parameter( name="sweep_time", label="Sweep time", get_cmd=":SENSe:SWEep:TIME?", @@ -352,7 +352,7 @@ def __init__( docstring="gets sweep time", ) """gets sweep time""" - self.auto_sweep_time_enabled: Parameter = self.add_parameter( + self.auto_sweep_time_enabled: Parameter[bool, Self] = self.add_parameter( name="auto_sweep_time_enabled", get_cmd=":SENSe:SWEep:TIME:AUTO?", set_cmd=":SENSe:SWEep:TIME:AUTO {}", @@ -360,7 +360,7 @@ def __init__( docstring="enables auto sweep time", ) """enables auto sweep time""" - self.auto_sweep_type_enabled: Parameter = self.add_parameter( + self.auto_sweep_type_enabled: Parameter[bool, Self] = self.add_parameter( name="auto_sweep_type_enabled", get_cmd=":SENSe:SWEep:TYPE:AUTO?", set_cmd=":SENSe:SWEep:TYPE:AUTO {}", @@ -368,7 +368,7 @@ def __init__( docstring="enables auto sweep type", ) """enables auto sweep type""" - self.sweep_type: Parameter = self.add_parameter( + self.sweep_type: Parameter[str, Self] = self.add_parameter( name="sweep_type", get_cmd=":SENSe:SWEep:TYPE?", set_cmd=":SENSe:SWEep:TYPE {}", @@ -543,7 +543,7 @@ def __init__( assert opt is not None self._max_freq = self._valid_max_freq[opt] - self.npts: Parameter = self.add_parameter( + self.npts: Parameter[int, Self] = self.add_parameter( name="npts", get_cmd=":SENSe:LPLot:SWEep:POINts?", set_cmd=":SENSe:LPLot:SWEep:POINts {}", @@ -553,7 +553,7 @@ def __init__( ) """Number of points for the sweep""" - self.start_offset: Parameter = self.add_parameter( + self.start_offset: Parameter[float, Self] = self.add_parameter( name="start_offset", unit="Hz", get_cmd=":SENSe:LPLot:FREQuency:OFFSet:STARt?", @@ -564,7 +564,7 @@ def __init__( ) """start frequency offset for the plot""" - self.stop_offset: Parameter = self.add_parameter( + self.stop_offset: Parameter[float, Self] = self.add_parameter( name="stop_offset", unit="Hz", get_cmd=":SENSe:LPLot:FREQuency:OFFSet:STOP?", @@ -575,7 +575,7 @@ def __init__( ) """stop frequency offset for the plot""" - self.signal_tracking_enabled: Parameter = self.add_parameter( + self.signal_tracking_enabled: Parameter[bool, Self] = self.add_parameter( name="signal_tracking_enabled", get_cmd=":SENSe:FREQuency:CARRier:TRACk?", set_cmd=":SENSe:FREQuency:CARRier:TRACk {}", @@ -750,7 +750,7 @@ def __init__( self._max_freq: float self._additional_wait: float = 1 - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( name="mode", get_cmd=":INSTrument:SELect?", set_cmd=":INSTrument:SELect {}", @@ -763,7 +763,7 @@ def __init__( for the instrument. """ - self.measurement: Parameter = self.add_parameter( + self.measurement: Parameter[str, Self] = self.add_parameter( name="measurement", get_cmd=":CONFigure?", set_cmd=":CONFigure:{}", @@ -773,7 +773,7 @@ def __init__( ) """Sets measurement type from among the available measurement types.""" - self.cont_meas: Parameter = self.add_parameter( + self.cont_meas: Parameter[bool, Self] = self.add_parameter( name="cont_meas", initial_value=False, get_cmd=":INITiate:CONTinuous?", @@ -786,7 +786,7 @@ def __init__( # Set auto_sweep parameter # If we want to return multiple traces per setpoint without sweeping # multiple times, or return data on screen, then we can set this value false - self.auto_sweep: Parameter = self.add_parameter( + self.auto_sweep: Parameter[bool, Self] = self.add_parameter( "auto_sweep", label="Auto Sweep", set_cmd=None, @@ -798,7 +798,7 @@ def __init__( # Set binary format and don't allow change. There isn't much point to # allow this value to be varied. Retained for backwards compatibility. - self.format: Parameter = self.add_parameter( + self.format: Parameter[str, Self] = self.add_parameter( name="format", get_cmd=lambda: "real64", set_cmd=False, diff --git a/src/qcodes/instrument_drivers/Keysight/KtM960x.py b/src/qcodes/instrument_drivers/Keysight/KtM960x.py index 354ec8985305..250345c73470 100644 --- a/src/qcodes/instrument_drivers/Keysight/KtM960x.py +++ b/src/qcodes/instrument_drivers/Keysight/KtM960x.py @@ -1,6 +1,6 @@ import ctypes from functools import partial -from typing import TYPE_CHECKING, Generic +from typing import TYPE_CHECKING, Generic, Self import qcodes.validators as vals from qcodes.instrument import Instrument, InstrumentBaseKWArgs @@ -65,7 +65,7 @@ def __init__( self._dll_loc = dll_path self._dll = ctypes.cdll.LoadLibrary(self._dll_loc) - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( "output", label="Source Output Enable", get_cmd=partial(self._get_vi_bool, KtM960xDefs.KTM960X_ATTR_OUTPUT_ENABLED), @@ -74,7 +74,7 @@ def __init__( ) """Parameter output""" - self.voltage_level: Parameter = self.add_parameter( + self.voltage_level: Parameter[float, Self] = self.add_parameter( "voltage_level", label="Source Voltage Level", unit="Volt", @@ -88,7 +88,7 @@ def __init__( ) """Parameter voltage_level""" - self.current_range: Parameter = self.add_parameter( + self.current_range: Parameter[float, Self] = self.add_parameter( "current_range", label="Output Current Range", unit="Amp", @@ -102,7 +102,7 @@ def __init__( ) """Parameter current_range""" - self.measure_current_range: Parameter = self.add_parameter( + self.measure_current_range: Parameter[float, Self] = self.add_parameter( "measure_current_range", label="Current Measurement Range", unit="Amp", @@ -116,7 +116,7 @@ def __init__( ) """Parameter measure_current_range""" - self.measure_current_time: Parameter = self.add_parameter( + self.measure_current_time: Parameter[float, Self] = self.add_parameter( "measure_current_time", label="Current Measurement Integration Time", unit="Seconds", diff --git a/src/qcodes/instrument_drivers/Keysight/KtMAwg.py b/src/qcodes/instrument_drivers/Keysight/KtMAwg.py index ea1b7f81ddc9..3720be3b6051 100644 --- a/src/qcodes/instrument_drivers/Keysight/KtMAwg.py +++ b/src/qcodes/instrument_drivers/Keysight/KtMAwg.py @@ -1,6 +1,6 @@ import ctypes from functools import partial -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import Instrument, InstrumentBaseKWArgs, InstrumentChannel from qcodes.parameters import Parameter, create_on_off_val_mapping @@ -42,7 +42,7 @@ def __init__( self._catch_error = self.root_instrument._catch_error - self.output_term_config: Parameter = self.add_parameter( + self.output_term_config: Parameter[str, Self] = self.add_parameter( "output_term_config", label="Output Terminal Configuration", get_cmd=partial( @@ -62,7 +62,7 @@ def __init__( ) """Parameter output_term_config""" - self.operation: Parameter = self.add_parameter( + self.operation: Parameter[str, Self] = self.add_parameter( "operation", label="Operating Mode", get_cmd=partial( @@ -82,7 +82,7 @@ def __init__( ) """Parameter operation""" - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( "output", label="Output Enable", get_cmd=partial( @@ -99,7 +99,7 @@ def __init__( ) """Parameter output""" - self.gain_config: Parameter = self.add_parameter( + self.gain_config: Parameter[str, Self] = self.add_parameter( "gain_config", label="AWG Gain Control Mode", set_cmd=self._set_gain_control, @@ -110,7 +110,7 @@ def __init__( }, ) """Parameter gain_config""" - self.gain: Parameter = self.add_parameter( + self.gain: Parameter[float, Self] = self.add_parameter( "gain", label="Composite Output Gain", set_cmd=self._set_gain, @@ -119,7 +119,7 @@ def __init__( ) """Parameter gain""" - self.analog_gain: Parameter = self.add_parameter( + self.analog_gain: Parameter[float, Self] = self.add_parameter( "analog_gain", label="Analog Output Gain", vals=Numbers(0, 1.32), @@ -128,7 +128,7 @@ def __init__( ) """Parameter analog_gain""" - self.digital_gain: Parameter = self.add_parameter( + self.digital_gain: Parameter[float, Self] = self.add_parameter( "digital_gain", label="Digital Output Gain", vals=Numbers(0, 1.0), diff --git a/src/qcodes/instrument_drivers/Keysight/N51x1.py b/src/qcodes/instrument_drivers/Keysight/N51x1.py index e84c20a4e1d4..0ed801ab668a 100644 --- a/src/qcodes/instrument_drivers/Keysight/N51x1.py +++ b/src/qcodes/instrument_drivers/Keysight/N51x1.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.parameters import Parameter, create_on_off_val_mapping @@ -47,7 +47,7 @@ def __init__( max_freq = freq_dict[frequency_option] - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( "power", label="Power", get_cmd="SOUR:POW?", @@ -58,7 +58,7 @@ def __init__( ) """Parameter power""" - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( "frequency", label="Frequency", get_cmd="SOUR:FREQ?", @@ -69,7 +69,7 @@ def __init__( ) """Parameter frequency""" - self.phase_offset: Parameter = self.add_parameter( + self.phase_offset: Parameter[float, Self] = self.add_parameter( "phase_offset", label="Phase Offset", get_cmd="SOUR:PHAS?", @@ -79,7 +79,7 @@ def __init__( ) """Parameter phase_offset""" - self.auto_freq_ref: Parameter = self.add_parameter( + self.auto_freq_ref: Parameter[bool, Self] = self.add_parameter( "auto_freq_ref", get_cmd=":ROSC:SOUR:AUTO?", set_cmd=":ROSC:SOUR:AUTO {}", @@ -87,7 +87,7 @@ def __init__( ) """Parameter auto_freq_ref""" - self.rf_output: Parameter = self.add_parameter( + self.rf_output: Parameter[bool, Self] = self.add_parameter( "rf_output", get_cmd="OUTP:STAT?", set_cmd="OUTP:STAT {}", @@ -96,7 +96,7 @@ def __init__( """Parameter rf_output""" if "UNW" in self._options: - self.pulse_modulation: Parameter = self.add_parameter( + self.pulse_modulation: Parameter[bool, Self] = self.add_parameter( "pulse_modulation", get_cmd="PULM:STAT?", set_cmd="PULM:STAT {}", @@ -104,7 +104,7 @@ def __init__( ) """Parameter pulse_modulation""" - self.pulse_modulation_source: Parameter = self.add_parameter( + self.pulse_modulation_source: Parameter[str, Self] = self.add_parameter( "pulse_modulation_source", get_cmd="PULM:SOUR?", set_cmd="PULM:SOUR {}", diff --git a/src/qcodes/instrument_drivers/Keysight/N52xx.py b/src/qcodes/instrument_drivers/Keysight/N52xx.py index 655e39edda4b..4f909c2f9f2e 100644 --- a/src/qcodes/instrument_drivers/Keysight/N52xx.py +++ b/src/qcodes/instrument_drivers/Keysight/N52xx.py @@ -1,6 +1,6 @@ import re import time -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np import numpy.typing as npt @@ -166,7 +166,7 @@ def __init__( raise ValueError("Port must be between 1 and 4.") pow_cmd = f"SOUR:POW{self.port}" - self.source_power: Parameter = self.add_parameter( + self.source_power: Parameter[float, Self] = self.add_parameter( "source_power", label="power", unit="dBm", @@ -206,7 +206,7 @@ def __init__( self.trace_num = trace_num # Name of parameter (i.e. S11, S21 ...) - self.trace: Parameter = self.add_parameter( + self.trace: Parameter[str, Self] = self.add_parameter( "trace", label="Trace", get_cmd=self._Sparam, set_cmd=self._set_Sparam ) """Parameter trace""" @@ -214,7 +214,7 @@ def __init__( # Note: Currently parameters that return complex values are not # supported as there isn't really a good way of saving them into the # dataset - self.format: Parameter = self.add_parameter( + self.format: Parameter[str, Self] = self.add_parameter( "format", label="Format", get_cmd="CALC:FORM?", @@ -457,7 +457,7 @@ def __init__( """Tuple of KeysightPNAPort submodules""" # RF output - self.output: Parameter = self.add_parameter( + self.output: Parameter[bool, Self] = self.add_parameter( "output", label="RF Output", get_cmd=":OUTPut?", @@ -467,7 +467,7 @@ def __init__( """Parameter output""" # Drive power - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( "power", label="Power", get_cmd="SOUR:POW?", @@ -479,7 +479,7 @@ def __init__( """Parameter power""" # IF bandwidth - self.if_bandwidth: Parameter = self.add_parameter( + self.if_bandwidth: Parameter[float, Self] = self.add_parameter( "if_bandwidth", label="IF Bandwidth", get_cmd="SENS:BAND?", @@ -491,7 +491,7 @@ def __init__( """Parameter if_bandwidth""" # Number of averages (also resets averages) - self.averages_enabled: Parameter = self.add_parameter( + self.averages_enabled: Parameter[bool, Self] = self.add_parameter( "averages_enabled", label="Averages Enabled", get_cmd="SENS:AVER?", @@ -499,19 +499,19 @@ def __init__( val_mapping={True: "1", False: "0"}, ) """Parameter averages_enabled""" - self.averages: Parameter = self.add_parameter( + self.averages: Parameter[int, Self] = self.add_parameter( "averages", label="Averages", get_cmd="SENS:AVER:COUN?", get_parser=int, set_cmd="SENS:AVER:COUN {:d}", unit="", - vals=Numbers(min_value=1, max_value=65536), + vals=Ints(min_value=1, max_value=65536), ) """Parameter averages""" # Setting frequency range - self.start: Parameter = self.add_parameter( + self.start: Parameter[float, Self] = self.add_parameter( "start", label="Start Frequency", get_cmd="SENS:FREQ:STAR?", @@ -521,7 +521,7 @@ def __init__( vals=Numbers(min_value=min_freq, max_value=max_freq), ) """Parameter start""" - self.stop: Parameter = self.add_parameter( + self.stop: Parameter[float, Self] = self.add_parameter( "stop", label="Stop Frequency", get_cmd="SENS:FREQ:STOP?", @@ -531,7 +531,7 @@ def __init__( vals=Numbers(min_value=min_freq, max_value=max_freq), ) """Parameter stop""" - self.center: Parameter = self.add_parameter( + self.center: Parameter[float, Self] = self.add_parameter( "center", label="Center Frequency", get_cmd="SENS:FREQ:CENT?", @@ -541,7 +541,7 @@ def __init__( vals=Numbers(min_value=min_freq, max_value=max_freq), ) """Parameter center""" - self.span: Parameter = self.add_parameter( + self.span: Parameter[float, Self] = self.add_parameter( "span", label="Frequency Span", get_cmd="SENS:FREQ:SPAN?", @@ -551,7 +551,7 @@ def __init__( vals=Numbers(min_value=0, max_value=max_freq), ) """Parameter span""" - self.cw: Parameter = self.add_parameter( + self.cw: Parameter[float, Self] = self.add_parameter( "cw", label="CW Frequency", get_cmd="SENS:FREQ:CW?", @@ -563,19 +563,19 @@ def __init__( """Parameter cw""" # Number of points in a sweep - self.points: Parameter = self.add_parameter( + self.points: Parameter[int, Self] = self.add_parameter( "points", label="Points", get_cmd="SENS:SWE:POIN?", get_parser=int, set_cmd="SENS:SWE:POIN {}", unit="", - vals=Numbers(min_value=1, max_value=100001), + vals=Ints(min_value=1, max_value=100001), ) """Parameter points""" # Electrical delay - self.electrical_delay: Parameter = self.add_parameter( + self.electrical_delay: Parameter[float, Self] = self.add_parameter( "electrical_delay", label="Electrical Delay", get_cmd="CALC:CORR:EDEL:TIME?", @@ -587,7 +587,7 @@ def __init__( """Parameter electrical_delay""" # Sweep Time - self.sweep_time: Parameter = self.add_parameter( + self.sweep_time: Parameter[float, Self] = self.add_parameter( "sweep_time", label="Time", get_cmd="SENS:SWE:TIME?", @@ -597,7 +597,7 @@ def __init__( ) """Parameter sweep_time""" # Sweep Mode - self.sweep_mode: Parameter = self.add_parameter( + self.sweep_mode: Parameter[str, Self] = self.add_parameter( "sweep_mode", label="Mode", get_cmd="SENS:SWE:MODE?", @@ -606,7 +606,7 @@ def __init__( ) """Parameter sweep_mode""" # Sweep Type - self.sweep_type: Parameter = self.add_parameter( + self.sweep_type: Parameter[str, Self] = self.add_parameter( "sweep_type", label="Type", get_cmd="SENS:SWE:TYPE?", @@ -616,7 +616,7 @@ def __init__( """Parameter sweep_type""" # Group trigger count - self.group_trigger_count: Parameter = self.add_parameter( + self.group_trigger_count: Parameter[int, Self] = self.add_parameter( "group_trigger_count", get_cmd="SENS:SWE:GRO:COUN?", get_parser=int, @@ -625,7 +625,7 @@ def __init__( ) """Parameter group_trigger_count""" # Trigger Source - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( "trigger_source", get_cmd="TRIG:SOUR?", set_cmd="TRIG:SOUR {}", @@ -669,13 +669,13 @@ def __init__( """Parameter time_axis""" # Traces - self.active_trace: Parameter = self.add_parameter( + self.active_trace: Parameter[int, Self] = self.add_parameter( "active_trace", label="Active Trace", get_cmd="CALC:PAR:MNUM?", get_parser=int, set_cmd="CALC:PAR:MNUM {}", - vals=Numbers(min_value=1, max_value=24), + vals=Ints(min_value=1, max_value=24), ) """Parameter active_trace""" # Note: Traces will be accessed through the traces property which @@ -701,7 +701,7 @@ def __init__( # Set auto_sweep parameter # If we want to return multiple traces per setpoint without sweeping # multiple times, we should set this to false - self.auto_sweep: Parameter = self.add_parameter( + self.auto_sweep: Parameter[bool, Self] = self.add_parameter( "auto_sweep", label="Auto Sweep", set_cmd=None, @@ -832,7 +832,7 @@ def _enable_fom(self) -> None: configurations. In practice, most of this will be set up manually on the unit, with power and frequency varied in a sweep. """ - self.aux_frequency: Parameter = self.add_parameter( + self.aux_frequency: Parameter[float, Self] = self.add_parameter( "aux_frequency", label="Aux Frequency", get_cmd="SENS:FOM:RANG4:FREQ:CW?", diff --git a/src/qcodes/instrument_drivers/Keysight/keysight_34934a.py b/src/qcodes/instrument_drivers/Keysight/keysight_34934a.py index b206bf733474..bd21ae442eb6 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysight_34934a.py +++ b/src/qcodes/instrument_drivers/Keysight/keysight_34934a.py @@ -1,5 +1,5 @@ import re -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators @@ -37,7 +37,7 @@ def __init__( ) -> None: super().__init__(parent, name, slot, **kwargs) - self.protection_mode: Parameter = self.add_parameter( + self.protection_mode: Parameter[str, Self] = self.add_parameter( name="protection_mode", get_cmd=self._get_relay_protection_mode, set_cmd=self._set_relay_protection_mode, diff --git a/src/qcodes/instrument_drivers/Keysight/keysight_34980a.py b/src/qcodes/instrument_drivers/Keysight/keysight_34980a.py index f7389e675cd3..6840c2dd85a8 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysight_34980a.py +++ b/src/qcodes/instrument_drivers/Keysight/keysight_34980a.py @@ -70,7 +70,7 @@ def __init__( self._total_slot = 8 self._system_slots_info_dict: dict[int, dict[str, str]] | None = None - self.module = dict.fromkeys(self.system_slots_info.keys()) + self.module: dict[int, Keysight34980ASwitchMatrixSubModule] = {} self.scan_slots() self.connect_message() @@ -121,27 +121,28 @@ def write(self, cmd: str) -> None: def scan_slots(self) -> None: """ Scan the occupied slots and make an object for each switch matrix - module installed + module installed. Slots that already have a module are skipped. """ for slot in self.system_slots_info: + if slot in self.module: + continue model_string = self.system_slots_info[slot]["model"] + sub_module: Keysight34980ASwitchMatrixSubModule for model, model_class in KEYSIGHT_MODELS.items(): if model in model_string: sub_module_name = f"slot_{slot}_{model}" sub_module = model_class(self, sub_module_name, slot) - self.module[slot] = sub_module - self.add_submodule(sub_module_name, sub_module) break - if self.module[slot] is None: + else: sub_module_name = f"slot_{slot}_{model_string}_no_driver" - sub_module_no_driver = Keysight34980ASwitchMatrixSubModule( + sub_module = Keysight34980ASwitchMatrixSubModule( self, sub_module_name, slot ) - self.module[slot] = sub_module_no_driver - self.add_submodule(sub_module_name, sub_module_no_driver) self.log.warning( f"can not find driver for {model_string} in slot {slot}" ) + self.add_submodule(sub_module_name, sub_module) + self.module[slot] = sub_module @property def system_slots_info(self) -> dict[int, dict[str, str]]: diff --git a/src/qcodes/instrument_drivers/Keysight/keysight_b220x.py b/src/qcodes/instrument_drivers/Keysight/keysight_b220x.py index 6a261b7ff895..a235bafd5c9c 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysight_b220x.py +++ b/src/qcodes/instrument_drivers/Keysight/keysight_b220x.py @@ -1,7 +1,7 @@ import re import warnings from functools import wraps -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.validators import Enum, Ints, Lists, MultiType @@ -66,7 +66,7 @@ def __init__( self._card = 0 - self.get_status: Parameter = self.add_parameter( + self.get_status: Parameter[int, Self] = self.add_parameter( name="get_status", get_cmd="*ESR?", get_parser=int, @@ -74,12 +74,12 @@ def __init__( ) """Queries status register.""" - self.get_error: Parameter = self.add_parameter( + self.get_error: Parameter[str, Self] = self.add_parameter( name="get_error", get_cmd=":SYST:ERR?", docstring="Queries error queue" ) """Queries error queue""" - self.connections: Parameter = self.add_parameter( + self.connections: Parameter[set[tuple[int, int]], Self] = self.add_parameter( name="connections", get_cmd=f":CLOS:CARD? {self._card}", get_parser=KeysightB220X.parse_channel_list, @@ -92,7 +92,7 @@ def __init__( set of tuples {(input, output), ...} """ - self.connection_rule: Parameter = self.add_parameter( + self.connection_rule: Parameter[str, Self] = self.add_parameter( name="connection_rule", get_cmd=self._get_connection_rule, set_cmd=self._set_connection_rule, @@ -134,7 +134,7 @@ def __init__( - existing connection to a port will be disconnected when a new connection is made. """ - self.connection_sequence: Parameter = self.add_parameter( + self.connection_sequence: Parameter[str, Self] = self.add_parameter( name="connection_sequence", get_cmd=f":CONN:SEQ? {self._card}", set_cmd=f":CONN:SEQ {self._card},{{}}", @@ -166,7 +166,7 @@ def __init__( mode is ON """ - self.bias_mode: Parameter = self.add_parameter( + self.bias_mode: Parameter[bool, Self] = self.add_parameter( name="bias_mode", get_cmd=f":BIAS? {self._card}", set_cmd=f":BIAS {self._card},{{}}", @@ -193,7 +193,7 @@ def __init__( `connect` or `disconnect` commands if GND mode is ON """ - self.gnd_mode: Parameter = self.add_parameter( + self.gnd_mode: Parameter[bool, Self] = self.add_parameter( name="gnd_mode", get_cmd=f":AGND? {self._card}", set_cmd=f":AGND {self._card},{{}}", @@ -225,7 +225,7 @@ def __init__( ) """Parameter couple_ports""" - self.couple_mode: Parameter = self.add_parameter( + self.couple_mode: Parameter[bool, Self] = self.add_parameter( name="couple_mode", get_cmd=f":COUP? {self._card}", set_cmd=f":COUP {self._card},{{}}", diff --git a/src/qcodes/instrument_drivers/Keysight/keysight_e4980a.py b/src/qcodes/instrument_drivers/Keysight/keysight_e4980a.py index 5b339d2e90bf..19793ca568a6 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysight_e4980a.py +++ b/src/qcodes/instrument_drivers/Keysight/keysight_e4980a.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self from packaging import version from pyvisa.errors import VisaIOError @@ -160,7 +160,7 @@ def __init__( ) """Executes OPEN correction based on all frequency points.""" - self.open_state: Parameter = self.add_parameter( + self.open_state: Parameter[bool, Self] = self.add_parameter( "open_state", get_cmd=":CORRection:OPEN:STATe?", set_cmd=":CORRection:OPEN:STATe {}", @@ -176,7 +176,7 @@ def __init__( ) """Executes SHORT correction based on all frequency points.""" - self.short_state: Parameter = self.add_parameter( + self.short_state: Parameter[bool, Self] = self.add_parameter( "short_state", get_cmd=":CORRection:SHORt:STATe?", set_cmd=":CORRection:SHORt:STATe {}", @@ -233,7 +233,7 @@ def __init__( "CPD", ("capacitance", "dissipation_factor"), ("F", "") ) - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( "frequency", get_cmd=":FREQuency?", set_cmd=":FREQuency {}", @@ -244,7 +244,7 @@ def __init__( ) """Gets and sets the frequency for normal measurement.""" - self.current_level: Parameter = self.add_parameter( + self.current_level: Parameter[float, Self] = self.add_parameter( "current_level", get_cmd=self._get_current_level, set_cmd=self._set_current_level, @@ -254,7 +254,7 @@ def __init__( ) """Gets and sets the current level for measurement signal.""" - self.voltage_level: Parameter = self.add_parameter( + self.voltage_level: Parameter[float, Self] = self.add_parameter( "voltage_level", get_cmd=self._get_voltage_level, set_cmd=self._set_voltage_level, @@ -271,10 +271,11 @@ def __init__( ) """Parameter measurement_function""" - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd=":FUNCtion:IMPedance:RANGe?", set_cmd=self._set_range, + get_parser=float, unit="Ohm", vals=self._imp_range, docstring="Selects the impedance measurement range, also turns " @@ -282,7 +283,7 @@ def __init__( ) """Selects the impedance measurement range, also turns the auto range function OFF.""" - self.imp_autorange_enabled: Parameter = self.add_parameter( + self.imp_autorange_enabled: Parameter[bool, Self] = self.add_parameter( "imp_autorange_enabled", get_cmd=":FUNCtion:IMPedance:RANGe:AUTO?", set_cmd=":FUNCtion:IMPedance:RANGe:AUTO {}", @@ -291,7 +292,7 @@ def __init__( ) """Enables the auto-range for impedance measurement.""" - self.dc_bias_enabled: Parameter = self.add_parameter( + self.dc_bias_enabled: Parameter[bool, Self] = self.add_parameter( "dc_bias_enabled", get_cmd=":BIAS:STATe?", set_cmd=":BIAS:STATe {}", @@ -302,7 +303,7 @@ def __init__( ) """Enables DC bias. DC bias is automatically turned off after recalling the state from memory.""" - self.dc_bias_voltage_level: Parameter = self.add_parameter( + self.dc_bias_voltage_level: Parameter[float, Self] = self.add_parameter( "dc_bias_voltage_level", get_cmd=":BIAS:VOLTage:LEVel?", set_cmd=":BIAS:VOLTage:LEVel {}", @@ -337,7 +338,7 @@ def __init__( ) if self.has_firmware_a_02_10_or_above: - self.dc_bias_autorange_enabled: Parameter = self.add_parameter( + self.dc_bias_autorange_enabled: Parameter[bool, Self] = self.add_parameter( "dc_bias_autorange_enabled", get_cmd=":BIAS:RANGe:AUTO?", set_cmd=":BIAS:RANGe:AUTO {}", @@ -374,7 +375,7 @@ def measure_impedance(self) -> KeysightE4980AMeasurementPair: def measurement(self) -> KeysightE4980AMeasurementPair: return self._measurement() - def _set_range(self, val: str) -> None: + def _set_range(self, val: float) -> None: self.write(f":FUNCtion:IMPedance:RANGe {val}") self.imp_autorange_enabled.get() @@ -427,7 +428,7 @@ def _get_voltage_level(self) -> float: return float(v_level) - def _set_voltage_level(self, val: str) -> None: + def _set_voltage_level(self, val: float) -> None: """ Sets voltage level """ @@ -437,7 +438,7 @@ def _set_voltage_level(self, val: str) -> None: self.write(f":VOLTage:LEVel {val}") - def _set_current_level(self, val: str) -> None: + def _set_current_level(self, val: float) -> None: """ Sets current level """ diff --git a/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1500_base.py b/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1500_base.py index eb7f73d9b4a2..32d0f467dda7 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1500_base.py +++ b/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1500_base.py @@ -1,7 +1,7 @@ import re import textwrap from collections import defaultdict -from typing import TYPE_CHECKING, Any, Generic, TypedDict, cast +from typing import TYPE_CHECKING, Any, Generic, Self, TypedDict, cast from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.parameters import MultiParameter, Parameter, create_on_off_val_mapping @@ -55,7 +55,7 @@ def __init__( self._find_modules() - self.autozero_enabled: Parameter = self.add_parameter( + self.autozero_enabled: Parameter[bool, Self] = self.add_parameter( "autozero_enabled", unit="", label="Autozero enabled of the high-resolution ADC", diff --git a/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1517A.py b/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1517A.py index a09ddd948c6d..65036f37b61b 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1517A.py +++ b/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1517A.py @@ -1,6 +1,15 @@ import re import textwrap -from typing import TYPE_CHECKING, Any, Generic, Literal, NotRequired, Unpack, overload +from typing import ( + TYPE_CHECKING, + Any, + Generic, + Literal, + NotRequired, + Self, + Unpack, + overload, +) import numpy as np import numpy.typing as npt @@ -351,7 +360,7 @@ def __init__( - Pcomp/output voltage > maximum current for the output range """ - self.sweep_start: Parameter = self.add_parameter( + self.sweep_start: Parameter[float, Self] = self.add_parameter( name="sweep_start", set_cmd=self._set_sweep_start, get_cmd=self._get_sweep_start, @@ -370,7 +379,7 @@ def __init__( start and stop must have the same polarity. """ - self.sweep_end: Parameter = self.add_parameter( + self.sweep_end: Parameter[float, Self] = self.add_parameter( name="sweep_end", set_cmd=self._set_sweep_end, get_cmd=self._get_sweep_end, @@ -389,7 +398,7 @@ def __init__( stop must have the same polarity. """ - self.sweep_steps: Parameter = self.add_parameter( + self.sweep_steps: Parameter[int, Self] = self.add_parameter( name="sweep_steps", set_cmd=self._set_sweep_steps, get_cmd=self._get_sweep_steps, @@ -406,12 +415,14 @@ def __init__( 1001 """ - self.current_compliance: Parameter = self.add_parameter( + self.current_compliance: Parameter[float | None, Self] = self.add_parameter( name="current_compliance", set_cmd=self._set_current_compliance, get_cmd=self._get_current_compliance, unit="A", - vals=vals.Numbers(-40, 40), + # None omits Icomp (and Pcomp) from the WV command, in which case + # the instrument keeps the previous current compliance + vals=vals.MultiType(vals.Numbers(-40, 40), vals.Enum(None)), snapshot_get=False, docstring=textwrap.dedent( """ @@ -439,12 +450,13 @@ def __init__( is allowed, regardless of the output range setting. """ - self.power_compliance: Parameter = self.add_parameter( + self.power_compliance: Parameter[float | None, Self] = self.add_parameter( name="power_compliance", set_cmd=self._set_power_compliance, get_cmd=self._get_power_compliance, unit="W", - vals=vals.Numbers(0.001, 80), + # None omits Pcomp from the WV command, i.e. no power compliance + vals=vals.MultiType(vals.Numbers(0.001, 80), vals.Enum(None)), snapshot_get=False, docstring=textwrap.dedent( """ @@ -513,7 +525,12 @@ def _get_current_compliance(self) -> float | None: return current_compliance def _set_power_compliance(self, value: float | None) -> None: - if self._sweep_step_parameters["current_compliance"] is None: + # Pcomp can only be sent together with Icomp, but clearing it is always + # allowed + if ( + value is not None + and self._sweep_step_parameters["current_compliance"] is None + ): raise ValueError( "Current compliance must be set before setting power compliance" ) @@ -1044,7 +1061,7 @@ def __init__( output mode (voltage or current). """ - self.enable_filter: Parameter = self.add_parameter( + self.enable_filter: Parameter[bool, Self] = self.add_parameter( name="enable_filter", set_cmd=self._set_enable_filter, get_cmd=None, diff --git a/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1520A.py b/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1520A.py index 2eda33050d2d..073dc5b3afdf 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1520A.py +++ b/src/qcodes/instrument_drivers/Keysight/keysightb1500/KeysightB1520A.py @@ -1,12 +1,18 @@ import re import textwrap -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any, Self, cast import numpy as np import qcodes.validators as vals from qcodes.instrument import InstrumentBaseKWArgs, InstrumentChannel -from qcodes.parameters import Group, GroupParameter, MultiParameter, Parameter +from qcodes.parameters import ( + Group, + GroupParameter, + MultiParameter, + Parameter, + create_on_off_val_mapping, +) from . import constants from .constants import MM, ChNr, ModuleKind @@ -481,7 +487,7 @@ def __init__( self._ranging_mode: constants.RangingMode = constants.RangingMode.AUTO self._measurement_range_for_non_auto: int | None = None - self.voltage_dc: Parameter = self.add_parameter( + self.voltage_dc: Parameter[float, Self] = self.add_parameter( name="voltage_dc", unit="V", set_cmd=self._set_voltage_dc, @@ -490,7 +496,7 @@ def __init__( ) """Parameter voltage_dc""" - self.voltage_ac: Parameter = self.add_parameter( + self.voltage_ac: Parameter[float, Self] = self.add_parameter( name="voltage_ac", unit="V", set_cmd=self._set_voltage_ac, @@ -499,7 +505,7 @@ def __init__( ) """Parameter voltage_ac""" - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", unit="Hz", set_cmd=self._set_frequency, @@ -508,7 +514,7 @@ def __init__( ) """Parameter frequency""" - self.capacitance: Parameter = self.add_parameter( + self.capacitance: Parameter[tuple[float, float], Self] = self.add_parameter( name="capacitance", get_cmd=self._get_capacitance, snapshot_value=False ) """Parameter capacitance""" @@ -660,19 +666,21 @@ def __init__( Possible ranging modes are autorange and fixed range. """ - self.measurement_range_for_non_auto: Parameter = self.add_parameter( - name="measurement_range_for_non_auto", - set_cmd=self._set_measurement_range_for_non_auto, - get_cmd=None, - docstring=textwrap.dedent( - """ + self.measurement_range_for_non_auto: Parameter[int | None, Self] = ( + self.add_parameter( + name="measurement_range_for_non_auto", + set_cmd=self._set_measurement_range_for_non_auto, + get_cmd=None, + docstring=textwrap.dedent( + """ Measurement range. Needs to set when ``ranging_mode`` is set to PLC. The value should be integer 0 or more. 50 ohm, 100 ohm, 300 ohm, 1 kilo ohm, 3 kilo ohm, 10 kilo ohm, 30 kilo ohm, 100 kilo ohm, and 300 kilo ohm are selectable. Available measurement ranges depend on the output signal frequency set by the FC command.""" - ), + ), + ) ) """ Measurement range. Needs to set when ``ranging_mode`` is set to @@ -730,29 +738,29 @@ def __init__( Look at the ``constants.IMP.MeasurementMode`` for all the modes. """ - self.ac_dc_volt_monitor: Parameter = self.add_parameter( + self.ac_dc_volt_monitor: Parameter[bool, Self] = self.add_parameter( name="ac_dc_volt_monitor", set_cmd=self._set_ac_dc_volt_monitor, get_cmd=None, - vals=vals.Ints(0, 1), + val_mapping=create_on_off_val_mapping(on_val=1, off_val=0), initial_value=False, docstring=textwrap.dedent( """ This command enables or disables the data monitor and data output of the MFCMU AC voltage and DC voltage. - 0: Disables the data monitor and output. Initial setting. - 1: Enables the data monitor and output. + False: Disables the data monitor and output. Initial setting. + True: Enables the data monitor and output. """ ), ) """ This command enables or disables the data monitor and data output of the MFCMU AC voltage and DC voltage. - 0: Disables the data monitor and output. Initial setting. - 1: Enables the data monitor and output. + False: Disables the data monitor and output. Initial setting. + True: Enables the data monitor and output. """ - self.cv_sweep_voltages: Parameter = self.add_parameter( + self.cv_sweep_voltages: Parameter[tuple[float, ...], Self] = self.add_parameter( name="cv_sweep_voltages", get_cmd=self._cv_sweep_voltages, unit="V", @@ -988,8 +996,8 @@ def _set_impedance_model(self, val: constants.IMP.MeasurementMode) -> None: if hasattr(self, "run_sweep"): self.run_sweep.update_name_label_unit_from_impedance_model(model=val) - def _set_ac_dc_volt_monitor(self, val: bool) -> None: - msg = MessageBuilder().lmn(enable_data_monitor=val) + def _set_ac_dc_volt_monitor(self, val: int) -> None: + msg = MessageBuilder().lmn(enable_data_monitor=bool(val)) self.write(msg.message) def _set_ranging_mode(self, val: constants.RangingMode | int) -> None: diff --git a/src/qcodes/instrument_drivers/Keysight/keysightb1500/message_builder.py b/src/qcodes/instrument_drivers/Keysight/keysightb1500/message_builder.py index 1baf36c672dc..752bb6a0a6ed 100644 --- a/src/qcodes/instrument_drivers/Keysight/keysightb1500/message_builder.py +++ b/src/qcodes/instrument_drivers/Keysight/keysightb1500/message_builder.py @@ -2605,7 +2605,7 @@ def pch( @final_command def pch_query(self, master: constants.ChNr | int | None = None) -> "MessageBuilder": - cmd = "PCH" + cmd = "PCH?" if master is not None: cmd += f" {master}" diff --git a/src/qcodes/instrument_drivers/Keysight/private/Keysight_344xxA_submodules.py b/src/qcodes/instrument_drivers/Keysight/private/Keysight_344xxA_submodules.py index 1369fe557b53..94f7deb654fc 100644 --- a/src/qcodes/instrument_drivers/Keysight/private/Keysight_344xxA_submodules.py +++ b/src/qcodes/instrument_drivers/Keysight/private/Keysight_344xxA_submodules.py @@ -2,7 +2,7 @@ from bisect import bisect_left from contextlib import ExitStack from functools import partial -from typing import TYPE_CHECKING, Any, Literal, get_args +from typing import TYPE_CHECKING, Any, Literal, Self, get_args import numpy as np import numpy.typing as npt @@ -118,7 +118,7 @@ def __init__( trigger delay. """ - self.auto_delay_enabled: Parameter = self.add_parameter( + self.auto_delay_enabled: Parameter[bool, Self] = self.add_parameter( "auto_delay_enabled", label="Auto Trigger Delay Enabled", set_cmd="TRIGger:DELay:AUTO {}", @@ -144,7 +144,7 @@ def __init__( the automatic trigger delay. """ - self.slope: Parameter = self.add_parameter( + self.slope: Parameter[str, Self] = self.add_parameter( "slope", label="Trigger Slope", set_cmd="TRIGger:SLOPe {}", @@ -212,7 +212,7 @@ def __init__( and set the level and slope with the `trigger.level` and `trigger.slope` parameters.""") - self.source: Parameter = self.add_parameter( + self.source: Parameter[str, Self] = self.add_parameter( "source", label="Trigger Source", set_cmd="TRIGger:SOURce {}", @@ -320,7 +320,7 @@ def __init__( number of sample counts.""" if self.parent.is_34465A_34470A or self.parent.is_34410A_34411A: - self.source: Parameter = self.add_parameter( + self.source: Parameter[str, Self] = self.add_parameter( "source", label="Sample Timing Source", set_cmd="SAMPle:SOURce {}", @@ -379,7 +379,7 @@ def __init__( Applying a value less than the absolute minimum will generate an error.""" - self.timer_minimum: Parameter = self.add_parameter( + self.timer_minimum: Parameter[float, Self] = self.add_parameter( "timer_minimum", label="Minimal recommended sample time", get_cmd="SAMPle:TIMer? MIN", @@ -436,7 +436,7 @@ def __init__( ): super().__init__(parent, name, **kwargs) - self.enabled: Parameter = self.add_parameter( + self.enabled: Parameter[bool, Self] = self.add_parameter( "enabled", label="Display enabled", set_cmd="DISPlay:STATe {}", @@ -465,7 +465,7 @@ def __init__( Displaying text with `display.text` parameter will work even when the display is disabled.""" - self.text: Parameter = self.add_parameter( + self.text: Parameter[str, Self] = self.add_parameter( "text", label="Display text", set_cmd='DISPLAY:TEXT "{}"', @@ -709,7 +709,7 @@ def __init__( # this is the "master" parameter that determines whether the DMM is # a voltmeter, an ampmeter, etc. - self.sense_function: Parameter = self.add_parameter( + self.sense_function: Parameter[str, Self] = self.add_parameter( "sense_function", label="Instrument sense function", get_cmd="SENSe:FUNCtion?", @@ -725,7 +725,7 @@ def __init__( ) """Parameter sense_function""" - self.line_frequency: Parameter = self.add_parameter( + self.line_frequency: Parameter[int, Self] = self.add_parameter( "line_frequency", get_cmd="SYSTem:LFRequency?", get_parser=int, @@ -738,7 +738,7 @@ def __init__( ) """The frequency of the power line where the instrument is plugged""" - self.NPLC: Parameter = self.add_parameter( + self.NPLC: Parameter[float, Self] = self.add_parameter( "NPLC", get_cmd=self._get_with_sense_function("NPLC"), get_parser=float, @@ -775,7 +775,7 @@ def __init__( Setting the integration time also sets the measurement resolution.""" - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd="SENSe:VOLTage:DC:RANGe?", get_parser=float, @@ -825,7 +825,7 @@ def __init__( sections of the instrument's manual for the available ranges for the resolution values.""" - self.autorange: Parameter = self.add_parameter( + self.autorange: Parameter[str, Self] = self.add_parameter( "autorange", label="Autorange", set_cmd=self._set_with_sense_function("RANGe:AUTO"), @@ -835,7 +835,7 @@ def __init__( ) """Parameter autorange""" - self.autozero: Parameter = self.add_parameter( + self.autozero: Parameter[str, Self] = self.add_parameter( "autozero", label="Autozero", set_cmd=self._set_with_sense_function("ZERO:AUTO"), @@ -921,7 +921,7 @@ def __init__( apt_times["34465A"][0] = 20e-6 apt_times["34470A"][0] = 20e-6 - self.aperture_mode: Parameter = self.add_parameter( + self.aperture_mode: Parameter[str, Self] = self.add_parameter( "aperture_mode", label="Aperture mode", set_cmd=self._set_with_sense_function("APERture:ENABled"), @@ -995,7 +995,7 @@ def __init__( # changes on initialization or snapshot update, however the cached # (last read) value will still be stored in the snapshot. - self.volt: Parameter = self.add_parameter( + self.volt: Parameter[float, Self] = self.add_parameter( "volt", get_cmd=partial(self._get_parameter, "DC Voltage"), label="Voltage", @@ -1004,7 +1004,7 @@ def __init__( ) """Parameter volt""" - self.curr: Parameter = self.add_parameter( + self.curr: Parameter[float, Self] = self.add_parameter( "curr", get_cmd=partial(self._get_parameter, "DC Current"), label="Current", @@ -1013,7 +1013,7 @@ def __init__( ) """Parameter curr""" - self.ac_volt: Parameter = self.add_parameter( + self.ac_volt: Parameter[float, Self] = self.add_parameter( "ac_volt", get_cmd=partial(self._get_parameter, "AC Voltage"), label="AC Voltage", @@ -1022,7 +1022,7 @@ def __init__( ) """Parameter ac_volt""" - self.ac_curr: Parameter = self.add_parameter( + self.ac_curr: Parameter[float, Self] = self.add_parameter( "ac_curr", get_cmd=partial(self._get_parameter, "AC Current"), label="AC Current", @@ -1031,7 +1031,7 @@ def __init__( ) """Parameter ac_curr""" - self.res: Parameter = self.add_parameter( + self.res: Parameter[float, Self] = self.add_parameter( "res", get_cmd=partial(self._get_parameter, "2 Wire Resistance"), label="Resistance", @@ -1040,7 +1040,7 @@ def __init__( ) """Parameter res""" - self.four_wire_res: Parameter = self.add_parameter( + self.four_wire_res: Parameter[float, Self] = self.add_parameter( "four_wire_res", get_cmd=partial(self._get_parameter, "4 Wire Resistance"), label="Resistance", @@ -1052,7 +1052,7 @@ def __init__( ##################################### # Time trace parameters - self.timetrace_npts: Parameter = self.add_parameter( + self.timetrace_npts: Parameter[int, Self] = self.add_parameter( "timetrace_npts", label="Time trace number of points", initial_value=500, @@ -1062,7 +1062,7 @@ def __init__( ) """Parameter timetrace_npts""" - self.timetrace_dt: Parameter = self.add_parameter( + self.timetrace_dt: Parameter[float, Self] = self.add_parameter( "timetrace_dt", label="Time trace time interval", unit="s", diff --git a/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_325.py b/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_325.py index b66ef86940b8..bde6ab4dec99 100644 --- a/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_325.py +++ b/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_325.py @@ -3,9 +3,12 @@ from typing import ( TYPE_CHECKING, Any, + Self, TextIO, ) +import numpy as np + from qcodes.instrument import ( ChannelList, InstrumentBaseKWArgs, @@ -14,7 +17,7 @@ VisaInstrumentKWArgs, ) from qcodes.parameters import Group, GroupParameter, Parameter -from qcodes.validators import Enum, Numbers +from qcodes.validators import Enum, Ints, Numbers if TYPE_CHECKING: from collections.abc import Iterable @@ -82,6 +85,16 @@ def _get_sanitize_data(file_data: dict[Any, Any]) -> dict[Any, Any]: return data_dict +def _format_curve_value(value: float) -> str: + """ + Format a curve data point value with 6 significant digits in positional + notation, which is the resolution the instrument stores points with. + """ + return np.format_float_positional( + value, precision=6, unique=False, fractional=False, trim="-" + ) + + class LakeshoreModel325Status(IntFlag): """ IntFlag that defines status codes for Lakeshore Model 325 @@ -158,9 +171,10 @@ def __init__( ) def get_data(self) -> dict[Any, Any]: + # a curve has up to 200 points curve = [ float(a) - for point_index in range(1, 200) + for point_index in range(1, 201) for a in self.ask(f"CRVPT? {self._index}, {point_index}").split(",") ] @@ -233,9 +247,11 @@ def set_data( for value_index, (temperature_value, sensor_value) in enumerate( zip(temperature_values, sensor_values) ): + # the instrument stores points to 6 digits cmd_str = ( f"CRVPT {self._index}, {value_index + 1}, " - f"{sensor_value:3.3f}, {temperature_value:3.3f}" + f"{_format_curve_value(sensor_value)}, " + f"{_format_curve_value(temperature_value)}" ) self.write(cmd_str) @@ -265,7 +281,7 @@ def __init__( super().__init__(parent, name) self._input = inp - self.temperature: Parameter = self.add_parameter( + self.temperature: Parameter[float, Self] = self.add_parameter( "temperature", get_cmd=f"KRDG? {self._input}", get_parser=float, @@ -274,7 +290,7 @@ def __init__( ) """Parameter temperature""" - self.status: Parameter = self.add_parameter( + self.status: Parameter[str, Self] = self.add_parameter( "status", get_cmd=f"RDGST? {self._input}", get_parser=lambda status: self.decode_sensor_status(int(status)), @@ -311,12 +327,14 @@ def __init__( get_cmd=f"INTYPE? {self._input}", ) - self.curve_index: Parameter = self.add_parameter( + self.curve_index: Parameter[int, Self] = self.add_parameter( "curve_index", set_cmd=f"INCRV {self._input}, {{}}", get_cmd=f"INCRV? {self._input}", get_parser=int, - vals=Numbers(min_value=1, max_value=35), + # 0 = none, 1-20 = standard curves, 21-35 = user curves. The + # instrument falls back to 0 if the curve does not match the input. + vals=Ints(min_value=0, max_value=35), ) """Parameter curve_index""" @@ -334,7 +352,18 @@ def decode_sensor_status(sum_of_codes: int) -> str: @property def curve(self) -> LakeshoreModel325Curve: - return LakeshoreModel325Curve(self.parent, self.curve_index()) + """ + The curve the sensor uses for temperature conversion. + + Raises: + RuntimeError: If no curve is selected for the sensor + (``curve_index`` is 0). + + """ + index = self.curve_index() + if index == 0: + raise RuntimeError(f"No curve is selected for {self.full_name}") + return LakeshoreModel325Curve(self.parent, index) class LakeshoreModel325Heater(InstrumentChannel): @@ -362,7 +391,7 @@ def __init__( super().__init__(parent, name, **kwargs) self._loop = loop - self.control_mode: Parameter = self.add_parameter( + self.control_mode: Parameter[str, Self] = self.add_parameter( "control_mode", get_cmd=f"CMODE? {self._loop}", set_cmd=f"CMODE {self._loop},{{}}", @@ -434,21 +463,20 @@ def __init__( get_cmd=f"PID? {self._loop}", ) + # the 25 W high range is only available on loop 1 + output_ranges = {"Off": "0", "Low (2.5W)": "1"} if self._loop == 1: - valid_output_ranges = Enum(0, 1, 2) - else: - valid_output_ranges = Enum(0, 1) + output_ranges["High (25W)"] = "2" - self.output_range: Parameter = self.add_parameter( + self.output_range: Parameter[str, Self] = self.add_parameter( "output_range", - vals=valid_output_ranges, set_cmd=f"RANGE {self._loop}, {{}}", get_cmd=f"RANGE? {self._loop}", - val_mapping={"Off": "0", "Low (2.5W)": "1", "High (25W)": "2"}, + val_mapping=output_ranges, ) """Parameter output_range""" - self.setpoint: Parameter = self.add_parameter( + self.setpoint: Parameter[float, Self] = self.add_parameter( "setpoint", vals=Numbers(0, 400), get_parser=float, @@ -478,12 +506,12 @@ def __init__( get_cmd=f"RAMP? {self._loop}", ) - self.is_ramping: Parameter = self.add_parameter( + self.is_ramping: Parameter[str, Self] = self.add_parameter( "is_ramping", get_cmd=f"RAMPST? {self._loop}" ) """Parameter is_ramping""" - self.resistance: Parameter = self.add_parameter( + self.resistance: Parameter[int, Self] = self.add_parameter( "resistance", get_cmd=f"HTRRES? {self._loop}", set_cmd=f"HTRRES {self._loop}, {{}}", @@ -496,7 +524,7 @@ def __init__( ) """Parameter resistance""" - self.heater_output: Parameter = self.add_parameter( + self.heater_output: Parameter[float, Self] = self.add_parameter( "heater_output", get_cmd=f"HTR? {self._loop}", get_parser=float, @@ -564,7 +592,8 @@ def __init__( curves = ChannelList(self, "curve", LakeshoreModel325Curve, snapshotable=False) - for curve_index in range(1, 35): + # curves 1-20 are standard curves and 21-35 user curves + for curve_index in range(1, 36): curve = LakeshoreModel325Curve(self, curve_index) curves.append(curve) diff --git a/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_336.py b/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_336.py index 44b5929a9651..5b83249a773d 100644 --- a/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_336.py +++ b/src/qcodes/instrument_drivers/Lakeshore/Lakeshore_model_336.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, ClassVar +from typing import TYPE_CHECKING, ClassVar, Self import qcodes.validators as vals from qcodes.parameters import Group, GroupParameter, Parameter @@ -210,7 +210,7 @@ def __init__( ) # Parameters related to temperature calibration curve (CRVHDR) - self.curve_number: Parameter = self.add_parameter( + self.curve_number: Parameter[int, Self] = self.add_parameter( "curve_number", get_cmd=f"INCRV? {self._channel}", set_cmd=False, diff --git a/src/qcodes/instrument_drivers/Lakeshore/lakeshore_base.py b/src/qcodes/instrument_drivers/Lakeshore/lakeshore_base.py index c95a9985eaf1..3e3c6c7bcbe0 100644 --- a/src/qcodes/instrument_drivers/Lakeshore/lakeshore_base.py +++ b/src/qcodes/instrument_drivers/Lakeshore/lakeshore_base.py @@ -1,6 +1,6 @@ import time from bisect import bisect -from typing import TYPE_CHECKING, Any, ClassVar, Generic +from typing import TYPE_CHECKING, Any, ClassVar, Generic, Self import numpy as np from typing_extensions import TypeVar @@ -137,7 +137,7 @@ def __init__( get_cmd=f"PID? {output_index}", ) - self.output_range: Parameter = self.add_parameter( + self.output_range: Parameter[str, Self] = self.add_parameter( "output_range", label="Heater range", docstring="Specifies heater output range. The range " @@ -156,7 +156,7 @@ def __init__( An output in `Monitor Out` mode is always on. """ - self.output: Parameter = self.add_parameter( + self.output: Parameter[float, Self] = self.add_parameter( "output", label="Output", unit="% of heater range", @@ -174,7 +174,7 @@ def __init__( Note that when the heater is off, this parameter will return the value of 0.005. """ - self.setpoint: Parameter = self.add_parameter( + self.setpoint: Parameter[float, Self] = self.add_parameter( "setpoint", label="Setpoint value (in sensor units)", docstring="The value of the setpoint in the " @@ -233,7 +233,7 @@ def __init__( get_cmd=f"RAMP? {output_index}", ) - self.setpoint_ramp_status: Parameter = self.add_parameter( + self.setpoint_ramp_status: Parameter[bool, Self] = self.add_parameter( "setpoint_ramp_status", label="Setpoint is ramping", docstring="0 = Not ramping, 1 = Setpoint is ramping", @@ -265,7 +265,7 @@ def __init__( instead of doing it directly """ - self.wait_cycle_time: Parameter = self.add_parameter( + self.wait_cycle_time: Parameter[float, Self] = self.add_parameter( "wait_cycle_time", set_cmd=None, get_cmd=None, @@ -278,7 +278,7 @@ def __init__( """Time between two readings when waiting for temperature to equilibrate""" self.wait_cycle_time(0.1) - self.wait_tolerance: Parameter = self.add_parameter( + self.wait_tolerance: Parameter[float, Self] = self.add_parameter( "wait_tolerance", set_cmd=None, get_cmd=None, @@ -291,7 +291,7 @@ def __init__( """Acceptable tolerance when waiting for temperature to equilibrate""" self.wait_tolerance(0.1) - self.wait_equilibration_time: Parameter = self.add_parameter( + self.wait_equilibration_time: Parameter[float, Self] = self.add_parameter( "wait_equilibration_time", set_cmd=None, get_cmd=None, @@ -303,7 +303,7 @@ def __init__( """Duration during which temperature has to be within tolerance""" self.wait_equilibration_time(0.5) - self.blocking_t: Parameter = self.add_parameter( + self.blocking_t: Parameter[float, Self] = self.add_parameter( "blocking_t", label="Setpoint value with blocking until it is reached", docstring="Sets the setpoint value, and input " @@ -617,7 +617,7 @@ def __init__( # Add the various channel parameters - self.temperature: Parameter = self.add_parameter( + self.temperature: Parameter[float, Self] = self.add_parameter( "temperature", get_cmd=f"KRDG? {self._channel}", get_parser=float, @@ -626,7 +626,7 @@ def __init__( ) """Parameter temperature""" - self.t_limit: Parameter = self.add_parameter( + self.t_limit: Parameter[float, Self] = self.add_parameter( "t_limit", get_cmd=f"TLIMIT? {self._channel}", set_cmd=f"TLIMIT {self._channel}, {{}}", @@ -645,7 +645,7 @@ def __init__( for the given sensor input. """ - self.sensor_raw: Parameter = self.add_parameter( + self.sensor_raw: Parameter[float, Self] = self.add_parameter( "sensor_raw", get_cmd=f"SRDG? {self._channel}", get_parser=float, @@ -654,7 +654,7 @@ def __init__( ) """Parameter sensor_raw""" - self.sensor_status: Parameter = self.add_parameter( + self.sensor_status: Parameter[str, Self] = self.add_parameter( "sensor_status", get_cmd=f"RDGST? {self._channel}", get_parser=self._decode_sensor_status, @@ -662,7 +662,7 @@ def __init__( ) """Parameter sensor_status""" - self.sensor_name: Parameter = self.add_parameter( + self.sensor_name: Parameter[str, Self] = self.add_parameter( "sensor_name", get_cmd=f"INNAME? {self._channel}", get_parser=str, diff --git a/src/qcodes/instrument_drivers/Minicircuits/Base_SPDT.py b/src/qcodes/instrument_drivers/Minicircuits/Base_SPDT.py index 48770b966a11..32d9dcd670f4 100644 --- a/src/qcodes/instrument_drivers/Minicircuits/Base_SPDT.py +++ b/src/qcodes/instrument_drivers/Minicircuits/Base_SPDT.py @@ -2,7 +2,7 @@ import logging import re -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import ( ChannelList, @@ -47,7 +47,7 @@ def __init__( _chanlist = ["a", "b", "c", "d", "e", "f", "g", "h"] self.channel_number = _chanlist.index(channel_letter) - self.switch: Parameter = self.add_parameter( + self.switch: Parameter[int, Self] = self.add_parameter( "switch", label=f"switch {self.channel_letter}", set_cmd=self._set_switch, diff --git a/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_sp4t.py b/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_sp4t.py index f64237503f1e..cb4027b7f219 100644 --- a/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_sp4t.py +++ b/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_sp4t.py @@ -1,5 +1,5 @@ import math -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators as vals from qcodes.instrument import ( @@ -37,7 +37,7 @@ def __init__( chanlist = ["a", "b"] self.channel_number = chanlist.index(channel_letter) - self.switch: Parameter = self.add_parameter( + self.switch: Parameter[int, Self] = self.add_parameter( "switch", label="switch", set_cmd=self._set_switch, diff --git a/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_spdt.py b/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_spdt.py index 04b28cbe0bd3..43a5b829d599 100644 --- a/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_spdt.py +++ b/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rc_spdt.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators as vals from qcodes.instrument import ( @@ -37,7 +37,7 @@ def __init__( _chanlist = ["a", "b", "c", "d", "e", "f", "g", "h"] self.channel_number = _chanlist.index(channel_letter) - self.switch: Parameter = self.add_parameter( + self.switch: Parameter[int, Self] = self.add_parameter( "switch", label="switch", set_cmd=self._set_switch, diff --git a/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rudat_13g_90.py b/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rudat_13g_90.py index d9e63796880c..a9eb4871a568 100644 --- a/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rudat_13g_90.py +++ b/src/qcodes/instrument_drivers/Minicircuits/_minicircuits_rudat_13g_90.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import Instrument, InstrumentBaseKWArgs @@ -23,23 +23,27 @@ def __init__(self, name: str, **kwargs: "Unpack[InstrumentBaseKWArgs]") -> None: """ super().__init__(name, **kwargs) - self.model_name: Parameter = self.add_parameter("model_name", get_cmd=":MN?") + self.model_name: Parameter[str, Self] = self.add_parameter( + "model_name", get_cmd=":MN?" + ) """Parameter model_name""" - self.serial_number: Parameter = self.add_parameter( + self.serial_number: Parameter[str, Self] = self.add_parameter( "serial_number", get_cmd=":SN?" ) """Parameter serial_number""" - self.firmware: Parameter = self.add_parameter("firmware", get_cmd=":FIRMWARE?") + self.firmware: Parameter[str, Self] = self.add_parameter( + "firmware", get_cmd=":FIRMWARE?" + ) """Parameter firmware""" - self.attenuation: Parameter = self.add_parameter( + self.attenuation: Parameter[float, Self] = self.add_parameter( "attenuation", set_cmd=":SETATT={}", get_cmd=":ATT?", get_parser=float ) """Parameter attenuation""" - self.startup_attenuation: Parameter = self.add_parameter( + self.startup_attenuation: Parameter[float, Self] = self.add_parameter( "startup_attenuation", set_cmd=":STARTUPATT:VALUE:{}", get_cmd=":STARTUPATT:VALUE?", @@ -47,7 +51,7 @@ def __init__(self, name: str, **kwargs: "Unpack[InstrumentBaseKWArgs]") -> None: ) """Parameter startup_attenuation""" - self.hop_points: Parameter = self.add_parameter( + self.hop_points: Parameter[int, Self] = self.add_parameter( "hop_points", get_cmd="HOP:POINTS?", get_parser=int ) """Parameter hop_points""" diff --git a/src/qcodes/instrument_drivers/QDev/QDac_channels.py b/src/qcodes/instrument_drivers/QDev/QDac_channels.py index acfd1189cd31..1bd5cd1aed1d 100644 --- a/src/qcodes/instrument_drivers/QDev/QDac_channels.py +++ b/src/qcodes/instrument_drivers/QDev/QDac_channels.py @@ -3,7 +3,7 @@ import logging import time from functools import partial -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import pyvisa.constants from pyvisa.resources.serial import SerialInstrument @@ -82,7 +82,7 @@ def __init__( ) """Parameter vrange""" - self.i: Parameter = self.add_parameter( + self.i: Parameter[float, Self] = self.add_parameter( "i", label=f"Channel {channum} current", get_cmd=f"get {channum}", @@ -91,7 +91,7 @@ def __init__( ) """Parameter i""" - self.irange: Parameter = self.add_parameter( + self.irange: Parameter[int, Self] = self.add_parameter( "irange", label=f"Channel {channum} irange", set_cmd=f"cur {channum} {{}}", @@ -315,13 +315,13 @@ def __init__( get_parser=self._num_verbose, ) - self.cal: Parameter = self.add_parameter( + self.cal: Parameter[int, Self] = self.add_parameter( name="cal", set_cmd="cal {}", vals=self.channel_validator ) """Parameter cal""" # TO-DO: maybe it's too dangerous to have this settable. # And perhaps ON is a better verbose mode default? - self.verbose: Parameter = self.add_parameter( + self.verbose: Parameter[bool, Self] = self.add_parameter( name="verbose", set_cmd="ver {}", val_mapping={True: 1, False: 0} ) """Parameter verbose""" diff --git a/src/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py b/src/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py index fdf01c55516e..1860c14f5320 100644 --- a/src/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py +++ b/src/qcodes/instrument_drivers/QuantumDesign/DynaCoolPPMS/DynaCool.py @@ -1,7 +1,7 @@ import warnings from functools import partial from time import sleep -from typing import TYPE_CHECKING, ClassVar, Literal, cast +from typing import TYPE_CHECKING, ClassVar, Literal, Self, cast import numpy as np from pyvisa import VisaIOError @@ -54,7 +54,7 @@ def __init__( ) -> None: super().__init__(name=name, address=address, **kwargs) - self.temperature: Parameter = self.add_parameter( + self.temperature: Parameter[float, Self] = self.add_parameter( "temperature", label="Temperature", unit="K", @@ -66,7 +66,7 @@ def __init__( # Note: from the Lyngby Materials Lab, we have been told that the # manual is wrong about the minimal temperature. The manual says # 1.8 K, but it is in fact 1.6 K - self.temperature_setpoint: Parameter = self.add_parameter( + self.temperature_setpoint: Parameter[float, Self] = self.add_parameter( "temperature_setpoint", label="Temperature setpoint", unit="K", @@ -76,24 +76,28 @@ def __init__( ) """Parameter temperature_setpoint""" - self.block_while_ramping_temperature: Parameter = self.add_parameter( - "block_while_ramping_temperature", - label="Block instrument while ramping temperature", - initial_value=False, - vals=vals.Bool(), - get_cmd=None, - set_cmd=None, + self.block_while_ramping_temperature: Parameter[bool, Self] = ( + self.add_parameter( + "block_while_ramping_temperature", + label="Block instrument while ramping temperature", + initial_value=False, + vals=vals.Bool(), + get_cmd=None, + set_cmd=None, + ) ) """Parameter block_while_ramping_temperature, when set to True, will block further interaction while temperature is ramping to setpoint.""" - self.blocking_t_state_check_interval: Parameter = self.add_parameter( - name="blocking_t_state_check_interval", - initial_value=0.5, - unit="s", - vals=vals.Numbers(0, 60), - set_cmd=None, - get_cmd=None, + self.blocking_t_state_check_interval: Parameter[float, Self] = ( + self.add_parameter( + name="blocking_t_state_check_interval", + initial_value=0.5, + unit="s", + vals=vals.Numbers(0, 60), + set_cmd=None, + get_cmd=None, + ) ) """Parameter blocking_t_state_check_interval sets how often temperature_setpoint checks for temperature stability when block_while_ramping_temperature is True.""" @@ -110,7 +114,7 @@ def __init__( ) """Parameter temperature_rate""" - self.temperature_settling: Parameter = self.add_parameter( + self.temperature_settling: Parameter[str, Self] = self.add_parameter( "temperature_settling", label="Temperature settling mode", val_mapping={"fast settle": 0, "no overshoot": 1}, @@ -119,7 +123,7 @@ def __init__( ) """Parameter temperature_settling""" - self.temperature_state: Parameter = self.add_parameter( + self.temperature_state: Parameter[str, Self] = self.add_parameter( "temperature_state", label="Temperature tracking state", val_mapping={ @@ -138,7 +142,7 @@ def __init__( ) """Parameter temperature_state""" - self.field_measured: Parameter = self.add_parameter( + self.field_measured: Parameter[float, Self] = self.add_parameter( "field_measured", label="Field", unit="T", @@ -146,7 +150,7 @@ def __init__( ) """Parameter field_measured""" - self.field_target: Parameter = self.add_parameter( + self.field_target: Parameter[float, Self] = self.add_parameter( "field_target", label="Field target", unit="T", @@ -156,7 +160,7 @@ def __init__( ) """Parameter field_target""" - self.field_ramp: Parameter = self.add_parameter( + self.field_ramp: Parameter[float, Self] = self.add_parameter( "field_ramp", label="Field [ramp]", unit="T", @@ -179,7 +183,7 @@ def __init__( ) """Parameter field_rate""" - self.field_approach: Parameter = self.add_parameter( + self.field_approach: Parameter[str, Self] = self.add_parameter( "field_approach", label="Field ramp approach", val_mapping={"linear": 0, "no overshoot": 1, "oscillate": 2}, @@ -189,7 +193,7 @@ def __init__( ) """Parameter field_approach""" - self.magnet_state: Parameter = self.add_parameter( + self.magnet_state: Parameter[str, Self] = self.add_parameter( "magnet_state", label="Magnet state", val_mapping={ @@ -214,7 +218,7 @@ def __init__( ) """Parameter magnet_state""" - self.chamber_temperature: Parameter = self.add_parameter( + self.chamber_temperature: Parameter[float, Self] = self.add_parameter( "chamber_temperature", label="Chamber Temperature", unit="K", @@ -223,7 +227,7 @@ def __init__( ) """Parameter chamber_temperature""" - self.chamber_state: Parameter = self.add_parameter( + self.chamber_state: Parameter[str, Self] = self.add_parameter( "chamber_state", label="Chamber vacuum state", val_mapping={ @@ -242,7 +246,7 @@ def __init__( ) """Parameter chamber_state""" - self.field_tolerance: Parameter = self.add_parameter( + self.field_tolerance: Parameter[float, Self] = self.add_parameter( "field_tolerance", label="Field Tolerance", unit="T", diff --git a/src/qcodes/instrument_drivers/agilent/Agilent_34401A.py b/src/qcodes/instrument_drivers/agilent/Agilent_34401A.py index 9a94a458f8ba..9830951829c3 100644 --- a/src/qcodes/instrument_drivers/agilent/Agilent_34401A.py +++ b/src/qcodes/instrument_drivers/agilent/Agilent_34401A.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.validators import Strings @@ -24,7 +24,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.display_text: Parameter = self.add_parameter( + self.display_text: Parameter[str, Self] = self.add_parameter( "display_text", get_cmd="DISP:TEXT?", set_cmd='DISP:TEXT "{}"', diff --git a/src/qcodes/instrument_drivers/agilent/Agilent_34410A.py b/src/qcodes/instrument_drivers/agilent/Agilent_34410A.py index 6b342e6e1480..8cce804653a8 100644 --- a/src/qcodes/instrument_drivers/agilent/Agilent_34410A.py +++ b/src/qcodes/instrument_drivers/agilent/Agilent_34410A.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.validators import Strings @@ -24,7 +24,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.display_text: Parameter = self.add_parameter( + self.display_text: Parameter[str, Self] = self.add_parameter( "display_text", get_cmd="DISP:WIND1:TEXT?", set_cmd='DISP:WIND1:TEXT "{}"', @@ -32,7 +32,7 @@ def __init__( ) """Parameter display_text""" - self.display_text_2: Parameter = self.add_parameter( + self.display_text_2: Parameter[str, Self] = self.add_parameter( "display_text_2", get_cmd="DISP:WIND2:TEXT?", set_cmd='DISP:WIND2:TEXT "{}"', diff --git a/src/qcodes/instrument_drivers/agilent/Agilent_34411A.py b/src/qcodes/instrument_drivers/agilent/Agilent_34411A.py index 09ee1292fa51..7f6137d91889 100644 --- a/src/qcodes/instrument_drivers/agilent/Agilent_34411A.py +++ b/src/qcodes/instrument_drivers/agilent/Agilent_34411A.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.validators import Strings @@ -24,7 +24,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.display_text: Parameter = self.add_parameter( + self.display_text: Parameter[str, Self] = self.add_parameter( "display_text", get_cmd="DISP:WIND1:TEXT?", set_cmd='DISP:WIND1:TEXT "{}"', @@ -32,7 +32,7 @@ def __init__( ) """Parameter display_text""" - self.display_text_2: Parameter = self.add_parameter( + self.display_text_2: Parameter[str, Self] = self.add_parameter( "display_text_2", get_cmd="DISP:WIND2:TEXT?", set_cmd='DISP:WIND2:TEXT "{}"', diff --git a/src/qcodes/instrument_drivers/agilent/Agilent_E8257D.py b/src/qcodes/instrument_drivers/agilent/Agilent_E8257D.py index 69b5b710ab3e..2dfbdf89f12c 100644 --- a/src/qcodes/instrument_drivers/agilent/Agilent_E8257D.py +++ b/src/qcodes/instrument_drivers/agilent/Agilent_E8257D.py @@ -1,5 +1,5 @@ import warnings -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np @@ -92,7 +92,7 @@ def __init__( self._min_power = -20 self._max_power = 5 - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", label="Frequency", unit="Hz", @@ -116,7 +116,7 @@ def __init__( ) """Parameter phase""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( name="power", label="Power", unit="dBm", @@ -128,7 +128,7 @@ def __init__( ) """Parameter power""" - self.output_enabled: Parameter = self.add_parameter( + self.output_enabled: Parameter[bool, Self] = self.add_parameter( "output_enabled", get_cmd=":OUTP?", set_cmd="OUTP {}", @@ -139,10 +139,10 @@ def __init__( self.connect_message() def on(self) -> None: - self.output_enabled.set("on") + self.output_enabled.set(True) def off(self) -> None: - self.output_enabled.set("off") + self.output_enabled.set(False) # functions to convert between rad and deg @staticmethod diff --git a/src/qcodes/instrument_drivers/agilent/Agilent_E8267C.py b/src/qcodes/instrument_drivers/agilent/Agilent_E8267C.py index 38fbeb4ed117..f2f9d0a3e237 100644 --- a/src/qcodes/instrument_drivers/agilent/Agilent_E8267C.py +++ b/src/qcodes/instrument_drivers/agilent/Agilent_E8267C.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np @@ -26,7 +26,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) # general commands - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", label="Frequency", unit="Hz", @@ -36,7 +36,7 @@ def __init__( vals=Numbers(min_value=100e3, max_value=40e9), ) """Parameter frequency""" - self.freq_offset: Parameter = self.add_parameter( + self.freq_offset: Parameter[float, Self] = self.add_parameter( name="freq_offset", label="Frequency offset", unit="Hz", @@ -46,7 +46,7 @@ def __init__( vals=Numbers(min_value=-200e9, max_value=200e9), ) """Parameter freq_offset""" - self.freq_mode: Parameter = self.add_parameter( + self.freq_mode: Parameter[str, Self] = self.add_parameter( "freq_mode", label="Frequency mode", set_cmd="FREQ:MODE {}", @@ -54,12 +54,13 @@ def __init__( vals=Enum("FIX", "CW", "SWE", "LIST"), ) """Parameter freq_mode""" - self.pulse_width: Parameter = self.add_parameter( + self.pulse_width: Parameter[float, Self] = self.add_parameter( "pulse_width", label="Pulse width", - unit="ns", + unit="s", set_cmd="PULM:INT:PWID {}", get_cmd="PULM:INT:PWID?", + get_parser=float, vals=Numbers(min_value=10e-9, max_value=20e-9), ) """Parameter pulse_width""" @@ -74,7 +75,7 @@ def __init__( vals=Numbers(min_value=-180, max_value=179), ) """Parameter phase""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( name="power", label="Power", unit="dBm", @@ -84,7 +85,7 @@ def __init__( vals=Numbers(min_value=-135, max_value=25), ) """Parameter power""" - self.power_offset: Parameter = self.add_parameter( + self.power_offset: Parameter[float, Self] = self.add_parameter( name="power_offset", label="Power offset", unit="dBm", @@ -94,14 +95,14 @@ def __init__( vals=Numbers(min_value=-200, max_value=200), ) """Parameter power_offset""" - self.output_rf: Parameter = self.add_parameter( + self.output_rf: Parameter[str, Self] = self.add_parameter( name="output_rf", get_cmd="OUTP?", set_cmd="OUTP {}", val_mapping={"OFF": 0, "ON": 1}, ) """Parameter output_rf""" - self.modulation_rf: Parameter = self.add_parameter( + self.modulation_rf: Parameter[str, Self] = self.add_parameter( name="modulation_rf", get_cmd="OUTP:MOD?", set_cmd="OUTP:MOD {}", diff --git a/src/qcodes/instrument_drivers/agilent/_Agilent_344xxA.py b/src/qcodes/instrument_drivers/agilent/_Agilent_344xxA.py index 2d424364b2a6..8ffc6e4598e8 100644 --- a/src/qcodes/instrument_drivers/agilent/_Agilent_344xxA.py +++ b/src/qcodes/instrument_drivers/agilent/_Agilent_344xxA.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.parameters import Parameter @@ -64,12 +64,12 @@ def __init__( ) """Resolution """ - self.volt: Parameter = self.add_parameter( + self.volt: Parameter[float, Self] = self.add_parameter( "volt", get_cmd="READ?", label="Voltage", get_parser=float, unit="V" ) """Parameter volt""" - self.fetch: Parameter = self.add_parameter( + self.fetch: Parameter[float, Self] = self.add_parameter( "fetch", get_cmd="FETCH?", label="Voltage", @@ -86,7 +86,7 @@ def __init__( ) """Parameter fetch""" - self.NPLC: Parameter = self.add_parameter( + self.NPLC: Parameter[float, Self] = self.add_parameter( "NPLC", get_cmd="VOLT:NPLC?", get_parser=float, @@ -97,12 +97,12 @@ def __init__( ) """Parameter NPLC""" - self.terminals: Parameter = self.add_parameter( + self.terminals: Parameter[str, Self] = self.add_parameter( "terminals", get_cmd="ROUT:TERM?" ) """Parameter terminals""" - self.range_auto: Parameter = self.add_parameter( + self.range_auto: Parameter[str, Self] = self.add_parameter( "range_auto", get_cmd="VOLT:RANG:AUTO?", set_cmd="VOLT:RANG:AUTO {:d}", @@ -110,7 +110,7 @@ def __init__( ) """Parameter range_auto""" - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", get_cmd="SENS:VOLT:DC:RANG?", get_parser=float, diff --git a/src/qcodes/instrument_drivers/american_magnetics/AMI430_visa.py b/src/qcodes/instrument_drivers/american_magnetics/AMI430_visa.py index 4e670639ba5c..64d490b9eb7d 100644 --- a/src/qcodes/instrument_drivers/american_magnetics/AMI430_visa.py +++ b/src/qcodes/instrument_drivers/american_magnetics/AMI430_visa.py @@ -6,7 +6,7 @@ from collections.abc import Callable, Iterable, Sequence from contextlib import ExitStack from functools import partial -from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, cast +from typing import TYPE_CHECKING, Any, ClassVar, Concatenate, Self, cast import numpy as np from pyvisa import VisaIOError @@ -64,7 +64,7 @@ def __init__( super().__init__(parent, "SwitchHeater", **kwargs) # Add state parameters - self.enabled: Parameter = self.add_parameter( + self.enabled: Parameter[bool, Self] = self.add_parameter( "enabled", label="Switch Heater Enabled", get_cmd=self._check_enabled, @@ -72,7 +72,7 @@ def __init__( vals=Bool(), ) """Parameter enabled""" - self.state: Parameter = self.add_parameter( + self.state: Parameter[bool, Self] = self.add_parameter( "state", label="Switch Heater On", get_cmd=self._check_state, @@ -80,7 +80,7 @@ def __init__( vals=Bool(), ) """Parameter state. Always False is the switch heater is not enabled""" - self.in_persistent_mode: Parameter = self.add_parameter( + self.in_persistent_mode: Parameter[bool, Self] = self.add_parameter( "in_persistent_mode", label="Persistent Mode", get_cmd="PERS?", @@ -89,7 +89,7 @@ def __init__( """Parameter in_persistent_mode""" # Configuration Parameters - self.current: Parameter = self.add_parameter( + self.current: Parameter[float, Self] = self.add_parameter( "current", label="Switch Heater Current", unit="mA", @@ -99,7 +99,7 @@ def __init__( vals=Numbers(0, 125), ) """Parameter current""" - self.heat_time: Parameter = self.add_parameter( + self.heat_time: Parameter[int, Self] = self.add_parameter( "heat_time", label="Heating Time", unit="s", @@ -109,7 +109,7 @@ def __init__( vals=Ints(5, 120), ) """Parameter heat_time""" - self.cool_time: Parameter = self.add_parameter( + self.cool_time: Parameter[int, Self] = self.add_parameter( "cool_time", label="Cooling Time", unit="s", @@ -249,14 +249,14 @@ def __init__( self.reset() # Add parameters setting instrument units - self.ramp_rate_units: Parameter = self.add_parameter( + self.ramp_rate_units: Parameter[str, Self] = self.add_parameter( "ramp_rate_units", get_cmd="RAMP:RATE:UNITS?", set_cmd=(lambda units: self._update_units(ramp_rate_units=units)), val_mapping={"seconds": 0, "minutes": 1}, ) """Parameter ramp_rate_units""" - self.field_units: Parameter = self.add_parameter( + self.field_units: Parameter[str, Self] = self.add_parameter( "field_units", get_cmd="FIELD:UNITS?", set_cmd=(lambda units: self._update_units(field_units=units)), @@ -265,14 +265,14 @@ def __init__( """Parameter field_units""" # Set programmatic safety limits - self.current_ramp_limit: Parameter = self.add_parameter( + self.current_ramp_limit: Parameter[float, Self] = self.add_parameter( "current_ramp_limit", get_cmd=lambda: self._current_ramp_limit, set_cmd=self._update_ramp_rate_limit, unit="A/s", ) """Parameter current_ramp_limit""" - self.field_ramp_limit: Parameter = self.add_parameter( + self.field_ramp_limit: Parameter[float, Self] = self.add_parameter( "field_ramp_limit", get_cmd=self.current_ramp_limit.get, set_cmd=self.current_ramp_limit.set, @@ -288,7 +288,7 @@ def __init__( self._update_ramp_rate_limit(current_ramp_limit, update=False) # Add solenoid parameters - self.coil_constant: Parameter = self.add_parameter( + self.coil_constant: Parameter[float, Self] = self.add_parameter( "coil_constant", get_cmd=self._update_coil_constant, set_cmd=self._update_coil_constant, @@ -296,7 +296,7 @@ def __init__( ) """Parameter coil_constant""" - self.current_limit: Parameter = self.add_parameter( + self.current_limit: Parameter[float, Self] = self.add_parameter( "current_limit", unit="A", set_cmd="CONF:CURR:LIMIT {}", @@ -306,7 +306,7 @@ def __init__( ) # what are good numbers here? """Parameter current_limit""" - self.field_limit: Parameter = self.add_parameter( + self.field_limit: Parameter[float, Self] = self.add_parameter( "field_limit", set_cmd=self.current_limit.set, get_cmd=self.current_limit.get, @@ -316,24 +316,24 @@ def __init__( # Add current solenoid parameters # Note that field is validated in set_field - self.field: Parameter = self.add_parameter( + self.field: Parameter[float, Self] = self.add_parameter( "field", get_cmd="FIELD:MAG?", get_parser=float, set_cmd=self.set_field ) """Parameter field""" - self.ramp_rate: Parameter = self.add_parameter( + self.ramp_rate: Parameter[float, Self] = self.add_parameter( "ramp_rate", get_cmd=self._get_ramp_rate, set_cmd=self._set_ramp_rate ) """Parameter ramp_rate""" - self.setpoint: Parameter = self.add_parameter( + self.setpoint: Parameter[float, Self] = self.add_parameter( "setpoint", get_cmd="FIELD:TARG?", get_parser=float ) """Parameter setpoint""" - self.is_quenched: Parameter = self.add_parameter( + self.is_quenched: Parameter[bool, Self] = self.add_parameter( "is_quenched", get_cmd="QU?", val_mapping={True: 1, False: 0} ) """Parameter is_quenched""" - self.ramping_state: Parameter = self.add_parameter( + self.ramping_state: Parameter[str, Self] = self.add_parameter( "ramping_state", get_cmd="STATE?", get_parser=int, @@ -351,7 +351,7 @@ def __init__( }, ) """Parameter ramping_state""" - self.ramping_state_check_interval: Parameter = self.add_parameter( + self.ramping_state_check_interval: Parameter[float, Self] = self.add_parameter( "ramping_state_check_interval", initial_value=0.05, unit="s", @@ -876,7 +876,7 @@ def find_ami430_with_name(ami430_name: str) -> AMIModel430: ) """Parameter rho""" - self.block_during_ramp: Parameter = self.add_parameter( + self.block_during_ramp: Parameter[bool, Self] = self.add_parameter( "block_during_ramp", set_cmd=None, initial_value=True, unit="", vals=Bool() ) """Parameter block_during_ramp""" diff --git a/src/qcodes/instrument_drivers/basel/BaselSP983a.py b/src/qcodes/instrument_drivers/basel/BaselSP983a.py index 93e076798df0..77a7e7458ca6 100644 --- a/src/qcodes/instrument_drivers/basel/BaselSP983a.py +++ b/src/qcodes/instrument_drivers/basel/BaselSP983a.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self import numpy as np @@ -69,7 +69,7 @@ def __init__( }, ) """Parameter fcut""" - self.overload_status: Parameter = self.add_parameter( + self.overload_status: Parameter[str, Self] = self.add_parameter( "overload_status", label="Overload Status", set_cmd=False, get_cmd="GET O" ) """Parameter overload_status""" diff --git a/src/qcodes/instrument_drivers/cryomagnetics/_TM620.py b/src/qcodes/instrument_drivers/cryomagnetics/_TM620.py index 1dee444cbc21..6e92e30fe822 100644 --- a/src/qcodes/instrument_drivers/cryomagnetics/_TM620.py +++ b/src/qcodes/instrument_drivers/cryomagnetics/_TM620.py @@ -1,6 +1,6 @@ import re from time import sleep -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs @@ -34,7 +34,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.shield: Parameter = self.add_parameter( + self.shield: Parameter[float, Self] = self.add_parameter( name="shield", unit="K", get_cmd=self._get_A, @@ -43,7 +43,7 @@ def __init__( ) """55K shield temperature""" - self.magnet: Parameter = self.add_parameter( + self.magnet: Parameter[float, Self] = self.add_parameter( name="magnet", unit="K", get_cmd=self._get_B, diff --git a/src/qcodes/instrument_drivers/cryomagnetics/_cryomagnetics4g.py b/src/qcodes/instrument_drivers/cryomagnetics/_cryomagnetics4g.py index e643217480bf..81d2957c442e 100644 --- a/src/qcodes/instrument_drivers/cryomagnetics/_cryomagnetics4g.py +++ b/src/qcodes/instrument_drivers/cryomagnetics/_cryomagnetics4g.py @@ -88,7 +88,7 @@ def __init__( self._stability_check_interval = 20 # Adding parameters - self.units: Parameter = self.add_parameter( + self.units: Parameter[str, Self] = self.add_parameter( name="units", set_cmd="UNITS {}", get_cmd="UNITS?", @@ -107,7 +107,7 @@ def __init__( ) """Parameter ramping_state_check_interval""" - self.field: Parameter = self.add_parameter( + self.field: Parameter[float, Self] = self.add_parameter( name="field", unit="T", set_cmd=self.set_field, @@ -118,7 +118,7 @@ def __init__( ) """Magnetic Field in Tesla""" - self.rate: Parameter = self.add_parameter( + self.rate: Parameter[float, Self] = self.add_parameter( name="rate", unit="T/min", get_cmd=self._get_rate, @@ -127,7 +127,7 @@ def __init__( ) """Rate for magnetic field T/min""" - self.Vmag: Parameter = self.add_parameter( + self.Vmag: Parameter[float, Self] = self.add_parameter( name="Vmag", unit="V", get_cmd="VMAG?", @@ -137,7 +137,7 @@ def __init__( ) """Magnet sense voltage""" - self.Vout: Parameter = self.add_parameter( + self.Vout: Parameter[float, Self] = self.add_parameter( name="Vout", unit="V", get_cmd="VOUT?", @@ -147,7 +147,7 @@ def __init__( ) """Magnet output voltage""" - self.Iout: Parameter = self.add_parameter( + self.Iout: Parameter[float, Self] = self.add_parameter( name="Iout", unit="A", get_cmd="IOUT?", diff --git a/src/qcodes/instrument_drivers/ithaco/Ithaco_1211.py b/src/qcodes/instrument_drivers/ithaco/Ithaco_1211.py index 3d81a798da35..fc1a716b86d4 100644 --- a/src/qcodes/instrument_drivers/ithaco/Ithaco_1211.py +++ b/src/qcodes/instrument_drivers/ithaco/Ithaco_1211.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import Instrument, InstrumentBaseKWArgs from qcodes.parameters import MultiParameter, Parameter, ParamRawDataType @@ -93,7 +93,7 @@ def __init__(self, name: str, **kwargs: "Unpack[InstrumentBaseKWArgs]"): ) """Parameter sens""" - self.invert: Parameter = self.add_parameter( + self.invert: Parameter[bool, Self] = self.add_parameter( "invert", initial_value=True, label="Inverted output", diff --git a/src/qcodes/instrument_drivers/mock_instruments/__init__.py b/src/qcodes/instrument_drivers/mock_instruments/__init__.py index 0fe7314d3e7e..24f5a67e46d1 100644 --- a/src/qcodes/instrument_drivers/mock_instruments/__init__.py +++ b/src/qcodes/instrument_drivers/mock_instruments/__init__.py @@ -3,7 +3,7 @@ import logging import time from functools import partial -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np import numpy.typing as npt @@ -68,18 +68,16 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): self.add_parameter( parname, unit="a.u.", - parameter_class=Parameter, vals=Numbers(), initial_value=0, get_cmd=None, set_cmd=None, ) - self.noise: Parameter = self.add_parameter( + self.noise: Parameter[float, Self] = self.add_parameter( "noise", unit="a.u.", label="white noise amplitude", - parameter_class=Parameter, vals=Numbers(), initial_value=0, get_cmd=None, @@ -87,11 +85,11 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): ) """Parameter noise""" - self.parabola: Parameter = self.add_parameter( + self.parabola: Parameter[float, Self] = self.add_parameter( "parabola", unit="a.u.", get_cmd=self._measure_parabola ) """Parameter parabola""" - self.skewed_parabola: Parameter = self.add_parameter( + self.skewed_parabola: Parameter[float, Self] = self.add_parameter( "skewed_parabola", unit="a.u.", get_cmd=self._measure_skewed_parabola ) """Parameter skewed_parabola""" @@ -141,18 +139,17 @@ def __init__( self.parameters[parname] = getattr(mock_parabola_inst, parname) self.gain: Parameter = self.add_parameter( "gain", - parameter_class=Parameter, initial_value=1, get_cmd=None, set_cmd=None, ) """Parameter gain""" - self.parabola: Parameter = self.add_parameter( + self.parabola: Parameter[float, Self] = self.add_parameter( "parabola", unit="a.u.", get_cmd=self._get_parabola ) """Parameter parabola""" - self.skewed_parabola: Parameter = self.add_parameter( + self.skewed_parabola: Parameter[float, Self] = self.add_parameter( "skewed_parabola", unit="a.u.", get_cmd=self._get_skew_parabola ) """Parameter skewed_parabola""" @@ -189,7 +186,6 @@ def __init__( for _, g in enumerate(gates): self.add_parameter( g, - parameter_class=Parameter, initial_value=0, label=f"Gate {g}", unit="V", @@ -383,9 +379,8 @@ def __init__( self._channel = channel # Add the various channel parameters - self.temperature: Parameter = self.add_parameter( + self.temperature: Parameter[float, Self] = self.add_parameter( "temperature", - parameter_class=Parameter, initial_value=0, label=f"Temperature_{channel}", unit="K", @@ -431,7 +426,7 @@ def __init__( ) """Parameter dummy_complex_array_parameter""" - self.dummy_start: Parameter = self.add_parameter( + self.dummy_start: Parameter[float, Self] = self.add_parameter( "dummy_start", initial_value=0, unit="some unit", @@ -442,7 +437,7 @@ def __init__( ) """Parameter dummy_start""" - self.dummy_stop: Parameter = self.add_parameter( + self.dummy_stop: Parameter[float, Self] = self.add_parameter( "dummy_stop", initial_value=100, unit="some unit", @@ -463,7 +458,7 @@ def __init__( ) """Parameter dummy_n_points""" - self.dummy_start_2: Parameter = self.add_parameter( + self.dummy_start_2: Parameter[float, Self] = self.add_parameter( "dummy_start_2", initial_value=0, unit="some unit", @@ -474,7 +469,7 @@ def __init__( ) """Parameter dummy_start_2""" - self.dummy_stop_2: Parameter = self.add_parameter( + self.dummy_stop_2: Parameter[float, Self] = self.add_parameter( "dummy_stop_2", initial_value=100, unit="some unit", @@ -543,7 +538,7 @@ def __init__( ) """Parameter dummy_parameter_with_setpoints_2d""" - self.dummy_text: Parameter = self.add_parameter( + self.dummy_text: Parameter[str, Self] = self.add_parameter( name="dummy_text", label="Dummy text", unit="text unit", @@ -1100,9 +1095,8 @@ def __init__( """ super().__init__(name=name, **kwargs) self._field = 0.0 - self.field: Parameter = self.add_parameter( + self.field: Parameter[float, Self] = self.add_parameter( "field", - parameter_class=Parameter, initial_value=0.0, unit="T", vals=vals, @@ -1112,7 +1106,6 @@ def __init__( """Parameter field""" self.ramp_rate: Parameter = self.add_parameter( "ramp_rate", - parameter_class=Parameter, initial_value=0.1, unit="T/min", get_cmd=None, @@ -1177,7 +1170,6 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): super().__init__(name=name, **kwargs) self.X: Parameter = self.add_parameter( "X", - parameter_class=Parameter, initial_value=1e-3, unit="V", get_cmd=None, @@ -1186,7 +1178,6 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): """Parameter X""" self.Y: Parameter = self.add_parameter( "Y", - parameter_class=Parameter, initial_value=1e-5, unit="V", get_cmd=None, @@ -1195,7 +1186,6 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): """Parameter Y""" self.frequency: Parameter = self.add_parameter( "frequency", - parameter_class=Parameter, initial_value=125.0, unit="Hz", get_cmd=None, @@ -1204,7 +1194,6 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): """Parameter frequency""" self.amplitude: Parameter = self.add_parameter( "amplitude", - parameter_class=Parameter, initial_value=0.0, unit="V", get_cmd=None, @@ -1213,7 +1202,6 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): """Parameter amplitude""" self.phase: Parameter = self.add_parameter( "phase", - parameter_class=Parameter, initial_value=0.0, unit="deg", get_cmd=None, @@ -1222,7 +1210,6 @@ def __init__(self, name: str, **kwargs: Unpack[InstrumentBaseKWArgs]): """Parameter phase""" self.time_constant: Parameter = self.add_parameter( "time_constant", - parameter_class=Parameter, initial_value=1.0e-3, unit="s", get_cmd=None, @@ -1246,9 +1233,8 @@ def __init__( super().__init__(parent, name, **kwargs) self._num = num - self.voltage: Parameter = self.add_parameter( + self.voltage: Parameter[float, Self] = self.add_parameter( "voltage", - parameter_class=Parameter, initial_value=0.0, label=f"Voltage_{name}", unit="V", @@ -1257,36 +1243,32 @@ def __init__( set_cmd=None, ) """Parameter voltage""" - self.dac_output: Parameter = self.add_parameter( + self.dac_output: Parameter[str, Self] = self.add_parameter( "dac_output", - parameter_class=Parameter, initial_value="off", vals=OnOff(), get_cmd=None, set_cmd=None, ) """Parameter dac_output""" - self.smc: Parameter = self.add_parameter( + self.smc: Parameter[str, Self] = self.add_parameter( "smc", - parameter_class=Parameter, initial_value="off", vals=OnOff(), get_cmd=None, set_cmd=None, ) """Parameter smc""" - self.bus: Parameter = self.add_parameter( + self.bus: Parameter[str, Self] = self.add_parameter( "bus", - parameter_class=Parameter, initial_value="off", vals=OnOff(), get_cmd=None, set_cmd=None, ) """Parameter bus""" - self.gnd: Parameter = self.add_parameter( + self.gnd: Parameter[str, Self] = self.add_parameter( "gnd", - parameter_class=Parameter, initial_value="off", vals=OnOff(), get_cmd=None, @@ -1377,9 +1359,8 @@ def __init__( set_cmd=None, ) - self.voltage: Parameter = self.add_parameter( + self.voltage: Parameter[float, Self] = self.add_parameter( "voltage", - parameter_class=Parameter, initial_value=0.0, label=f"Voltage_{name}", unit="V", diff --git a/src/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py b/src/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py index dd8593bd301b..c73966d07817 100644 --- a/src/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py +++ b/src/qcodes/instrument_drivers/oxford/MercuryiPS_VISA.py @@ -3,7 +3,7 @@ import logging import time from functools import partial -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING, Self, cast import numpy as np import numpy.typing as npt @@ -112,7 +112,7 @@ def __init__( else: self.psu_string = "PSU" - self.heater_switch: Parameter = self.add_parameter( + self.heater_switch: Parameter[str, Self] = self.add_parameter( "heater_switch", label="Heater switch status/set", get_cmd=partial(self._param_getter, "SIG:SWHT"), @@ -121,7 +121,7 @@ def __init__( ) """Parameter heater switch""" - self.voltage: Parameter = self.add_parameter( + self.voltage: Parameter[float, Self] = self.add_parameter( "voltage", label="Output voltage", get_cmd=partial(self._param_getter, "SIG:VOLT"), @@ -130,7 +130,7 @@ def __init__( ) """Parameter voltage""" - self.current: Parameter = self.add_parameter( + self.current: Parameter[float, Self] = self.add_parameter( "current", label="Output current", get_cmd=partial(self._param_getter, "SIG:CURR"), @@ -139,7 +139,7 @@ def __init__( ) """Parameter current""" - self.current_persistent: Parameter = self.add_parameter( + self.current_persistent: Parameter[float, Self] = self.add_parameter( "current_persistent", label="Output persistent current", get_cmd=partial(self._param_getter, "SIG:PCUR"), @@ -148,7 +148,7 @@ def __init__( ) """Parameter current_persistent""" - self.current_target: Parameter = self.add_parameter( + self.current_target: Parameter[float, Self] = self.add_parameter( "current_target", label="Target current", get_cmd=partial(self._param_getter, "SIG:CSET"), @@ -158,7 +158,7 @@ def __init__( ) """Parameter current_target""" - self.field_target: Parameter = self.add_parameter( + self.field_target: Parameter[float, Self] = self.add_parameter( "field_target", label="Target field", get_cmd=partial(self._param_getter, "SIG:FSET"), @@ -170,7 +170,7 @@ def __init__( # NB: The current ramp rate follows the field ramp rate # (converted via the ATOB param) - self.current_ramp_rate: Parameter = self.add_parameter( + self.current_ramp_rate: Parameter[float, Self] = self.add_parameter( "current_ramp_rate", label="Ramp rate (current)", unit="A/s", @@ -192,7 +192,7 @@ def __init__( ) """Parameter field_ramp_rate""" - self.field: Parameter = self.add_parameter( + self.field: Parameter[float, Self] = self.add_parameter( "field", label="Field strength", unit="T", @@ -201,7 +201,7 @@ def __init__( ) """Parameter field""" - self.field_persistent: Parameter = self.add_parameter( + self.field_persistent: Parameter[float, Self] = self.add_parameter( "field_persistent", label="Persistent field strength", unit="T", @@ -210,7 +210,7 @@ def __init__( ) """Parameter field_persistent""" - self.ATOB: Parameter = self.add_parameter( + self.ATOB: Parameter[float, Self] = self.add_parameter( "ATOB", label="Current to field ratio", unit="A/T", @@ -220,7 +220,7 @@ def __init__( ) """Parameter ATOB""" - self.ramp_status: Parameter = self.add_parameter( + self.ramp_status: Parameter[str, Self] = self.add_parameter( "ramp_status", label="Ramp status", get_cmd=partial(self._param_getter, "ACTN"), @@ -363,7 +363,7 @@ def __init__( self._pt1_temp_addr = "DEV:DB8.T1:TEMP" self._pt2_temp_addr = "DEV:DB7.T1:TEMP" - self.magnet_temp: Parameter = self.add_parameter( + self.magnet_temp: Parameter[float, Self] = self.add_parameter( name="magnet_temp", label="Magnet Temperature", unit="K", @@ -373,7 +373,7 @@ def __init__( ) """Parameter magnet temperature""" - self.pt1_temp: Parameter = self.add_parameter( + self.pt1_temp: Parameter[float, Self] = self.add_parameter( name="pt1_temp", label="pt1 Temperature", unit="K", @@ -383,7 +383,7 @@ def __init__( ) """Parameter pt1 temperature""" - self.pt2_temp: Parameter = self.add_parameter( + self.pt2_temp: Parameter[float, Self] = self.add_parameter( name="pt2_temp", label="pt2 Temperature", unit="K", diff --git a/src/qcodes/instrument_drivers/oxford/triton.py b/src/qcodes/instrument_drivers/oxford/triton.py index 2a5cac3e2af5..244602ae624b 100644 --- a/src/qcodes/instrument_drivers/oxford/triton.py +++ b/src/qcodes/instrument_drivers/oxford/triton.py @@ -2,7 +2,7 @@ import re from functools import partial from time import sleep -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import InstrumentBaseKWArgs, IPInstrument from qcodes.validators import Enum, Ints, Numbers @@ -69,7 +69,7 @@ def __init__( ) """Indicates if a magnet is equipped *and* controlled by the Triton.""" - self.time: Parameter = self.add_parameter( + self.time: Parameter[str, Self] = self.add_parameter( name="time", label="System Time", get_cmd="READ:SYS:TIME", @@ -77,7 +77,7 @@ def __init__( ) """Parameter time""" - self.action: Parameter = self.add_parameter( + self.action: Parameter[str, Self] = self.add_parameter( name="action", label="Current action", get_cmd="READ:SYS:DR:ACTN", @@ -85,7 +85,7 @@ def __init__( ) """Parameter action""" - self.status: Parameter = self.add_parameter( + self.status: Parameter[str, Self] = self.add_parameter( name="status", label="Status", get_cmd="READ:SYS:DR:STATUS", @@ -93,7 +93,7 @@ def __init__( ) """Parameter status""" - self.pid_control_channel: Parameter = self.add_parameter( + self.pid_control_channel: Parameter[int, Self] = self.add_parameter( name="pid_control_channel", label="PID control channel", get_cmd=self._get_control_channel, @@ -102,7 +102,7 @@ def __init__( ) """Parameter pid_control_channel""" - self.pid_mode: Parameter = self.add_parameter( + self.pid_mode: Parameter[str, Self] = self.add_parameter( name="pid_mode", label="PID Mode", get_cmd=partial(self._get_control_param, "MODE"), @@ -111,7 +111,7 @@ def __init__( ) """Parameter pid_mode""" - self.pid_ramp: Parameter = self.add_parameter( + self.pid_ramp: Parameter[str, Self] = self.add_parameter( name="pid_ramp", label="PID ramp enabled", get_cmd=partial(self._get_control_param, "RAMP:ENAB"), diff --git a/src/qcodes/instrument_drivers/rigol/Rigol_DG1062.py b/src/qcodes/instrument_drivers/rigol/Rigol_DG1062.py index f522af152ade..edfce3d5653b 100644 --- a/src/qcodes/instrument_drivers/rigol/Rigol_DG1062.py +++ b/src/qcodes/instrument_drivers/rigol/Rigol_DG1062.py @@ -1,6 +1,6 @@ import logging from functools import partial -from typing import TYPE_CHECKING, Any, ClassVar +from typing import TYPE_CHECKING, Any, ClassVar, Self from qcodes import validators as vals from qcodes.instrument import ( @@ -44,7 +44,7 @@ def __init__( ) """Parameter on""" - self.polarity: Parameter = self.add_parameter( + self.polarity: Parameter[str, Self] = self.add_parameter( "polarity", get_cmd=f":SOUR{channel}:BURS:GATE:POL?", set_cmd=f":SOUR{channel}:BURS:GATE:POL {{}}", @@ -62,7 +62,7 @@ def __init__( ) """Parameter period""" - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", get_cmd=f":SOUR{channel}:BURS:MODE?", set_cmd=f":SOUR{channel}:BURS:MODE {{}}", @@ -70,31 +70,35 @@ def __init__( ) """Parameter mode""" - self.ncycles: Parameter = self.add_parameter( + self.ncycles: Parameter[int, Self] = self.add_parameter( "ncycles", get_cmd=f":SOUR{channel}:BURS:NCYC?", set_cmd=f":SOUR{channel}:BURS:NCYC {{}}", + # returned in scientific notation, e.g. 1.000000E+01 + get_parser=lambda s: int(float(s)), vals=vals.Numbers(min_value=1, max_value=500000), ) """Parameter ncycles""" - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( "phase", get_cmd=f":SOUR{channel}:BURS:PHAS?", set_cmd=f":SOUR{channel}:BURS:PHAS {{}}", + get_parser=float, vals=vals.Numbers(min_value=0, max_value=360), ) """Parameter phase""" - self.time_delay: Parameter = self.add_parameter( + self.time_delay: Parameter[float, Self] = self.add_parameter( "time_delay", get_cmd=f":SOUR{channel}:BURS:TDEL?", set_cmd=f":SOUR{channel}:BURS:TDEL {{}}", + get_parser=float, vals=vals.Numbers(min_value=0), ) """Parameter time_delay""" - self.trigger_slope: Parameter = self.add_parameter( + self.trigger_slope: Parameter[str, Self] = self.add_parameter( "trigger_slope", get_cmd=f":SOUR{channel}:BURS:TRIG:SLOP?", set_cmd=f":SOUR{channel}:BURS:TRIG:SLOP {{}}", @@ -102,7 +106,7 @@ def __init__( ) """Parameter trigger_slope""" - self.source: Parameter = self.add_parameter( + self.source: Parameter[str, Self] = self.add_parameter( "source", get_cmd=f":SOUR{channel}:BURS:TRIG:SOUR?", set_cmd=f":SOUR{channel}:BURS:TRIG:SOUR {{}}", @@ -191,8 +195,8 @@ def __init__( set_cmd=partial(self._set_waveform_param, param), ) - self.waveform: Parameter = self.add_parameter( - "waveform", get_cmd=partial(self._get_waveform_param, "waveform") + self.waveform: Parameter[str, Self] = self.add_parameter( + "waveform", get_cmd=self._get_waveform ) """Parameter waveform""" @@ -227,23 +231,22 @@ def __init__( ) """Parameter sync""" - self.polarity: Parameter = self.add_parameter( + self.polarity: Parameter[int, Self] = self.add_parameter( "polarity", get_cmd=f":OUTPUT{channel}:GAT:POL?", set_cmd=f":OUTPUT{channel}:GAT:POL {{}}", - vals=vals.OnOff(), val_mapping={1: "POSITIVE", 0: "NEGATIVE"}, ) """Parameter polarity""" - self.state: Parameter = self.add_parameter( + self.state: Parameter[str, Self] = self.add_parameter( "state", get_cmd=f"OUTPUT{channel}:STATE?", set_cmd=f"OUTPUT{channel}:STATE {{}}", ) """Parameter state""" - self.duty_cycle: Parameter = self.add_parameter( + self.duty_cycle: Parameter[float, Self] = self.add_parameter( "duty_cycle", get_cmd=self._get_duty_cycle, set_cmd=self._set_duty_cycle, @@ -302,6 +305,12 @@ def current_waveform(self) -> dict[Any, Any]: """Public interface to get the current waveform""" return self._get_waveform_params() + def _get_waveform(self) -> str: + """ + Get the name of the current waveform, e.g. "SIN" or "SQU". + """ + return self._get_waveform_params()["waveform"] + def _get_waveform_param(self, param: str) -> float | None: """ Get a parameter of the current waveform. Valid param names are @@ -372,14 +381,16 @@ def _set_waveform_params(self, **params_dict: float) -> None: string += ",".join(values) self.parent.write_raw(string) - def _get_duty_cycle(self) -> str: + def _get_duty_cycle(self) -> float: """ Reads the duty cycle after checking waveform """ wf = self.waveform() if wf in ["PULS", "SQU"]: - duty_cycle = self.parent.ask_raw(f":SOUR{self.channel}:FUNC:{wf}:DCYC?") + duty_cycle = float( + self.parent.ask_raw(f":SOUR{self.channel}:FUNC:{wf}:DCYC?") + ) else: raise ValueError( f"Current function does not contain duty cycle. Current function: {wf}" diff --git a/src/qcodes/instrument_drivers/rigol/Rigol_DG4000.py b/src/qcodes/instrument_drivers/rigol/Rigol_DG4000.py index c0ad3006f209..d73e0079fdcf 100644 --- a/src/qcodes/instrument_drivers/rigol/Rigol_DG4000.py +++ b/src/qcodes/instrument_drivers/rigol/Rigol_DG4000.py @@ -1,5 +1,5 @@ from functools import partial -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs from qcodes.validators import Anything, Enum, Ints, MultiType, Numbers @@ -109,7 +109,7 @@ def __init__( on_off_map = {True: "ON", False: "OFF"} # Counter - self.counter_attenuation: Parameter = self.add_parameter( + self.counter_attenuation: Parameter[int, Self] = self.add_parameter( "counter_attenuation", get_cmd="COUN:ATT?", set_cmd="COUN:ATT {}", @@ -119,7 +119,7 @@ def __init__( self.add_function("auto_counter", call_cmd="COUN:AUTO") - self.counter_coupling: Parameter = self.add_parameter( + self.counter_coupling: Parameter[str, Self] = self.add_parameter( "counter_coupling", get_cmd="COUN:COUP?", set_cmd="COUN:COUP {}", @@ -144,7 +144,7 @@ def __init__( ) """Parameter counter_gate_time""" - self.counter_hf_reject_enabled: Parameter = self.add_parameter( + self.counter_hf_reject_enabled: Parameter[bool, Self] = self.add_parameter( "counter_hf_reject_enabled", get_cmd="COUN:HF?", set_cmd="COUN:HF {}", @@ -161,7 +161,7 @@ def __init__( ) """Parameter counter_impedance""" - self.counter_trigger_level: Parameter = self.add_parameter( + self.counter_trigger_level: Parameter[float, Self] = self.add_parameter( "counter_trigger_level", get_cmd="COUN:LEVE?", get_parser=float, @@ -171,7 +171,7 @@ def __init__( ) """Parameter counter_trigger_level""" - self.counter_enabled: Parameter = self.add_parameter( + self.counter_enabled: Parameter[bool, Self] = self.add_parameter( "counter_enabled", get_cmd="COUN:STAT?", set_cmd="COUN:STAT {}", @@ -195,7 +195,7 @@ def __init__( get_parser=partial(parse_single_output, i), ) - self.counter_trigger_sensitivity: Parameter = self.add_parameter( + self.counter_trigger_sensitivity: Parameter[float, Self] = self.add_parameter( "counter_trigger_sensitivity", get_cmd="COUN:SENS?", get_parser=float, @@ -669,7 +669,7 @@ def __init__( # System self.add_function("beep", call_cmd="SYST:BEEP") - self.beeper_enabled: Parameter = self.add_parameter( + self.beeper_enabled: Parameter[bool, Self] = self.add_parameter( "beeper_enabled", get_cmd="SYST:BEEP:STAT?", set_cmd="SYST:BEEP:STAT {}", @@ -685,7 +685,7 @@ def __init__( self.add_function("get_error", call_cmd="SYST:ERR?", return_parser=str) - self.keyboard_locked: Parameter = self.add_parameter( + self.keyboard_locked: Parameter[bool, Self] = self.add_parameter( "keyboard_locked", get_cmd="SYST:KLOCK?", set_cmd="SYST:KLOCK {}", @@ -693,7 +693,7 @@ def __init__( ) """Parameter keyboard_locked""" - self.startup_mode: Parameter = self.add_parameter( + self.startup_mode: Parameter[str, Self] = self.add_parameter( "startup_mode", get_cmd="SYST:POWS?", get_parser=str.lower, @@ -720,7 +720,7 @@ def __init__( self.add_function("restart", call_cmd="SYST:RESTART") - self.reference_clock_source: Parameter = self.add_parameter( + self.reference_clock_source: Parameter[str, Self] = self.add_parameter( "reference_clock_source", get_cmd="SYST:ROSC:SOUR?", set_cmd="SYST:ROSC:SOUR {}", @@ -730,7 +730,7 @@ def __init__( self.add_function("shutdown", call_cmd="SYST:SHUTDOWN") - self.scpi_version: Parameter = self.add_parameter( + self.scpi_version: Parameter[str, Self] = self.add_parameter( "scpi_version", get_cmd="SYST:VERS?" ) """Parameter scpi_version""" diff --git a/src/qcodes/instrument_drivers/rigol/Rigol_DS1074Z.py b/src/qcodes/instrument_drivers/rigol/Rigol_DS1074Z.py index 75cad0548fa2..9403baab7acc 100644 --- a/src/qcodes/instrument_drivers/rigol/Rigol_DS1074Z.py +++ b/src/qcodes/instrument_drivers/rigol/Rigol_DS1074Z.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self import numpy as np import numpy.typing as npt @@ -38,7 +38,7 @@ def __init__( super().__init__(parent, name, **kwargs) self.channel = channel - self.vertical_scale: Parameter = self.add_parameter( + self.vertical_scale: Parameter[float, Self] = self.add_parameter( "vertical_scale", get_cmd=f":CHANnel{channel}:SCALe?", set_cmd=":CHANnel{}:SCALe {}".format(channel, "{}"), @@ -103,12 +103,12 @@ def __init__( ): super().__init__(name, address, **kwargs) - self.waveform_xorigin: Parameter = self.add_parameter( + self.waveform_xorigin: Parameter[float, Self] = self.add_parameter( "waveform_xorigin", get_cmd="WAVeform:XORigin?", unit="s", get_parser=float ) """Parameter waveform_xorigin""" - self.waveform_xincrem: Parameter = self.add_parameter( + self.waveform_xincrem: Parameter[float, Self] = self.add_parameter( "waveform_xincrem", get_cmd=":WAVeform:XINCrement?", unit="s", @@ -116,7 +116,7 @@ def __init__( ) """Parameter waveform_xincrem""" - self.waveform_npoints: Parameter = self.add_parameter( + self.waveform_npoints: Parameter[int, Self] = self.add_parameter( "waveform_npoints", get_cmd="WAV:POIN?", set_cmd="WAV:POIN {}", @@ -125,12 +125,12 @@ def __init__( ) """Parameter waveform_npoints""" - self.waveform_yorigin: Parameter = self.add_parameter( + self.waveform_yorigin: Parameter[float, Self] = self.add_parameter( "waveform_yorigin", get_cmd="WAVeform:YORigin?", unit="V", get_parser=float ) """Parameter waveform_yorigin""" - self.waveform_yincrem: Parameter = self.add_parameter( + self.waveform_yincrem: Parameter[float, Self] = self.add_parameter( "waveform_yincrem", get_cmd=":WAVeform:YINCrement?", unit="V", @@ -138,12 +138,12 @@ def __init__( ) """Parameter waveform_yincrem""" - self.waveform_yref: Parameter = self.add_parameter( + self.waveform_yref: Parameter[float, Self] = self.add_parameter( "waveform_yref", get_cmd=":WAVeform:YREFerence?", unit="V", get_parser=float ) """Parameter waveform_yref""" - self.trigger_mode: Parameter = self.add_parameter( + self.trigger_mode: Parameter[str, Self] = self.add_parameter( "trigger_mode", get_cmd=":TRIGger:MODE?", set_cmd=":TRIGger:MODE {}", @@ -154,7 +154,7 @@ def __init__( """Parameter trigger_mode""" # trigger source - self.trigger_level: Parameter = self.add_parameter( + self.trigger_level: Parameter[float, Self] = self.add_parameter( "trigger_level", unit="V", get_cmd=self._get_trigger_level, @@ -163,7 +163,7 @@ def __init__( ) """Parameter trigger_level""" - self.trigger_edge_source: Parameter = self.add_parameter( + self.trigger_edge_source: Parameter[str, Self] = self.add_parameter( "trigger_edge_source", label="Source channel for the edge trigger", get_cmd=":TRIGger:EDGE:SOURce?", @@ -177,7 +177,7 @@ def __init__( ) """Parameter trigger_edge_source""" - self.trigger_edge_slope: Parameter = self.add_parameter( + self.trigger_edge_slope: Parameter[str, Self] = self.add_parameter( "trigger_edge_slope", label="Slope of the edge trigger", get_cmd=":TRIGger:EDGE:SLOPe?", @@ -186,7 +186,7 @@ def __init__( ) """Parameter trigger_edge_slope""" - self.data_source: Parameter = self.add_parameter( + self.data_source: Parameter[str, Self] = self.add_parameter( "data_source", label="Waveform Data source", get_cmd=":WAVeform:SOURce?", @@ -230,9 +230,9 @@ def _get_time_axis(self) -> npt.NDArray: xdata = np.linspace(xorigin, npts * xincrem + xorigin, npts) return xdata - def _get_trigger_level(self) -> str: - trigger_level = self.ask(f":TRIGger:{self.trigger_mode()}:LEVel?") - return trigger_level + def _get_trigger_level(self) -> float: + # returned in scientific notation, e.g. 1.600000e-01 + return float(self.ask(f":TRIGger:{self.trigger_mode()}:LEVel?")) - def _set_trigger_level(self, value: str) -> None: + def _set_trigger_level(self, value: float) -> None: self.write(f":TRIGger:{self.trigger_mode()}:LEVel {value}") diff --git a/src/qcodes/instrument_drivers/rigol/Rigol_DS4000.py b/src/qcodes/instrument_drivers/rigol/Rigol_DS4000.py index 7ad09bec987a..6a83687d71b4 100644 --- a/src/qcodes/instrument_drivers/rigol/Rigol_DS4000.py +++ b/src/qcodes/instrument_drivers/rigol/Rigol_DS4000.py @@ -4,7 +4,7 @@ import re import time import warnings -from typing import TYPE_CHECKING, NamedTuple +from typing import TYPE_CHECKING, Any, NamedTuple, Self import numpy as np from packaging import version @@ -17,7 +17,11 @@ VisaInstrument, VisaInstrumentKWArgs, ) -from qcodes.parameters import ArrayParameter, ParamRawDataType +from qcodes.parameters import ( + ArrayParameter, + ParamRawDataType, + create_on_off_val_mapping, +) if TYPE_CHECKING: from typing import Unpack @@ -38,6 +42,7 @@ def __init__( instrument: RigolDS4000Channel, channel: int, raw: bool = False, + **kwargs: Any, ): super().__init__( name=name, @@ -49,6 +54,7 @@ def __init__( setpoint_units=("s",), docstring="holds an array from scope", instrument=instrument, + **kwargs, ) self.channel = channel self.raw = raw @@ -210,11 +216,11 @@ def __init__( ): super().__init__(parent, name, **kwargs) - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( "amplitude", get_cmd=f":MEASure:VAMP? chan{channel}", get_parser=float ) """Parameter amplitude""" - self.vertical_scale: Parameter = self.add_parameter( + self.vertical_scale: Parameter[float, Self] = self.add_parameter( "vertical_scale", get_cmd=f":CHANnel{channel}:SCALe?", set_cmd=":CHANnel{}:SCALe {}".format(channel, "{}"), @@ -281,7 +287,7 @@ def __init__( ) # general parameters - self.trigger_type: Parameter = self.add_parameter( + self.trigger_type: Parameter[str, Self] = self.add_parameter( "trigger_type", label="Type of the trigger", get_cmd=":TRIGger:MODE?", @@ -303,7 +309,7 @@ def __init__( ), ) """Parameter trigger_type""" - self.trigger_mode: Parameter = self.add_parameter( + self.trigger_mode: Parameter[str, Self] = self.add_parameter( "trigger_mode", label="Mode of the trigger", get_cmd=":TRIGger:SWEep?", @@ -311,7 +317,7 @@ def __init__( vals=vals.Enum("AUTO", "NORM", "SING"), ) """Parameter trigger_mode""" - self.time_base: Parameter = self.add_parameter( + self.time_base: Parameter[float, Self] = self.add_parameter( "time_base", label="Horizontal time base", get_cmd=":TIMebase:MAIN:SCALe?", @@ -320,7 +326,7 @@ def __init__( unit="s/div", ) """Parameter time_base""" - self.sample_point_count: Parameter = self.add_parameter( + self.sample_point_count: Parameter[int, Self] = self.add_parameter( "sample_point_count", label="Number of the waveform points", get_cmd=":WAVeform:POINts?", @@ -329,13 +335,12 @@ def __init__( vals=vals.Ints(min_value=1), ) """Parameter sample_point_count""" - self.enable_auto_scale: Parameter = self.add_parameter( + self.enable_auto_scale: Parameter[bool, Self] = self.add_parameter( "enable_auto_scale", label="Enable or disable autoscale", get_cmd=":SYSTem:AUToscale?", set_cmd=":SYSTem:AUToscale {}", - get_parser=bool, - vals=vals.Bool(), + val_mapping=create_on_off_val_mapping(on_val=1, off_val=0), ) """Parameter enable_auto_scale""" diff --git a/src/qcodes/instrument_drivers/rigol/private/DP8xx.py b/src/qcodes/instrument_drivers/rigol/private/DP8xx.py index 493c752cd01d..fce506eecfaf 100644 --- a/src/qcodes/instrument_drivers/rigol/private/DP8xx.py +++ b/src/qcodes/instrument_drivers/rigol/private/DP8xx.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators as vals from qcodes.instrument import ( @@ -39,7 +39,7 @@ def __init__( def strstrip(s: str) -> str: return str(s).strip() - self.set_voltage: Parameter = self.add_parameter( + self.set_voltage: Parameter[float, Self] = self.add_parameter( "set_voltage", label="Target voltage output", set_cmd="{} :SOURce:VOLTage:LEVel:IMMediate:AMPLitude {}".format( @@ -51,7 +51,7 @@ def strstrip(s: str) -> str: vals=vals.Numbers(min(0, self.vmax), max(0, self.vmax)), ) """Parameter set_voltage""" - self.set_current: Parameter = self.add_parameter( + self.set_current: Parameter[float, Self] = self.add_parameter( "set_current", label="Target current output", set_cmd="{} :SOURce:CURRent:LEVel:IMMediate:AMPLitude {}".format( @@ -63,7 +63,7 @@ def strstrip(s: str) -> str: vals=vals.Numbers(0, self.imax), ) """Parameter set_current""" - self.state: Parameter = self.add_parameter( + self.state: Parameter[str, Self] = self.add_parameter( "state", label="Output enabled", set_cmd="{} :OUTPut:STATe {}".format(select_cmd, "{}"), @@ -72,7 +72,7 @@ def strstrip(s: str) -> str: vals=vals.OnOff(), ) """Parameter state""" - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", label="Get the output mode", get_cmd=f"{select_cmd} :OUTPut:MODE?", @@ -84,7 +84,7 @@ def strstrip(s: str) -> str: }, ) """Parameter mode""" - self.voltage: Parameter = self.add_parameter( + self.voltage: Parameter[float, Self] = self.add_parameter( "voltage", label="Measured voltage", get_cmd=f"{select_cmd} :MEASure:VOLTage:DC?", @@ -92,7 +92,7 @@ def strstrip(s: str) -> str: unit="V", ) """Parameter voltage""" - self.current: Parameter = self.add_parameter( + self.current: Parameter[float, Self] = self.add_parameter( "current", label="Measured current", get_cmd=f"{select_cmd} :MEASure:CURRent:DC?", @@ -100,7 +100,7 @@ def strstrip(s: str) -> str: unit="A", ) """Parameter current""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( "power", label="Measured power", get_cmd=f"{select_cmd} :MEASure:POWer?", @@ -108,7 +108,7 @@ def strstrip(s: str) -> str: unit="W", ) """Parameter power""" - self.ovp_value: Parameter = self.add_parameter( + self.ovp_value: Parameter[float, Self] = self.add_parameter( "ovp_value", label="Over Voltage Protection value", set_cmd="{} :VOLTage:PROTection:LEVel {}".format(select_cmd, "{}"), @@ -118,7 +118,7 @@ def strstrip(s: str) -> str: vals=vals.Numbers(self.ovp_range[0], self.ovp_range[1]), ) """Parameter ovp_value""" - self.ovp_state: Parameter = self.add_parameter( + self.ovp_state: Parameter[str, Self] = self.add_parameter( "ovp_state", label="Over Voltage Protection status", set_cmd="{} :VOLTage:PROTection:STATe {}".format(select_cmd, "{}"), @@ -127,7 +127,7 @@ def strstrip(s: str) -> str: vals=vals.OnOff(), ) """Parameter ovp_state""" - self.ocp_value: Parameter = self.add_parameter( + self.ocp_value: Parameter[float, Self] = self.add_parameter( "ocp_value", label="Over Current Protection value", set_cmd="{} :CURRent:PROTection:LEVel {}".format(select_cmd, "{}"), @@ -137,7 +137,7 @@ def strstrip(s: str) -> str: vals=vals.Numbers(self.ocp_range[0], self.ocp_range[1]), ) """Parameter ocp_value""" - self.ocp_state: Parameter = self.add_parameter( + self.ocp_state: Parameter[str, Self] = self.add_parameter( "ocp_state", label="Over Current Protection status", set_cmd="{} :CURRent:PROTection:STATe {}".format(select_cmd, "{}"), diff --git a/src/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py b/src/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py index af5981f72c9e..e90361e298d9 100644 --- a/src/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py +++ b/src/qcodes/instrument_drivers/rohde_schwarz/RTO1000.py @@ -3,7 +3,7 @@ import logging import time import warnings -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np import numpy.typing as npt @@ -365,7 +365,7 @@ def __init__( "MKNegative", ) - self.enable: Parameter = self.add_parameter( + self.enable: Parameter[str, Self] = self.add_parameter( "enable", label=f"Measurement {meas_nr} enable", set_cmd=f"MEASurement{meas_nr}:ENABle {{}}", @@ -374,7 +374,7 @@ def __init__( ) """Switches the measurement on or off.""" - self.source: Parameter = self.add_parameter( + self.source: Parameter[str, Self] = self.add_parameter( "source", label=f"Measurement {meas_nr} source", set_cmd=f"MEASurement{meas_nr}:SOURce {{}}", @@ -384,7 +384,7 @@ def __init__( ) """Set the source of a measurement if the measurement only needs one source.""" - self.source_first: Parameter = self.add_parameter( + self.source_first: Parameter[str, Self] = self.add_parameter( "source_first", label=f"Measurement {meas_nr} first source", set_cmd=f"MEASurement{meas_nr}:FSRC {{}}", @@ -395,7 +395,7 @@ def __init__( ) """Set the first source of a measurement if the measurement only needs multiple sources.""" - self.source_second: Parameter = self.add_parameter( + self.source_second: Parameter[str, Self] = self.add_parameter( "source_second", label=f"Measurement {meas_nr} second source", set_cmd=f"MEASurement{meas_nr}:SSRC {{}}", @@ -406,7 +406,7 @@ def __init__( ) """Set the second source of a measurement if the measurement only needs multiple sources.""" - self.category: Parameter = self.add_parameter( + self.category: Parameter[str, Self] = self.add_parameter( "category", label=f"Measurement {meas_nr} category", set_cmd=f"MEASurement{meas_nr}:CATegory {{}}", @@ -415,7 +415,7 @@ def __init__( ) """Set the category of a measurement.""" - self.main: Parameter = self.add_parameter( + self.main: Parameter[str, Self] = self.add_parameter( "main", label=f"Measurement {meas_nr} main", set_cmd=f"MEASurement{meas_nr}:MAIN {{}}", @@ -424,7 +424,7 @@ def __init__( ) """Set the main of a measurement.""" - self.statistics_enable: Parameter = self.add_parameter( + self.statistics_enable: Parameter[str, Self] = self.add_parameter( "statistics_enable", label=f"Measurement {meas_nr} enable statistics", set_cmd=f"MEASurement{meas_nr}:STATistics:ENABle {{}}", @@ -441,7 +441,7 @@ def __init__( ) """Clears/reset measurement.""" - self.event_count: Parameter = self.add_parameter( + self.event_count: Parameter[int, Self] = self.add_parameter( "event_count", label=f"Measurement {meas_nr} number of events", get_cmd=f"MEASurement{meas_nr}:RESult:EVTCount?", @@ -450,7 +450,7 @@ def __init__( ) """Number of measurement results in the long-term measurement.""" - self.result_avg: Parameter = self.add_parameter( + self.result_avg: Parameter[float, Self] = self.add_parameter( "result_avg", label=f"Measurement {meas_nr} averages", get_cmd=f"MEASurement{meas_nr}:RESult:AVG?", @@ -495,7 +495,7 @@ def __init__( super().__init__(parent, name, **kwargs) - self.state: Parameter = self.add_parameter( + self.state: Parameter[str, Self] = self.add_parameter( "state", label=f"Channel {channum} state", get_cmd=f"CHANnel{channum}:STATe?", @@ -505,7 +505,7 @@ def __init__( ) """Switches the channel on or off""" - self.coupling: Parameter = self.add_parameter( + self.coupling: Parameter[str, Self] = self.add_parameter( "coupling", label=f"Channel {channum} coupling", get_cmd=f"CHANnel{channum}:COUPling?", @@ -522,7 +522,7 @@ def __init__( DC: 50 Ohm, DCLimit 1 MOhm, AC: Con. through DC capacitor """ - self.ground: Parameter = self.add_parameter( + self.ground: Parameter[str, Self] = self.add_parameter( "ground", label=f"Channel {channum} ground", get_cmd=f"CHANnel{channum}:GND?", @@ -534,7 +534,7 @@ def __init__( # NB (WilliamHPNielsen): This parameter depends on other parameters and # should be dynamically updated accordingly. Cf. p 1178 of the manual - self.scale: Parameter = self.add_parameter( + self.scale: Parameter[float, Self] = self.add_parameter( "scale", label=f"Channel {channum} Y scale", unit="V/div", @@ -544,7 +544,7 @@ def __init__( ) """Parameter scale""" - self.range: Parameter = self.add_parameter( + self.range: Parameter[float, Self] = self.add_parameter( "range", label=f"Channel {channum} Y range", unit="V", @@ -556,7 +556,7 @@ def __init__( # TODO (WilliamHPNielsen): would it be better to recast this in terms # of Volts? - self.position: Parameter = self.add_parameter( + self.position: Parameter[float, Self] = self.add_parameter( "position", label=f"Channel {channum} vert. pos.", unit="div", @@ -570,7 +570,7 @@ def __init__( ) """Positive values move the waveform up, negative values move it down.""" - self.offset: Parameter = self.add_parameter( + self.offset: Parameter[float, Self] = self.add_parameter( "offset", label=f"Channel {channum} offset", unit="V", @@ -580,7 +580,7 @@ def __init__( ) """Parameter offset""" - self.invert: Parameter = self.add_parameter( + self.invert: Parameter[str, Self] = self.add_parameter( "invert", label=f"Channel {channum} inverted", get_cmd=f"CHANnel{channum}:INVert?", @@ -591,7 +591,7 @@ def __init__( # TODO (WilliamHPNielsen): This parameter should be dynamically # validated since 800 MHz BW is only available for 50 Ohm coupling - self.bandwidth: Parameter = self.add_parameter( + self.bandwidth: Parameter[str, Self] = self.add_parameter( "bandwidth", label=f"Channel {channum} bandwidth", get_cmd=f"CHANnel{channum}:BANDwidth?", @@ -600,12 +600,13 @@ def __init__( ) """Parameter bandwidth""" - self.impedance: Parameter = self.add_parameter( + self.impedance: Parameter[float, Self] = self.add_parameter( "impedance", label=f"Channel {channum} impedance", unit="Ohm", get_cmd=f"CHANnel{channum}:IMPedance?", set_cmd=f"CHANnel{channum}:IMPedance {{}}", + get_parser=float, vals=vals.Ints(1, 100000), docstring=( "Sets the impedance of the channel " @@ -615,14 +616,14 @@ def __init__( ) """Sets the impedance of the channel for power calculations and measurements.""" - self.overload: Parameter = self.add_parameter( + self.overload: Parameter[str, Self] = self.add_parameter( "overload", label=f"Channel {channum} overload", get_cmd=f"CHANnel{channum}:OVERload?", ) """Parameter overload""" - self.arithmetics: Parameter = self.add_parameter( + self.arithmetics: Parameter[str, Self] = self.add_parameter( "arithmetics", label=f"Channel {channum} arithmetics", set_cmd=f"CHANnel{channum}:ARIThmetics {{}}", @@ -726,7 +727,7 @@ def __init__( self._horisontal_divs = int(self.ask("TIMebase:DIVisions?")) - self.display: Parameter = self.add_parameter( + self.display: Parameter[str, Self] = self.add_parameter( "display", label="Display state", set_cmd="SYSTem:DISPlay:UPDate {}", @@ -736,7 +737,7 @@ def __init__( # Triggering - self.trigger_display: Parameter = self.add_parameter( + self.trigger_display: Parameter[str, Self] = self.add_parameter( "trigger_display", label="Trigger display state", set_cmd="DISPlay:TRIGger:LINes {}", @@ -749,7 +750,7 @@ def __init__( # settings than implemented here. See p. 1261 of the manual # here we just use trigger1, which is the A-trigger - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( "trigger_source", label="Trigger source", set_cmd="TRIGger1:SOURce {}", @@ -764,11 +765,11 @@ def __init__( ) """Parameter trigger_source""" - self.trigger_mode: Parameter = self.add_parameter( + self.trigger_mode: Parameter[str, Self] = self.add_parameter( "trigger_mode", label="Trigger mode", set_cmd="TRIGger:MODE {}", - get_cmd="TRIGger1:SOURce?", + get_cmd="TRIGger:MODE?", vals=vals.Enum("AUTO", "NORMAL", "FREERUN"), docstring="Sets the trigger mode which determines" " the behaviour of the instrument if no" @@ -779,7 +780,7 @@ def __init__( """Sets the trigger mode which determines the behaviour of the instrument if no trigger occurs. Options: AUTO, NORMAL, FREERUN.""" - self.trigger_type: Parameter = self.add_parameter( + self.trigger_type: Parameter[str, Self] = self.add_parameter( "trigger_type", label="Trigger type", set_cmd="TRIGger1:TYPE {}", @@ -806,7 +807,7 @@ def __init__( """Parameter trigger_type""" # See manual p. 1262 for an explanation of trigger types - self.trigger_level: Parameter = self.add_parameter( + self.trigger_level: Parameter[float, Self] = self.add_parameter( "trigger_level", label="Trigger level", set_cmd=self._set_trigger_level, @@ -814,7 +815,7 @@ def __init__( ) """Parameter trigger_level""" - self.trigger_edge_slope: Parameter = self.add_parameter( + self.trigger_edge_slope: Parameter[str, Self] = self.add_parameter( "trigger_edge_slope", label="Edge trigger slope", set_cmd="TRIGger1:EDGE:SLOPe {}", @@ -825,7 +826,7 @@ def __init__( # Horizontal settings - self.timebase_scale: Parameter = self.add_parameter( + self.timebase_scale: Parameter[float, Self] = self.add_parameter( "timebase_scale", label="Timebase scale", set_cmd=self._set_timebase_scale, @@ -836,7 +837,7 @@ def __init__( ) """Parameter timebase_scale""" - self.timebase_range: Parameter = self.add_parameter( + self.timebase_range: Parameter[float, Self] = self.add_parameter( "timebase_range", label="Timebase range", set_cmd=self._set_timebase_range, @@ -847,7 +848,7 @@ def __init__( ) """Parameter timebase_range""" - self.timebase_position: Parameter = self.add_parameter( + self.timebase_position: Parameter[float, Self] = self.add_parameter( "timebase_position", label="Horizontal position", set_cmd=self._set_timebase_position, @@ -873,7 +874,7 @@ def __init__( self.run_mode("RUN CONT") - self.num_acquisitions: Parameter = self.add_parameter( + self.num_acquisitions: Parameter[int, Self] = self.add_parameter( "num_acquisitions", label="Number of single acquisitions to perform", get_cmd="ACQuire:COUNt?", @@ -883,7 +884,7 @@ def __init__( ) """Parameter num_acquisitions""" - self.completed_acquisitions: Parameter = self.add_parameter( + self.completed_acquisitions: Parameter[int, Self] = self.add_parameter( "completed_acquisitions", label="Number of completed acquisitions", get_cmd="ACQuire:CURRent?", @@ -891,7 +892,7 @@ def __init__( ) """Parameter completed_acquisitions""" - self.sampling_rate: Parameter = self.add_parameter( + self.sampling_rate: Parameter[int, Self] = self.add_parameter( "sampling_rate", label="Sample rate", docstring="Number of averages for measuring trace.", @@ -901,7 +902,7 @@ def __init__( ) """Number of averages for measuring trace.""" - self.acquisition_sample_rate: Parameter = self.add_parameter( + self.acquisition_sample_rate: Parameter[float, Self] = self.add_parameter( "acquisition_sample_rate", label="Acquisition sample rate", unit="Sa/s", @@ -915,7 +916,7 @@ def __init__( # Data - self.dataformat: Parameter = self.add_parameter( + self.dataformat: Parameter[str, Self] = self.add_parameter( "dataformat", label="Export data format", set_cmd="FORMat:DATA {}", @@ -927,7 +928,7 @@ def __init__( # High definition mode (might not be available on all instruments) if HD: - self.high_definition_state: Parameter = self.add_parameter( + self.high_definition_state: Parameter[bool, Self] = self.add_parameter( "high_definition_state", label="High definition (16 bit) state", set_cmd=self._set_hd_mode, @@ -948,7 +949,7 @@ def __init__( Warning/Bug: By opening the HD acquisition menu on the scope, this value will be set to "ON".""" - self.high_definition_bandwidth: Parameter = self.add_parameter( + self.high_definition_bandwidth: Parameter[float, Self] = self.add_parameter( "high_definition_bandwidth", label="High definition mode bandwidth", set_cmd="HDEFinition:BWIDth {}", @@ -959,7 +960,7 @@ def __init__( ) """Parameter high_definition_bandwidth""" - self.error_count: Parameter = self.add_parameter( + self.error_count: Parameter[int, Self] = self.add_parameter( "error_count", label="Number of errors in the error stack", get_cmd="SYSTem:ERRor:COUNt?", @@ -968,7 +969,7 @@ def __init__( ) """Parameter error_count""" - self.error_next: Parameter = self.add_parameter( + self.error_next: Parameter[str, Self] = self.add_parameter( "error_next", label="Next error from the error stack", get_cmd="SYSTem:ERRor:NEXT?", @@ -1005,11 +1006,13 @@ def __init__( self.add_function("stop", call_cmd="STOP") self.add_function("reset", call_cmd="*RST") - self.opc: Parameter = self.add_parameter("opc", get_cmd="*OPC?") + self.opc: Parameter[str, Self] = self.add_parameter("opc", get_cmd="*OPC?") """Parameter opc""" - self.stop_opc: Parameter = self.add_parameter("stop_opc", get_cmd="STOP;*OPC?") + self.stop_opc: Parameter[str, Self] = self.add_parameter( + "stop_opc", get_cmd="STOP;*OPC?" + ) """Parameter stop_opc""" - self.status_operation: Parameter = self.add_parameter( + self.status_operation: Parameter[int, Self] = self.add_parameter( "status_operation", get_cmd="STATus:OPERation:CONDition?", get_parser=int ) """Parameter status_operation""" diff --git a/src/qcodes/instrument_drivers/rohde_schwarz/SGS100A.py b/src/qcodes/instrument_drivers/rohde_schwarz/SGS100A.py index 6e5288ee7be6..55c2da724d03 100644 --- a/src/qcodes/instrument_drivers/rohde_schwarz/SGS100A.py +++ b/src/qcodes/instrument_drivers/rohde_schwarz/SGS100A.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self import qcodes.validators as vals from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs @@ -42,7 +42,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", label="Frequency", unit="Hz", @@ -52,7 +52,7 @@ def __init__( vals=vals.Numbers(1e6, 20e9), ) """Parameter frequency""" - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( name="phase", label="Phase", unit="deg", @@ -62,7 +62,7 @@ def __init__( vals=vals.Numbers(0, 360), ) """Parameter phase""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( name="power", label="Power", unit="dBm", @@ -72,7 +72,7 @@ def __init__( vals=vals.Numbers(-120, 25), ) """Parameter power""" - self.status: Parameter = self.add_parameter( + self.status: Parameter[bool, Self] = self.add_parameter( "status", label="RF Output", get_cmd=":OUTP:STAT?", @@ -80,7 +80,7 @@ def __init__( val_mapping=create_on_off_val_mapping(on_val="1", off_val="0"), ) """Parameter status""" - self.IQ_state: Parameter = self.add_parameter( + self.IQ_state: Parameter[bool, Self] = self.add_parameter( "IQ_state", label="IQ Modulation", get_cmd=":IQ:STAT?", @@ -88,7 +88,7 @@ def __init__( val_mapping=create_on_off_val_mapping(on_val="1", off_val="0"), ) """Parameter IQ_state""" - self.pulsemod_state: Parameter = self.add_parameter( + self.pulsemod_state: Parameter[bool, Self] = self.add_parameter( "pulsemod_state", label="Pulse Modulation", get_cmd=":SOUR:PULM:STAT?", @@ -96,7 +96,7 @@ def __init__( val_mapping=create_on_off_val_mapping(on_val="1", off_val="0"), ) """Parameter pulsemod_state""" - self.pulsemod_source: Parameter = self.add_parameter( + self.pulsemod_source: Parameter[str, Self] = self.add_parameter( "pulsemod_source", label="Pulse Modulation Source", get_cmd="SOUR:PULM:SOUR?", @@ -104,7 +104,7 @@ def __init__( vals=vals.Enum("INT", "EXT", "int", "ext"), ) """Parameter pulsemod_source""" - self.ref_osc_source: Parameter = self.add_parameter( + self.ref_osc_source: Parameter[str, Self] = self.add_parameter( "ref_osc_source", label="Reference Oscillator Source", get_cmd="SOUR:ROSC:SOUR?", @@ -113,7 +113,7 @@ def __init__( ) """Parameter ref_osc_source""" # Define LO source INT/EXT (Only with K-90 option) - self.LO_source: Parameter = self.add_parameter( + self.LO_source: Parameter[str, Self] = self.add_parameter( "LO_source", label="Local Oscillator Source", get_cmd="SOUR:LOSC:SOUR?", @@ -122,7 +122,7 @@ def __init__( ) """Parameter LO_source""" # Define output at REF/LO Output (Only with K-90 option) - self.ref_LO_out: Parameter = self.add_parameter( + self.ref_LO_out: Parameter[str, Self] = self.add_parameter( "ref_LO_out", label="REF/LO Output", get_cmd="CONN:REFL:OUTP?", @@ -131,7 +131,7 @@ def __init__( ) """Parameter ref_LO_out""" # Frequency mw_source outputs when used as a reference - self.ref_osc_output_freq: Parameter = self.add_parameter( + self.ref_osc_output_freq: Parameter[str, Self] = self.add_parameter( "ref_osc_output_freq", label="Reference Oscillator Output Frequency", get_cmd="SOUR:ROSC:OUTP:FREQ?", @@ -140,7 +140,7 @@ def __init__( ) """Parameter ref_osc_output_freq""" # Frequency of the external reference mw_source uses - self.ref_osc_external_freq: Parameter = self.add_parameter( + self.ref_osc_external_freq: Parameter[str, Self] = self.add_parameter( "ref_osc_external_freq", label="Reference Oscillator External Frequency", get_cmd="SOUR:ROSC:EXT:FREQ?", @@ -149,7 +149,7 @@ def __init__( ) """Parameter ref_osc_external_freq""" # IQ impairments - self.IQ_impairments: Parameter = self.add_parameter( + self.IQ_impairments: Parameter[bool, Self] = self.add_parameter( "IQ_impairments", label="IQ Impairments", get_cmd=":SOUR:IQ:IMP:STAT?", @@ -157,7 +157,7 @@ def __init__( val_mapping=create_on_off_val_mapping(on_val="1", off_val="0"), ) """Parameter IQ_impairments""" - self.I_offset: Parameter = self.add_parameter( + self.I_offset: Parameter[float, Self] = self.add_parameter( "I_offset", label="I Offset", get_cmd="SOUR:IQ:IMP:LEAK:I?", @@ -168,7 +168,7 @@ def __init__( docstring="Carrier offset for I channel in percentage of the peak envelope power.", ) """Parameter I_offset. Carrier offset for I channel in percentage of the peak envelope power.""" - self.Q_offset: Parameter = self.add_parameter( + self.Q_offset: Parameter[float, Self] = self.add_parameter( "Q_offset", label="Q Offset", get_cmd="SOUR:IQ:IMP:LEAK:Q?", @@ -179,7 +179,7 @@ def __init__( docstring="Carrier offset for Q channel in percentage of the peak envelope power.", ) """Parameter Q_offset. Carrier offset for Q channel in percentage of the peak envelope power.""" - self.IQ_gain_imbalance: Parameter = self.add_parameter( + self.IQ_gain_imbalance: Parameter[float, Self] = self.add_parameter( "IQ_gain_imbalance", label="IQ Gain Imbalance", get_cmd="SOUR:IQ:IMP:IQR?", @@ -190,7 +190,7 @@ def __init__( docstring="IQ Gain imbalance. Postive value means the Q vector is amplified more.", ) """Parameter IQ_gain_imbalance. Postive value means the Q vector is amplified more.""" - self.IQ_angle: Parameter = self.add_parameter( + self.IQ_angle: Parameter[float, Self] = self.add_parameter( "IQ_angle", label="IQ Angle Offset", get_cmd="SOUR:IQ:IMP:QUAD?", @@ -201,7 +201,7 @@ def __init__( ) """Parameter IQ_angle""" # Determines the signal at the input/output of the multi purpose [TRIG] connector. - self.trigger_connector_mode: Parameter = self.add_parameter( + self.trigger_connector_mode: Parameter[str, Self] = self.add_parameter( "trigger_connector_mode", label="Trigger Connector Mode", get_cmd="CONN:TRIG:OMOD?", @@ -221,7 +221,7 @@ def __init__( ) """Parameter trigger_connector_mode""" # Pulse modulator - self.pulsemod_delay: Parameter = self.add_parameter( + self.pulsemod_delay: Parameter[float, Self] = self.add_parameter( "pulsemod_delay", label="Pulse delay", unit="s", @@ -231,7 +231,7 @@ def __init__( vals=vals.Numbers(0, 100), ) """Parameter pulsemod_delay""" - self.pulsemod_double_delay: Parameter = self.add_parameter( + self.pulsemod_double_delay: Parameter[float, Self] = self.add_parameter( "pulsemod_double_delay", label="Pulse double delay", unit="s", @@ -241,7 +241,7 @@ def __init__( vals=vals.Numbers(40e-9, 100), ) """Parameter pulsemod_double_delay""" - self.pulsemod_double_width: Parameter = self.add_parameter( + self.pulsemod_double_width: Parameter[float, Self] = self.add_parameter( "pulsemod_double_width", label="Double pulse second width", unit="s", @@ -251,7 +251,7 @@ def __init__( vals=vals.Numbers(20e-9, 100), ) """Parameter pulsemod_double_width""" - self.pulsemod_mode: Parameter = self.add_parameter( + self.pulsemod_mode: Parameter[str, Self] = self.add_parameter( "pulsemod_mode", label="Pulse modulation mode", get_cmd="SOUR:PULM:MODE?", @@ -259,7 +259,7 @@ def __init__( vals=vals.Enum("SING", "DOUB", "sing", "doub", "single", "double"), ) """Parameter pulsemod_mode""" - self.pulsemod_period: Parameter = self.add_parameter( + self.pulsemod_period: Parameter[float, Self] = self.add_parameter( "pulsemod_period", label="Pulse mode period", unit="s", @@ -269,7 +269,7 @@ def __init__( vals=vals.Numbers(100e-9, 100), ) """Parameter pulsemod_period""" - self.pulsemod_polarity: Parameter = self.add_parameter( + self.pulsemod_polarity: Parameter[str, Self] = self.add_parameter( "pulsemod_polarity", label="Pulse modulator signal polarity", get_cmd="SOUR:PULM:POL?", @@ -277,7 +277,7 @@ def __init__( vals=vals.Enum("NORM", "INV", "norm", "inv", "normal", "inverted"), ) """Parameter pulsemod_polarity""" - self.pulsemod_trig_ext_gate_polarity: Parameter = self.add_parameter( + self.pulsemod_trig_ext_gate_polarity: Parameter[str, Self] = self.add_parameter( "pulsemod_trig_ext_gate_polarity", label="Polarity of the Gate signal", get_cmd="SOUR:PULM:TRIG:EXT:GATE:POL?", @@ -285,7 +285,7 @@ def __init__( vals=vals.Enum("NORM", "INV", "norm", "inv", "normal", "inverted"), ) """Parameter pulsemod_trig_ext_gate_polarity""" - self.pulsemod_trig_ext_impedance: Parameter = self.add_parameter( + self.pulsemod_trig_ext_impedance: Parameter[str, Self] = self.add_parameter( "pulsemod_trig_ext_impedance", label="Impedance of the external pulse trigger", get_cmd="SOUR:PULM:TRIG:EXT:IMP?", @@ -294,7 +294,7 @@ def __init__( ) """Parameter pulsemod_trig_ext_impedance""" # Sets the polarity of the active slope of an externally applied trigger signal. - self.pulsemod_trig_ext_slope: Parameter = self.add_parameter( + self.pulsemod_trig_ext_slope: Parameter[str, Self] = self.add_parameter( "pulsemod_trig_ext_slope", label="external pulse trigger active slope", get_cmd="SOUR:PULM:TRIG:EXT:SLOP?", @@ -302,7 +302,7 @@ def __init__( vals=vals.Enum("NEG", "POS", "neg", "pos", "negative", "positive"), ) """Parameter pulsemod_trig_ext_slope""" - self.pulsemod_trig_mode: Parameter = self.add_parameter( + self.pulsemod_trig_mode: Parameter[str, Self] = self.add_parameter( "pulsemod_trig_mode", label="external pulse trigger active slope", get_cmd="SOUR:PULM:TRIG:MODE?", @@ -312,7 +312,7 @@ def __init__( ), ) """Parameter pulsemod_trig_mode""" - self.pulsemod_width: Parameter = self.add_parameter( + self.pulsemod_width: Parameter[float, Self] = self.add_parameter( "pulsemod_width", label="Pulse width", unit="s", @@ -322,7 +322,7 @@ def __init__( vals=vals.Numbers(20e-9, 100), ) """Parameter pulsemod_width""" - self.operation_mode: Parameter = self.add_parameter( + self.operation_mode: Parameter[str, Self] = self.add_parameter( "operation_mode", label="Operation Mode", get_cmd=":SOUR:OPMode?", @@ -339,7 +339,7 @@ def __init__( self.connect_message() def on(self) -> None: - self.status("on") + self.status(True) def off(self) -> None: - self.status("off") + self.status(False) diff --git a/src/qcodes/instrument_drivers/rohde_schwarz/ZNB.py b/src/qcodes/instrument_drivers/rohde_schwarz/ZNB.py index d9c1033f49d3..82b820888b45 100644 --- a/src/qcodes/instrument_drivers/rohde_schwarz/ZNB.py +++ b/src/qcodes/instrument_drivers/rohde_schwarz/ZNB.py @@ -1,6 +1,6 @@ import logging from functools import partial -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np import numpy.typing as npt @@ -47,7 +47,7 @@ def __init__( name: str, instrument: "RohdeSchwarzZNBChannel", npts: int, - bandwidth: int, + bandwidth: float, **kwargs: Any, ) -> None: super().__init__( @@ -70,7 +70,7 @@ def __init__( ) self.set_cw_sweep(npts, bandwidth) - def set_cw_sweep(self, npts: int, bandwidth: int) -> None: + def set_cw_sweep(self, npts: int, bandwidth: float) -> None: """ Updates config of the software parameter on sweep change. This is needed in order to sync the setpoint shape with the returned data @@ -487,14 +487,14 @@ def __init__( self._max_source_power: float self._max_source_power = self._model_max_source_power[model] - self.vna_parameter: Parameter = self.add_parameter( + self.vna_parameter: Parameter[str, Self] = self.add_parameter( name="vna_parameter", label="VNA parameter", get_cmd=f"CALC{self._instrument_channel}:PAR:MEAS? '{self._tracename}'", get_parser=self._strip, ) """Parameter vna_parameter""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( name="power", label="Power", unit="dBm", @@ -504,13 +504,14 @@ def __init__( vals=vals.Numbers(self._min_source_power, self._max_source_power), ) """Parameter power""" - self.bandwidth: Parameter = self.add_parameter( + self.bandwidth: Parameter[float, Self] = self.add_parameter( name="bandwidth", label="Bandwidth", unit="Hz", get_cmd=f"SENS{n}:BAND?", set_cmd=self._set_bandwidth, - get_parser=int, + # The instrument returns e.g. 1.5 for a bandwidth of 1.5 Hz + get_parser=float, vals=vals.Enum( *np.append(10**6, np.kron([1, 1.5, 2, 3, 5, 7], 10 ** np.arange(6))) ), @@ -527,7 +528,7 @@ def __init__( There is an 'increased bandwidth option' (p. 4 of manual) that does not get taken into account here. """ - self.avg: Parameter = self.add_parameter( + self.avg: Parameter[int, Self] = self.add_parameter( name="avg", label="Averages", unit="", @@ -537,7 +538,7 @@ def __init__( vals=vals.Ints(1, 5000), ) """Parameter avg""" - self.start: Parameter = self.add_parameter( + self.start: Parameter[float, Self] = self.add_parameter( name="start", get_cmd=f"SENS{n}:FREQ:START?", set_cmd=self._set_start, @@ -545,7 +546,7 @@ def __init__( vals=vals.Numbers(self._parent._min_freq, self._parent._max_freq - 10), ) """Parameter start""" - self.stop: Parameter = self.add_parameter( + self.stop: Parameter[float, Self] = self.add_parameter( name="stop", get_cmd=f"SENS{n}:FREQ:STOP?", set_cmd=self._set_stop, @@ -553,7 +554,7 @@ def __init__( vals=vals.Numbers(self._parent._min_freq + 1, self._parent._max_freq), ) """Parameter stop""" - self.center: Parameter = self.add_parameter( + self.center: Parameter[float, Self] = self.add_parameter( name="center", get_cmd=f"SENS{n}:FREQ:CENT?", set_cmd=self._set_center, @@ -563,7 +564,7 @@ def __init__( ), ) """Parameter center""" - self.span: Parameter = self.add_parameter( + self.span: Parameter[float, Self] = self.add_parameter( name="span", get_cmd=f"SENS{n}:FREQ:SPAN?", set_cmd=self._set_span, @@ -571,21 +572,21 @@ def __init__( vals=vals.Numbers(1, self._parent._max_freq - self._parent._min_freq), ) """Parameter span""" - self.npts: Parameter = self.add_parameter( + self.npts: Parameter[int, Self] = self.add_parameter( name="npts", get_cmd=f"SENS{n}:SWE:POIN?", set_cmd=self._set_npts, get_parser=int, ) """Parameter npts""" - self.status: Parameter = self.add_parameter( + self.status: Parameter[int, Self] = self.add_parameter( name="status", get_cmd=f"CONF:CHAN{n}:MEAS?", set_cmd=f"CONF:CHAN{n}:MEAS {{}}", get_parser=int, ) """Parameter status""" - self.format: Parameter = self.add_parameter( + self.format: Parameter[str, Self] = self.add_parameter( name="format", get_cmd=partial(self._get_format, tracename=self._tracename), set_cmd=self._set_format, @@ -634,7 +635,7 @@ def __init__( parameter_class=FrequencySweep, ) """Parameter trace""" - self.electrical_delay: Parameter = self.add_parameter( + self.electrical_delay: Parameter[float, Self] = self.add_parameter( name="electrical_delay", label="Electrical delay", get_cmd=f"SENS{n}:CORR:EDEL2:TIME?", @@ -643,7 +644,7 @@ def __init__( unit="s", ) """Parameter electrical_delay""" - self.sweep_time: Parameter = self.add_parameter( + self.sweep_time: Parameter[float, Self] = self.add_parameter( name="sweep_time", label="Sweep time", get_cmd=f"SENS{n}:SWE:TIME?", @@ -651,7 +652,7 @@ def __init__( unit="s", ) """Parameter sweep_time""" - self.sweep_type: Parameter = self.add_parameter( + self.sweep_type: Parameter[str, Self] = self.add_parameter( name="sweep_type", get_cmd=f"SENS{n}:SWE:TYPE?", set_cmd=self._set_sweep_type, @@ -677,7 +678,7 @@ def __init__( Note that at the moment only the linear and CW_Point modes have supporting measurement parameters. """ - self.cw_frequency: Parameter = self.add_parameter( + self.cw_frequency: Parameter[float, Self] = self.add_parameter( name="cw_frequency", get_cmd=f"SENS{n}:FREQ:CW?", set_cmd=self._set_cw_frequency, @@ -732,7 +733,7 @@ def __init__( ) ) """Parameter point_fixed_frequency_mag_phase""" - self.averaging_enabled: Parameter = self.add_parameter( + self.averaging_enabled: Parameter[bool, Self] = self.add_parameter( name="averaging_enabled", initial_value=False, get_cmd=None, @@ -741,7 +742,7 @@ def __init__( val_mapping=create_on_off_val_mapping(on_val="ON", off_val="OFF"), ) """Parameter averaging_enabled""" - self.auto_sweep_time_enabled: Parameter = self.add_parameter( + self.auto_sweep_time_enabled: Parameter[bool, Self] = self.add_parameter( name="auto_sweep_time_enabled", initial_value=False, get_cmd=None, @@ -843,7 +844,7 @@ def _set_npts(self, val: int) -> None: else: self.update_lin_traces() - def _set_bandwidth(self, val: int) -> None: + def _set_bandwidth(self, val: float) -> None: channel = self._instrument_channel self.write(f"SENS{channel}:BAND {val:.4f}") self.update_cw_traces() @@ -1113,7 +1114,7 @@ def __init__( """Parameter num_ports""" num_ports = self.num_ports() - self.rf_power: Parameter = self.add_parameter( + self.rf_power: Parameter[bool, Self] = self.add_parameter( name="rf_power", get_cmd="OUTP1?", set_cmd="OUTP1 {}", @@ -1121,7 +1122,7 @@ def __init__( ) """Parameter rf_power""" - self.ref_osc_source: Parameter = self.add_parameter( + self.ref_osc_source: Parameter[str, Self] = self.add_parameter( name="ref_osc_source", label="Reference oscillator source", get_cmd="ROSC:SOUR?", @@ -1132,7 +1133,7 @@ def __init__( ) """Reference oscillator source""" - self.ref_osc_external_freq: Parameter = self.add_parameter( + self.ref_osc_external_freq: Parameter[float, Self] = self.add_parameter( name="ref_osc_external_freq", label="Reference oscillator frequency", docstring="Frequency of the external reference clock signal at REF IN", @@ -1146,7 +1147,7 @@ def __init__( ) """Frequency of the external reference clock signal at REF IN""" - self.ref_osc_PLL_locked: Parameter = self.add_parameter( + self.ref_osc_PLL_locked: Parameter[bool, Self] = self.add_parameter( name="ref_osc_PLL_locked", label="Reference frequency PLL lock", get_cmd=self._get_PLL_locked, diff --git a/src/qcodes/instrument_drivers/signal_hound/SignalHound_USB_SA124B.py b/src/qcodes/instrument_drivers/signal_hound/SignalHound_USB_SA124B.py index 01355f7bca32..8ee870b1e959 100644 --- a/src/qcodes/instrument_drivers/signal_hound/SignalHound_USB_SA124B.py +++ b/src/qcodes/instrument_drivers/signal_hound/SignalHound_USB_SA124B.py @@ -2,7 +2,7 @@ import logging from enum import IntEnum from time import sleep -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np import numpy.typing as npt @@ -246,7 +246,7 @@ def __init__( This is the set span, the actual span may be subject to round off compared to this value """ - self.npts: Parameter = self.add_parameter( + self.npts: Parameter[int, Self] = self.add_parameter( "npts", label="Number of Points", get_cmd=self._get_npts, @@ -254,7 +254,7 @@ def __init__( docstring="Number of points in frequency sweep.", ) """Number of points in frequency sweep.""" - self.avg: Parameter = self.add_parameter( + self.avg: Parameter[int, Self] = self.add_parameter( "avg", label="Averages", initial_value=1, @@ -301,11 +301,11 @@ def __init__( Note that Signal Hound does not support disabling external ref. To disable close the connection and restart. """ - self.device_type: Parameter = self.add_parameter( + self.device_type: Parameter[str, Self] = self.add_parameter( "device_type", set_cmd=False, get_cmd=self._get_device_type ) """Parameter device_type""" - self.device_mode: Parameter = self.add_parameter( + self.device_mode: Parameter[str, Self] = self.add_parameter( "device_mode", get_cmd=lambda: "sweeping", set_cmd=False, @@ -319,7 +319,7 @@ def __init__( It is therefor not possible to set this parameter to anything else """ - self.acquisition_mode: Parameter = self.add_parameter( + self.acquisition_mode: Parameter[str, Self] = self.add_parameter( "acquisition_mode", get_cmd=lambda: "average", set_cmd=False, @@ -383,7 +383,7 @@ def __init__( vals=vals.Bool(), ) """Apply software filter to remove undersampling mirroring""" - self.sleep_time: Parameter = self.add_parameter( + self.sleep_time: Parameter[float, Self] = self.add_parameter( "sleep_time", label="Sleep time", unit="s", @@ -405,7 +405,7 @@ def __init__( parameter_class=FrequencySweep, ) """Parameter trace""" - self.power: Parameter = self.add_parameter( + self.power: Parameter[float, Self] = self.add_parameter( "power", label="Power", unit="dBm", diff --git a/src/qcodes/instrument_drivers/stahl/stahl.py b/src/qcodes/instrument_drivers/stahl/stahl.py index 93a8afb65368..efb8c55d895f 100644 --- a/src/qcodes/instrument_drivers/stahl/stahl.py +++ b/src/qcodes/instrument_drivers/stahl/stahl.py @@ -7,7 +7,7 @@ from collections import OrderedDict from collections.abc import Callable, Iterable from functools import partial -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Self import numpy as np from pyvisa.resources.serial import SerialInstrument @@ -84,7 +84,7 @@ def __init__( _FLOATING_POINT_RE = r"[+\-]?(?:[.,]\d+|\d+(?:[.,]\d*)?)(?:[eE][-+]?\d+)?" - self.voltage: Parameter = self.add_parameter( + self.voltage: Parameter[float, Self] = self.add_parameter( "voltage", get_cmd=f"{self.parent.identifier} U{self._channel_string}", get_parser=chain( @@ -98,7 +98,7 @@ def __init__( ) """Parameter voltage""" - self.current: Parameter = self.add_parameter( + self.current: Parameter[float, Self] = self.add_parameter( "current", get_cmd=f"{self.parent.identifier} I{self._channel_string}", get_parser=chain( @@ -110,7 +110,7 @@ def __init__( ) """Parameter current""" - self.is_locked: Parameter = self.add_parameter( + self.is_locked: Parameter[bool, Self] = self.add_parameter( "is_locked", get_cmd=self._get_lock_status ) """Parameter is_locked""" @@ -220,7 +220,7 @@ def __init__( ) """ChannelList of channels""" - self.temperature: Parameter = self.add_parameter( + self.temperature: Parameter[float, Self] = self.add_parameter( "temperature", get_cmd=f"{self.identifier} TEMP", get_parser=chain(re.compile("^TEMP (.*)°C$").findall, float), diff --git a/src/qcodes/instrument_drivers/stanford_research/SG384.py b/src/qcodes/instrument_drivers/stanford_research/SG384.py index cad410d55f6a..d65181fbe4e7 100644 --- a/src/qcodes/instrument_drivers/stanford_research/SG384.py +++ b/src/qcodes/instrument_drivers/stanford_research/SG384.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes import validators as vals from qcodes.instrument import VisaInstrument, VisaInstrumentKWArgs @@ -28,7 +28,7 @@ def __init__( ): super().__init__(name, address, **kwargs) # signal synthesis commands - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", label="Frequency", unit="Hz", @@ -38,7 +38,7 @@ def __init__( vals=vals.Numbers(min_value=9.5e5, max_value=4.05e9), ) """Parameter frequency""" - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( name="phase", label="Carrier phase", unit="deg", @@ -48,7 +48,7 @@ def __init__( vals=vals.Numbers(min_value=-360, max_value=360), ) """Parameter phase""" - self.amplitude_LF: Parameter = self.add_parameter( + self.amplitude_LF: Parameter[float, Self] = self.add_parameter( name="amplitude_LF", label="Power of BNC output", unit="dBm", @@ -58,7 +58,7 @@ def __init__( vals=vals.Numbers(min_value=-47, max_value=13), ) """Parameter amplitude_LF""" - self.amplitude_RF: Parameter = self.add_parameter( + self.amplitude_RF: Parameter[float, Self] = self.add_parameter( name="amplitude_RF", label="Power of type-N RF output", unit="dBm", @@ -68,7 +68,7 @@ def __init__( vals=vals.Numbers(min_value=-110, max_value=16.5), ) """Parameter amplitude_RF""" - self.amplitude_HF: Parameter = self.add_parameter( + self.amplitude_HF: Parameter[float, Self] = self.add_parameter( name="amplitude_HF", label="Power of RF doubler output", unit="dBm", @@ -78,7 +78,7 @@ def __init__( vals=vals.Numbers(min_value=-10, max_value=13), ) """Parameter amplitude_HF""" - self.amplitude_clock: Parameter = self.add_parameter( + self.amplitude_clock: Parameter[float, Self] = self.add_parameter( name="amplitude_clock", label="Rear clock output", unit="Vpp", @@ -88,7 +88,7 @@ def __init__( vals=vals.Numbers(min_value=0.4, max_value=1.00), ) """Parameter amplitude_clock""" - self.noise_mode: Parameter = self.add_parameter( + self.noise_mode: Parameter[str, Self] = self.add_parameter( name="noise_mode", label="RF PLL loop filter mode", get_cmd="NOIS?", @@ -96,7 +96,7 @@ def __init__( val_mapping={"Mode 1": 0, "Mode 2": 1}, ) """Parameter noise_mode""" - self.enable_RF: Parameter = self.add_parameter( + self.enable_RF: Parameter[str, Self] = self.add_parameter( name="enable_RF", label="Type-N RF output", get_cmd="ENBR?", @@ -104,7 +104,7 @@ def __init__( val_mapping={"OFF": 0, "ON": 1}, ) """Parameter enable_RF""" - self.enable_LF: Parameter = self.add_parameter( + self.enable_LF: Parameter[str, Self] = self.add_parameter( name="enable_LF", label="BNC output", get_cmd="ENBL?", @@ -112,7 +112,7 @@ def __init__( val_mapping={"OFF": 0, "ON": 1}, ) """Parameter enable_LF""" - self.enable_HF: Parameter = self.add_parameter( + self.enable_HF: Parameter[str, Self] = self.add_parameter( name="enable_HF", label="RF doubler output", get_cmd="ENBH?", @@ -120,7 +120,7 @@ def __init__( val_mapping={"OFF": 0, "ON": 1}, ) """Parameter enable_HF""" - self.enable_clock: Parameter = self.add_parameter( + self.enable_clock: Parameter[str, Self] = self.add_parameter( name="enable_clock", label="Rear clock output", get_cmd="ENBC?", @@ -128,7 +128,7 @@ def __init__( val_mapping={"OFF": 0, "ON": 1}, ) """Parameter enable_clock""" - self.offset_clock: Parameter = self.add_parameter( + self.offset_clock: Parameter[float, Self] = self.add_parameter( name="offset_clock", label="Rear clock offset voltage", unit="V", @@ -138,7 +138,7 @@ def __init__( vals=vals.Numbers(min_value=-2, max_value=2), ) """Parameter offset_clock""" - self.offset_rearDC: Parameter = self.add_parameter( + self.offset_rearDC: Parameter[float, Self] = self.add_parameter( name="offset_rearDC", label="Rear DC offset voltage", unit="V", @@ -148,7 +148,7 @@ def __init__( vals=vals.Numbers(min_value=-10, max_value=10), ) """Parameter offset_rearDC""" - self.offset_bnc: Parameter = self.add_parameter( + self.offset_bnc: Parameter[float, Self] = self.add_parameter( name="offset_bnc", label="Low frequency BNC output", unit="V", @@ -159,7 +159,7 @@ def __init__( ) """Parameter offset_bnc""" # Modulation commands - self.modulation_coupling: Parameter = self.add_parameter( + self.modulation_coupling: Parameter[str, Self] = self.add_parameter( name="modulation_coupling", label="External modulation input coupling", get_cmd="COUP?", @@ -167,7 +167,7 @@ def __init__( val_mapping={"AC": 0, "DC": 1}, ) """Parameter modulation_coupling""" - self.FM_deviation: Parameter = self.add_parameter( + self.FM_deviation: Parameter[float, Self] = self.add_parameter( name="FM_deviation", label="Frequency modulation deviation", unit="Hz", @@ -177,7 +177,7 @@ def __init__( vals=vals.Numbers(min_value=0.1, max_value=32e6), ) """Parameter FM_deviation""" - self.modulation_function: Parameter = self.add_parameter( + self.modulation_function: Parameter[str, Self] = self.add_parameter( name="modulation_function", label="Modulation function for AM/FM/PhiM", get_cmd="MFNC?", @@ -192,14 +192,14 @@ def __init__( }, ) """Parameter modulation_function""" - self.enable_modulation: Parameter = self.add_parameter( + self.enable_modulation: Parameter[str, Self] = self.add_parameter( name="enable_modulation", get_cmd="MODL?", set_cmd="MODL {}", val_mapping={"OFF": 0, "ON": 1}, ) """Parameter enable_modulation""" - self.modulation_rate: Parameter = self.add_parameter( + self.modulation_rate: Parameter[float, Self] = self.add_parameter( name="modulation_rate", get_cmd="RATE?", set_cmd="RATE {:.6f}", @@ -207,7 +207,7 @@ def __init__( vals=vals.Numbers(min_value=1e-6, max_value=50e3), ) """Parameter modulation_rate""" - self.modulation_type: Parameter = self.add_parameter( + self.modulation_type: Parameter[str, Self] = self.add_parameter( name="modulation_type", label="Current modulation type", get_cmd="TYPE?", diff --git a/src/qcodes/instrument_drivers/stanford_research/SR560.py b/src/qcodes/instrument_drivers/stanford_research/SR560.py index 78c7b6d09f26..57f9cea85174 100644 --- a/src/qcodes/instrument_drivers/stanford_research/SR560.py +++ b/src/qcodes/instrument_drivers/stanford_research/SR560.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Self from qcodes.instrument import Instrument, InstrumentBaseKWArgs from qcodes.parameters import MultiParameter, Parameter, ParamRawDataType @@ -148,7 +148,7 @@ def __init__(self, name: str, **kwargs: "Unpack[InstrumentBaseKWArgs]"): ) """Parameter cutoff_hi""" - self.invert: Parameter = self.add_parameter( + self.invert: Parameter[bool, Self] = self.add_parameter( "invert", get_cmd=None, set_cmd=None, diff --git a/src/qcodes/instrument_drivers/stanford_research/SR830.py b/src/qcodes/instrument_drivers/stanford_research/SR830.py index 74c232717b78..fb8b5c7fbe74 100644 --- a/src/qcodes/instrument_drivers/stanford_research/SR830.py +++ b/src/qcodes/instrument_drivers/stanford_research/SR830.py @@ -2,7 +2,7 @@ import time from functools import partial -from typing import TYPE_CHECKING, Any, ClassVar +from typing import TYPE_CHECKING, Any, ClassVar, Self import numpy as np @@ -286,7 +286,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg super().__init__(name, address, **kwargs) # Reference and phase - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( "phase", label="Phase", get_cmd="PHAS?", @@ -297,7 +297,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter phase""" - self.reference_source: Parameter = self.add_parameter( + self.reference_source: Parameter[str, Self] = self.add_parameter( "reference_source", label="Reference source", get_cmd="FMOD?", @@ -310,7 +310,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter reference_source""" - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( "frequency", label="Frequency", get_cmd="FREQ?", @@ -321,7 +321,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter frequency""" - self.ext_trigger: Parameter = self.add_parameter( + self.ext_trigger: Parameter[str, Self] = self.add_parameter( "ext_trigger", label="External trigger", get_cmd="RSLP?", @@ -334,7 +334,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter ext_trigger""" - self.harmonic: Parameter = self.add_parameter( + self.harmonic: Parameter[int, Self] = self.add_parameter( "harmonic", label="Harmonic", get_cmd="HARM?", @@ -344,7 +344,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter harmonic""" - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( "amplitude", label="Amplitude", get_cmd="SLVL?", @@ -356,7 +356,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg """Parameter amplitude""" # Input and filter - self.input_config: Parameter = self.add_parameter( + self.input_config: Parameter[str, Self] = self.add_parameter( "input_config", label="Input configuration", get_cmd="ISRC?", @@ -367,7 +367,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter input_config""" - self.input_shield: Parameter = self.add_parameter( + self.input_shield: Parameter[str, Self] = self.add_parameter( "input_shield", label="Input shield", get_cmd="IGND?", @@ -379,7 +379,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter input_shield""" - self.input_coupling: Parameter = self.add_parameter( + self.input_coupling: Parameter[str, Self] = self.add_parameter( "input_coupling", label="Input coupling", get_cmd="ICPL?", @@ -391,7 +391,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter input_coupling""" - self.notch_filter: Parameter = self.add_parameter( + self.notch_filter: Parameter[str, Self] = self.add_parameter( "notch_filter", label="Notch filter", get_cmd="ILIN?", @@ -406,7 +406,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg """Parameter notch_filter""" # Gain and time constant - self.sensitivity: Parameter = self.add_parameter( + self.sensitivity: Parameter[float, Self] = self.add_parameter( name="sensitivity", label="Sensitivity", get_cmd="SENS?", @@ -416,7 +416,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter sensitivity""" - self.reserve: Parameter = self.add_parameter( + self.reserve: Parameter[str, Self] = self.add_parameter( "reserve", label="Reserve", get_cmd="RMOD?", @@ -460,7 +460,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter time_constant""" - self.filter_slope: Parameter = self.add_parameter( + self.filter_slope: Parameter[int, Self] = self.add_parameter( "filter_slope", label="Filter slope", get_cmd="OFSL?", @@ -475,7 +475,7 @@ def __init__(self, name: str, address: str, **kwargs: Unpack[VisaInstrumentKWArg ) """Parameter filter_slope""" - self.sync_filter: Parameter = self.add_parameter( + self.sync_filter: Parameter[str, Self] = self.add_parameter( "sync_filter", label="Sync filter", get_cmd="SYNC?", @@ -494,17 +494,17 @@ def parse_offset_get(s: str) -> tuple[float, int]: # TODO: Parameters that can be set with multiple arguments # For the OEXP command for example two arguments are needed - self.X_offset: Parameter = self.add_parameter( + self.X_offset: Parameter[tuple[float, int], Self] = self.add_parameter( "X_offset", get_cmd="OEXP? 1", get_parser=parse_offset_get ) """Parameter X_offset""" - self.Y_offset: Parameter = self.add_parameter( + self.Y_offset: Parameter[tuple[float, int], Self] = self.add_parameter( "Y_offset", get_cmd="OEXP? 2", get_parser=parse_offset_get ) """Parameter Y_offset""" - self.R_offset: Parameter = self.add_parameter( + self.R_offset: Parameter[tuple[float, int], Self] = self.add_parameter( "R_offset", get_cmd="OEXP? 3", get_parser=parse_offset_get ) """Parameter R_offset""" @@ -529,7 +529,7 @@ def parse_offset_get(s: str) -> tuple[float, int]: ) # Setup - self.output_interface: Parameter = self.add_parameter( + self.output_interface: Parameter[str, Self] = self.add_parameter( "output_interface", label="Output interface", get_cmd="OUTX?", @@ -542,22 +542,22 @@ def parse_offset_get(s: str) -> tuple[float, int]: """Parameter output_interface""" # Data transfer - self.X: Parameter = self.add_parameter( + self.X: Parameter[float, Self] = self.add_parameter( "X", get_cmd="OUTP? 1", get_parser=float, unit="V" ) """Parameter X""" - self.Y: Parameter = self.add_parameter( + self.Y: Parameter[float, Self] = self.add_parameter( "Y", get_cmd="OUTP? 2", get_parser=float, unit="V" ) """Parameter Y""" - self.R: Parameter = self.add_parameter( + self.R: Parameter[float, Self] = self.add_parameter( "R", get_cmd="OUTP? 3", get_parser=float, unit="V" ) """Parameter R""" - self.P: Parameter = self.add_parameter( + self.P: Parameter[float, Self] = self.add_parameter( "P", get_cmd="OUTP? 4", get_parser=float, unit="deg" ) """Parameter P""" @@ -602,7 +602,7 @@ def parse_offset_get(s: str) -> tuple[float, int]: ) """Parameter buffer_SR""" - self.buffer_acq_mode: Parameter = self.add_parameter( + self.buffer_acq_mode: Parameter[str, Self] = self.add_parameter( "buffer_acq_mode", label="Buffer acquistion mode", get_cmd="SEND ?", @@ -612,7 +612,7 @@ def parse_offset_get(s: str) -> tuple[float, int]: ) """Parameter buffer_acq_mode""" - self.buffer_trig_mode: Parameter = self.add_parameter( + self.buffer_trig_mode: Parameter[str, Self] = self.add_parameter( "buffer_trig_mode", label="Buffer trigger start mode", get_cmd="TSTR ?", @@ -622,7 +622,7 @@ def parse_offset_get(s: str) -> tuple[float, int]: ) """Parameter buffer_trig_mode""" - self.buffer_npts: Parameter = self.add_parameter( + self.buffer_npts: Parameter[int, Self] = self.add_parameter( "buffer_npts", label="Buffer number of stored points", get_cmd="SPTS ?", diff --git a/src/qcodes/instrument_drivers/stanford_research/SR86x.py b/src/qcodes/instrument_drivers/stanford_research/SR86x.py index 569f272bc0fb..d2bec07c386f 100644 --- a/src/qcodes/instrument_drivers/stanford_research/SR86x.py +++ b/src/qcodes/instrument_drivers/stanford_research/SR86x.py @@ -1,7 +1,7 @@ from __future__ import annotations import logging -from typing import TYPE_CHECKING, Any, ClassVar +from typing import TYPE_CHECKING, Any, ClassVar, Self import numpy as np import numpy.typing as npt @@ -103,7 +103,7 @@ def __init__( ) -> None: super().__init__(parent, name, **kwargs) - self.capture_length_in_kb: Parameter = self.add_parameter( + self.capture_length_in_kb: Parameter[int, Self] = self.add_parameter( "capture_length_in_kb", label="get/set capture length", get_cmd="CAPTURELEN?", @@ -119,7 +119,7 @@ def __init__( # Maximum amount of kB that can be read per single CAPTUREGET command self.max_size_per_reading_in_kb = 64 - self.capture_config: Parameter = self.add_parameter( + self.capture_config: Parameter[str, Self] = self.add_parameter( "capture_config", label="capture configuration", get_cmd="CAPTURECFG?", @@ -128,7 +128,7 @@ def __init__( ) """Parameter capture_config configures which parameters we want to capture""" - self.capture_rate_max: Parameter = self.add_parameter( + self.capture_rate_max: Parameter[float, Self] = self.add_parameter( "capture_rate_max", label="capture rate maximum", get_cmd="CAPTURERATEMAX?", @@ -136,7 +136,7 @@ def __init__( ) """Parameter capture_rate_max""" - self.capture_rate: Parameter = self.add_parameter( + self.capture_rate: Parameter[float, Self] = self.add_parameter( "capture_rate", label="capture rate raw", get_cmd="CAPTURERATE?", @@ -149,12 +149,12 @@ def __init__( max_rate = self.capture_rate_max() self.available_frequencies = [max_rate / 2**i for i in range(20)] - self.capture_status: Parameter = self.add_parameter( + self.capture_status: Parameter[str, Self] = self.add_parameter( "capture_status", label="capture status", get_cmd="CAPTURESTAT?" ) """Parameter capture_status: Are we capturing at the moment?""" - self.count_capture_bytes: Parameter = self.add_parameter( + self.count_capture_bytes: Parameter[int, Self] = self.add_parameter( "count_capture_bytes", label="captured bytes", get_cmd="CAPTUREBYTES?", @@ -165,10 +165,11 @@ def __init__( ) """Number of bytes captured so far in the buffer. Can be used to track live progress.""" - self.count_capture_kilobytes: Parameter = self.add_parameter( + self.count_capture_kilobytes: Parameter[int, Self] = self.add_parameter( "count_capture_kilobytes", label="captured kilobytes", get_cmd="CAPTUREPROG?", + get_parser=int, unit="kB", docstring="Number of kilobytes captured so far in the buffer, " "rounded-up to 2 kilobyte chunks. Capture must be " @@ -661,7 +662,7 @@ def __init__( self._cmd_id_name = cmd_id_name self._color = color - self.assigned_parameter: Parameter = self.add_parameter( + self.assigned_parameter: Parameter[str, Self] = self.add_parameter( "assigned_parameter", label=f"Data channel {cmd_id} parameter", docstring=f"Allows to set and get the " @@ -802,7 +803,7 @@ def __init__( super().__init__(name, address, **kwargs) self._max_frequency = max_frequency # Reference commands - self.frequency: Parameter = self.add_parameter( + self.frequency: Parameter[float, Self] = self.add_parameter( name="frequency", label="Frequency", unit="Hz", @@ -812,7 +813,7 @@ def __init__( vals=Numbers(min_value=1e-3, max_value=self._max_frequency), ) """Parameter frequency""" - self.sine_outdc: Parameter = self.add_parameter( + self.sine_outdc: Parameter[float, Self] = self.add_parameter( name="sine_outdc", label="Sine out dc level", unit="V", @@ -822,7 +823,7 @@ def __init__( vals=Numbers(min_value=-5, max_value=5), ) """Parameter sine_outdc""" - self.amplitude: Parameter = self.add_parameter( + self.amplitude: Parameter[float, Self] = self.add_parameter( name="amplitude", label="Amplitude", unit="V", @@ -832,7 +833,7 @@ def __init__( vals=Numbers(min_value=0, max_value=2), ) """Parameter amplitude""" - self.harmonic: Parameter = self.add_parameter( + self.harmonic: Parameter[int, Self] = self.add_parameter( name="harmonic", label="Harmonic", get_cmd="HARM?", @@ -841,7 +842,7 @@ def __init__( vals=Ints(min_value=1, max_value=99), ) """Parameter harmonic""" - self.phase: Parameter = self.add_parameter( + self.phase: Parameter[float, Self] = self.add_parameter( name="phase", label="Phase", unit="deg", @@ -852,7 +853,7 @@ def __init__( ) """Parameter phase""" # Signal commands - self.sensitivity: Parameter = self.add_parameter( + self.sensitivity: Parameter[float, Self] = self.add_parameter( name="sensitivity", label="Sensitivity", get_cmd="SCAL?", @@ -861,7 +862,7 @@ def __init__( set_parser=self._set_sensitivity, ) """Parameter sensitivity""" - self.filter_slope: Parameter = self.add_parameter( + self.filter_slope: Parameter[int, Self] = self.add_parameter( name="filter_slope", label="Filter slope", unit="dB/oct", @@ -870,7 +871,7 @@ def __init__( val_mapping={6: 0, 12: 1, 18: 2, 24: 3}, ) """Parameter filter_slope""" - self.sync_filter: Parameter = self.add_parameter( + self.sync_filter: Parameter[str, Self] = self.add_parameter( name="sync_filter", label="Sync filter", get_cmd="SYNC?", @@ -878,7 +879,7 @@ def __init__( val_mapping={"OFF": 0, "ON": 1}, ) """Parameter sync_filter""" - self.noise_bandwidth: Parameter = self.add_parameter( + self.noise_bandwidth: Parameter[float, Self] = self.add_parameter( name="noise_bandwidth", label="Noise bandwidth", unit="Hz", @@ -886,14 +887,14 @@ def __init__( get_parser=float, ) """Parameter noise_bandwidth""" - self.signal_strength: Parameter = self.add_parameter( + self.signal_strength: Parameter[int, Self] = self.add_parameter( name="signal_strength", label="Signal strength indicator", get_cmd="ILVL?", get_parser=int, ) """Parameter signal_strength""" - self.signal_input: Parameter = self.add_parameter( + self.signal_input: Parameter[str, Self] = self.add_parameter( name="signal_input", label="Signal input", get_cmd="IVMD?", @@ -912,7 +913,7 @@ def __init__( val_mapping={1: 0, 300e-3: 1, 100e-3: 2, 30e-3: 3, 10e-3: 4}, ) """Parameter input_range""" - self.input_config: Parameter = self.add_parameter( + self.input_config: Parameter[str, Self] = self.add_parameter( name="input_config", label="Input configuration", get_cmd="ISRC?", @@ -920,7 +921,7 @@ def __init__( val_mapping={"a": 0, "a-b": 1}, ) """Parameter input_config""" - self.input_shield: Parameter = self.add_parameter( + self.input_shield: Parameter[str, Self] = self.add_parameter( name="input_shield", label="Input shield", get_cmd="IGND?", @@ -928,7 +929,7 @@ def __init__( val_mapping={"float": 0, "ground": 1}, ) """Parameter input_shield""" - self.input_gain: Parameter = self.add_parameter( + self.input_gain: Parameter[float, Self] = self.add_parameter( name="input_gain", label="Input gain", unit="ohm", @@ -937,7 +938,7 @@ def __init__( val_mapping={1e6: 0, 100e6: 1}, ) """Parameter input_gain""" - self.adv_filter: Parameter = self.add_parameter( + self.adv_filter: Parameter[str, Self] = self.add_parameter( name="adv_filter", label="Advanced filter", get_cmd="ADVFILT?", @@ -945,7 +946,7 @@ def __init__( val_mapping={"OFF": 0, "ON": 1}, ) """Parameter adv_filter""" - self.input_coupling: Parameter = self.add_parameter( + self.input_coupling: Parameter[str, Self] = self.add_parameter( name="input_coupling", label="Input coupling", get_cmd="ICPL?", @@ -986,7 +987,7 @@ def __init__( ) """Parameter time_constant""" - self.external_reference_trigger: Parameter = self.add_parameter( + self.external_reference_trigger: Parameter[str, Self] = self.add_parameter( name="external_reference_trigger", label="External reference trigger mode", get_cmd="RTRG?", @@ -1004,7 +1005,7 @@ def __init__( ) """The triggering mode for synchronization of the internal reference signal with the externally provided one""" - self.reference_source: Parameter = self.add_parameter( + self.reference_source: Parameter[str, Self] = self.add_parameter( name="reference_source", label="Reference source", get_cmd="RSRC?", @@ -1041,7 +1042,7 @@ def __init__( # Data transfer # first 4 parameters from a list of 16 below. - self.X: Parameter = self.add_parameter( + self.X: Parameter[float, Self] = self.add_parameter( "X", label="In-phase Magnitude", get_cmd="OUTP? 0", @@ -1049,7 +1050,7 @@ def __init__( unit="V", ) """Parameter X""" - self.Y: Parameter = self.add_parameter( + self.Y: Parameter[float, Self] = self.add_parameter( "Y", label="Out-phase Magnitude", get_cmd="OUTP? 1", @@ -1057,11 +1058,11 @@ def __init__( unit="V", ) """Parameter Y""" - self.R: Parameter = self.add_parameter( + self.R: Parameter[float, Self] = self.add_parameter( "R", label="Magnitude", get_cmd="OUTP? 2", get_parser=float, unit="V" ) """Parameter R""" - self.P: Parameter = self.add_parameter( + self.P: Parameter[float, Self] = self.add_parameter( "P", label="Phase", get_cmd="OUTP? 3", get_parser=float, unit="deg" ) """Parameter P""" @@ -1076,7 +1077,7 @@ def __init__( """Parameter complex_voltage""" # CH1/CH2 Output Commands - self.X_offset: Parameter = self.add_parameter( + self.X_offset: Parameter[float, Self] = self.add_parameter( "X_offset", label="X offset ", unit="%", @@ -1086,7 +1087,7 @@ def __init__( vals=Numbers(min_value=-999.99, max_value=999.99), ) """Parameter X_offset""" - self.Y_offset: Parameter = self.add_parameter( + self.Y_offset: Parameter[float, Self] = self.add_parameter( "Y_offset", label="Y offset", unit="%", @@ -1096,7 +1097,7 @@ def __init__( vals=Numbers(min_value=-999.99, max_value=999.99), ) """Parameter Y_offset""" - self.R_offset: Parameter = self.add_parameter( + self.R_offset: Parameter[float, Self] = self.add_parameter( "R_offset", label="R offset", unit="%", @@ -1106,7 +1107,7 @@ def __init__( vals=Numbers(min_value=-999.99, max_value=999.99), ) """Parameter R_offset""" - self.X_expand: Parameter = self.add_parameter( + self.X_expand: Parameter[str, Self] = self.add_parameter( "X_expand", label="X expand multiplier", get_cmd="CEXP? 0", @@ -1114,7 +1115,7 @@ def __init__( val_mapping={"OFF": "0", "X10": "1", "X100": "2"}, ) """Parameter X_expand""" - self.Y_expand: Parameter = self.add_parameter( + self.Y_expand: Parameter[str, Self] = self.add_parameter( "Y_expand", label="Y expand multiplier", get_cmd="CEXP? 1", @@ -1122,7 +1123,7 @@ def __init__( val_mapping={"OFF": 0, "X10": 1, "X100": 2}, ) """Parameter Y_expand""" - self.R_expand: Parameter = self.add_parameter( + self.R_expand: Parameter[str, Self] = self.add_parameter( "R_expand", label="R expand multiplier", get_cmd="CEXP? 2", diff --git a/src/qcodes/instrument_drivers/tektronix/AWG5014.py b/src/qcodes/instrument_drivers/tektronix/AWG5014.py index 8e897d455183..68878fe76e68 100644 --- a/src/qcodes/instrument_drivers/tektronix/AWG5014.py +++ b/src/qcodes/instrument_drivers/tektronix/AWG5014.py @@ -14,6 +14,7 @@ ClassVar, Literal, NamedTuple, + Self, cast, ) @@ -30,6 +31,7 @@ VisaInstrument, VisaInstrumentKWArgs, ) +from qcodes.parameters import create_on_off_val_mapping from qcodes.utils.deprecate import QCoDeSDeprecationWarning if TYPE_CHECKING: @@ -84,7 +86,7 @@ def __init__( m_high_cmd = f"SOURce{channel}:MARKer{marker}:VOLTage:LEVel:IMMediate:HIGH" m_low_cmd = f"SOURce{channel}:MARKer{marker}:VOLTage:LEVel:IMMediate:LOW" - self.delay: Parameter = self.add_parameter( + self.delay: Parameter[float, Self] = self.add_parameter( "delay", label=f"Channel {channel} Marker {marker} delay", unit="ns", @@ -94,7 +96,7 @@ def __init__( get_parser=float, ) """Parameter delay""" - self.high: Parameter = self.add_parameter( + self.high: Parameter[float, Self] = self.add_parameter( "high", label=f"Channel {channel} Marker {marker} high level", unit="V", @@ -104,7 +106,7 @@ def __init__( get_parser=float, ) """Parameter high""" - self.low: Parameter = self.add_parameter( + self.low: Parameter[float, Self] = self.add_parameter( "low", label=f"Channel {channel} Marker {marker} low level", unit="V", @@ -155,16 +157,15 @@ def __init__( dc_out_cmd = f"AWGControl:DC{i}:VOLTage:OFFSet" # Set channel first to ensure sensible sorting of pars - self.state: Parameter = self.add_parameter( + self.state: Parameter[bool, Self] = self.add_parameter( "state", label=f"Status channel {i}", get_cmd=state_cmd + "?", set_cmd=state_cmd + " {}", - vals=vals.Ints(0, 1), - get_parser=int, + val_mapping=create_on_off_val_mapping(on_val=1, off_val=0), ) """Parameter state""" - self.amp: Parameter = self.add_parameter( + self.amp: Parameter[float, Self] = self.add_parameter( "amp", label=f"Amplitude channel {i}", unit="Vpp", @@ -174,7 +175,7 @@ def __init__( get_parser=float, ) """Parameter amp""" - self.offset: Parameter = self.add_parameter( + self.offset: Parameter[float, Self] = self.add_parameter( "offset", label=f"Offset channel {i}", unit="V", @@ -184,7 +185,7 @@ def __init__( get_parser=float, ) """Parameter offset""" - self.waveform: Parameter = self.add_parameter( + self.waveform: Parameter[str, Self] = self.add_parameter( "waveform", label=f"Waveform channel {i}", get_cmd=waveform_cmd + "?", @@ -193,15 +194,15 @@ def __init__( get_parser=parsestr, ) """Parameter waveform""" - self.direct_output: Parameter = self.add_parameter( + self.direct_output: Parameter[bool, Self] = self.add_parameter( "direct_output", label=f"Direct output channel {i}", get_cmd=directoutput_cmd + "?", set_cmd=directoutput_cmd + " {}", - vals=vals.Ints(0, 1), + val_mapping=create_on_off_val_mapping(on_val=1, off_val=0), ) """Parameter direct_output""" - self.add_input: Parameter = self.add_parameter( + self.add_input: Parameter[str, Self] = self.add_parameter( "add_input", label=f"Add input channel {i}", get_cmd=add_input_cmd + "?", @@ -220,7 +221,7 @@ def __init__( get_parser=self.parent._tek_outofrange_get_parser, ) """Parameter filter""" - self.DC_out: Parameter = self.add_parameter( + self.DC_out: Parameter[float, Self] = self.add_parameter( "DC_out", label=f"DC output level channel {i}", unit="V", @@ -380,9 +381,11 @@ def __init__( self.add_function("reset", call_cmd="*RST") - self.state: Parameter = self.add_parameter("state", get_cmd=self.get_state) + self.state: Parameter[str, Self] = self.add_parameter( + "state", get_cmd=self.get_state + ) """Parameter state""" - self.run_mode: Parameter = self.add_parameter( + self.run_mode: Parameter[str, Self] = self.add_parameter( "run_mode", get_cmd="AWGControl:RMODe?", set_cmd="AWGControl:RMODe " + "{}", @@ -390,7 +393,7 @@ def __init__( get_parser=self.newlinestripper, ) """Parameter run_mode""" - self.clock_source: Parameter = self.add_parameter( + self.clock_source: Parameter[str, Self] = self.add_parameter( "clock_source", label="Clock source", get_cmd="AWGControl:CLOCk:SOURce?", @@ -400,7 +403,7 @@ def __init__( ) """Parameter clock_source""" - self.ref_source: Parameter = self.add_parameter( + self.ref_source: Parameter[str, Self] = self.add_parameter( "ref_source", label="Reference source", get_cmd="SOURce1:ROSCillator:SOURce?", @@ -410,18 +413,17 @@ def __init__( ) """Parameter ref_source""" - self.DC_output: Parameter = self.add_parameter( + self.DC_output: Parameter[bool, Self] = self.add_parameter( "DC_output", label="DC Output (ON/OFF)", get_cmd="AWGControl:DC:STATe?", set_cmd="AWGControl:DC:STATe {}", - vals=vals.Ints(0, 1), - get_parser=int, + val_mapping=create_on_off_val_mapping(on_val=1, off_val=0), ) """Parameter DC_output""" # sequence parameter(s) - self.sequence_length: Parameter = self.add_parameter( + self.sequence_length: Parameter[int, Self] = self.add_parameter( "sequence_length", label="Sequence length", get_cmd="SEQuence:LENGth?", @@ -468,12 +470,13 @@ def __init__( 20 will be deleted. """ - self.sequence_pos: Parameter = self.add_parameter( + self.sequence_pos: Parameter[int, Self] = self.add_parameter( "sequence_pos", label="Sequence position", get_cmd="AWGControl:SEQuencer:POSition?", set_cmd="SEQuence:JUMP:IMMediate {}", vals=vals.PermissiveInts(1), + get_parser=int, set_parser=round, ) """Parameter sequence_pos""" @@ -481,7 +484,7 @@ def __init__( # Trigger parameters # # Warning: `trigger_mode` is the same as `run_mode`, do not use! exists # solely for legacy purposes - self.trigger_mode: Parameter = self.add_parameter( + self.trigger_mode: Parameter[str, Self] = self.add_parameter( "trigger_mode", get_cmd="AWGControl:RMODe?", set_cmd="AWGControl:RMODe " + "{}", @@ -489,7 +492,7 @@ def __init__( get_parser=self.newlinestripper, ) """Parameter trigger_mode""" - self.trigger_impedance: Parameter = self.add_parameter( + self.trigger_impedance: Parameter[float, Self] = self.add_parameter( "trigger_impedance", label="Trigger impedance", unit="Ohm", @@ -499,7 +502,7 @@ def __init__( get_parser=float, ) """Parameter trigger_impedance""" - self.trigger_level: Parameter = self.add_parameter( + self.trigger_level: Parameter[float, Self] = self.add_parameter( "trigger_level", unit="V", label="Trigger level", @@ -509,7 +512,7 @@ def __init__( get_parser=float, ) """Parameter trigger_level""" - self.trigger_slope: Parameter = self.add_parameter( + self.trigger_slope: Parameter[str, Self] = self.add_parameter( "trigger_slope", get_cmd="TRIGger:SLOPe?", set_cmd="TRIGger:SLOPe " + "{}", @@ -518,7 +521,7 @@ def __init__( ) """Parameter trigger_slope""" - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( "trigger_source", get_cmd="TRIGger:SOURce?", set_cmd="TRIGger:SOURce " + "{}", @@ -528,7 +531,7 @@ def __init__( """Parameter trigger_source""" # Event parameters - self.event_polarity: Parameter = self.add_parameter( + self.event_polarity: Parameter[str, Self] = self.add_parameter( "event_polarity", get_cmd="EVENt:POL?", set_cmd="EVENt:POL " + "{}", @@ -536,7 +539,7 @@ def __init__( get_parser=self.newlinestripper, ) """Parameter event_polarity""" - self.event_impedance: Parameter = self.add_parameter( + self.event_impedance: Parameter[float, Self] = self.add_parameter( "event_impedance", label="Event impedance", unit="Ohm", @@ -546,7 +549,7 @@ def __init__( get_parser=float, ) """Parameter event_impedance""" - self.event_level: Parameter = self.add_parameter( + self.event_level: Parameter[float, Self] = self.add_parameter( "event_level", label="Event level", unit="V", @@ -556,7 +559,7 @@ def __init__( get_parser=float, ) """Parameter event_level""" - self.event_jump_timing: Parameter = self.add_parameter( + self.event_jump_timing: Parameter[str, Self] = self.add_parameter( "event_jump_timing", get_cmd="EVENt:JTIMing?", set_cmd="EVENt:JTIMing {}", @@ -565,7 +568,7 @@ def __init__( ) """Parameter event_jump_timing""" - self.clock_freq: Parameter = self.add_parameter( + self.clock_freq: Parameter[float, Self] = self.add_parameter( "clock_freq", label="Clock frequency", unit="Hz", @@ -576,7 +579,7 @@ def __init__( ) """Parameter clock_freq""" - self.setup_filename: Parameter = self.add_parameter( + self.setup_filename: Parameter[str, Self] = self.add_parameter( "setup_filename", get_cmd="AWGControl:SNAMe?" ) """Parameter setup_filename""" diff --git a/src/qcodes/instrument_drivers/tektronix/AWG70000A.py b/src/qcodes/instrument_drivers/tektronix/AWG70000A.py index bf1aa4170d47..731b23ccb9b8 100644 --- a/src/qcodes/instrument_drivers/tektronix/AWG70000A.py +++ b/src/qcodes/instrument_drivers/tektronix/AWG70000A.py @@ -214,7 +214,7 @@ def __init__( # FGEN PARAMETERS # TODO: Setting high and low will change this parameter's value - self.fgen_amplitude: Parameter = self.add_parameter( + self.fgen_amplitude: Parameter[float, Self] = self.add_parameter( "fgen_amplitude", label=f"Channel {channel} {fg} amplitude", get_cmd=f"FGEN:CHANnel{channel}:AMPLitude?", @@ -225,7 +225,7 @@ def __init__( ) """Parameter fgen_amplitude""" - self.fgen_offset: Parameter = self.add_parameter( + self.fgen_offset: Parameter[float, Self] = self.add_parameter( "fgen_offset", label=f"Channel {channel} {fg} offset", get_cmd=f"FGEN:CHANnel{channel}:OFFSet?", @@ -236,7 +236,7 @@ def __init__( ) """Parameter fgen_offset""" - self.fgen_frequency: Parameter = self.add_parameter( + self.fgen_frequency: Parameter[float, Self] = self.add_parameter( "fgen_frequency", label=f"Channel {channel} {fg} frequency", get_cmd=f"FGEN:CHANnel{channel}:FREQuency?", @@ -246,7 +246,7 @@ def __init__( ) """Parameter fgen_frequency""" - self.fgen_dclevel: Parameter = self.add_parameter( + self.fgen_dclevel: Parameter[float, Self] = self.add_parameter( "fgen_dclevel", label=f"Channel {channel} {fg} DC level", get_cmd=f"FGEN:CHANnel{channel}:DCLevel?", @@ -257,7 +257,7 @@ def __init__( ) """Parameter fgen_dclevel""" - self.fgen_signalpath: Parameter = self.add_parameter( + self.fgen_signalpath: Parameter[str, Self] = self.add_parameter( "fgen_signalpath", label=f"Channel {channel} {fg} signal path", set_cmd=f"FGEN:CHANnel{channel}:PATH {{}}", @@ -266,7 +266,7 @@ def __init__( ) """Parameter fgen_signalpath""" - self.fgen_period: Parameter = self.add_parameter( + self.fgen_period: Parameter[float, Self] = self.add_parameter( "fgen_period", label=f"Channel {channel} {fg} period", get_cmd=f"FGEN:CHANnel{channel}:PERiod?", @@ -275,7 +275,7 @@ def __init__( ) """Parameter fgen_period""" - self.fgen_phase: Parameter = self.add_parameter( + self.fgen_phase: Parameter[float, Self] = self.add_parameter( "fgen_phase", label=f"Channel {channel} {fg} phase", get_cmd=f"FGEN:CHANnel{channel}:PHASe?", @@ -286,7 +286,7 @@ def __init__( ) """Parameter fgen_phase""" - self.fgen_symmetry: Parameter = self.add_parameter( + self.fgen_symmetry: Parameter[float, Self] = self.add_parameter( "fgen_symmetry", label=f"Channel {channel} {fg} symmetry", set_cmd=f"FGEN:CHANnel{channel}:SYMMetry {{}}", @@ -297,7 +297,7 @@ def __init__( ) """Parameter fgen_symmetry""" - self.fgen_type: Parameter = self.add_parameter( + self.fgen_type: Parameter[str, Self] = self.add_parameter( "fgen_type", label=f"Channel {channel} {fg} type", set_cmd=f"FGEN:CHANnel{channel}:TYPE {{}}", @@ -323,7 +323,7 @@ def __init__( # the manual claims that this command only works in AC mode # (OUTPut[n]:PATH is AC), but I've tested that it does what # one would expect in DIR mode. - self.awg_amplitude: Parameter = self.add_parameter( + self.awg_amplitude: Parameter[float, Self] = self.add_parameter( "awg_amplitude", label=f"Channel {channel} AWG peak-to-peak amplitude", set_cmd=f"SOURCe{channel}:VOLTage {{}}", @@ -334,7 +334,7 @@ def __init__( ) """Parameter awg_amplitude""" - self.offset: Parameter = self.add_parameter( + self.offset: Parameter[float, Self] = self.add_parameter( "offset", label=f"Channel {channel} Offset for DC Output paths", set_cmd=f"SOURce{channel}:VOLTage:LEVel:IMMediate:OFFSet {{}}", @@ -345,7 +345,7 @@ def __init__( ) """Parameter offset""" - self.assigned_asset: Parameter = self.add_parameter( + self.assigned_asset: Parameter[str, Self] = self.add_parameter( "assigned_asset", label=(f"Waveform/sequence assigned to channel {self.channel}"), get_cmd=f"SOURCE{self.channel}:CASSet?", @@ -394,7 +394,7 @@ def __init__( ################################################## # MISC. - self.resolution: Parameter = self.add_parameter( + self.resolution: Parameter[int, Self] = self.add_parameter( "resolution", label=f"Channel {channel} bit resolution", get_cmd=f"SOURce{channel}:DAC:RESolution?", @@ -515,7 +515,7 @@ def __init__( f"the right driver for your instrument?" ) - self.current_directory: Parameter = self.add_parameter( + self.current_directory: Parameter[str, Self] = self.add_parameter( "current_directory", label="Current file system directory", set_cmd='MMEMory:CDIRectory "{}"', @@ -524,7 +524,7 @@ def __init__( ) """Parameter current_directory""" - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", label="Instrument operation mode", set_cmd="INSTrument:MODE {}", @@ -536,7 +536,7 @@ def __init__( ################################################## # Clock parameters - self.sample_rate: Parameter = self.add_parameter( + self.sample_rate: Parameter[float, Self] = self.add_parameter( "sample_rate", label="Clock sample rate", set_cmd="CLOCk:SRATe {}", @@ -547,7 +547,7 @@ def __init__( ) """Parameter sample_rate""" - self.clock_source: Parameter = self.add_parameter( + self.clock_source: Parameter[str, Self] = self.add_parameter( "clock_source", label="Clock source", set_cmd="CLOCk:SOURce {}", @@ -561,7 +561,7 @@ def __init__( ) """Parameter clock_source""" - self.clock_external_frequency: Parameter = self.add_parameter( + self.clock_external_frequency: Parameter[float, Self] = self.add_parameter( "clock_external_frequency", label="External clock frequency", set_cmd="CLOCk:ECLock:FREQuency {}", @@ -572,7 +572,7 @@ def __init__( ) """Parameter clock_external_frequency""" - self.run_state: Parameter = self.add_parameter( + self.run_state: Parameter[str, Self] = self.add_parameter( "run_state", label="Run state", get_cmd="AWGControl:RSTATe?", @@ -580,7 +580,7 @@ def __init__( ) """Parameter run_state""" - self.all_output_off: Parameter = self.add_parameter( + self.all_output_off: Parameter[bool, Self] = self.add_parameter( "all_output_off", label="All Output Off", get_cmd="OUTPut:OFF?", diff --git a/src/qcodes/instrument_drivers/tektronix/DPO7200xx.py b/src/qcodes/instrument_drivers/tektronix/DPO7200xx.py index b8d1591c67f1..ef0c85c00ae0 100644 --- a/src/qcodes/instrument_drivers/tektronix/DPO7200xx.py +++ b/src/qcodes/instrument_drivers/tektronix/DPO7200xx.py @@ -166,7 +166,7 @@ def __init__( super().__init__(parent, name, **kwargs) # We can choose to retrieve data from arbitrary # start and stop indices of the buffer. - self.start_index: Parameter = self.add_parameter( + self.start_index: Parameter[int, Self] = self.add_parameter( "start_index", get_cmd="DATa:STARt?", set_cmd="DATa:STARt {}", @@ -174,12 +174,12 @@ def __init__( ) """Parameter start_index""" - self.stop_index: Parameter = self.add_parameter( + self.stop_index: Parameter[int, Self] = self.add_parameter( "stop_index", get_cmd="DATa:STOP?", set_cmd="DATa:STOP {}", get_parser=int ) """Parameter stop_index""" - self.source: Parameter = self.add_parameter( + self.source: Parameter[str, Self] = self.add_parameter( "source", get_cmd="DATa:SOU?", set_cmd="DATa:SOU {}", @@ -187,7 +187,7 @@ def __init__( ) """Parameter source""" - self.encoding: Parameter = self.add_parameter( + self.encoding: Parameter[str, Self] = self.add_parameter( "encoding", get_cmd="DATa:ENCdg?", set_cmd="DATa:ENCdg {}", @@ -251,7 +251,7 @@ def __init__( self._identifier = identifier - self.raw_data_offset: Parameter = self.add_parameter( + self.raw_data_offset: Parameter[float, Self] = self.add_parameter( "raw_data_offset", get_cmd=self._get_cmd("WFMOutPRE:YOFF?"), get_parser=float, @@ -271,12 +271,12 @@ def __init__( the center of this range """ - self.x_unit: Parameter = self.add_parameter( + self.x_unit: Parameter[str, Self] = self.add_parameter( "x_unit", get_cmd=self._get_cmd("WFMOutpre:XUNit?"), get_parser=strip_quotes ) """Parameter x_unit""" - self.x_increment: Parameter = self.add_parameter( + self.x_increment: Parameter[float, Self] = self.add_parameter( "x_increment", get_cmd=self._get_cmd("WFMOutPRE:XINCR?"), unit=self.x_unit(), @@ -284,12 +284,12 @@ def __init__( ) """Parameter x_increment""" - self.y_unit: Parameter = self.add_parameter( + self.y_unit: Parameter[str, Self] = self.add_parameter( "y_unit", get_cmd=self._get_cmd("WFMOutpre:YUNit?"), get_parser=strip_quotes ) """Parameter y_unit""" - self.offset: Parameter = self.add_parameter( + self.offset: Parameter[float, Self] = self.add_parameter( "offset", get_cmd=self._get_cmd("WFMOutPRE:YZERO?"), get_parser=float, @@ -297,7 +297,7 @@ def __init__( ) """Parameter offset""" - self.scale: Parameter = self.add_parameter( + self.scale: Parameter[float, Self] = self.add_parameter( "scale", get_cmd=self._get_cmd("WFMOutPRE:YMULT?"), get_parser=float, @@ -305,7 +305,7 @@ def __init__( ) """Parameter scale""" - self.length: Parameter = self.add_parameter( + self.length: Parameter[int, Self] = self.add_parameter( "length", get_cmd=self._get_cmd("WFMOutpre:NR_Pt?"), get_parser=int ) """Parameter length""" @@ -394,7 +394,10 @@ def _get_trace_data(self) -> npt.NDArray: container=np.ndarray, ) - return (raw_data - self.raw_data_offset()) * self.scale() + self.offset() + # pyvisa returns an ndarray here, but its annotations only promise a + # Sequence + data = np.asarray(raw_data, dtype=float) + return (data - self.raw_data_offset()) * self.scale() + self.offset() def _get_trace_setpoints(self) -> npt.NDArray: """ @@ -498,7 +501,7 @@ def __init__( ) """Parameter coupling: 'AC', 'DC', 'DCREJECT', 'GND'""" - self.scale: Parameter = self.add_parameter( + self.scale: Parameter[float, Self] = self.add_parameter( "scale", get_cmd=f"{self._identifier}:SCA?", set_cmd=f"{self._identifier}:SCA {{}}", @@ -507,7 +510,7 @@ def __init__( ) """Parameter scale V/div""" - self.offset: Parameter = self.add_parameter( + self.offset: Parameter[float, Self] = self.add_parameter( "offset", get_cmd=f"{self._identifier}:OFFS?", set_cmd=f"{self._identifier}:OFFS {{}}", @@ -516,7 +519,7 @@ def __init__( ) """Parameter offset voltage""" - self.position: Parameter = self.add_parameter( + self.position: Parameter[float, Self] = self.add_parameter( "position", get_cmd=f"{self._identifier}:POS?", set_cmd=f"{self._identifier}:POS {{}}", @@ -526,7 +529,7 @@ def __init__( ) """Parameter position [-8, 8] divisions""" - self.termination: Parameter = self.add_parameter( + self.termination: Parameter[float, Self] = self.add_parameter( "termination", get_cmd=f"{self._identifier}:TER?", set_cmd=f"{self._identifier}:TER {{}}", @@ -536,7 +539,7 @@ def __init__( ) """Parameter termination""" - self.analog_to_digital_threshold: Parameter = self.add_parameter( + self.analog_to_digital_threshold: Parameter[float, Self] = self.add_parameter( "analog_to_digital_threshold", get_cmd=f"{self._identifier}:THRESH?", set_cmd=f"{self._identifier}:THRESH {{}}", @@ -545,7 +548,7 @@ def __init__( ) """Parameter analog_to_digital_threshold""" - self.termination_voltage: Parameter = self.add_parameter( + self.termination_voltage: Parameter[float, Self] = self.add_parameter( "termination_voltage", get_cmd=f"{self._identifier}:VTERm:BIAS?", set_cmd=f"{self._identifier}:VTERm:BIAS {{}}", @@ -597,7 +600,7 @@ def __init__( ) -> None: super().__init__(parent, name, **kwargs) - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", get_cmd="HORizontal:MODE?", set_cmd="HORizontal:MODE {}", @@ -631,20 +634,21 @@ def __init__( scale is read only. """ - self.unit: Parameter = self.add_parameter( + self.unit: Parameter[str, Self] = self.add_parameter( "unit", get_cmd="HORizontal:MAIn:UNIts?", get_parser=strip_quotes ) """Parameter unit""" - self.record_length: Parameter = self.add_parameter( + self.record_length: Parameter[int, Self] = self.add_parameter( "record_length", get_cmd="HORizontal:MODE:RECOrdlength?", set_cmd=self._set_record_length, - get_parser=float, + # the record length in samples, returned as an integer () + get_parser=int, ) """Parameter record_length""" - self.sample_rate: Parameter = self.add_parameter( + self.sample_rate: Parameter[float, Self] = self.add_parameter( "sample_rate", get_cmd="HORizontal:MODE:SAMPLERate?", set_cmd="HORizontal:MODE:SAMPLERate {}", @@ -653,7 +657,7 @@ def __init__( ) """Parameter sample_rate""" - self.scale: Parameter = self.add_parameter( + self.scale: Parameter[float, Self] = self.add_parameter( "scale", get_cmd="HORizontal:MODE:SCAle?", set_cmd=self._set_scale, @@ -662,7 +666,7 @@ def __init__( ) """Parameter scale""" - self.position: Parameter = self.add_parameter( + self.position: Parameter[float, Self] = self.add_parameter( "position", get_cmd="HORizontal:POSition?", set_cmd="HORizontal:POSition {}", @@ -686,7 +690,7 @@ def __init__( left of the trigger position. """ - self.roll: Parameter = self.add_parameter( + self.roll: Parameter[str, Self] = self.add_parameter( "roll", get_cmd="HORizontal:ROLL?", set_cmd="HORizontal:ROLL {}", @@ -789,7 +793,7 @@ def __init__( """ - self.stop_after: Parameter = self.add_parameter( + self.stop_after: Parameter[str, Self] = self.add_parameter( "stop_after", get_cmd="ACQuire:STOPAfter?", set_cmd="ACQuire:STOPAfter {}", @@ -837,7 +841,7 @@ def __init__( ["video", "i2c", "can", "spi", "communication", "serial", "rs232"] ) - self.ready: Parameter = self.add_parameter( + self.ready: Parameter[str, Self] = self.add_parameter( "ready", get_cmd=f"TRIGger:{self._identifier}:READY?", get_parser=str.lower, @@ -847,7 +851,7 @@ def __init__( A value of 0 indicates that the trigger system is not ready to accept a trigger. """ - self.state: Parameter = self.add_parameter( + self.state: Parameter[str, Self] = self.add_parameter( "state", get_cmd="TRIGger:STATe?", get_parser=str.lower, @@ -873,7 +877,7 @@ def __init__( information. """ - self.type: Parameter = self.add_parameter( + self.type: Parameter[str, Self] = self.add_parameter( "type", get_cmd=f"TRIGger:{self._identifier}:TYPE?", set_cmd=self._trigger_type, @@ -886,7 +890,7 @@ def __init__( if self._identifier == "B": edge_couplings.append("atrigger") - self.edge_coupling: Parameter = self.add_parameter( + self.edge_coupling: Parameter[str, Self] = self.add_parameter( "edge_coupling", get_cmd=f"TRIGger:{self._identifier}:EDGE:COUPling?", set_cmd=f"TRIGger:{self._identifier}:EDGE:COUPling {{}}", @@ -898,7 +902,7 @@ def __init__( Trigger B: 'ac', 'dc', 'hfrej', 'lfrej', 'noiserej', 'atrigger' """ - self.edge_slope: Parameter = self.add_parameter( + self.edge_slope: Parameter[str, Self] = self.add_parameter( "edge_slope", get_cmd=f"TRIGger:{self._identifier}:EDGE:SLOpe?", set_cmd=f"TRIGger:{self._identifier}:EDGE:SLOpe {{}}", @@ -918,7 +922,7 @@ def __init__( trigger_sources.append("AUX") - self.source: Parameter = self.add_parameter( + self.source: Parameter[str, Self] = self.add_parameter( "source", get_cmd=f"TRIGger:{self._identifier}:EDGE:SOUrce?", set_cmd=f"TRIGger:{self._identifier}:EDGE:SOUrce {{}}", @@ -926,7 +930,7 @@ def __init__( ) """Trigger source: 'CH1', 'CH2', ..., 'CH4', 'D0', 'D1', ..., 'D15', 'AUX', 'LINE'""" - self.level: Parameter = self.add_parameter( + self.level: Parameter[float, Self] = self.add_parameter( "level", get_cmd=f"TRIGger:{self._identifier}:LEVel?", set_cmd=f"TRIGger:{self._identifier}:LEVel {{}}", @@ -963,7 +967,7 @@ def _get(self, metric: str) -> float: if measurement_channel.type.get_latest() != self.name: measurement_channel.type(self.name) - measurement_channel.state(1) + measurement_channel.state(True) measurement_channel.wait_adjustment_time() measurement_number = measurement_channel.measurement_number @@ -1071,7 +1075,7 @@ def __init__( self._measurement_number = measurement_number self._adjustment_time = time.perf_counter() - self.state: Parameter = self.add_parameter( + self.state: Parameter[bool, Self] = self.add_parameter( "state", get_cmd=f"MEASUrement:MEAS{self._measurement_number}:STATe?", set_cmd=f"MEASUrement:MEAS{self._measurement_number}:STATe {{}}", @@ -1079,7 +1083,7 @@ def __init__( ) """Parameter state""" - self.type: Parameter = self.add_parameter( + self.type: Parameter[str, Self] = self.add_parameter( "type", get_cmd=f"MEASUrement:MEAS{self._measurement_number}:TYPe?", set_cmd=self._set_measurement_type, @@ -1142,7 +1146,7 @@ def __init__( ): super().__init__(parent=parent, name=name, **kwargs) - self.mode: Parameter = self.add_parameter( + self.mode: Parameter[str, Self] = self.add_parameter( "mode", get_cmd="MEASUrement:STATIstics:MODe?", set_cmd="MEASUrement:STATIstics:MODe {}", @@ -1163,7 +1167,7 @@ def __init__( ) """Parameter mode""" - self.time_constant: Parameter = self.add_parameter( + self.time_constant: Parameter[int, Self] = self.add_parameter( "time_constant", get_cmd="MEASUrement:STATIstics:WEIghting?", set_cmd="MEASUrement:STATIstics:WEIghting {}", @@ -1198,7 +1202,7 @@ def __init__( ) -> None: super().__init__(parent, name, **kwargs) - self.gating: Parameter = self.add_parameter( + self.gating: Parameter[str, Self] = self.add_parameter( "gating", get_cmd="MEASUrement:GATing?", set_cmd="MEASUrement:GATing {}", @@ -1211,7 +1215,7 @@ def __init__( cursor gate (CURSOR), which uses the horizontal positions of the cursors to define the gate. """ - self.source1: Parameter = self.add_parameter( + self.source1: Parameter[str, Self] = self.add_parameter( "source1", get_cmd="MEASUrement:IMMed:SOUrce1?", set_cmd="MEASUrement:IMMed:SOUrce1 {}", @@ -1221,7 +1225,7 @@ def __init__( CH1, CH2, CH3, CH4, MATH1, MATH2, MATH3, MATH4, REF1, REF2, REF3, REF4, HISTogram""" - self.source2: Parameter = self.add_parameter( + self.source2: Parameter[str, Self] = self.add_parameter( "source2", get_cmd="MEASUrement:IMMed:SOUrce2?", set_cmd="MEASUrement:IMMed:SOUrce2 {}", @@ -1234,7 +1238,7 @@ def __init__( REF1, REF2, REF3, REF4 """ - self.type: Parameter = self.add_parameter( + self.type: Parameter[str, Self] = self.add_parameter( "type", get_cmd="MEASUrement:IMMed:TYPE?", set_cmd="MEASUrement:IMMed:TYPE {}", @@ -1301,14 +1305,14 @@ def __init__( https://download.tek.com/manual/MSO-DPO5000-B-DPO7000-C-DPO70000-B-C-D-DX-DSA70000-B-C-D-and-MSO70000-C-DX-_2.pdf """ - self.units: Parameter = self.add_parameter( + self.units: Parameter[str, Self] = self.add_parameter( "units", get_cmd="MEASUrement:IMMed:UNITS?", get_parser=strip_quotes, ) """Units of the immediate measurement""" - self.value: Parameter = self.add_parameter( + self.value: Parameter[float, Self] = self.add_parameter( "value", get_cmd="MEASUrement:IMMed:VALue?", get_parser=float, @@ -1342,7 +1346,7 @@ def __init__( ) -> None: super().__init__(parent, name, **kwargs) - self.function: Parameter = self.add_parameter( + self.function: Parameter[str, Self] = self.add_parameter( "function", get_cmd="CURSOR:FUNCtion?", set_cmd="CURSOR:FUNCtion {}", @@ -1357,7 +1361,7 @@ def __init__( ) """Cursor Type [OFF, HBARS, VBARS, SCREEN, WAVEFORM]""" - self.state: Parameter = self.add_parameter( + self.state: Parameter[str, Self] = self.add_parameter( "state", get_cmd="CURSOR:STATE?", set_cmd="CURSOR:STATE {}", @@ -1366,7 +1370,7 @@ def __init__( ) """Cursor state [ON, OFF]""" - self.x1: Parameter = self.add_parameter( + self.x1: Parameter[float, Self] = self.add_parameter( "x1", get_cmd="CURSOR:VBARS:POSITION1?", set_cmd="CURSOR:VBARS:POSITION1 {}", @@ -1375,7 +1379,7 @@ def __init__( ) """Cursor x1 position in seconds""" - self.x2: Parameter = self.add_parameter( + self.x2: Parameter[float, Self] = self.add_parameter( "x2", get_cmd="CURSOR:VBARS:POSITION2?", set_cmd="CURSOR:VBARS:POSITION2 {}", @@ -1384,7 +1388,7 @@ def __init__( ) """Cursor x2 position in seconds""" - self.y1: Parameter = self.add_parameter( + self.y1: Parameter[float, Self] = self.add_parameter( "y1", get_cmd="CURSOR:HBARS:POSITION1?", set_cmd="CURSOR:HBARS:POSITION1 {}", @@ -1393,7 +1397,7 @@ def __init__( ) """Cursor y1 position in Volts""" - self.y2: Parameter = self.add_parameter( + self.y2: Parameter[float, Self] = self.add_parameter( "y2", get_cmd="CURSOR:HBARS:POSITION2?", set_cmd="CURSOR:HBARS:POSITION2 {}", diff --git a/src/qcodes/instrument_drivers/tektronix/TPS2012.py b/src/qcodes/instrument_drivers/tektronix/TPS2012.py index aa5556cef29e..b66b435e4eea 100644 --- a/src/qcodes/instrument_drivers/tektronix/TPS2012.py +++ b/src/qcodes/instrument_drivers/tektronix/TPS2012.py @@ -1,7 +1,7 @@ import binascii import logging from functools import partial -from typing import TYPE_CHECKING, Any, Unpack +from typing import TYPE_CHECKING, Any, Self, Unpack import numpy as np import numpy.typing as npt @@ -235,7 +235,7 @@ def __init__( ): super().__init__(parent, name, **kwargs) - self.scale: Parameter = self.add_parameter( + self.scale: Parameter[float, Self] = self.add_parameter( "scale", label=f"Channel {channel} Scale", unit="V/div", @@ -244,7 +244,7 @@ def __init__( get_parser=float, ) """Parameter scale""" - self.position: Parameter = self.add_parameter( + self.position: Parameter[float, Self] = self.add_parameter( "position", label=f"Channel {channel} Position", unit="div", @@ -259,7 +259,7 @@ def __init__( parameter_class=ScopeArray, ) """Parameter curvedata""" - self.state: Parameter = self.add_parameter( + self.state: Parameter[str, Self] = self.add_parameter( "state", label=f"Channel {channel} display state", set_cmd="SELect:CH{} {}".format(channel, "{}"), @@ -326,7 +326,7 @@ def __init__( ) # general parameters - self.trigger_type: Parameter = self.add_parameter( + self.trigger_type: Parameter[str, Self] = self.add_parameter( "trigger_type", label="Type of the trigger", get_cmd="TRIGger:MAIn:TYPe?", @@ -334,7 +334,7 @@ def __init__( vals=vals.Enum("EDGE", "VIDEO", "PULSE"), ) """Parameter trigger_type""" - self.trigger_source: Parameter = self.add_parameter( + self.trigger_source: Parameter[str, Self] = self.add_parameter( "trigger_source", label="Source for the trigger", get_cmd="TRIGger:MAIn:EDGE:SOURce?", @@ -342,7 +342,7 @@ def __init__( vals=vals.Enum("CH1", "CH2"), ) """Parameter trigger_source""" - self.trigger_edge_slope: Parameter = self.add_parameter( + self.trigger_edge_slope: Parameter[str, Self] = self.add_parameter( "trigger_edge_slope", label="Slope for edge trigger", get_cmd="TRIGger:MAIn:EDGE:SLOpe?", @@ -350,16 +350,17 @@ def __init__( vals=vals.Enum("FALL", "RISE"), ) """Parameter trigger_edge_slope""" - self.trigger_level: Parameter = self.add_parameter( + self.trigger_level: Parameter[float, Self] = self.add_parameter( "trigger_level", label="Trigger level", unit="V", get_cmd="TRIGger:MAIn:LEVel?", set_cmd="TRIGger:MAIn:LEVel {}", + get_parser=float, vals=vals.Numbers(), ) """Parameter trigger_level""" - self.data_source: Parameter = self.add_parameter( + self.data_source: Parameter[str, Self] = self.add_parameter( "data_source", label="Data source", get_cmd="DATa:SOUrce?", @@ -367,7 +368,7 @@ def __init__( vals=vals.Enum("CH1", "CH2"), ) """Parameter data_source""" - self.horizontal_scale: Parameter = self.add_parameter( + self.horizontal_scale: Parameter[float, Self] = self.add_parameter( "horizontal_scale", label="Horizontal scale", unit="s", diff --git a/src/qcodes/instrument_drivers/yokogawa/Yokogawa_GS200.py b/src/qcodes/instrument_drivers/yokogawa/Yokogawa_GS200.py index c78ae88b2d8d..5c4f309b06ac 100644 --- a/src/qcodes/instrument_drivers/yokogawa/Yokogawa_GS200.py +++ b/src/qcodes/instrument_drivers/yokogawa/Yokogawa_GS200.py @@ -185,7 +185,7 @@ def __init__( # Set up monitoring parameters if present: - self.enabled: Parameter = self.add_parameter( + self.enabled: Parameter[str, Self] = self.add_parameter( "enabled", label="Measurement Enabled", get_cmd=self.state, @@ -199,7 +199,7 @@ def __init__( # Note: Measurement will only run if source and # measurement is enabled. - self.measure: Parameter = self.add_parameter( + self.measure: Parameter[float, Self] = self.add_parameter( "measure", label="", unit="V/I", @@ -208,7 +208,7 @@ def __init__( ) """Parameter measure""" - self.NPLC: Parameter = self.add_parameter( + self.NPLC: Parameter[int, Self] = self.add_parameter( "NPLC", label="NPLC", unit="1/LineFreq", @@ -219,7 +219,7 @@ def __init__( get_parser=_float_round, ) """Parameter NPLC""" - self.delay: Parameter = self.add_parameter( + self.delay: Parameter[int, Self] = self.add_parameter( "delay", label="Measurement Delay", unit="ms", @@ -230,7 +230,7 @@ def __init__( get_parser=_float_round, ) """Parameter delay""" - self.trigger: Parameter = self.add_parameter( + self.trigger: Parameter[str, Self] = self.add_parameter( "trigger", label="Trigger Source", set_cmd=":SENS:TRIG {}", @@ -246,7 +246,7 @@ def __init__( }, ) """Parameter trigger""" - self.interval: Parameter = self.add_parameter( + self.interval: Parameter[float, Self] = self.add_parameter( "interval", label="Measurement Interval", unit="s", @@ -337,7 +337,7 @@ def __init__( # What the manual does not mention: the internal clock is an astonishing 10 Hz, # so only multiples of 0.1 s are allowed. - self.interval: Parameter = self.add_parameter( + self.interval: Parameter[float, Self] = self.add_parameter( "interval", label="the program interval time", unit="s", @@ -349,7 +349,7 @@ def __init__( ) """Parameter interval""" - self.slope: Parameter = self.add_parameter( + self.slope: Parameter[float, Self] = self.add_parameter( "slope", label="the program slope time", unit="s", @@ -362,7 +362,7 @@ def __init__( """Parameter slope""" if monitor_present: - self.trigger: Parameter = self.add_parameter( + self.trigger: Parameter[str, Self] = self.add_parameter( "trigger", label="the program trigger", get_cmd=":PROG:TRIG?", @@ -378,7 +378,7 @@ def __init__( ) """save the program to the system memory (.csv file)""" - self.load: Parameter = self.add_parameter( + self.load: Parameter[str, Self] = self.add_parameter( "load", get_cmd=":PROG:LOAD?", set_cmd=":PROG:LOAD '{}'", @@ -386,7 +386,7 @@ def __init__( ) """load the program (.csv file) from the system memory""" - self.repeat: Parameter = self.add_parameter( + self.repeat: Parameter[str, Self] = self.add_parameter( "repeat", label="program execution repetition", get_cmd=":PROG:REP?", @@ -450,7 +450,7 @@ def __init__( ) -> None: super().__init__(name, address, **kwargs) - self.output: Parameter = self.add_parameter( + self.output: Parameter[str, Self] = self.add_parameter( "output", label="Output State", get_cmd=self.state, @@ -508,7 +508,7 @@ def __init__( # The instrument does not support auto range. The parameter # auto_range is introduced to add this capability with # setting the initial state at False mode. - self.auto_range: Parameter = self.add_parameter( + self.auto_range: Parameter[bool, Self] = self.add_parameter( "auto_range", label="Auto Range", set_cmd=self._set_auto_range, @@ -560,7 +560,7 @@ def __init__( f"Invalid mode {mode}. Mode must be one of 'CURR' or 'VOLT'" ) - self.voltage_limit: Parameter = self.add_parameter( + self.voltage_limit: Parameter[int, Self] = self.add_parameter( "voltage_limit", label="Voltage Protection Limit", unit="V", @@ -584,7 +584,7 @@ def __init__( ) """Parameter current_limit""" - self.four_wire: Parameter = self.add_parameter( + self.four_wire: Parameter[str, Self] = self.add_parameter( "four_wire", label="Four Wire Sensing", get_cmd=":SENS:REM?", @@ -598,7 +598,7 @@ def __init__( # Note: The guard feature can be used to remove common mode noise. # Read the manual to see if you would like to use it - self.guard: Parameter = self.add_parameter( + self.guard: Parameter[str, Self] = self.add_parameter( "guard", label="Guard Terminal", get_cmd=":SENS:GUAR?", @@ -608,7 +608,7 @@ def __init__( """Parameter guard""" # Return measured line frequency - self.line_freq: Parameter = self.add_parameter( + self.line_freq: Parameter[int, Self] = self.add_parameter( "line_freq", label="Line Frequency", unit="Hz", @@ -632,7 +632,7 @@ def __init__( ) """Instrument module program""" - self.BNC_out: Parameter = self.add_parameter( + self.BNC_out: Parameter[str, Self] = self.add_parameter( "BNC_out", label="BNC trigger out", get_cmd=":ROUT:BNCO?", @@ -642,7 +642,7 @@ def __init__( ) """Sets or queries the output BNC signal""" - self.BNC_in: Parameter = self.add_parameter( + self.BNC_in: Parameter[str, Self] = self.add_parameter( "BNC_in", label="BNC trigger in", get_cmd=":ROUT:BNCI?", @@ -652,7 +652,7 @@ def __init__( ) """Sets or queries the input BNC signal""" - self.system_errors: Parameter = self.add_parameter( + self.system_errors: Parameter[str, Self] = self.add_parameter( "system_errors", get_cmd=":SYSTem:ERRor?", docstring="returns the oldest unread error message from the event " diff --git a/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1517a_smu.py b/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1517a_smu.py index 6c3a094568d7..b48e1b9e992f 100644 --- a/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1517a_smu.py +++ b/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1517a_smu.py @@ -470,6 +470,55 @@ def test_iv_sweep_mode_start_end_steps_compliance(smu: KeysightB1517A) -> None: ) +def test_iv_sweep_compliance_can_be_unset(smu: KeysightB1517A) -> None: + # Icomp and Pcomp are optional in the WV command. Without Pcomp no power + # compliance is set, without Icomp the previous current compliance is used. + mainframe = smu.parent + assert isinstance(mainframe, MagicMock) + + smu.iv_sweep.current_compliance(45e-3) + smu.iv_sweep.power_compliance(0.2) + smu.iv_sweep.power_compliance(None) + smu.iv_sweep.current_compliance(None) + + mainframe.write.assert_has_calls( + [ + call("WV 1,1,0,0.0,0.0,1,0.045"), + call("WV 1,1,0,0.0,0.0,1,0.045,0.2"), + call("WV 1,1,0,0.0,0.0,1,0.045"), + call("WV 1,1,0,0.0,0.0,1"), + ] + ) + + +def test_iv_sweep_clear_current_then_power_compliance(smu: KeysightB1517A) -> None: + mainframe = smu.parent + assert isinstance(mainframe, MagicMock) + + smu.iv_sweep.current_compliance(45e-3) + smu.iv_sweep.power_compliance(0.2) + smu.iv_sweep.current_compliance(None) + smu.iv_sweep.power_compliance(None) + + mainframe.write.assert_has_calls( + [ + call("WV 1,1,0,0.0,0.0,1,0.045"), + call("WV 1,1,0,0.0,0.0,1,0.045,0.2"), + call("WV 1,1,0,0.0,0.0,1"), + call("WV 1,1,0,0.0,0.0,1"), + ] + ) + + +def test_iv_sweep_power_compliance(smu: KeysightB1517A) -> None: + # clearing the power compliance is allowed without a current compliance, + # but setting one requires a current compliance + smu.iv_sweep.power_compliance(None) + + with pytest.raises(ValueError, match="Current compliance must be set"): + smu.iv_sweep.power_compliance(0.2) + + def test_set_sweep_auto_abort(smu: KeysightB1517A) -> None: mainframe = smu.parent assert isinstance(mainframe, MagicMock) diff --git a/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1520a_cmu.py b/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1520a_cmu.py index b7b54cef35d9..60d3c3ab0906 100644 --- a/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1520a_cmu.py +++ b/tests/drivers/keysight_b1500/b1500_driver_tests/test_b1520a_cmu.py @@ -135,6 +135,31 @@ def test_ranging_mode(cmu: KeysightB1520A) -> None: mainframe.write.assert_called_once_with("RC 3,0") +def test_ac_dc_volt_monitor(cmu: KeysightB1520A) -> None: + mainframe = cmu.parent + assert isinstance(mainframe, MagicMock) + + assert cmu.ac_dc_volt_monitor() is False + + cmu.ac_dc_volt_monitor(True) + assert cmu.ac_dc_volt_monitor() is True + cmu.ac_dc_volt_monitor(False) + assert cmu.ac_dc_volt_monitor() is False + + mainframe.write.assert_has_calls([call("LMN 1"), call("LMN 0")]) + + +@pytest.mark.parametrize( + ("value", "expected"), [(1, True), (0, False), ("on", True), ("off", False)] +) +def test_ac_dc_volt_monitor_accepts_on_off_ints_and_strings( + cmu: KeysightB1520A, value: int | str, expected: bool +) -> None: + # while it does not type check, on/off ints and strings are accepted + cmu.ac_dc_volt_monitor(value) # pyright: ignore[reportArgumentType] + assert cmu.ac_dc_volt_monitor() is expected + + def test_set_sweep_auto_abort(cmu: KeysightB1520A) -> None: mainframe = cmu.parent assert isinstance(mainframe, MagicMock) diff --git a/tests/drivers/keysight_b1500/test_messagebuilder.py b/tests/drivers/keysight_b1500/test_messagebuilder.py index 5e8182f1dfdb..0e7192f14189 100644 --- a/tests/drivers/keysight_b1500/test_messagebuilder.py +++ b/tests/drivers/keysight_b1500/test_messagebuilder.py @@ -952,13 +952,15 @@ def test_pax(mb: MessageBuilder) -> None: def test_pch(mb: MessageBuilder) -> None: - # assert '' == mb.().message - _skip() + assert "PCH 1,2" == mb.pch(1, 2).message def test_pch_query(mb: MessageBuilder) -> None: - # assert '' == mb.().message - _skip() + assert "PCH?" == mb.pch_query().message + + +def test_pch_query_with_master(mb: MessageBuilder) -> None: + assert "PCH? 1" == mb.pch_query(1).message def test_pdcv(mb: MessageBuilder) -> None: diff --git a/tests/drivers/test_agilent_e8257d.py b/tests/drivers/test_agilent_e8257d.py index 0e1bc6e24421..42de831800d6 100644 --- a/tests/drivers/test_agilent_e8257d.py +++ b/tests/drivers/test_agilent_e8257d.py @@ -1,6 +1,15 @@ +from typing import TYPE_CHECKING + +import pytest + from qcodes.extensions import DriverTestCase from qcodes.instrument_drivers.agilent import AgilentE8257D +if TYPE_CHECKING: + from collections.abc import Generator + + from pytest_mock import MockerFixture + class TestAgilentE8257D(DriverTestCase[AgilentE8257D]): """ @@ -95,3 +104,42 @@ def test_phase(self) -> None: # leave the setup in the initial state self.instrument.phase.set(cur_val) + + +@pytest.fixture(name="e8257d") +def _make_e8257d() -> "Generator[AgilentE8257D, None, None]": + # the simulated instrument is closed after each test, so it is never + # picked up by the hardware tests in TestAgilentE8257D above + driver = AgilentE8257D( + "e8257d", address="GPIB::1::INSTR", pyvisa_sim_file="Agilent_E8257D.yaml" + ) + try: + yield driver + finally: + driver.close() + + +def test_on_off(e8257d: AgilentE8257D, mocker: "MockerFixture") -> None: + write_raw = mocker.spy(e8257d, "write_raw") + + e8257d.on() + assert e8257d.output_enabled() is True + + e8257d.off() + assert e8257d.output_enabled() is False + + assert write_raw.call_args_list == [ + mocker.call("OUTP 1"), + mocker.call("OUTP 0"), + ] + + +def test_limits_from_options(e8257d: AgilentE8257D) -> None: + # frequency option 520 with the 1E1 step attenuator + e8257d.frequency.validate(20e9) + with pytest.raises(ValueError): + e8257d.frequency.validate(21e9) + + e8257d.power.validate(-135) + with pytest.raises(ValueError): + e8257d.power.validate(11) diff --git a/tests/drivers/test_agilent_e8267c.py b/tests/drivers/test_agilent_e8267c.py new file mode 100644 index 000000000000..e374d5865e3f --- /dev/null +++ b/tests/drivers/test_agilent_e8267c.py @@ -0,0 +1,30 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.agilent import AgilentE8267C + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(scope="function", name="e8267c") +def _make_e8267c() -> "Generator[AgilentE8267C, None, None]": + driver = AgilentE8267C( + "e8267c", address="GPIB::1::INSTR", pyvisa_sim_file="Agilent_E8267C.yaml" + ) + try: + yield driver + finally: + driver.close() + + +def test_pulse_width_is_float_in_seconds(e8267c: AgilentE8267C) -> None: + assert e8267c.pulse_width.unit == "s" + + pulse_width = e8267c.pulse_width() + assert isinstance(pulse_width, float) + assert pulse_width == pytest.approx(1e-6) + + e8267c.pulse_width(15e-9) + assert e8267c.pulse_width() == pytest.approx(15e-9) diff --git a/tests/drivers/test_coppermountain_m5065.py b/tests/drivers/test_coppermountain_m5065.py index b4e676960bee..04b9577216a6 100644 --- a/tests/drivers/test_coppermountain_m5065.py +++ b/tests/drivers/test_coppermountain_m5065.py @@ -66,6 +66,27 @@ def test_averages_param(vna: CopperMountainM5065) -> None: assert vna.averages() == 2 +def test_averages_enabled_enables_averages_trigger( + vna: CopperMountainM5065, +) -> None: + assert vna.averages_trigger_enabled() is False + vna.averages_enabled(True) + assert vna.averages_enabled() is True + assert vna.averages_trigger_enabled() is True + + +@pytest.mark.parametrize( + ("value", "expected"), + [("ON", True), ("off", False), (1, True), (0, False)], +) +def test_averages_trigger_enabled_accepts_on_off_strings_and_ints( + vna: CopperMountainM5065, value: str | int, expected: bool +) -> None: + # while it does not type check, on/off strings and ints are accepted + vna.averages_trigger_enabled(value) # pyright: ignore[reportArgumentType] + assert vna.averages_trigger_enabled() is expected + + def test_frequency_params(vna: CopperMountainM5065) -> None: vna.start(1e6) vna.stop(2e6) diff --git a/tests/drivers/test_keithley_2450.py b/tests/drivers/test_keithley_2450.py index c108ef1dd7fe..dfb1dee47728 100644 --- a/tests/drivers/test_keithley_2450.py +++ b/tests/drivers/test_keithley_2450.py @@ -135,3 +135,36 @@ def test_sweep(k2450: Keithley2450) -> None: k2450.source.function("voltage") k2450.source.sweep_setup(0, 1, 10) k2450.sense.sweep.get() + + +def test_sense_count_is_int(k2450: Keithley2450) -> None: + assert k2450.sense.count() == 1 + + k2450.sense.count(5) + count = k2450.sense.count() + assert isinstance(count, int) + assert count == 5 + + +def test_line_frequency_is_int(k2450: Keithley2450) -> None: + line_frequency = k2450.line_frequency() + assert isinstance(line_frequency, int) + assert line_frequency == 50 + + +def test_sense_nplc_is_float(k2450: Keithley2450) -> None: + assert k2450.sense.nplc() == 1.0 + + k2450.sense.nplc(0.5) + nplc = k2450.sense.nplc() + assert isinstance(nplc, float) + assert nplc == 0.5 + + +def test_source_delay_is_float(k2450: Keithley2450) -> None: + assert k2450.source.delay() == 0.0 + + k2450.source.delay(0.25) + delay = k2450.source.delay() + assert isinstance(delay, float) + assert delay == 0.25 diff --git a/tests/drivers/test_keithley_6500.py b/tests/drivers/test_keithley_6500.py new file mode 100644 index 000000000000..f42b00cf21e2 --- /dev/null +++ b/tests/drivers/test_keithley_6500.py @@ -0,0 +1,26 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.Keithley import Keithley6500 + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(scope="function", name="dmm6500") +def _make_dmm6500() -> "Generator[Keithley6500, None, None]": + driver = Keithley6500( + "dmm6500", address="GPIB::1::INSTR", pyvisa_sim_file="Keithley_6500.yaml" + ) + try: + yield driver + finally: + driver.close() + + +def test_digits(dmm6500: Keithley6500) -> None: + assert dmm6500.digits() == 6 + + dmm6500.digits(5) + assert dmm6500.digits() == 5 diff --git a/tests/drivers/test_keithley_7510.py b/tests/drivers/test_keithley_7510.py index 0f2082b6dfc9..14863896fced 100644 --- a/tests/drivers/test_keithley_7510.py +++ b/tests/drivers/test_keithley_7510.py @@ -59,3 +59,40 @@ def test_set_range_and_nplc( assert dmm_7510_driver.sense.range() == upper_limit dmm_7510_driver.sense.nplc(nplc) assert dmm_7510_driver.sense.nplc() == nplc + + +def test_user_delay_is_float(dmm_7510_driver: Keithley7510) -> None: + sense = dmm_7510_driver.sense + sense.user_number(1) + assert sense.user_delay() == 0.0 + + sense.user_delay(0.2) + user_delay = sense.user_delay() + assert isinstance(user_delay, float) + assert user_delay == 0.2 + + +def test_average_count_is_int(dmm_7510_driver: Keithley7510) -> None: + sense = dmm_7510_driver.sense + assert sense.average_count() == 10 + + sense.average_count(25) + average_count = sense.average_count() + assert isinstance(average_count, int) + assert average_count == 25 + + +def test_digitize_acq_rate_is_int(dmm_7510_driver: Keithley7510) -> None: + acq_rate = dmm_7510_driver.digi_sense.acq_rate() + assert isinstance(acq_rate, int) + assert acq_rate == 1_000_000 + + +def test_digitize_count_is_int(dmm_7510_driver: Keithley7510) -> None: + digi_sense = dmm_7510_driver.digi_sense + assert digi_sense.count() == 10_000 + + digi_sense.count(500) + count = digi_sense.count() + assert isinstance(count, int) + assert count == 500 diff --git a/tests/drivers/test_keysight_34980a.py b/tests/drivers/test_keysight_34980a.py index 01a194e4a9d0..0bf0910142b3 100644 --- a/tests/drivers/test_keysight_34980a.py +++ b/tests/drivers/test_keysight_34980a.py @@ -4,7 +4,12 @@ import pytest from pytest import FixtureRequest, LogCaptureFixture +from qcodes.instrument_drivers.Keysight import keysight_34980a +from qcodes.instrument_drivers.Keysight.keysight_34934a import Keysight34934A from qcodes.instrument_drivers.Keysight.keysight_34980a import Keysight34980A +from qcodes.instrument_drivers.Keysight.keysight_34980a_submodules import ( + Keysight34980ASwitchMatrixSubModule, +) if TYPE_CHECKING: from collections.abc import Generator @@ -85,7 +90,75 @@ def test_safety_interlock( interlock state """ module = switch_driver.module[3] - assert module is not None module.write("*CLS") with caplog.at_level(logging.DEBUG): assert "safety interlock" in caplog.text + + +def test_modules_only_for_occupied_slots(switch_driver: Keysight34980A) -> None: + # empty slots report model "0" and get no module + assert set(switch_driver.module) == {1, 3} + for slot, module in switch_driver.module.items(): + assert isinstance(module, Keysight34934A) + assert switch_driver.submodules[f"slot_{slot}_34934A"] is module + + +def test_unknown_module_falls_back_to_generic_submodule( + request: FixtureRequest, + caplog: LogCaptureFixture, + monkeypatch: pytest.MonkeyPatch, +) -> None: + monkeypatch.setattr(keysight_34980a, "KEYSIGHT_MODELS", {}) + # the model string contains a "-", which is not valid in a name + with ( + caplog.at_level(logging.WARNING), + pytest.warns(UserWarning, match="_no_driver") as warning_records, + ): + inst = Keysight34980A( + "keysight_34980A_sim", + address="GPIB::1::INSTR", + pyvisa_sim_file="keysight_34980A.yaml", + ) + request.addfinalizer(inst.close) + + warning_messages = {str(record.message) for record in warning_records} + assert any("slot_1_34934A_8x64_no_driver" in msg for msg in warning_messages) + assert any("slot_3_34934A_4x32_no_driver" in msg for msg in warning_messages) + + assert set(inst.module) == {1, 3} + for slot, model in ((1, "34934A-8x64"), (3, "34934A-4x32")): + module = inst.module[slot] + assert type(module) is Keysight34980ASwitchMatrixSubModule + assert inst.submodules[f"slot_{slot}_{model}_no_driver"] is module + assert f"can not find driver for {model} in slot {slot}" in caplog.text + + +def test_rescan_slots_keeps_existing_modules(switch_driver: Keysight34980A) -> None: + modules = dict(switch_driver.module) + submodules = dict(switch_driver.submodules) + + switch_driver.scan_slots() + + assert switch_driver.module == modules + assert switch_driver.submodules == submodules + + +def test_rescan_slots_keeps_existing_generic_modules( + request: FixtureRequest, + monkeypatch: pytest.MonkeyPatch, +) -> None: + monkeypatch.setattr(keysight_34980a, "KEYSIGHT_MODELS", {}) + with pytest.warns(UserWarning, match="_no_driver"): + inst = Keysight34980A( + "keysight_34980A_sim", + address="GPIB::1::INSTR", + pyvisa_sim_file="keysight_34980A.yaml", + ) + request.addfinalizer(inst.close) + modules = dict(inst.module) + + inst.scan_slots() + + assert inst.module == modules + for slot, model in ((1, "34934A-8x64"), (3, "34934A-4x32")): + assert inst.submodules[f"slot_{slot}_{model}_no_driver"] is inst.module[slot] diff --git a/tests/drivers/test_keysight_e4980a.py b/tests/drivers/test_keysight_e4980a.py index 7375171a977e..844a5f98ae5f 100644 --- a/tests/drivers/test_keysight_e4980a.py +++ b/tests/drivers/test_keysight_e4980a.py @@ -65,3 +65,12 @@ def test_raise_error_for_curr_level_query_when_signal_set_as_voltage( def test_current_level_set_method(driver: E4980A.KeysightE4980A) -> None: driver.current_level(0.003) assert driver.current_level() == 0.003 + + +def test_range_is_float(driver: E4980A.KeysightE4980A) -> None: + impedance_range = driver.range() + assert isinstance(impedance_range, float) + assert impedance_range == 100.0 + + driver.range(1000) + assert driver.range() == 1000.0 diff --git a/tests/drivers/test_keysight_n5222b.py b/tests/drivers/test_keysight_n5222b.py new file mode 100644 index 000000000000..2ff162803149 --- /dev/null +++ b/tests/drivers/test_keysight_n5222b.py @@ -0,0 +1,45 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.Keysight import KeysightN5222B + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(name="pna") +def _make_pna() -> "Generator[KeysightN5222B, None, None]": + driver = KeysightN5222B( + "n5222b", + address="GPIB::1::INSTR", + pyvisa_sim_file="Keysight_N5222B.yaml", + ) + yield driver + driver.close() + + +def test_active_trace(pna: KeysightN5222B) -> None: + active_trace = pna.active_trace() + assert active_trace == 1 + assert isinstance(active_trace, int) + + # while it does not type check, make sure a non-integer trace number is + # rejected at runtime + with pytest.raises(TypeError): + pna.active_trace(1.5) # pyright: ignore[reportArgumentType] + + +@pytest.mark.parametrize("name", ["averages", "points"]) +def test_int_parameters(pna: KeysightN5222B, name: str) -> None: + param = pna.parameters[name] + param(10) + value = param() + assert value == 10 + assert isinstance(value, int) + + # these are counts so a non-integer value is rejected by the validator + # before anything is sent to the instrument + with pytest.raises(TypeError): + param(2.5) + assert param() == 10 diff --git a/tests/drivers/test_lakeshore_325.py b/tests/drivers/test_lakeshore_325.py index f683421a52f6..180cc3459592 100644 --- a/tests/drivers/test_lakeshore_325.py +++ b/tests/drivers/test_lakeshore_325.py @@ -1,11 +1,144 @@ +from typing import TYPE_CHECKING + import hypothesis.strategies as st +import pytest from hypothesis import given from qcodes.instrument_drivers.Lakeshore import ( + LakeshoreModel325, LakeshoreModel325Sensor, LakeshoreModel325Status, ) +if TYPE_CHECKING: + from collections.abc import Generator + + from pytest_mock import MockerFixture + + +@pytest.fixture(scope="function", name="lakeshore_325") +def _make_lakeshore_325() -> "Generator[LakeshoreModel325, None, None]": + driver = LakeshoreModel325( + "lakeshore_325", + address="GPIB::1::INSTR", + pyvisa_sim_file="lakeshore_model325.yaml", + ) + try: + yield driver + finally: + driver.close() + + +def test_output_range(lakeshore_325: LakeshoreModel325) -> None: + heater_1 = lakeshore_325.heater_1 + heater_2 = lakeshore_325.heater_2 + + assert heater_1.output_range() == "Off" + heater_1.output_range("High (25W)") + assert heater_1.output_range() == "High (25W)" + + heater_2.output_range("Low (2.5W)") + assert heater_2.output_range() == "Low (2.5W)" + + +def test_high_output_range_only_on_loop_1(lakeshore_325: LakeshoreModel325) -> None: + with pytest.raises(ValueError, match="High \\(25W\\)"): + lakeshore_325.heater_2.output_range("High (25W)") + assert lakeshore_325.heater_2.output_range() == "Off" + + +def test_curve_index(lakeshore_325: LakeshoreModel325) -> None: + sensor_a = lakeshore_325.sensor_A + assert sensor_a.curve_index() == 2 + + sensor_a.curve_index(23) + assert sensor_a.curve_index() == 23 + + # 0 means no curve, which the instrument also falls back to when the + # curve does not match the input + assert lakeshore_325.sensor_B.curve_index() == 0 + sensor_a.curve_index(0) + assert sensor_a.curve_index() == 0 + + +@pytest.mark.parametrize("value", [-1, 36, 2.5]) +def test_curve_index_rejects_invalid( + lakeshore_325: LakeshoreModel325, value: float +) -> None: + with pytest.raises((TypeError, ValueError)): + lakeshore_325.sensor_A.curve_index(value) # pyright: ignore[reportArgumentType] + + +def test_sensor_curve(lakeshore_325: LakeshoreModel325) -> None: + sensor_a = lakeshore_325.sensor_A + assert sensor_a.curve.short_name == "curve_2" + + sensor_a.curve_index(23) + assert sensor_a.curve.short_name == "curve_23" + + +def test_sensor_curve_none_selected(lakeshore_325: LakeshoreModel325) -> None: + # curve index 0 means no curve; there is no curve 0 to query + assert lakeshore_325.sensor_B.curve_index() == 0 + with pytest.raises(RuntimeError, match="No curve is selected"): + _ = lakeshore_325.sensor_B.curve + + +def _fake_curve_ask(cmd: str) -> str: + # a header with the V/K format and a point n with units n/1000 at n K + if cmd.startswith("CRVHDR?"): + return "DT-470,00011134,2,325.0,1" + if cmd.startswith("CRVPT?"): + point = int(cmd.split(",")[1]) + return f"{point / 1000},{float(point)}" + raise ValueError(f"unexpected query {cmd}") + + +def test_curves_include_user_curve_35( + lakeshore_325: LakeshoreModel325, mocker: "MockerFixture" +) -> None: + # curves 1-20 are standard and 21-35 user curves + assert len(lakeshore_325.curve) == 35 + assert lakeshore_325.curve[-1].short_name == "curve_35" + + mocker.patch.object(lakeshore_325, "ask", side_effect=_fake_curve_ask) + write = mocker.patch.object(lakeshore_325, "write") + lakeshore_325.upload_curve( + 35, + name="DT-470", + serial_number="00011134", + data_dict={"Temperature (K)": [470.0], "V": [0.10191]}, + ) + assert write.call_args_list[-1] == mocker.call("CRVPT 35, 1, 0.10191, 470") + + +def test_curve_get_data_reads_200_points( + lakeshore_325: LakeshoreModel325, mocker: "MockerFixture" +) -> None: + ask = mocker.patch.object(lakeshore_325, "ask", side_effect=_fake_curve_ask) + + data = lakeshore_325.curve[20].get_data() + + assert data["Temperature (K)"] == [float(point) for point in range(1, 201)] + assert data["V"] == [point / 1000 for point in range(1, 201)] + ask.assert_any_call("CRVPT? 21, 200") + + +def test_curve_set_data_uses_6_digits( + lakeshore_325: LakeshoreModel325, mocker: "MockerFixture" +) -> None: + # the instrument stores curve points to 6 digits + write = mocker.patch.object(lakeshore_325, "write") + + lakeshore_325.curve[20].set_data( + {"Temperature (K)": [470.0, 1.4], "V": [0.10191, 1.70333]} + ) + + assert write.call_args_list == [ + mocker.call("CRVPT 21, 1, 0.10191, 470"), + mocker.call("CRVPT 21, 2, 1.70333, 1.4"), + ] + @given( st.lists( diff --git a/tests/drivers/test_rigol_dg1062.py b/tests/drivers/test_rigol_dg1062.py new file mode 100644 index 000000000000..957b8d9d2ef0 --- /dev/null +++ b/tests/drivers/test_rigol_dg1062.py @@ -0,0 +1,69 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.rigol import RigolDG1062 + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(scope="function", name="dg1062") +def _make_dg1062() -> "Generator[RigolDG1062, None, None]": + driver = RigolDG1062( + "dg1062", address="GPIB::1::INSTR", pyvisa_sim_file="Rigol_DG1062.yaml" + ) + try: + yield driver + finally: + driver.close() + + +def test_burst_ncycles_is_int(dg1062: RigolDG1062) -> None: + burst = dg1062.ch1.burst + assert burst.ncycles() == 1 + + burst.ncycles(10) + ncycles = burst.ncycles() + assert isinstance(ncycles, int) + assert ncycles == 10 + + +def test_burst_phase_is_float(dg1062: RigolDG1062) -> None: + burst = dg1062.ch1.burst + assert burst.phase() == 0.0 + + burst.phase(10.5) + phase = burst.phase() + assert isinstance(phase, float) + assert phase == 10.5 + + +def test_burst_time_delay_is_float(dg1062: RigolDG1062) -> None: + burst = dg1062.ch1.burst + assert burst.time_delay() == 0.0 + + burst.time_delay(0.1) + time_delay = burst.time_delay() + assert isinstance(time_delay, float) + assert time_delay == 0.1 + + +def test_waveform_is_str(dg1062: RigolDG1062) -> None: + assert dg1062.ch1.waveform() == "SQU" + assert dg1062.ch2.waveform() == "SIN" + + +def test_waveform_params_are_floats(dg1062: RigolDG1062) -> None: + assert dg1062.ch1.freq() == 1000.0 + assert dg1062.ch1.ampl() == 5.0 + + +def test_duty_cycle_is_float(dg1062: RigolDG1062) -> None: + assert dg1062.ch1.waveform() == "SQU" + assert dg1062.ch1.duty_cycle() == 50.0 + + dg1062.ch1.duty_cycle(45) + duty_cycle = dg1062.ch1.duty_cycle() + assert isinstance(duty_cycle, float) + assert duty_cycle == 45.0 diff --git a/tests/drivers/test_rigol_ds1074z.py b/tests/drivers/test_rigol_ds1074z.py index 9790508488e1..9acfad919a0e 100644 --- a/tests/drivers/test_rigol_ds1074z.py +++ b/tests/drivers/test_rigol_ds1074z.py @@ -65,6 +65,16 @@ def test_sets_correct_trigger_mode(driver: RigolDS1074Z) -> None: assert driver.trigger_mode() == "video" +def test_trigger_level_is_float(driver: RigolDS1074Z) -> None: + driver.trigger_mode("edge") + trigger_level = driver.trigger_level() + assert isinstance(trigger_level, float) + assert trigger_level == 0.16 + + driver.trigger_level(0.5) + assert driver.trigger_level() == 0.5 + + def test_get_data_source(driver: RigolDS1074Z) -> None: driver.data_source("ch1") assert driver.data_source() == "ch1" diff --git a/tests/drivers/test_rigol_ds4000.py b/tests/drivers/test_rigol_ds4000.py new file mode 100644 index 000000000000..bcd8c743a81e --- /dev/null +++ b/tests/drivers/test_rigol_ds4000.py @@ -0,0 +1,33 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.rigol import RigolDS4000 + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(scope="function", name="ds4000") +def _make_ds4000() -> "Generator[RigolDS4000, None, None]": + driver = RigolDS4000( + "rigol_ds4000", + address="GPIB::1::INSTR", + pyvisa_sim_file="Rigol_DS4000.yaml", + # the driver does not set a default terminator; pyvisa-sim needs one + terminator="\n", + ) + try: + yield driver + finally: + driver.close() + + +def test_enable_auto_scale(ds4000: RigolDS4000) -> None: + assert ds4000.enable_auto_scale() is True + + ds4000.enable_auto_scale(False) + assert ds4000.enable_auto_scale() is False + + ds4000.enable_auto_scale(True) + assert ds4000.enable_auto_scale() is True diff --git a/tests/drivers/test_rohde_schwarz_znb.py b/tests/drivers/test_rohde_schwarz_znb.py new file mode 100644 index 000000000000..fb2ee7b397bf --- /dev/null +++ b/tests/drivers/test_rohde_schwarz_znb.py @@ -0,0 +1,44 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.rohde_schwarz import RohdeSchwarzZNB20 + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(name="znb") +def _make_znb() -> "Generator[RohdeSchwarzZNB20, None, None]": + driver = RohdeSchwarzZNB20( + "znb20", + address="TCPIP0::localhost::inst0::INSTR", + pyvisa_sim_file="Rohde_Schwarz_ZNB20.yaml", + terminator="\n", + init_s_params=False, + reset_channels=False, + ) + driver.add_channel("S21") + yield driver + driver.close() + + +def test_bandwidth_default(znb: RohdeSchwarzZNB20) -> None: + assert znb.channels[0].bandwidth() == 10e3 + + +def test_bandwidth_non_integer(znb: RohdeSchwarzZNB20) -> None: + # The IF bandwidth can be set in 1 - 1.5 - 2 - 3 - 5 - 7 steps from 1 Hz + # (see the R&S ZNB user manual, [SENSe:]BANDwidth[:RESolution]), so + # 1.5 Hz is a valid value, which the instrument reports as a non-integer + channel = znb.channels[0] + channel.bandwidth(1.5) + bandwidth = channel.bandwidth() + assert bandwidth == 1.5 + assert isinstance(bandwidth, float) + + # the CW trace setpoints are derived from the bandwidth + npts = channel.npts() + setpoints = channel.trace_fixed_frequency.setpoints + assert setpoints is not None + assert setpoints[0][0][-1] == pytest.approx(npts / 1.5) diff --git a/tests/drivers/test_rs_sgs100a.py b/tests/drivers/test_rs_sgs100a.py index 9361c7098595..a40d158b27c7 100644 --- a/tests/drivers/test_rs_sgs100a.py +++ b/tests/drivers/test_rs_sgs100a.py @@ -50,6 +50,25 @@ def test_status(sg: RohdeSchwarzSGS100A) -> None: verify_property(sg, "status", [True, False]) +def test_on_off(sg: RohdeSchwarzSGS100A) -> None: + sg.on() + assert sg.status() is True + sg.off() + assert sg.status() is False + + +@pytest.mark.parametrize( + ("value", "expected"), + [("on", True), ("OFF", False), (1, True), (0, False)], +) +def test_status_accepts_on_off_strings_and_ints( + sg: RohdeSchwarzSGS100A, value: str | int, expected: bool +) -> None: + # while it does not type check, on/off strings and ints are accepted + sg.status(value) # pyright: ignore[reportArgumentType] + assert sg.status() is expected + + def test_IQ_state(sg: RohdeSchwarzSGS100A) -> None: verify_property(sg, "IQ_state", [True, False]) diff --git a/tests/drivers/test_rto_1000.py b/tests/drivers/test_rto_1000.py index 4987a6dc4ee4..2f96d0284c9b 100644 --- a/tests/drivers/test_rto_1000.py +++ b/tests/drivers/test_rto_1000.py @@ -33,3 +33,24 @@ def test_trigger_source_level(driver: RTO1000) -> None: driver.trigger_level(1.0) assert driver.trigger_level() == 1 driver.trigger_level(0) + + +def test_trigger_mode(driver: RTO1000) -> None: + assert driver.trigger_mode() == "AUTO" + driver.trigger_mode("NORMAL") + assert driver.trigger_mode() == "NORMAL" + + +def test_set_trigger_source(driver: RTO1000) -> None: + driver.trigger_source("CH2") + assert driver.trigger_source() == "CH2" + + +def test_channel_impedance_is_float(driver: RTO1000) -> None: + ch1 = driver.ch1 + impedance = ch1.impedance() + assert isinstance(impedance, float) + assert impedance == 50.0 + + ch1.impedance(1000) + assert ch1.impedance() == 1000.0 diff --git a/tests/drivers/test_stanford_research_sr86x.py b/tests/drivers/test_stanford_research_sr86x.py new file mode 100644 index 000000000000..aade8416cbac --- /dev/null +++ b/tests/drivers/test_stanford_research_sr86x.py @@ -0,0 +1,23 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.stanford_research import SR860 + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(scope="function", name="sr860") +def _make_sr860() -> "Generator[SR860, None, None]": + driver = SR860("sr860", address="GPIB::1::INSTR", pyvisa_sim_file="SR860.yaml") + try: + yield driver + finally: + driver.close() + + +def test_count_capture_kilobytes_is_int(sr860: SR860) -> None: + captured = sr860.buffer.count_capture_kilobytes() + assert isinstance(captured, int) + assert captured == 12 diff --git a/tests/drivers/test_tektronix_awg5014c.py b/tests/drivers/test_tektronix_awg5014c.py index 2e41616e7d3c..24a3502dea72 100644 --- a/tests/drivers/test_tektronix_awg5014c.py +++ b/tests/drivers/test_tektronix_awg5014c.py @@ -137,6 +137,29 @@ def test_trigger_impedance_get(awg: TektronixAWG5014) -> None: assert val == 50.0 +def test_sequence_pos_is_int(awg: TektronixAWG5014) -> None: + val = awg.sequence_pos.get() + assert isinstance(val, int) + assert val == 1 + + awg.sequence_pos.set(3) + assert awg.sequence_pos.get() == 3 + + +def test_direct_output_is_bool(awg: TektronixAWG5014) -> None: + ch1 = awg.ch1 + assert ch1.direct_output.get() is False + + ch1.direct_output.set(True) + assert ch1.direct_output.get() is True + + # the on/off mapping also accepts 0/1 and "on"/"off" + ch1.direct_output.set(0) + assert ch1.direct_output.get() is False + ch1.direct_output.set("on") + assert ch1.direct_output.get() is True + + def test_clock_source_get(awg: TektronixAWG5014) -> None: assert awg.clock_source.get() == "INT" @@ -178,7 +201,18 @@ def test_event_jump_timing_get(awg: TektronixAWG5014) -> None: def test_DC_output_get(awg: TektronixAWG5014) -> None: - assert awg.DC_output.get() == 0 + assert awg.DC_output.get() is False + + +def test_DC_output_set(awg: TektronixAWG5014) -> None: + awg.DC_output.set(True) + assert awg.DC_output.get() is True + + # the on/off mapping also accepts 0/1 and "on"/"off" + awg.DC_output.set(0) + assert awg.DC_output.get() is False + awg.DC_output.set("on") + assert awg.DC_output.get() is True def test_sequence_length_get(awg: TektronixAWG5014) -> None: @@ -193,7 +227,7 @@ def test_get_state(awg: TektronixAWG5014) -> None: def test_channel_state_get(awg: TektronixAWG5014) -> None: - assert awg.channels[0].state.get() == 0 + assert awg.channels[0].state.get() is False def test_channel_amp_get(awg: TektronixAWG5014) -> None: @@ -216,7 +250,7 @@ def test_channel_filter_get(awg: TektronixAWG5014) -> None: def test_all_channels_have_consistent_defaults(awg: TektronixAWG5014) -> None: """All four channels should return the same default values.""" for ch in awg.channels: - assert ch.state.get() == 0 + assert ch.state.get() is False assert ch.amp.get() == 0.5 assert ch.offset.get() == 0.0 @@ -254,20 +288,20 @@ def test_all_markers_have_consistent_defaults(awg: TektronixAWG5014) -> None: def test_all_channels_off(awg: TektronixAWG5014) -> None: awg.all_channels_off() for ch in awg.channels: - assert ch.state.get() == 0 + assert ch.state.get() is False def test_all_channels_on(awg: TektronixAWG5014) -> None: awg.all_channels_on() for ch in awg.channels: - assert ch.state.get() == 1 + assert ch.state.get() is True def test_all_channels_on_then_off(awg: TektronixAWG5014) -> None: awg.all_channels_on() awg.all_channels_off() for ch in awg.channels: - assert ch.state.get() == 0 + assert ch.state.get() is False # ── _pack_waveform ──────────────────────────────────────────────────── diff --git a/tests/drivers/test_tektronix_dpo7200xx.py b/tests/drivers/test_tektronix_dpo7200xx.py index 17208ce87beb..13556e8f9ddb 100644 --- a/tests/drivers/test_tektronix_dpo7200xx.py +++ b/tests/drivers/test_tektronix_dpo7200xx.py @@ -1,5 +1,6 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal +import numpy as np import pytest from qcodes.instrument_drivers.tektronix.DPO7200xx import TektronixDPO7000xx @@ -74,4 +75,116 @@ def test_measurements_return_float(tektronix_dpo: TektronixDPO7000xx) -> None: def test_measurement_sets_state(tektronix_dpo: TektronixDPO7000xx) -> None: tektronix_dpo.measurement[1].frequency() - assert tektronix_dpo.measurement[1].state() == 1 + assert tektronix_dpo.measurement[1].state() is True + + +def test_record_length(tektronix_dpo: TektronixDPO7000xx) -> None: + record_length = tektronix_dpo.horizontal.record_length() + assert record_length == 1_000_000 + assert isinstance(record_length, int) + + tektronix_dpo.horizontal.record_length(1000) + assert tektronix_dpo.horizontal.record_length() == 1000 + + +@pytest.mark.parametrize( + ("value", "expected"), + [("ON", True), ("off", False), (1, True), (0, False)], +) +def test_measurement_state_accepts_on_off_strings_and_ints( + tektronix_dpo: TektronixDPO7000xx, value: str | int, expected: bool +) -> None: + # while it does not type check, on/off strings and ints are accepted + tektronix_dpo.measurement[1].state(value) # pyright: ignore[reportArgumentType] + assert tektronix_dpo.measurement[1].state() is expected + + +# raw samples in digitizing levels (valid for all binary formats) and the same +# samples scaled with the simulated preamble: (raw - YOFF) * YMULT + YZERO +# with YOFF = -50, YMULT = 4 mV and YZERO = -100 mV +RAW_SAMPLES = [0, 50, 75] +SCALED_SAMPLES = [0.1, 0.3, 0.4] + + +def test_waveform_preamble(tektronix_dpo: TektronixDPO7000xx) -> None: + waveform = tektronix_dpo.channel[0].waveform + raw_data_offset = waveform.raw_data_offset() + assert raw_data_offset == -50 + assert isinstance(raw_data_offset, float) + assert waveform.scale() == 4e-3 + assert waveform.offset() == -0.1 + + +def test_trace_ascii( + tektronix_dpo: TektronixDPO7000xx, mocker: "MockerFixture" +) -> None: + tektronix_dpo.waveform.is_binary(False) + query = mocker.patch.object( + tektronix_dpo.visa_handle, + "query_ascii_values", + return_value=np.array(RAW_SAMPLES, dtype=float), + ) + + trace = tektronix_dpo.channel[0].waveform.trace() + + query.assert_called_once_with("CURVE?", container=np.ndarray) + assert trace.dtype == np.float64 + np.testing.assert_allclose(trace, SCALED_SAMPLES) + + +@pytest.mark.parametrize( + ("data_format", "bytes_per_sample", "is_big_endian", "datatype"), + [ + ("signed_integer", 1, False, "b"), + ("unsigned_integer", 1, False, "B"), + ("signed_integer", 2, True, "h"), + ("unsigned_integer", 2, False, "H"), + ("floating_point", 4, False, "f"), + ("floating_point", 8, True, "d"), + ], +) +def test_trace_binary( + tektronix_dpo: TektronixDPO7000xx, + mocker: "MockerFixture", + data_format: Literal["signed_integer", "unsigned_integer", "floating_point"], + bytes_per_sample: Literal[1, 2, 4, 8], + is_big_endian: bool, + datatype: str, +) -> None: + waveform_format = tektronix_dpo.waveform + waveform_format.is_binary(True) + waveform_format.data_format(data_format) + waveform_format.bytes_per_sample(bytes_per_sample) + waveform_format.is_big_endian(is_big_endian) + # integer samples are returned as an integer array, which must still be + # scaled to floats + query = mocker.patch.object( + tektronix_dpo.visa_handle, + "query_binary_values", + return_value=np.array(RAW_SAMPLES, dtype=np.dtype(datatype)), + ) + + trace = tektronix_dpo.channel[0].waveform.trace() + + query.assert_called_once_with( + "CURVE?", + datatype=datatype, + is_big_endian=is_big_endian, + container=np.ndarray, + ) + assert trace.dtype == np.float64 + np.testing.assert_allclose(trace, SCALED_SAMPLES) + + +def test_trace_binary_unsupported_format( + tektronix_dpo: TektronixDPO7000xx, mocker: "MockerFixture" +) -> None: + waveform_format = tektronix_dpo.waveform + waveform_format.is_binary(True) + waveform_format.data_format("floating_point") + waveform_format.bytes_per_sample(1) + query = mocker.patch.object(tektronix_dpo.visa_handle, "query_binary_values") + + with pytest.raises(ValueError, match="Unsupported combination"): + tektronix_dpo.channel[0].waveform.trace() + query.assert_not_called() diff --git a/tests/drivers/test_tektronix_tps2012.py b/tests/drivers/test_tektronix_tps2012.py new file mode 100644 index 000000000000..c980b5e216e9 --- /dev/null +++ b/tests/drivers/test_tektronix_tps2012.py @@ -0,0 +1,32 @@ +from typing import TYPE_CHECKING + +import pytest + +from qcodes.instrument_drivers.tektronix import TektronixTPS2012 + +if TYPE_CHECKING: + from collections.abc import Generator + + +@pytest.fixture(scope="function", name="tps2012") +def _make_tps2012() -> "Generator[TektronixTPS2012, None, None]": + driver = TektronixTPS2012( + "tps2012", + address="GPIB::1::INSTR", + pyvisa_sim_file="Tektronix_TPS2012.yaml", + # the driver does not set a default terminator; pyvisa-sim needs one + terminator="\n", + ) + try: + yield driver + finally: + driver.close() + + +def test_trigger_level_is_float(tps2012: TektronixTPS2012) -> None: + trigger_level = tps2012.trigger_level() + assert isinstance(trigger_level, float) + assert trigger_level == 1.4 + + tps2012.trigger_level(0.25) + assert tps2012.trigger_level() == 0.25