This page was generated from docs/examples/driver_examples/QCoDeS Example with Keysight E4980A LCR meter.ipynb. Interactive online version: .

# QCoDeS Example with Keysight E4980A LCR meter

This example is following the “Capacitor Measurements” on P215 of the user’s guide: https://literature.cdn.keysight.com/litweb/pdf/E4980-90230.pdf?id=789356

A 8400 pF (8E-9 F) leaded ceramic capacitor is connected to the LCR meter.

```
[1]:
```

```
import time
import numpy as np
from qcodes.dataset import Measurement, initialise_database, new_experiment, plot_by_id
from qcodes.instrument_drivers.Keysight import (
KeysightE4980A,
KeysightE4980AMeasurements,
)
```

```
[2]:
```

```
meter = KeysightE4980A("lcr_e4980a", 'USB0::0x2A8D::0x2F01::MY46618801::INSTR')
```

```
Connected to: Keysight Technologies E4980A (serial:MY46618801, firmware:B.07.05) in 0.07s
```

```
[3]:
```

```
meter.IDN()
```

```
[3]:
```

```
{'vendor': 'Keysight Technologies',
'model': 'E4980A',
'serial': 'MY46618801',
'firmware': 'B.07.05'}
```

```
[4]:
```

```
meter.reset()
```

## Step 1. Set up the E4980A’s measurement conditions:

set frequency to be 1MHz (system default is 1kHz)

set the voltage level to be 1.5 V (system default is 1V)

```
[5]:
```

```
meter.frequency(1e6)
freq = meter.frequency()
print(f'The frequency for normal measurement is set to be {freq/1e6} MHz.')
```

```
The frequency for normal measurement is set to be 1.0 MHz.
```

```
[6]:
```

```
meter.voltage_level(1.5)
volt_lv = meter.voltage_level()
print(f'the voltage for measurement signal is set to be {volt_lv} V.')
```

```
the voltage for measurement signal is set to be 1.5 V.
```

## Step 2. (optional) Set up the corrections for the unit

In the “Capacitor Measurements” example, a Keysight 16047E Direct Couple Test Fixture (general purpose) was used. To compensate for its residuals and strays, an OPEN/SHORT correction is required.

However, for our setup with a leaded ceramic capacitor, this step may not be necessary.

```
[7]:
```

```
meter.correction.open()
meter.correction.open_state('on')
meter.correction.short()
meter.correction.short_state('on')
```

## step 3. Set the meausurement function.

User should chose one function from the follow list, for example “**E4980AMeasurements.CPD**”.

```
"CPD": "Capacitance - Dissipation factor", (by default)
"CPQ": "Capacitance - Quality factor",
"CPG": "Capacitance - Conductance",
"CPRP": "Capacitance - Resistance",
"CSD": "Capacitance - Dissipation factor",
"CSQ": "Capacitance - Quality factor",
"CSRS": "Capacitance - Resistance",
"LPD": "Inductance - Dissipation factor",
"LPQ": "Inductance - Quality factor",
"LPG": "Inductance - Conductance",
"LPRP": "Inductance - Resistance",
"LPRD": "Inductance - DC resistance",
"LSD": "Inductance - Dissipation factor",
"LSQ": "Inductance - Quality factor",
"LSRS": "Inductance - Resistance",
"LSRD": "Inductance - DC resistance",
"RX": "Resistance - Reactance",
"ZTD": "Absolute value of impedance - Theta in degree",
"ZTR": "Absolute value of impedance - Theta in radiant",
"GB": "Conductance - Susceptance",
"YTD": "Absolute value of admittance - Theta in degree",
"YTR": "Absolute value of admittance - Theta in radiant",
"VDID": "DC voltage - DC current"
```

