Skip to content

Commit

Permalink
Release 2.19.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Lienemann committed Nov 9, 2023
1 parent ecf0302 commit 3f2206d
Show file tree
Hide file tree
Showing 89 changed files with 2,149 additions and 1,647 deletions.
3 changes: 1 addition & 2 deletions examples/00_reference/04_pulse_library.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,7 @@
" res = np.ones(len(x))\n",
"\n",
" res[x <= -relative_length_flat] = np.exp(\n",
" -((x[x <= -relative_length_flat] + relative_length_flat) ** 2)\n",
" / (2 * sigma**2)\n",
" -((x[x <= -relative_length_flat] + relative_length_flat) ** 2) / (2 * sigma**2)\n",
" )\n",
" res[x >= relative_length_flat] = np.exp(\n",
" -((x[x >= relative_length_flat] - relative_length_flat) ** 2) / (2 * sigma**2)\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"code_folding": []
},
"source": [
"# User Functions in Near-Time Loops\n",
"# Callbacks in Near-Time Loops\n",
"\n",
"In near-time loops of experiments, any Python function can be executed. These functions are dubbed callback or user functions.\n",
"In near-time loops of experiments, any Python function can be executed. These functions are dubbed near-time callback or user functions.\n",
"\n",
"They can be used to:\n",
"- control non-QCCS instruments, such as Zurich Instruments lock-in amplifiers or third-party instruments, and acquire results from these instruments\n",
Expand Down Expand Up @@ -224,9 +224,9 @@
"id": "28d93015",
"metadata": {},
"source": [
"## 2. User functions\n",
"## 2. Near-time callbacks\n",
"\n",
"First, the user functions are defined. User functions can contain name arguments and return values. Then, the user functions are used in a near-time sweep in an example experiment."
"First, the near-time callbacks are defined. Near-time callbacks can contain name arguments and return values. Then, the near-time callbacks are used in a near-time sweep in an example experiment."
]
},
{
Expand Down Expand Up @@ -262,8 +262,8 @@
"id": "6d973230",
"metadata": {},
"source": [
"### 2.2 Define user functions\n",
"User functions are normal Python functions, but their first argument must be the `session` object. This enables access to all QCCS instruments and the results that have already been collected. The return values will be stored in the `session.results` object."
"### 2.2 Define near-time callbacks\n",
"Near-time callbacks are normal Python functions, but their first argument must be the `session` object. This enables access to all QCCS instruments and the results that have already been collected. The return values will be stored in the `session.results` object."
]
},
{
Expand All @@ -276,15 +276,15 @@
"# additional import for the purpose of demonstration\n",
"import logging\n",
"\n",
"mylogger = logging.getLogger(\"user_func\")\n",
"mylogger = logging.getLogger(\"neartime_callback\")\n",
"\n",
"\n",
"# A user function is a regular python function, taking named arguments\n",
"# A near-time callback is a regular python function, taking named arguments\n",
"# The function may return values, which will be accessible after execution\n",
"# The first argument must be the LabOne Q SW session\n",
"def user_func(session, frequency, amplitude):\n",
"def neartime_callback(session, frequency, amplitude):\n",
" mylogger.info(\n",
" f\"Called 'user_func' with params: frequency={frequency}, amplitude={amplitude:.1f}\"\n",
" f\"Called 'neartime_callback' with params: frequency={frequency}, amplitude={amplitude:.1f}\"\n",
" )\n",
" return f\"frequency={frequency}, amplitude={amplitude:.1f}\"\n",
"\n",
Expand Down Expand Up @@ -333,9 +333,9 @@
"id": "ef00bb1d",
"metadata": {},
"source": [
"User functions can be added before or after the near-time sweep acquisition. The order of their execution follows this position:\n",
"Near-time callbacks can be added before or after the near-time sweep acquisition. The order of their execution follows this position:\n",
"\n",
"`inner_user_func` fills the `inner_results` list in the inner loop, `after_inner_user_func` consumes and clears it afterwards."
"`inner_neartime_callback` fills the `inner_results` list in the inner loop, `after_inner_neartime_callback` consumes and clears it afterwards."
]
},
{
Expand All @@ -349,14 +349,14 @@
"multiplier = [1]\n",
"\n",
"\n",
"def inner_user_func(session, param):\n",
"def inner_neartime_callback(session, param):\n",
" inner_results.append(param * multiplier[0])\n",
" mylogger.info(f\"Called 'inner_user_func' with param={param}\")\n",
" mylogger.info(f\"Called 'inner_neartime_callback' with param={param}\")\n",
"\n",
"\n",
"def after_inner_user_func(session):\n",
"def after_inner_neartime_callback(session):\n",
" mylogger.info(\n",
" f\"Called 'after_inner_user_func', collected inner values: {inner_results}\"\n",
" f\"Called 'after_inner_neartime_callback', collected inner values: {inner_results}\"\n",
" )\n",
" res = inner_results.copy()\n",
" inner_results.clear()\n",
Expand All @@ -370,7 +370,7 @@
"id": "e2875948",
"metadata": {},
"source": [
"User functions can access the results the experiment has already acquired:"
"Near-time callbacks can access the results the experiment has already acquired:"
]
},
{
Expand Down Expand Up @@ -454,7 +454,7 @@
"source": [
"# Create Experiment - no explicit mapping to qubit lines\n",
"exp = Experiment(\n",
" uid=\"User Function\",\n",
" uid=\"Near-time Callback\",\n",
" signals=[\n",
" ExperimentSignal(\"q0_drive\"),\n",
" ExperimentSignal(\"q0_measure\"),\n",
Expand All @@ -465,15 +465,14 @@
"## experimental pulse sequence\n",
"# outer loop - near-time sweep\n",
"with exp.sweep(uid=\"sweep\", parameter=outer_sweep_parameter):\n",
" # Call user functions.\n",
" # Call near-time callbacks.\n",
"\n",
" # Either constant float values or parameters of the containing\n",
" # loop can be used as arguments. Only named arguments supported,\n",
" # arguments to `exp.call` must match those of the user function\n",
" # being called.\n",
" # Either constant float values or parameters of the containing loop can be\n",
" # used as arguments. Only named arguments supported, arguments to `exp.call`\n",
" # must match those of the near-time callbacks being called.\n",
"\n",
" # Variant 1: Use python function name as reference\n",
" exp.call(user_func, frequency=500e6, amplitude=outer_sweep_parameter)\n",
" exp.call(neartime_callback, frequency=500e6, amplitude=outer_sweep_parameter)\n",
"\n",
" # Variant 2: Use custom name as reference, see section 2.3 below\n",
" exp.call(\"calc_power\", amplitude=outer_sweep_parameter, gain=1.0)\n",
Expand All @@ -494,7 +493,7 @@
" # inner loop - near-time sweep\n",
" with exp.sweep(uid=\"inner_sweep\", parameter=inner_arbitrary_sweep):\n",
" # Variant 2: Use custom name as reference\n",
" exp.call(\"inner_user_func\", param=inner_arbitrary_sweep)\n",
" exp.call(\"inner_neartime_callback\", param=inner_arbitrary_sweep)\n",
" # innermost loop - real-time pulse sequence with averaging\n",
" with exp.acquire_loop_rt(\n",
" uid=\"shots\",\n",
Expand Down Expand Up @@ -524,8 +523,8 @@
" with exp.section(uid=\"relax\"):\n",
" exp.delay(signal=\"q0_measure\", time=1e-6)\n",
"\n",
" # The call order of user functions is preserved relative to the nested sections\n",
" exp.call(\"after_inner_user_func\")"
" # The call order of near-time callbacks is preserved relative to the nested sections\n",
" exp.call(\"after_inner_neartime_callback\")"
]
},
{
Expand Down Expand Up @@ -576,7 +575,7 @@
"id": "68f0504f",
"metadata": {},
"source": [
"All user functions referred to from the experiment must be registered with the session."
"All near-time callbacks referred to from the experiment must be registered with the session."
]
},
{
Expand All @@ -587,19 +586,21 @@
"outputs": [],
"source": [
"# Variant 1: Use python function name as reference\n",
"session.register_user_function(user_func)\n",
"session.register_user_function(query_hdawg_device_info)\n",
"session.register_neartime_callback(neartime_callback)\n",
"session.register_neartime_callback(query_hdawg_device_info)\n",
"\n",
"# Variant 2: Give the name explicitly\n",
"session.register_user_function(my_power_func, \"calc_power\")\n",
"session.register_neartime_callback(my_power_func, \"calc_power\")\n",
"\n",
"# Same python function may be registered multiple times with different names\n",
"session.register_user_function(my_power_func, \"calc_power_alt\")\n",
"session.register_neartime_callback(my_power_func, \"calc_power_alt\")\n",
"\n",
"session.register_user_function(inner_user_func, \"inner_user_func\")\n",
"session.register_user_function(after_inner_user_func, \"after_inner_user_func\")\n",
"session.register_neartime_callback(inner_neartime_callback, \"inner_neartime_callback\")\n",
"session.register_neartime_callback(\n",
" after_inner_neartime_callback, \"after_inner_neartime_callback\"\n",
")\n",
"\n",
"session.register_user_function(process_partial_result)"
"session.register_neartime_callback(process_partial_result)"
]
},
{
Expand Down Expand Up @@ -643,7 +644,7 @@
"source": [
"### 2.4 Results\n",
"\n",
"Investigate the results returned from the calls of user functions"
"Investigate the results returned from the calls of near-time callbacks"
]
},
{
Expand All @@ -653,8 +654,8 @@
"metadata": {},
"outputs": [],
"source": [
"# Return values of user functions upon execution are available per function, use function name as a key.\n",
"my_results.user_func_results[\"user_func\"]"
"# Return values of near-time callbacks upon execution are available per function, use function name as a key.\n",
"my_results.neartime_callback_results[\"neartime_callback\"]"
]
},
{
Expand All @@ -665,7 +666,7 @@
"outputs": [],
"source": [
"# Two calls per iteration to `calc_power` result in two adjacent entries in the results\n",
"my_results.user_func_results[\"calc_power\"]"
"my_results.neartime_callback_results[\"calc_power\"]"
]
},
{
Expand All @@ -675,7 +676,7 @@
"metadata": {},
"outputs": [],
"source": [
"plt.scatter(*zip(*my_results.user_func_results[\"calc_power\"]))"
"plt.scatter(*zip(*my_results.neartime_callback_results[\"calc_power\"]))"
]
},
{
Expand All @@ -685,7 +686,7 @@
"metadata": {},
"outputs": [],
"source": [
"my_results.user_func_results[\"calc_power_alt\"]"
"my_results.neartime_callback_results[\"calc_power_alt\"]"
]
},
{
Expand All @@ -695,7 +696,7 @@
"metadata": {},
"outputs": [],
"source": [
"plt.scatter(*zip(*my_results.user_func_results[\"calc_power_alt\"]))"
"plt.scatter(*zip(*my_results.neartime_callback_results[\"calc_power_alt\"]))"
]
},
{
Expand All @@ -705,7 +706,7 @@
"metadata": {},
"outputs": [],
"source": [
"my_results.user_func_results[\"after_inner_user_func\"]"
"my_results.neartime_callback_results[\"after_inner_neartime_callback\"]"
]
},
{
Expand All @@ -715,29 +716,33 @@
"metadata": {},
"outputs": [],
"source": [
"my_results.user_func_results[\"query_hdawg_device_info\"]"
"my_results.neartime_callback_results[\"query_hdawg_device_info\"]"
]
},
{
"cell_type": "markdown",
"source": [
"### 2.5 Aborting experiment execution\n",
"\n",
"Call `session.abort_execution()` in a user function to gracefully terminate the execution of the experiment. "
],
"id": "fdf1dd78e2180bf5",
"metadata": {
"collapsed": false
},
"id": "fdf1dd78e2180bf5"
"source": [
"### 2.5 Aborting experiment execution\n",
"\n",
"Call `session.abort_execution()` in a near-time callback to gracefully terminate the execution of the experiment. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "428255cef1667833",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Create Experiment - no explicit mapping to qubit lines\n",
"exp = Experiment(\n",
" uid=\"User Function\",\n",
" uid=\"Near-time Callback\",\n",
" signals=[ExperimentSignal(\"q0_drive\")],\n",
")\n",
"exp.set_signal_map(\n",
Expand All @@ -747,22 +752,22 @@
"sweep_parameter = LinearSweepParameter(start=0, stop=10, count=11)\n",
"\n",
"\n",
"def user_function_abort_experiment(session, foo):\n",
" print(f\"In user function, foo={foo}\")\n",
"def neartime_callback_abort_experiment(session, foo):\n",
" print(f\"In near-time callback, foo={foo}\")\n",
" if foo >= 5: # Abort execution after 5 steps\n",
" print(\"Aborting execution\")\n",
" session.abort_execution()\n",
" # Calling `session.abort_execution()` will not return. The code below is not executed for `foo == 5`.\n",
" print(\"Continuing execution\")\n",
"\n",
"\n",
"session.register_user_function(user_function_abort_experiment)\n",
"session.register_neartime_callback(neartime_callback_abort_experiment)\n",
"\n",
"## experimental pulse sequence\n",
"# outer loop - near-time sweep\n",
"with exp.sweep(uid=\"sweep\", parameter=sweep_parameter):\n",
" # Call user function\n",
" exp.call(user_function_abort_experiment, foo=sweep_parameter)\n",
" # Call near-time callback\n",
" exp.call(neartime_callback_abort_experiment, foo=sweep_parameter)\n",
"\n",
" with exp.acquire_loop_rt(\n",
" uid=\"shots\",\n",
Expand All @@ -772,23 +777,19 @@
" # dummy pulse playback\n",
" with exp.section(uid=\"qubit_excitation\"):\n",
" exp.play(signal=\"q0_drive\", pulse=x90)"
],
"metadata": {
"collapsed": false
},
"id": "428255cef1667833"
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"session.run(exp);"
],
"id": "4c708bf7afddcbe2",
"metadata": {
"collapsed": false
},
"id": "4c708bf7afddcbe2"
"outputs": [],
"source": [
"session.run(exp);"
]
}
],
"metadata": {
Expand Down
Loading

0 comments on commit 3f2206d

Please sign in to comment.