{ "cells": [ { "cell_type": "markdown", "id": "417f1cec", "metadata": {}, "source": [ "# Quantify Deprecated Code Suggestions\n", "\n", "```{seealso}\n", "Download the notebook: {nb-download}`deprecated.ipynb`\n", "```\n", "\n", "- {ref}`1. Qcompile => SerialCompiler`\n", "- {ref}`2. Qblox Hardware Configuration`\n", "- {ref}`3. TransmonElement => BasicTransmonElement`\n", "\n", "As of `quantify-scheduler==0.10.0`, deprecation warnings are shown by default (as `FutureWarning`).\n", "\n", "### Compilation Setup" ] }, { "cell_type": "code", "execution_count": 1, "id": "2b64b8e3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Data will be saved in:\n", "/home/slavoutich/quantify-data\n", "qcm => None\n", "qrm => None\n", "qcm_rf => None\n", "qrm_rf => \n" ] } ], "source": [ "from quantify_core.data import handling as dh\n", "from quantify_core.measurement.control import MeasurementControl\n", "from quantify_scheduler.instrument_coordinator import InstrumentCoordinator\n", "from quantify_scheduler.instrument_coordinator.components.qblox import ClusterComponent\n", "\n", "from qblox_instruments import Cluster, ClusterType\n", "from qcodes import Instrument\n", "\n", "dh.set_datadir(dh.default_datadir())\n", "\n", "Instrument.close_all()\n", "meas_ctrl = MeasurementControl(\"meas_ctrl\")\n", "ic = InstrumentCoordinator(\"ic\")\n", "\n", "cluster = Cluster(\n", " \"cluster\",\n", " dummy_cfg={\n", " 1: ClusterType.CLUSTER_QRM_RF,\n", " },\n", ")\n", "\n", "ic_cluster = ClusterComponent(cluster)\n", "ic.add_component(ic_cluster)\n", "\n", "# Always picks the first module of a certain type, and ignores the others of same type!\n", "qcm_rf, qrm_rf, qcm, qrm = [None] * 4\n", "for module in cluster.modules:\n", " try:\n", " if module.is_rf_type:\n", " if module.is_qcm_type:\n", " if qcm_rf is None:\n", " qcm_rf = module\n", " else:\n", " if qrm_rf is None:\n", " qrm_rf = module\n", " else:\n", " if module.is_qcm_type:\n", " if qcm is None:\n", " qcm = module\n", " else:\n", " if qrm is None:\n", " qrm = module\n", " except KeyError:\n", " continue\n", "\n", "print(f\"qcm => {qcm}\\nqrm => {qrm}\\nqcm_rf => {qcm_rf}\\nqrm_rf => {qrm_rf}\")" ] }, { "cell_type": "code", "execution_count": 2, "id": "fdd81f7a", "metadata": {}, "outputs": [], "source": [ "from quantify_scheduler.device_under_test.quantum_device import QuantumDevice\n", "from quantify_scheduler.device_under_test.transmon_element import BasicTransmonElement\n", "\n", "q0 = BasicTransmonElement(\"q0\")\n", "\n", "quantum_device = QuantumDevice(\"quantum_device\")\n", "quantum_device.add_element(q0)\n", "quantum_device.instr_measurement_control(meas_ctrl.name)\n", "quantum_device.instr_instrument_coordinator(ic.name)\n", "\n", "q0.clock_freqs.f01(7.3e9)\n", "q0.clock_freqs.f12(7.0e9)\n", "q0.clock_freqs.readout(8.2e9)\n", "q0.measure.acq_delay(100e-9)\n", "q0.measure.acq_channel(0)\n", "q0.measure.pulse_amp(0.2)\n", "\n", "device_cfg = quantum_device.generate_device_config()" ] }, { "cell_type": "code", "execution_count": 3, "id": "39ed62cb", "metadata": {}, "outputs": [], "source": [ "hardware_cfg = {\n", " \"backend\": \"quantify_scheduler.backends.qblox_backend.hardware_compile\",\n", " \"cluster\": {\n", " \"ref\": \"internal\",\n", " \"instrument_type\": \"Cluster\",\n", " f\"cluster_module{qrm_rf.slot_idx}\": {\n", " \"instrument_type\": \"QRM_RF\",\n", " \"complex_output_0\": {\n", " \"lo_freq\": 2e9,\n", " \"portclock_configs\": [\n", " {\n", " \"port\": \"q0:res\",\n", " \"clock\": \"q0.ro\",\n", " },\n", " ],\n", " },\n", " },\n", " },\n", "}" ] }, { "cell_type": "code", "execution_count": 4, "id": "912de9fc", "metadata": {}, "outputs": [], "source": [ "from quantify_scheduler import Schedule\n", "from quantify_scheduler.operations.gate_library import Measure, Reset\n", "from quantify_scheduler.operations.pulse_library import DRAGPulse\n", "from quantify_scheduler.resources import ClockResource\n", "\n", "\n", "def simple_trace_sched(\n", " repetitions: int,\n", " pulse_amp: float = 0.2, \n", ") -> Schedule:\n", " sched = Schedule(\"Simple trace schedule\", repetitions)\n", "\n", " port = \"q0:res\"\n", " clock = \"q0.ro\"\n", "\n", " sched.add(Reset(\"q0\"))\n", " sched.add(Measure(\"q0\", acq_index=0, acq_protocol=\"Trace\"))\n", " sched.add(\n", " DRAGPulse(\n", " G_amp=pulse_amp,\n", " D_amp=0,\n", " phase=0,\n", " duration=160e-9,\n", " port=port,\n", " clock=clock,\n", " )\n", " )\n", "\n", " return sched\n", "\n", "\n", "sched = simple_trace_sched(repetitions=1)" ] }, { "cell_type": "markdown", "id": "9863bc6a", "metadata": {}, "source": [ "## 1. Qcompile => SerialCompiler\n", "\n", "First, run {ref}`Compilation Setup`." ] }, { "cell_type": "code", "execution_count": 5, "id": "a5a09b14", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_23681/1962686608.py:3: FutureWarning: Function quantify_scheduler.compilation.qcompile() is deprecated and will be removed in quantify-scheduler-0.9.0. Use the `QuantifyCompiler.compile` method instead. See the user guide section on compilers for details.\n", " compiled_schedule = qcompile(sched, device_cfg, hardware_cfg)\n" ] } ], "source": [ "from quantify_scheduler.compilation import qcompile\n", "\n", "compiled_schedule = qcompile(sched, device_cfg, hardware_cfg)" ] }, { "cell_type": "code", "execution_count": 6, "id": "85adeaaf", "metadata": {}, "outputs": [], "source": [ "from quantify_scheduler.backends.graph_compilation import SerialCompiler\n", "\n", "quantum_device.hardware_config(hardware_cfg)\n", "\n", "compiler = SerialCompiler(name=\"compiler\")\n", "compiled_schedule = compiler.compile(\n", " schedule=sched, config=quantum_device.generate_compilation_config()\n", ")" ] }, { "cell_type": "code", "execution_count": 7, "id": "e674a298", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
 waveform_op_idportclockis_acquisitionabs_timedurationoperationwf_idx
0Reset('q0')_p_0Nonecl0.basebandFalse0.0 ns200,000.0 nsReset('q0')0
1Measure('q0', acq_index=0, acq_protocol=\"Trace\", bin_mode=None)_p_0Noneq0.roFalse200,000.0 ns0.0 nsMeasure('q0', acq_index=0, acq_protocol=\"Trace\", bin_mode=None)0
2Measure('q0', acq_index=0, acq_protocol=\"Trace\", bin_mode=None)_p_1q0:resq0.roFalse200,000.0 ns300.0 nsMeasure('q0', acq_index=0, acq_protocol=\"Trace\", bin_mode=None)1
3Measure('q0', acq_index=0, acq_protocol=\"Trace\", bin_mode=None)_acq_0q0:resq0.roTrue200,100.0 ns1,000.0 nsMeasure('q0', acq_index=0, acq_protocol=\"Trace\", bin_mode=None)0
4DRAGPulse(G_amp=0.2,D_amp=0,phase=0,clock='q0.ro',duration=1.6e-07,port='q0:res',t0=0)_p_0q0:resq0.roFalse201,100.0 ns160.0 nsDRAGPulse(G_amp=0.2,D_amp=0,phase=0,clock='q0.ro',duration=1.6e-07,port='q0:res',t0=0)0
\n" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "compiled_schedule.timing_table" ] }, { "cell_type": "markdown", "id": "38af3ed3", "metadata": {}, "source": [ "## 2. Qblox Hardware Configuration\n", "1. `seqx` => `portclock_configs` \n", "1. `latency_correction` => standalone/top-level `latency_corrections`\n", "1. `line_gain_db` removed" ] }, { "cell_type": "code", "execution_count": 8, "id": "3811b293", "metadata": {}, "outputs": [], "source": [ "depr_hardware_cfg = {\n", " \"backend\": \"quantify_scheduler.backends.qblox_backend.hardware_compile\",\n", " \"cluster\": {\n", " \"ref\": \"internal\",\n", " \"instrument_type\": \"Cluster\",\n", " \"cluster_module1\": {\n", " \"instrument_type\": \"QRM_RF\",\n", " \"complex_output_0\": {\n", " \"line_gain_db\": 0,\n", " \"seq0\": {\n", " \"port\": \"q6:res\",\n", " \"clock\": \"q6.ro\",\n", " \"latency_correction\": 4e-9,\n", " },\n", " \"seq1\": {\n", " \"port\": \"q1:res\",\n", " \"clock\": \"q1.ro\",\n", " },\n", " },\n", " },\n", " },\n", "}" ] }, { "cell_type": "code", "execution_count": 9, "id": "54a3b425", "metadata": {}, "outputs": [], "source": [ "from quantify_scheduler.backends.qblox.helpers import (\n", " convert_hw_config_to_portclock_configs_spec,\n", ")\n", "\n", "new_hardware_cfg = convert_hw_config_to_portclock_configs_spec(depr_hardware_cfg)\n", "\n", "\n", "fnc = lambda sub: {\n", " key1: fnc(val1) if isinstance(val1, dict) else val1\n", " for key1, val1 in sub.items()\n", " if key1 != \"line_gain_db\"\n", "}\n", "\n", "new_hardware_cfg = fnc(new_hardware_cfg)" ] }, { "cell_type": "code", "execution_count": 10, "id": "ad2e38be", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"backend\": \"quantify_scheduler.backends.qblox_backend.hardware_compile\",\n", " \"cluster\": {\n", " \"ref\": \"internal\",\n", " \"instrument_type\": \"Cluster\",\n", " \"cluster_module1\": {\n", " \"instrument_type\": \"QRM_RF\",\n", " \"complex_output_0\": {\n", " \"portclock_configs\": [\n", " {\n", " \"port\": \"q6:res\",\n", " \"clock\": \"q6.ro\"\n", " },\n", " {\n", " \"port\": \"q1:res\",\n", " \"clock\": \"q1.ro\"\n", " }\n", " ]\n", " }\n", " }\n", " },\n", " \"latency_corrections\": {\n", " \"q6:res-q6.ro\": 4e-09\n", " }\n", "}\n" ] } ], "source": [ "import json\n", "\n", "print(json.dumps(new_hardware_cfg, indent=4))" ] }, { "cell_type": "markdown", "id": "eea0292e", "metadata": {}, "source": [ "## 3. TransmonElement => BasicTransmonElement" ] }, { "cell_type": "code", "execution_count": 11, "id": "761ae84b", "metadata": {}, "outputs": [], "source": [ "from qcodes import Instrument\n", "\n", "Instrument.close_all()" ] }, { "cell_type": "code", "execution_count": 12, "id": "c7ae9f82", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "transmon: ['IDN', 'instrument_coordinator', 'init_duration', 'mw_amp180', 'mw_motzoi', 'mw_pulse_duration', 'mw_ef_amp180', 'mw_port', 'fl_port', 'ro_port', 'mw_01_clock', 'mw_12_clock', 'ro_clock', 'freq_01', 'freq_12', 'ro_freq', 'ro_pulse_amp', 'ro_pulse_duration', 'ro_pulse_type', 'ro_pulse_delay', 'ro_acq_channel', 'ro_acq_delay', 'ro_acq_integration_time', 'spec_pulse_duration', 'spec_pulse_frequency', 'spec_pulse_amp', 'spec_pulse_clock', 'acquisition', 'ro_acq_weight_type']\n", "\n", "basic: ['IDN', 'reset', 'rxy', 'measure', 'ports', 'clock_freqs']\n", "basic.reset: ['duration']\n", "basic.rxy: ['amp180', 'motzoi', 'duration']\n", "basic.measure: ['pulse_type', 'pulse_amp', 'pulse_duration', 'acq_channel', 'acq_delay', 'integration_time', 'reset_clock_phase', 'acq_weight_type']\n", "basic.ports: ['microwave', 'flux', 'readout']\n", "basic.clock_freqs: ['f01', 'f12', 'readout']\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/home/slavoutich/.local/opt/conda/envs/docs_qs0111/lib/python3.9/site-packages/qcodes/instrument/instrument_meta.py:36: FutureWarning: Class quantify_scheduler.device_under_test.transmon_element.TransmonElement is deprecated and will be removed in quantify-scheduler-0.8. Consider replacing with BasicTransmonElement or implementing a custom device element.\n", " new_inst = super().__call__(*args, **kwargs)\n" ] } ], "source": [ "from quantify_scheduler.device_under_test.transmon_element import (\n", " BasicTransmonElement,\n", " TransmonElement,\n", ")\n", "\n", "transmon = TransmonElement(\"transmon\")\n", "print(f\"{transmon.name}: {list(transmon.parameters.keys())}\")\n", "print()\n", "\n", "basic = BasicTransmonElement(\"basic\")\n", "print(f\"{basic.name}: {list(basic.parameters.keys()) + list(basic.submodules.keys())}\")\n", "for submodule_name, submodule in basic.submodules.items():\n", " print(f\"{basic.name}.{submodule_name}: {list(submodule.parameters.keys())}\")" ] }, { "cell_type": "code", "execution_count": 13, "id": "67c8db51", "metadata": {}, "outputs": [], "source": [ "spec_str = f'via:\\tschedule.add(SpectroscopyOperation(\"{basic.name}\")), not implemented for BasicTransmonElement, see BasicElectronicNVElement.spectroscopy_operation'\n", "\n", "convert = {\n", " \".IDN\": \".IDN\",\n", " \".init_duration\": \".reset.duration\",\n", " \".mw_amp180\": \".rxy.amp180\",\n", " \".mw_motzoi\": \".rxy.motzoi\",\n", " \".mw_pulse_duration\": \".rxy.duration\",\n", " \".mw_ef_amp180\": None,\n", " \".mw_port\": \".ports.microwave\",\n", " \".fl_port\": \".ports.flux\",\n", " \".ro_port\": \".ports.readout\",\n", " \".mw_01_clock\": f'no longer settable, always \"{basic.name}.01\"',\n", " \".mw_12_clock\": f'no longer settable, always \"{basic.name}.12\"',\n", " \".ro_clock\": f'no longer settable, always \"{basic.name}.ro\"',\n", " \".freq_01\": \".clock_freqs.f01\",\n", " \".freq_12\": \".clock_freqs.f12\",\n", " \".ro_freq\": \".clock_freqs.readout\",\n", " \".ro_pulse_amp\": \".measure.pulse_amp\",\n", " \".ro_pulse_duration\": \".measure.pulse_duration\",\n", " \".ro_pulse_type\": \".measure.pulse_type\",\n", " \".ro_pulse_delay\": \"via:\\tschedule.add(..., rel_time=...)\",\n", " \".ro_acq_channel\": \".measure.acq_channel\",\n", " f'schedule.add(Measure(\"{transmon.name}\", acq_channel=...))': \".measure.acq_channel\",\n", " \".ro_acq_delay\": \".measure.acq_delay\",\n", " \".ro_acq_integration_time\": \".measure.integration_time\",\n", " \".spec_pulse_duration\": spec_str,\n", " \".spec_pulse_frequency\": spec_str,\n", " \".spec_pulse_amp\": spec_str,\n", " \".spec_pulse_clock\": spec_str,\n", " \".acquisition\": f'via:\\tschedule.add(Measure(\"{basic.name}\", acq_protocol=...))',\n", " \".ro_acq_weight_type\": \".measure.acq_weight_type\",\n", "}" ] }, { "cell_type": "code", "execution_count": 14, "id": "c3b52b62", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "transmon.IDN => basic.IDN\n", "transmon.instrument_coordinator => None\n", "transmon.init_duration => basic.reset.duration\n", "transmon.mw_amp180 => basic.rxy.amp180\n", "transmon.mw_motzoi => basic.rxy.motzoi\n", "transmon.mw_pulse_duration => basic.rxy.duration\n", "transmon.mw_ef_amp180 => None\n", "transmon.mw_port => basic.ports.microwave\n", "transmon.fl_port => basic.ports.flux\n", "transmon.ro_port => basic.ports.readout\n", "transmon.mw_01_clock => no longer settable, always \"basic.01\"\n", "transmon.mw_12_clock => no longer settable, always \"basic.12\"\n", "transmon.ro_clock => no longer settable, always \"basic.ro\"\n", "transmon.freq_01 => basic.clock_freqs.f01\n", "transmon.freq_12 => basic.clock_freqs.f12\n", "transmon.ro_freq => basic.clock_freqs.readout\n", "transmon.ro_pulse_amp => basic.measure.pulse_amp\n", "transmon.ro_pulse_duration => basic.measure.pulse_duration\n", "transmon.ro_pulse_type => basic.measure.pulse_type\n", "transmon.ro_pulse_delay => via:\tschedule.add(..., rel_time=...)\n", "transmon.ro_acq_channel => basic.measure.acq_channel\n", "transmon.ro_acq_delay => basic.measure.acq_delay\n", "transmon.ro_acq_integration_time => basic.measure.integration_time\n", "transmon.spec_pulse_duration => via:\tschedule.add(SpectroscopyOperation(\"basic\")), not implemented for BasicTransmonElement, see BasicElectronicNVElement.spectroscopy_operation\n", "transmon.spec_pulse_frequency => via:\tschedule.add(SpectroscopyOperation(\"basic\")), not implemented for BasicTransmonElement, see BasicElectronicNVElement.spectroscopy_operation\n", "transmon.spec_pulse_amp => via:\tschedule.add(SpectroscopyOperation(\"basic\")), not implemented for BasicTransmonElement, see BasicElectronicNVElement.spectroscopy_operation\n", "transmon.spec_pulse_clock => via:\tschedule.add(SpectroscopyOperation(\"basic\")), not implemented for BasicTransmonElement, see BasicElectronicNVElement.spectroscopy_operation\n", "transmon.acquisition => via:\tschedule.add(Measure(\"basic\", acq_protocol=...))\n", "transmon.ro_acq_weight_type => basic.measure.acq_weight_type\n", "schedule.add(Measure(\"transmon\", acq_channel=...)) => basic.measure.acq_channel\n" ] } ], "source": [ "transmon_params = [f\".{param}\" for param in transmon.parameters]\n", "\n", "for transmon_param in transmon_params + list(convert.keys() - transmon_params):\n", " basic_param = str(convert.get(transmon_param, None))\n", " print(\n", " f\"{transmon.name if transmon_param.startswith('.') else ''}{transmon_param:<42} => {basic.name if basic_param.startswith('.') else ''}{basic_param}\"\n", " )" ] }, { "cell_type": "code", "execution_count": 15, "id": "4ce593b1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'backend': 'quantify_scheduler.backends.circuit_to_device.compile_circuit_to_device',\n", " 'clocks': {'transmon.01': nan, 'transmon.12': nan, 'transmon.ro': nan},\n", " 'edges': {},\n", " 'elements': {'transmon': {'Rxy': {'factory_func': 'quantify_scheduler.operations.pulse_factories.rxy_drag_pulse',\n", " 'factory_kwargs': {'amp180': nan,\n", " 'clock': 'transmon.01',\n", " 'duration': 2e-08,\n", " 'motzoi': 0,\n", " 'port': 'transmon:mw'},\n", " 'gate_info_factory_kwargs': ['theta',\n", " 'phi']},\n", " 'measure': {'factory_func': 'quantify_scheduler.operations.measurement_factories.dispersive_measurement',\n", " 'factory_kwargs': {'acq_channel': 0,\n", " 'acq_delay': 0,\n", " 'acq_duration': 1e-06,\n", " 'acq_protocol_default': 'SSBIntegrationComplex',\n", " 'clock': 'transmon.ro',\n", " 'port': 'transmon:res',\n", " 'pulse_amp': 0.5,\n", " 'pulse_duration': 3e-07,\n", " 'pulse_type': 'SquarePulse'},\n", " 'gate_info_factory_kwargs': ['acq_index',\n", " 'bin_mode',\n", " 'acq_protocol']},\n", " 'reset': {'factory_func': 'quantify_scheduler.operations.pulse_library.IdlePulse',\n", " 'factory_kwargs': {'duration': 0.0002},\n", " 'gate_info_factory_kwargs': None}}}}\n" ] } ], "source": [ "import pprint\n", "\n", "device_config_transmon = transmon.generate_device_config().dict()\n", "pprint.pprint(device_config_transmon)" ] }, { "cell_type": "code", "execution_count": 16, "id": "07e78646", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'backend': 'quantify_scheduler.backends.circuit_to_device.compile_circuit_to_device',\n", " 'clocks': {'basic.01': nan, 'basic.12': nan, 'basic.ro': nan},\n", " 'edges': {},\n", " 'elements': {'basic': {'Rxy': {'factory_func': 'quantify_scheduler.operations.pulse_factories.rxy_drag_pulse',\n", " 'factory_kwargs': {'amp180': nan,\n", " 'clock': 'basic.01',\n", " 'duration': 2e-08,\n", " 'motzoi': 0,\n", " 'port': 'basic:mw'},\n", " 'gate_info_factory_kwargs': ['theta', 'phi']},\n", " 'measure': {'factory_func': 'quantify_scheduler.operations.measurement_factories.dispersive_measurement',\n", " 'factory_kwargs': {'acq_channel': 0,\n", " 'acq_delay': 0,\n", " 'acq_duration': 1e-06,\n", " 'acq_protocol_default': 'SSBIntegrationComplex',\n", " 'clock': 'basic.ro',\n", " 'port': 'basic:res',\n", " 'pulse_amp': 0.25,\n", " 'pulse_duration': 3e-07,\n", " 'pulse_type': 'SquarePulse',\n", " 'reset_clock_phase': True},\n", " 'gate_info_factory_kwargs': ['acq_index',\n", " 'bin_mode',\n", " 'acq_protocol']},\n", " 'reset': {'factory_func': 'quantify_scheduler.operations.pulse_library.IdlePulse',\n", " 'factory_kwargs': {'duration': 0.0002},\n", " 'gate_info_factory_kwargs': None}}}}\n" ] } ], "source": [ "import pprint\n", "\n", "device_config_basic_transmon = basic.generate_device_config().dict()\n", "pprint.pprint(device_config_basic_transmon)" ] } ], "metadata": { "file_format": "mystnb", "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.18" }, "source_map": [ 4, 20, 69, 90, 112, 145, 151, 157, 168, 170, 178, 203, 220, 224, 228, 234, 250, 286, 296, 303 ] }, "nbformat": 4, "nbformat_minor": 5 }