{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "6ff38bea", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:33.247513Z", "iopub.status.busy": "2024-10-11T06:15:33.246911Z", "iopub.status.idle": "2024-10-11T06:15:33.253951Z", "shell.execute_reply": "2024-10-11T06:15:33.253011Z" }, "nbsphinx": "hidden" }, "outputs": [], "source": [ "# Copyright 2024 Keysight Technologies Inc." ] }, { "cell_type": "raw", "id": "40e3f664", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Interfacing with HDF5 files\n", "===========================\n", "After executing a program, its results can be exported from the database to a portable\n", "HDF5 file with the :py:meth:`~keysight.qcs.programs.Program.to_hdf5` method, as shown\n", "in :doc:`hello_hardware`\\. In this tutorial, we go over of the structure of these\n", "files." ] }, { "cell_type": "code", "execution_count": 2, "id": "6114b0cd", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:33.257410Z", "iopub.status.busy": "2024-10-11T06:15:33.257084Z", "iopub.status.idle": "2024-10-11T06:15:36.402793Z", "shell.execute_reply": "2024-10-11T06:15:36.401723Z" } }, "outputs": [], "source": [ "import h5py\n", "import keysight.qcs as qcs\n", "import numpy as np\n", "\n", "file = h5py.File(\"swept_program.hdf5\")" ] }, { "cell_type": "raw", "id": "364ee812", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Attributes on the file\n", "----------------------\n", "The attributes of the HDF5 are accessed with the ``attrs`` property." ] }, { "cell_type": "code", "execution_count": 3, "id": "6d29410d", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.407262Z", "iopub.status.busy": "2024-10-11T06:15:36.406779Z", "iopub.status.idle": "2024-10-11T06:15:36.415605Z", "shell.execute_reply": "2024-10-11T06:15:36.414926Z" } }, "outputs": [ { "data": { "text/plain": [ "['Program', 'ChannelMapper', 'FPGAPostprocessing', 'Shape', 'Version']" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(file.attrs.keys())" ] }, { "cell_type": "raw", "id": "5c524c33", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The ``FPGAPostprocessing`` attribute specifies whether these results are obtained with\n", "(``True``) or without (``False``) hardware demodulation. The file contains either\n", "IQ or trace data, respectively. This file contains trace data." ] }, { "cell_type": "code", "execution_count": 4, "id": "d523b4b6", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.419091Z", "iopub.status.busy": "2024-10-11T06:15:36.418765Z", "iopub.status.idle": "2024-10-11T06:15:36.424812Z", "shell.execute_reply": "2024-10-11T06:15:36.424061Z" } }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "file.attrs[\"FPGAPostprocessing\"]" ] }, { "cell_type": "raw", "id": "e9f7b36b", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The ``Shape`` attribute describes how the program was repeated during execution and is\n", "similar to the shape of a program's\n", ":py:attr:`~keysight.qcs.programs.Program.repetitions`\\. As we flatten the data, this\n", "value describes how the data should be reshaped. For trace data the innermost value is\n", "set to :math:`-1` to account for different numbers of samples, following the\n", "the convention of, e.g., :py:meth:`numpy.reshape`\\." ] }, { "cell_type": "code", "execution_count": 5, "id": "af730178", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.428020Z", "iopub.status.busy": "2024-10-11T06:15:36.427724Z", "iopub.status.idle": "2024-10-11T06:15:36.433877Z", "shell.execute_reply": "2024-10-11T06:15:36.432953Z" } }, "outputs": [ { "data": { "text/plain": [ "array([11, 10, -1], dtype=int32)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "file.attrs[\"Shape\"]" ] }, { "cell_type": "raw", "id": "3b64492e", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The above value indicates that the trace data should be interpreted as an array of\n", "shape :math:`(11, 10, n / (11 * 10))`\\, where :math:`n` is the total number of data\n", "points.\n", "\n", "Finally, the ``Program`` and the ``ChannelMapper`` used during its execution are\n", "serialized and stored in the file.\n", "\n", "Datasets on the file\n", "--------------------\n", "The file structure is different dependent on whether the program contains IQ or trace\n", "data.\n", "\n", "Trace data\n", "^^^^^^^^^^\n", "An HDF5 file containing trace data will store each repeated acquisition in its own\n", "dataset. The datasets are stored in groups named\n", "``DutChannel_{channel_number}_Acquisition_{acquisition_number}`` that are keys of the\n", "file, each of which corresponds to a physical channel." ] }, { "cell_type": "code", "execution_count": 6, "id": "aa1cab10", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.437504Z", "iopub.status.busy": "2024-10-11T06:15:36.437194Z", "iopub.status.idle": "2024-10-11T06:15:36.442787Z", "shell.execute_reply": "2024-10-11T06:15:36.441923Z" } }, "outputs": [ { "data": { "text/plain": [ "['DutChannel_1_Acquisition_0']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(file.keys())" ] }, { "cell_type": "raw", "id": "a5435c04", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "This file contains a single group for the acquisitions on ``DutChannel_1``. The group\n", "has a dataset with no additional attributes named ``trace``." ] }, { "cell_type": "code", "execution_count": 7, "id": "eda34292", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.445912Z", "iopub.status.busy": "2024-10-11T06:15:36.445601Z", "iopub.status.idle": "2024-10-11T06:15:36.451111Z", "shell.execute_reply": "2024-10-11T06:15:36.450445Z" } }, "outputs": [ { "data": { "text/plain": [ "(42240,)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "acquisition = file[\"DutChannel_1_Acquisition_0\"][\"trace\"]\n", "acquisition.shape" ] }, { "cell_type": "raw", "id": "8ceadc48", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "We then reshape to and display the innermost value, the number of samples per\n", "repetition." ] }, { "cell_type": "code", "execution_count": 8, "id": "c35ef523", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.454223Z", "iopub.status.busy": "2024-10-11T06:15:36.453923Z", "iopub.status.idle": "2024-10-11T06:15:36.459967Z", "shell.execute_reply": "2024-10-11T06:15:36.459196Z" } }, "outputs": [ { "data": { "text/plain": [ "384" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.reshape(acquisition, file.attrs[\"Shape\"]).shape[-1]" ] }, { "cell_type": "raw", "id": "ee520848", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "IQ data\n", "^^^^^^^\n", "We now load a file that contains results from the same program run with hardware\n", "demodulation." ] }, { "cell_type": "code", "execution_count": 9, "id": "f0afa03a", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.463087Z", "iopub.status.busy": "2024-10-11T06:15:36.462789Z", "iopub.status.idle": "2024-10-11T06:15:36.469507Z", "shell.execute_reply": "2024-10-11T06:15:36.468612Z" } }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "file_demod = h5py.File(\"swept_program_demod.hdf5\")\n", "file_demod.attrs[\"FPGAPostprocessing\"]" ] }, { "cell_type": "raw", "id": "40ee3a45", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Instead of using physical channels as keys, the IQ data uses virtual channels\n", "to label the groups as\n", "``Channel_{channel_name}_{channel_label}_Acquisition_{acquisition_number}``." ] }, { "cell_type": "code", "execution_count": 10, "id": "9931b3d8", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.472623Z", "iopub.status.busy": "2024-10-11T06:15:36.472232Z", "iopub.status.idle": "2024-10-11T06:15:36.477995Z", "shell.execute_reply": "2024-10-11T06:15:36.476927Z" } }, "outputs": [ { "data": { "text/plain": [ "['Channel_digs_0_Acquisition_0',\n", " 'Channel_digs_1_Acquisition_0',\n", " 'Channel_digs_2_Acquisition_0',\n", " 'Channel_digs_3_Acquisition_0']" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(file_demod.keys())" ] }, { "cell_type": "raw", "id": "a016d734", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The IQ data is separated into real and imaginary parts." ] }, { "cell_type": "code", "execution_count": 11, "id": "e0c1e563", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.481176Z", "iopub.status.busy": "2024-10-11T06:15:36.480868Z", "iopub.status.idle": "2024-10-11T06:15:36.486228Z", "shell.execute_reply": "2024-10-11T06:15:36.485487Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "acquisition_demod = file_demod[\"Channel_digs_0_Acquisition_0\"]\n", "print(acquisition_demod[\"iq_real\"])\n", "print(acquisition_demod[\"iq_imaginary\"])" ] }, { "cell_type": "raw", "id": "d32c22f2", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "The shape of the IQ data is exactly the program's repetitions' shape." ] }, { "cell_type": "code", "execution_count": 12, "id": "78d2119f", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.489462Z", "iopub.status.busy": "2024-10-11T06:15:36.489146Z", "iopub.status.idle": "2024-10-11T06:15:36.495347Z", "shell.execute_reply": "2024-10-11T06:15:36.494620Z" } }, "outputs": [ { "data": { "text/plain": [ "(11, 10)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.reshape(acquisition_demod[\"iq_real\"], file_demod.attrs[\"Shape\"]).shape" ] }, { "cell_type": "raw", "id": "2b08b70d", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Accessing metadata from the program\n", "-----------------------------------\n", "The program that was executed can be loaded from the file by calling\n", ":py:meth:`~keysight.qcs.utils.load`\\." ] }, { "cell_type": "code", "execution_count": 13, "id": "68c71d4e", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:36.498497Z", "iopub.status.busy": "2024-10-11T06:15:36.498197Z", "iopub.status.idle": "2024-10-11T06:15:37.003617Z", "shell.execute_reply": "2024-10-11T06:15:37.002444Z" } }, "outputs": [], "source": [ "program = qcs.load(\"swept_program.hdf5\")" ] }, { "cell_type": "raw", "id": "acc38193", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "We can access metadata including, e.g., the program's repetitions." ] }, { "cell_type": "code", "execution_count": 14, "id": "ae92ea3b", "metadata": { "execution": { "iopub.execute_input": "2024-10-11T06:15:37.008762Z", "iopub.status.busy": "2024-10-11T06:15:37.007110Z", "iopub.status.idle": "2024-10-11T06:15:37.020776Z", "shell.execute_reply": "2024-10-11T06:15:37.019942Z" } }, "outputs": [ { "data": { "text/plain": [ "NestedRepetition(Sweep(rf=Array(name=freq_vals, shape=(11, 4), dtype=float, unit=none)), Repeat(10))" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "program.repetitions" ] }, { "cell_type": "raw", "id": "27bc8df1", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "From this, we see that the program's ``rf`` variable was swept with ``freq_vals`` and\n", "each sweep point was repeated :math:`10` times." ] } ], "metadata": { "jupytext": { "cell_metadata_filter": "nbsphinx,raw_mimetype,-all", "main_language": "python", "notebook_metadata_filter": "-all", "text_representation": { "extension": ".py", "format_name": "percent" } }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.6" } }, "nbformat": 4, "nbformat_minor": 5 }