Download
Download this file as Jupyter notebook: hdf5_file_interface.ipynb.
Interfacing with HDF5 files
After executing a program, its results can be exported from the database to a portable
HDF5 file with the to_hdf5()
method, as shown
in Running a program on hardware. In this tutorial, we go over of the structure of these
files.
[2]:
import h5py
import keysight.qcs as qcs
import numpy as np
file = h5py.File("swept_program.hdf5")
Accessing the program and data through QCS
The program that was executed can be loaded from the file by calling
load()
.
[3]:
program = qcs.load("swept_program.hdf5")
We can inspect the program that was executed.
[4]:
program.draw()
Program
Program
|
|||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Layer #0
Layer #0
|
|||||||||||||||||||||||
|
|
RFWaveform on ('awgs', 0)
Parameters
|
Delay on ('awgs', 0)
Parameters
|
||||||||||||||||||||
|
RFWaveform on ('awgs', 1)
Parameters
|
Delay on ('awgs', 1)
Parameters
|
|||||||||||||||||||||
|
RFWaveform on ('awgs', 2)
Parameters
|
Delay on ('awgs', 2)
Parameters
|
|||||||||||||||||||||
|
RFWaveform on ('awgs', 3)
Parameters
|
Delay on ('awgs', 3)
Parameters
|
|||||||||||||||||||||
|
|
Delay on ('digs', 0)
Parameters
|
Acquisition on ('digs', 0)
Parameters
|
||||||||||||||||||||
|
Delay on ('digs', 1)
Parameters
|
Acquisition on ('digs', 1)
Parameters
|
|||||||||||||||||||||
|
Delay on ('digs', 2)
Parameters
|
Acquisition on ('digs', 2)
Parameters
|
|||||||||||||||||||||
|
Delay on ('digs', 3)
Parameters
|
Acquisition on ('digs', 3)
Parameters
|
We can load the data. This will load from the hdf5 file, rather than the database.
[5]:
program.get_trace()
[5]:
(((Channels(labels=[0], name=digs, absolute_phase=True)))) | ... | (((Channels(labels=[3], name=digs, absolute_phase=True)))) | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
(rf, [3.85 GHz, 3.9 GHz, 3.95 GHz, ... ]) | ... | (rf, [4.25 GHz, 4.3 GHz, 4.35 GHz, ... ]) | |||||||||||||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
0 | 0.007910 | 0.007690 | 0.006812 | 0.008130 | 0.005054 | 0.005933 | 0.007471 | 0.008130 | 0.008789 | 0.007471 | ... | 0.007031 | 0.005933 | 0.005273 | 0.003076 | 0.003955 | 0.007471 | 0.005054 | 0.005933 | 0.006372 | 0.005273 |
1 | 0.007690 | 0.007251 | 0.007251 | 0.008350 | 0.008350 | 0.007910 | 0.007031 | 0.009009 | 0.006592 | 0.007690 | ... | 0.006372 | 0.005713 | 0.005273 | 0.004175 | 0.006812 | 0.005273 | 0.007471 | 0.007251 | 0.004175 | 0.005713 |
2 | 0.009229 | 0.005933 | 0.006812 | 0.005273 | 0.007690 | 0.008350 | 0.006812 | 0.007690 | 0.006152 | 0.007471 | ... | 0.003076 | 0.006152 | 0.005493 | 0.005054 | 0.005273 | 0.007251 | 0.004395 | 0.004395 | 0.005054 | 0.003296 |
3 | 0.007031 | 0.009668 | 0.010107 | 0.006592 | 0.006592 | 0.009668 | 0.008130 | 0.006812 | 0.009888 | 0.010547 | ... | 0.007251 | 0.004834 | 0.005933 | 0.005273 | 0.004834 | 0.005273 | 0.005713 | 0.005933 | 0.005273 | 0.005493 |
4 | 0.008350 | 0.006592 | 0.005713 | 0.010767 | 0.007910 | 0.007251 | 0.007251 | 0.009668 | 0.007471 | 0.007031 | ... | 0.004614 | 0.006812 | 0.005713 | 0.008130 | 0.007251 | 0.004834 | 0.007031 | 0.006812 | 0.005713 | 0.005933 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
379 | 0.005493 | 0.001099 | 0.002417 | 0.005273 | 0.001538 | 0.004175 | 0.005713 | 0.002637 | 0.004614 | 0.002417 | ... | 0.008130 | 0.003955 | 0.005273 | 0.007031 | 0.008350 | 0.008789 | 0.008789 | 0.007031 | 0.008350 | 0.008789 |
380 | 0.000879 | 0.001538 | 0.001318 | 0.002856 | 0.003076 | 0.004834 | 0.003516 | 0.003296 | 0.003516 | 0.004395 | ... | 0.006592 | 0.007251 | 0.005713 | 0.007471 | 0.007910 | 0.005273 | 0.004614 | 0.007690 | 0.003735 | 0.005713 |
381 | 0.004395 | 0.002637 | 0.001099 | 0.003516 | 0.002856 | 0.003735 | 0.002856 | 0.002197 | 0.004614 | 0.002637 | ... | 0.009229 | 0.005713 | 0.007251 | 0.007690 | 0.006812 | 0.005713 | 0.006812 | 0.005933 | 0.006152 | 0.008130 |
382 | 0.005713 | 0.003516 | 0.000659 | 0.003296 | 0.004175 | 0.001538 | 0.004175 | 0.001758 | 0.000000 | 0.003296 | ... | 0.008789 | 0.007690 | 0.006812 | 0.006592 | 0.005713 | 0.005273 | 0.006152 | 0.009448 | 0.005493 | 0.006592 |
383 | 0.004614 | 0.002417 | 0.002637 | 0.001099 | 0.004614 | 0.005933 | 0.004395 | 0.003296 | 0.003296 | 0.001538 | ... | 0.007031 | 0.008569 | 0.006812 | 0.006592 | 0.005933 | 0.007690 | 0.005493 | 0.004834 | 0.005933 | 0.005273 |
384 rows × 440 columns
Inspecting the file directly
We can also use the hdf5 python library to inspect the file directly.
The attributes of the HDF5 are accessed with the attrs
property.
[6]:
list(file.attrs.keys())
[6]:
['Program', 'ChannelMapper', 'FPGAPostprocessing', 'Shape', 'Version']
The FPGAPostprocessing
attribute specifies whether these results are obtained with
(True
) or without (False
) hardware demodulation. The file contains either
IQ or trace data, respectively. This file contains trace data.
[7]:
file.attrs["FPGAPostprocessing"]
[7]:
False
The Shape
attribute describes how the program was repeated during execution and is
similar to the shape of a program’s
repetitions
. As we flatten the data, this
value describes how the data should be reshaped. For trace data the innermost value is
set to \(-1\) to account for different numbers of samples, following the
the convention of, e.g., numpy.reshape()
.
[8]:
file.attrs["Shape"]
[8]:
array([[11, 10, -1]], dtype=int32)
The above value indicates that the trace data should be interpreted as an array of shape \((11, 10, n / (11 * 10))\), where \(n\) is the total number of data points.
Finally, the Program
and the ChannelMapper
used during its execution are
serialized and stored in the file.
Datasets on the file
The file structure is different dependent on whether the program contains IQ or trace data.
Trace data
An HDF5 file containing trace data will store each repeated acquisition in its own
dataset. The datasets are stored in groups named
DutChannel_{channel_number}_Acquisition_{acquisition_number}
that are keys of the
file, each of which corresponds to a physical channel.
[9]:
list(file.keys())
[9]:
['DutChannel_20_Acquisition_0']
This file contains a single group for the acquisitions on DutChannel_20
. The group
has a dataset with no additional attributes named trace
.
[10]:
acquisition = file["DutChannel_20_Acquisition_0"]["trace"]
acquisition.shape
[10]:
(42240,)
We then reshape to and display the innermost value, the number of samples per repetition.
[11]:
np.reshape(acquisition, file.attrs["Shape"][0]).shape[-1]
[11]:
384
IQ data
We now load a file that contains results from the same program run with hardware demodulation.
[12]:
file_demod = h5py.File("swept_program_demod.hdf5")
file_demod.attrs["FPGAPostprocessing"]
[12]:
True
Instead of using physical channels as keys, the IQ data uses virtual channels
to label the groups as
Channel_{channel_name}_{channel_label}_Acquisition_{acquisition_number}
.
[13]:
list(file_demod.keys())
[13]:
['Channel_digs_0_Acquisition_0',
'Channel_digs_1_Acquisition_0',
'Channel_digs_2_Acquisition_0',
'Channel_digs_3_Acquisition_0']
The IQ data is separated into real and imaginary parts.
[14]:
acquisition_demod = file_demod["Channel_digs_0_Acquisition_0"]
print(acquisition_demod["iq_real"])
print(acquisition_demod["iq_imaginary"])
<HDF5 dataset "iq_real": shape (110,), type "<f8">
<HDF5 dataset "iq_imaginary": shape (110,), type "<f8">
The shape of the IQ data is exactly the program’s repetitions’ shape.
[15]:
np.reshape(acquisition_demod["iq_real"], file_demod.attrs["Shape"][0]).shape
[15]:
(11, 10, 1)
Download
Download this file as Jupyter notebook: hdf5_file_interface.ipynb.