Note: 1. CP vs CS: **P** means measured using parallel equivalent circuit model, and **S** means measured using series equivalent circuit model. 2. Same for LP and LS 3. RP vs RS: Equivalent **p**arallel/**s**eries resistance

By default, the measurement function is “CPD”, which mean “Capacitance - Dissipation factor”:

```
[8]:
```

```
meter.measurement_function()
```

```
[8]:
```

```
'CPD'
```

The “measurement” property will return a “MeasurementPair” class (sub class of “MultiParameter”):

```
[9]:
```

```
measurement = meter.measurement
type(measurement)
```

```
[9]:
```

```
qcodes.instrument_drivers.Keysight.keysight_e4980a.MeasurementPair
```

which has the same name as the **current** “measurement_function”:

```
[10]:
```

```
measurement.name
```

```
[10]:
```

```
'CPD'
```

User can view the parameters to be measured, and the corresponding units as following:

```
[11]:
```

```
print(f'The parameters to be measured are {measurement.names}, with units {measurement.units}')
```

```
The parameters to be measured are ('capacitance', 'dissipation_factor'), with units ('F', '')
```

and take measurements by calling:

```
[12]:
```

```
measurement()
```

```
[12]:
```

```
(-8.35219e-09, -0.00183439)
```

User may also directly call the name of the physics parameters: (can’t call the unit this way though)

```
[13]:
```

```
print(f'The capacitance is measured to be {measurement.capacitance}')
print(f'The dissipation_factor is measured to be {measurement.dissipation_factor}')
```

```
The capacitance is measured to be -8.35219e-09
The dissipation_factor is measured to be -0.00183439
```

To change to another measurement function, for example, “LPD” for Inductance measurement:

```
[14]:
```

```
meter.measurement_function(KeysightE4980AMeasurements.LPD)
meter.measurement_function()
```

```
[14]:
```

```
'LPD'
```

```
[15]:
```

```
measurement = meter.measurement
print(f'The measurement "{measurement.name}" returns values {measurement.get()}')
print(f'for parameters {measurement.names}')
print(f'with units {measurement.units}')
```

```
The measurement "LPD" returns values (3.03277e-06, -0.00183439)
for parameters ('inductance', 'dissipation_factor')
with units ('H', '')
```

Any “MeasurementPair” object, when first initialized, will dynamically generate the corresponding attributes. For the LPD measurement above, the “measurement” object will have attributes “inductance” instead of “capacitance”:

```
[16]:
```

```
measurement.inductance
```

```
[16]:
```

```
3.03277e-06
```

```
[17]:
```

```
try:
measurement.capacitance
except AttributeError as err:
print(err)
```

```
'MeasurementPair' object has no attribute 'capacitance'
```

To validate the measurement, we can measure the impedance, and calculate the capacitance.

For a capacitor, we have Zc = - j / (2 * Pi * f * C), where Zc is the impedance of the capacitor, f is the frequency, and C is the capacitance.

There are actually two methods to measure the impedance: 1. to use the “measurement_function” method as above, and choose “RX”; 2. to use the “measure_impedance()” call, which will always return impedance in complex format, Z = R + iX, where Z is impedance, R is resistance, and X is the reactance.

(The results from the two methods should be the same.)

```
[18]:
```

```
meter.measurement_function(KeysightE4980AMeasurements.RX)
measurement = meter.measurement
print(measurement.names)
print(measurement())
print(measurement.units)
```

```
('resistance', 'reactance')
(-0.0349551, 19.0554)
('Ohm', 'Ohm')
```

```
[19]:
```

```
imp = meter.measure_impedance
print(imp.names)
print(imp())
print(imp.units)
```

```
('resistance', 'reactance')
(-0.0349551, 19.0554)
('Ohm', 'Ohm')
```

To calculate the impedance: (“imp” here is also a “MeasurementPair”, so user can call the resistance/reactance directly.)

```
[20]:
```

```
Zc = np.sqrt(imp.resistance**2 + imp.reactance**2)
print(f"The impedance is {Zc} Ohm.")
```

```
The impedance is 19.0554320606754 Ohm.
```

and the capacitance:

```
[21]:
```

```
C = -1/(2*np.pi*freq*Zc)
print(f"The capacitance is {C}F.")
```

```
The capacitance is -8.352208576804858e-09F.
```

which is the same as what we got previously using the “CPD” function:

```
[22]:
```

```
meter.measurement_function(KeysightE4980AMeasurements.CPD)
measurement = meter.measurement
print(f"The capacitance is {measurement.capacitance} F.")
```

```
The capacitance is -8.35219e-09 F.
```

## To work with QCoDeS “Measurement”:

```
[23]:
```

```
initialise_database()
exp = new_experiment(
name='capacitance_measurement',
sample_name="no sample"
)
```

```
[24]:
```

```
meas = Measurement()
meas.register_parameter(meter.frequency)
meas.register_parameter(meter.measurement, setpoints=(meter.frequency,))
```

```
[24]:
```

```
<qcodes.dataset.measurements.Measurement at 0x1f356cfd3c8>
```

```
[25]:
```

```
with meas.run() as datasaver:
for freq in np.linspace(1.0E6, 1.5E6, 5):
meter.frequency(freq)
time.sleep(1)
value_pair = meter.measurement()
datasaver.add_result((meter.frequency, freq),
(meter.measurement, value_pair))
run_id = datasaver.run_id
```

```
Starting experimental run with id: 73.
```

```
[26]:
```

```
plot = plot_by_id(run_id)
```

The dataset will have two items, one for “capacitance”, and the other for “dissipation_factor”:

```
[27]:
```

```
dataset = datasaver.dataset
dataset.get_parameter_data()
```

```
[27]:
```

```
{'capacitance': {'capacitance': array([-8.35219e-09, -8.34623e-09, -8.41993e-09, -8.45158e-09,
-8.63672e-09]),
'lcr_e4980a_frequency': array([1000000, 1125000, 1250000, 1375000, 1500000])},
'dissipation_factor': {'dissipation_factor': array([-0.00183439, -0.00214259, -0.00246672, -0.00283031, -0.00317048]),
'lcr_e4980a_frequency': array([1000000, 1125000, 1250000, 1375000, 1500000])}}
```

To switch to another measurement function:

```
[28]:
```

```
meter.measurement_function(KeysightE4980AMeasurements.RX)
meter.measurement_function()
```

```
[28]:
```

```
'RX'
```

which will measure the following:

```
[29]:
```

```
KeysightE4980AMeasurements.RX.names
```

```
[29]:
```

```
('resistance', 'reactance')
```

We need to re-set the measurement, and re-register parameters so that qcodes knows the correct units:

```
[30]:
```

```
meas = Measurement()
meas.register_parameter(meter.frequency)
meas.register_parameter(meter.measurement, setpoints=(meter.frequency,))
```

```
[30]:
```

```
<qcodes.dataset.measurements.Measurement at 0x1f35934db88>
```

```
[31]:
```

```
with meas.run() as datasaver:
for freq in np.linspace(1.0E6, 1.5E6, 5):
meter.frequency(freq)
time.sleep(1)
value_pair = meter.measurement()
datasaver.add_result((meter.frequency, freq),
(meter.measurement, value_pair))
run_id = datasaver.run_id
```

```
Starting experimental run with id: 74.
```

```
[32]:
```

```
plot = plot_by_id(run_id)
```

```
[33]:
```

```
meter.reset()
```

```
[ ]:
```

```
```