{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "cell-00",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Backend-Eigenschaften mit Echtzeit-Benchmarking aktualisieren\"\n",
        "description: \"Führen Sie schnelle Charakterisierungsexperimente durch, um die Eigenschaften der QPU in Echtzeit zu messen und ein Backend mit aktuellen Daten zu „ T1 “, „ T2 “, Auslesefehlern und Gate-Fehlern zu aktualisieren.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore CPMG dephase ylim */}\n",
        "\n",
        "<span id=\"refresh-backend-properties-with-real-time-benchmarking\" />\n",
        "\n",
        "# Backend-Eigenschaften mit Echtzeit-Benchmarking aktualisieren\n",
        "\n",
        "Geschätzte *Nutzungsdauer: 3 Minuten auf ibm\\_kingston (HINWEIS: Dies ist lediglich eine Schätzung. (Die Laufzeit kann variieren.)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-01",
      "metadata": {},
      "source": [
        "<span id=\"learning-outcomes\" />\n",
        "\n",
        "## Lernziele\n",
        "\n",
        "* Warum die von einer QPU gemeldeten Eigenschaften hinter dem aktuellen Verhalten des Geräts zurückbleiben können und wann es sich lohnt, sie selbst erneut zu messen\n",
        "* Was bei jedem der fünf Standard-Charakterisierungsexperimente (Readout, „Single-Qubit Randomized Benchmarking“, „Layered Two-Qubit Randomized Benchmarking“, „ $T_1$ “ und „ $T_2$ “) gemessen wird\n",
        "* So führen Sie die gesamte Charakterisierungssuite in einem einzigen Aufruf oder Schritt für Schritt aus und erhalten ein Backend-Objekt mit aktualisierten Eigenschaften zurück\n",
        "* Wie lassen sich die gemessenen Eigenschaften mit den angegebenen vergleichen, und warum sind manche Abweichungen eher auf die Messmethodik als auf eine Drift des Geräts zurückzuführen?\n",
        "\n",
        "<span id=\"prerequisites\" />\n",
        "\n",
        "## Voraussetzungen\n",
        "\n",
        "* Der [Qiskit-Patterns](/docs/guides/intro-to-patterns) -Workflow\n",
        "* [Qiskit Runtime Ausführungsmodi](/docs/guides/execution-modes), insbesondere der Batch-Modus\n",
        "* So rufen Sie [Informationen zur QPU](/docs/guides/qpu-information) ab, z. B. Backend-Eigenschaften und Kalibrierungsdaten\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-02",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## Hintergrund\n",
        "\n",
        "Jede „ IBM Quantum® “-QPU meldet eine Reihe von Eigenschaften, die beschreiben, wie gut jedes ihrer Qubits derzeit funktioniert: Relaxationszeiten ( $T_1$ ), Kohärenzzeiten ( $T_2$ ), Auslesefehler sowie Fehler bei Ein- und Zwei-Qubit-Gattern. Diese Zahlen spielen in der Praxis eine Rolle. Der Transpiler nutzt sie, um zu entscheiden, auf welchen physikalischen Qubits Ihre Schaltung ausgeführt werden soll; Techniken zur Fehlerminderung stützen sich auf sie, und Sie können sie nutzen, um zu beurteilen, ob ein Gerät für ein Experiment gut genug funktioniert.\n",
        "\n",
        "Die gemeldeten Werte stammen aus Kalibrierungsvorgängen, die in der Regel etwa einmal täglich durchgeführt werden. Supraleitende Qubits können jedoch bereits auf kürzeren Zeitskalen driften, und vorübergehende Defekte (sogenannte Zwei-Niveau-Systeme) können ein Qubit, das zum Zeitpunkt der Kalibrierung noch einwandfrei erschien, vorübergehend beeinträchtigen. Zudem wird ein Job oft schon lange vor seiner tatsächlichen Ausführung transpiliert, sodass Entscheidungen, die auf den gemeldeten Eigenschaften basieren, möglicherweise auf veralteten Informationen beruhen. Das Tutorial [„Echtzeit-Benchmarking zur Qubit-Auswahl“](/docs/tutorials/real-time-benchmarking-for-qubit-selection) zeigt, wie stark diese Eigenschaften von Tag zu Tag schwanken können, und erstellt manuell einen vollständigen Charakterisierungs-Workflow aus einzelnen [Qiskit-Experimenten](https://qiskit-community.github.io/qiskit-experiments/).\n",
        "\n",
        "Dieses Tutorial zeigt die optimierte Version dieses Arbeitsablaufs unter Verwendung des Dienstprogramms `BackendCharacterization` aus [dem](https://github.com/qiskit-community/qiskit-device-benchmarking) Qiskit Device Benchmarking, das die Erstellung des Experiments, die Übermittlung des Auftrags und die Kurvenanpassung in wenigen Aufrufen bündelt. Sie benötigen etwa 70 Sekunden QPU-Zeit und erhalten im Gegenzug ein Backend-Objekt, dessen Eigenschaften *den aktuellen Zustand* des Geräts widerspiegeln und das sofort mit den gemeldeten Werten verglichen oder an nachgelagerte Tools weitergeleitet werden kann.\n",
        "\n",
        "<span id=\"the-characterization-experiments\" />\n",
        "\n",
        "### Die Charakterisierungsversuche\n",
        "\n",
        "Die Suite umfasst fünf Objekte, von denen jedes ein Standardexperiment enthält:\n",
        "\n",
        "* **Auslesefehler** (`readout`): Jedes Qubit wird in den Zuständen $|0\\rangle$ oder $|1\\rangle$ vorbereitet und sofort gemessen. Die Wahrscheinlichkeit, den falschen Zustand auszulesen, ergibt den SPAM-Fehler (State Preparation and Measurement).\n",
        "* **Fehler bei Einzelqubit-Gates** (`rb_1q`): Beim Randomized Benchmarking (RB) werden Sequenzen zufälliger Clifford-Gates für einzelne Qubits ausgeführt, die sich im Idealfall zur Identitätsmatrix zusammensetzen. Die Art und Weise, wie die Überlebenswahrscheinlichkeit mit der Sequenzlänge abnimmt, ergibt den durchschnittlichen Fehler pro Gate, unabhängig von SPAM-Fehlern.\n",
        "* **Fehler bei Zwei-Qubit-Gattern** (`rb_2q`): Dasselbe RB-Konzept, angewendet auf vollständige Schichten von nicht überlappenden Zwei-Qubit-Gattern, die gleichzeitig ausgeführt werden, wie in einem Experiment [zur Schichttreue](https://arxiv.org/abs/2311.05933). Da viele Gatter gleichzeitig arbeiten, beinhalten die daraus resultierenden Fehlerraten Übersprecheffekte und entsprechen eher den tatsächlichen Bedingungen in einer tiefen Schaltung.\n",
        "* **$T_1$** (`t1`): Jedes Qubit wird nach zunehmend längeren Verzögerungen angeregt und gemessen. Der Zerfall der Population im angeregten Zustand ergibt die Relaxationszeit.\n",
        "* **$T_2$** (`t2`): Bei einem Hahn-Echo-Experiment wird jedes Qubit in eine Überlagerung versetzt, nach der Hälfte der Verzögerungszeit ein Echoimpuls angelegt und gemessen, wie schnell die Phasenkohärenz verloren geht. Standardmäßig wird ein einzelnes Echo verwendet; eine Variante mit mehreren Echos (im CPMG-Stil) wird am Ende dieses Tutorials vorgestellt.\n",
        "\n",
        "<span id=\"what-refreshing-does-and-does-not-do\" />\n",
        "\n",
        "### Was die Auffrischung bewirkt und was nicht\n",
        "\n",
        "Beachten Sie bei der Verwendung dieses Arbeitsablaufs bitte drei Punkte:\n",
        "\n",
        "* Die aktualisierten Eigenschaften sind ausschließlich in dem Backend-Objekt enthalten, das an Sie zurückgegeben wird. Am Gerät selbst oder an den Kalibrierungsdaten, die IBM Quantum an andere Nutzer übermittelt, ändert sich nichts.\n",
        "* Die Messwerte stellen eine Momentaufnahme dar, die nach einer bestimmten Methodik ermittelt wurde. Einige davon, insbesondere die geschichteten Zwei-Qubit-Fehler und die Werte für die parallele Single-Echo- $T_2$, werden anders gemessen als in den veröffentlichten Kalibrierungsdaten, sodass ein Teil der von Ihnen beobachteten Abweichung eher auf methodische Unterschiede als auf eine Drift zurückzuführen ist. In dieser Anleitung wird gezeigt, wo dies geschieht.\n",
        "* Die Charakterisierung selbst kostet QPU-Zeit (etwa 70 Sekunden für die gesamte Testsuite auf einem Heron- r2 -Prozessor) – das ist der Preis für aktuelle Informationen.\n",
        "\n",
        "Der Arbeitsablauf folgt den vier Schritten eines Qiskit-Musters:\n",
        "\n",
        "* **Schritt 1: Ordnen Sie klassische Eingaben einem Quantenproblem zu.** Wählen Sie das Gerät und die zu messenden Eigenschaften aus.\n",
        "* **Schritt 2: Optimierung des Problems für die Ausführung auf Quantenhardware.** Das Dienstprogramm erstellt die Versuchsschaltungen direkt in den nativen Logikgattern des Bausteins und parallelisiert sie über den gesamten Chip hinweg.\n",
        "* **Schritt 3: Führen Sie den Befehl „ Qiskit primitives “ aus.** Die Experimente werden als Sampler-Jobs innerhalb eines Batches ausgeführt.\n",
        "* **Schritt 4: Nachbearbeitung und Ausgabe des Ergebnisses im gewünschten klassischen Format.** Ordnen Sie die Messdaten den Fehlerkarten pro Qubit zu, aktualisieren Sie das Backend und vergleichen Sie die gemessenen Eigenschaften mit den gemeldeten.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-03",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## Anforderungen\n",
        "\n",
        "Bevor Sie mit dieser Anleitung beginnen, stellen Sie bitte sicher, dass Folgendes installiert ist:\n",
        "\n",
        "* Qiskit SDK v2.0 oder höher, mit [Visualisierungsunterstützung](/docs/api/qiskit/visualization)\n",
        "* Qiskit Runtime v0.40 oder später (`pip install qiskit-ibm-runtime`)\n",
        "* Qiskit Device Benchmarking, bei dem auch [Qiskit Experiments](https://qiskit-community.github.io/qiskit-experiments/) (`pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git`) installiert wird\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-04",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## Einrichtung\n",
        "\n",
        "Importieren Sie die erforderlichen Bibliotheken.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "cell-05",
      "metadata": {},
      "outputs": [],
      "source": [
        "import logging\n",
        "import sys\n",
        "\n",
        "import numpy as np\n",
        "from qiskit_ibm_runtime import Batch, QiskitRuntimeService\n",
        "\n",
        "from qiskit_device_benchmarking.utilities.characterization_utils import (\n",
        "    BackendCharacterization,\n",
        "    plot_characterization_comparison,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-06",
      "metadata": {},
      "source": [
        "Die Charakterisierungssuite erstellt mehrere Experimente, übermittelt mehrere Aufträge und wertet die Ergebnisse aus, was insgesamt einige Minuten dauern kann. Aktivieren Sie die Protokollierung auf der Stufe „INFO“, damit jede Phase ihren Fortschritt in Echtzeit anzeigt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "cell-07",
      "metadata": {},
      "outputs": [],
      "source": [
        "logger = logging.getLogger(\"qiskit_device_benchmarking\")\n",
        "logger.setLevel(logging.INFO)\n",
        "logger.addHandler(logging.StreamHandler(stream=sys.stdout))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-08",
      "metadata": {},
      "source": [
        "<span id=\"small-scale-simulator-example\" />\n",
        "\n",
        "## Beispiel für einen Simulator im kleinen Maßstab\n",
        "\n",
        "Dieses Tutorial enthält kein Simulatorbeispiel. Der Arbeitsablauf misst die physikalischen Unvollkommenheiten eines bestimmten Geräts: wie schnell sich seine Qubits entspannen und aus der Phase geraten und wie oft seine Gatter und Auslesevorgänge fehlschlagen. Ein idealer Simulator weist keine dieser Unvollkommenheiten auf, sodass es nichts zu charakterisieren gibt. Man könnte ein synthetisches Rauschmodell an ein gefälschtes Backend anbinden, aber die Experimente würden dann nur die Zahlen wiedergeben, die man selbst eingegeben hat. Aus diesem Grund gehen wir direkt zur Hardware über, die in die vier Schritte eines Qiskit-Musters unterteilt ist.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-09",
      "metadata": {},
      "source": [
        "<span id=\"large-scale-hardware-example\" />\n",
        "\n",
        "## Beispiel für groß angelegte Hardware\n",
        "\n",
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "### Schritt 1: Klassische Eingaben auf ein Quantenproblem abbilden\n",
        "\n",
        "In diesem Arbeitsablauf ist das „Problem“ das Gerät selbst: Die klassischen Eingaben sind die QPU, die charakterisiert werden soll, und die Liste der zu messenden Eigenschaften, und die Quantenexperimente sind die daraus generierten Charakterisierungsschaltungen.\n",
        "\n",
        "Wählen Sie zunächst ein Backend aus. In diesem Tutorial wird ein „Heron“ r2 -Prozessor mit 156 Qubits verwendet `ibm_kingston`; Sie können stattdessen jedes beliebige „ IBM Quantum “-Gerät verwenden, auf das Sie Zugriff haben (oder eines mit \\[…] auswählen `service.least_busy()`).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "cell-10",
      "metadata": {},
      "outputs": [],
      "source": [
        "service = QiskitRuntimeService()\n",
        "device = \"ibm_kingston\"\n",
        "backend = service.backend(device)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-11",
      "metadata": {},
      "source": [
        "Wählen Sie als Nächstes aus, welche Eigenschaften gemessen werden sollen. Sie können eine beliebige Teilmenge der folgenden Experimente bestehen:\n",
        "\n",
        "* `readout`: SPAM-Experiment (Zustandsvorbereitung und -messung)\n",
        "* `rb_1q`: Isoliertes, randomisiertes Benchmarking mit einem einzelnen Qubit\n",
        "* `rb_2q`: Gleichzeitiges randomisiertes Benchmarking mit zwei Qubits anhand eines Experiments zur Schichtentreue\n",
        "* `t2`: $T_2$ Hahn-Echo-Experiment (standardmäßig ein einzelnes Echo)\n",
        "* `t1`: $T_1$ -Entspannungsversuch\n",
        "\n",
        "Führen Sie die gesamte Testsuite aus, um sich einen umfassenden Überblick über das Gerät zu verschaffen; entfernen Sie Einträge aus der Liste, wenn Sie nur an bestimmten Eigenschaften interessiert sind und QPU-Zeit sparen möchten.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "cell-12",
      "metadata": {},
      "outputs": [],
      "source": [
        "experiments = [\"readout\", \"rb_1q\", \"rb_2q\", \"t1\", \"t2\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-13",
      "metadata": {},
      "source": [
        "<span id=\"step-2-optimize-problem-for-quantum-hardware-execution\" />\n",
        "\n",
        "### Schritt 2: Optimierung des Problems für die Ausführung auf Quantenhardware\n",
        "\n",
        "In den meisten Tutorials würde man an dieser Stelle seine Schaltungen transpilieren. Hier `BackendCharacterization` kümmert sich intern darum. Es baut die Versuchskreisläufe direkt in den nativen Gattern des Bausteins auf, führt die Einzel-Qubit-Experimente auf allen Qubits parallel durch und plant die Zwei-Qubit-Benchmarks über disjunkte Schichten der Kopplungskarte so, dass der gesamte Baustein mit nur wenigen Aufträgen abgedeckt wird. Aufgrund dieser Parallelisierung benötigt die gesamte Suite nur etwa 70 Sekunden QPU-Zeit.\n",
        "\n",
        "Initialisieren Sie die Klasse, die den Workflow verwaltet:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "cell-14",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Initialize the class used to run the experiments\n",
        "characterizer = BackendCharacterization(backend)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-15",
      "metadata": {},
      "source": [
        "<span id=\"step-3-execute-using-qiskit-primitives\" />\n",
        "\n",
        "### Schritt 3: Mit „ Qiskit primitives “ ausführen\n",
        "\n",
        "Die Methode `run_experiments` erstellt die Schaltkreise und übermittelt sie als [Sampler](/docs/guides/get-started-with-sampler) -Aufträge. Führen Sie es in einem Kontext [`Batch`](/docs/guides/run-jobs-batch) aus, damit die Jobs gemeinsam auf der QPU eingeplant werden und die Methode erst dann zurückkehrt, wenn alle Jobs übermittelt wurden. (Du kannst es auch außerhalb eines Batch-Skripts oder innerhalb eines ausführen `Session`.)\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Möglicherweise wird eine Warnung angezeigt, dass ein Backend übergeben wird, während ein Session-Kontextmanager geöffnet ist. Das ist zu erwarten und kann getrost ignoriert werden.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "cell-16",
      "metadata": {},
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "base_primitive.get_mode_service_backend:WARNING:2026-07-14 14:23:02,051: A backend was passed in as the mode but a session context manager is open so this job will run inside this session/batch instead of in job mode.\n"
          ]
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Building readout experiments\n",
            "Building 1Q RB experiments\n",
            "Building 2Q RB experiments\n",
            "Building T1 experiments\n",
            "Building T2 experiments\n",
            "Layered two-qubit RB submitted: ['d9b7tfu6hjac73ffba2g', 'd9b7tjug26ic73dfju3g', 'd9b7u3u6hjac73ffban0', 'd9b7u7rv6alc73csmicg']\n",
            "Readout job submitted: d9b7u8bv6alc73csmidg\n",
            "T1 experiment submitted: ['d9b7u8ug26ic73dfjuqg']\n",
            "T2 (Hahn) experiment submitted: ['d9b7u9fu62qs738othg0']\n",
            "Single-qubit RB submitted: ['d9b7v8m6hjac73ffbc40', 'd9b7veeg26ic73dfk040']\n"
          ]
        }
      ],
      "source": [
        "# Run the characterization experiments inside a Batch\n",
        "with Batch(backend=backend):\n",
        "    jobs = characterizer.run_experiments(experiments=experiments)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-17",
      "metadata": {},
      "source": [
        "Die Methode gibt die übermittelten Aufträge als Dictionary zurück, dessen Schlüssel die Experiment-Bezeichnungen sind. Dies ist nützlich, um sie im [Dashboard unter „ IBM Quantum Platform “ zu verfolgen oder zur Fehlerbehebung.](/docs/guides/monitor-job)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "cell-18",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'rb_2q': [<RuntimeJobV2('d9b7tfu6hjac73ffba2g', 'sampler')>,\n",
              "  <RuntimeJobV2('d9b7tjug26ic73dfju3g', 'sampler')>,\n",
              "  <RuntimeJobV2('d9b7u3u6hjac73ffban0', 'sampler')>,\n",
              "  <RuntimeJobV2('d9b7u7rv6alc73csmicg', 'sampler')>],\n",
              " 'readout': [<RuntimeJobV2('d9b7u8bv6alc73csmidg', 'sampler')>],\n",
              " 't1': [<RuntimeJobV2('d9b7u8ug26ic73dfjuqg', 'sampler')>],\n",
              " 't2': [<RuntimeJobV2('d9b7u9fu62qs738othg0', 'sampler')>],\n",
              " 'rb_1q': [<RuntimeJobV2('d9b7v8m6hjac73ffbc40', 'sampler')>,\n",
              "  <RuntimeJobV2('d9b7veeg26ic73dfk040', 'sampler')>]}"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Print all the job IDs for debugging purposes\n",
        "jobs"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-19",
      "metadata": {},
      "source": [
        "<span id=\"step-4-post-process-and-return-result-in-desired-classical-format\" />\n",
        "\n",
        "### Schritt 4: Nachbearbeitung und Ausgabe des Ergebnisses im gewünschten klassischen Format\n",
        "\n",
        "<span id=\"analyze-the-results\" />\n",
        "\n",
        "#### Die Ergebnisse analysieren\n",
        "\n",
        "Die Methode `analyze_results` wartet, bis die Jobs abgeschlossen sind, und passt die Messdaten an: exponentielle Abklingkurven für $T_1$ und $T_2$, Überlebenswahrscheinlichkeitskurven für die RB-Experimente und Zuordnungsmatrizen für das Auslesen. Die Funktion gibt ein Wörterbuch mit *Fehlerabbildungen* zurück, mit einem Eintrag pro gemessener Eigenschaft, wobei jede Abbildung ein Qubit (oder ein Qubit-Paar) seinem Messwert zuordnet.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "cell-20",
      "metadata": {},
      "outputs": [],
      "source": [
        "error_maps = characterizer.analyze_results()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "cell-21",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "The following error maps are available: ['readout_error', 'oneq_error_x', 'oneq_error_sx', 'lf_error_map', 't1_map', 't2_map']\n",
            "For example, readout error for qubit 0 is 0.007600000000000051\n"
          ]
        }
      ],
      "source": [
        "print(f\"The following error maps are available: {list(error_maps.keys())}\")\n",
        "readout_q0 = error_maps[\"readout_error\"][0]\n",
        "print(f\"For example, readout error for qubit 0 is {readout_q0}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-22",
      "metadata": {},
      "source": [
        "Die Diagramme zeigen Auslesefehler, Einzel-Qubit- und `x` `sx` Gatterfehler, die geschichteten Zwei-Qubit-Fehler (`lf_error_map`aus dem Experiment zur Schichttreue) sowie die Zeiten für „ $T_1$ “ und „ $T_2$ “ in Sekunden.\n",
        "\n",
        "<span id=\"update-the-backend-properties\" />\n",
        "\n",
        "#### Die Backend-Eigenschaften aktualisieren\n",
        "\n",
        "Die Methode `update_backend` schreibt die Messwerte in die Eigenschaften einer Kopie des Backends und gibt diese zurück. Das ursprüngliche Objekt `backend` speichert die gemeldeten Kalibrierungsdaten, sodass wir beide miteinander vergleichen können, wie unten dargestellt. Beachten Sie, dass diese Aktualisierung ausschließlich für Ihre „ Python “-Sitzung gilt; sie hat keinerlei Auswirkungen auf das Gerät oder andere Benutzer.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "cell-23",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Updating readout error\n",
            "Updating single-qubit X error\n",
            "Updating single-qubit SX error\n",
            "Updating two-qubit error\n",
            "Updating T1\n",
            "Updating T2\n"
          ]
        }
      ],
      "source": [
        "backend_updated = characterizer.update_backend()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-24",
      "metadata": {},
      "source": [
        "<span id=\"compare-the-measured-properties-against-the-reported-ones\" />\n",
        "\n",
        "#### Vergleichen Sie die gemessenen Eigenschaften mit den angegebenen\n",
        "\n",
        "Zeichnen Sie schließlich die gemessenen Echtzeit-Eigenschaften als Diagramm auf, verglichen mit den vom Backend gemeldeten Werten. In jedem Diagramm sind die Qubits (bzw. Qubit-Paare) nach dem Messwert sortiert, sodass die Messkurve naturgemäß glatt verläuft und die Streuung der angegebenen Werte um diese Kurve herum zeigt, wo die beiden Ergebnisse voneinander abweichen. Für das Einzel-Qubit-RB wird nur ein einziges Diagramm dargestellt, da beiden Gatter `sx` – sowohl dem als `x` auch dem – derselbe gemessene Fehler pro Gatter zugeordnet wird. Die Achsenbegrenzungen werden aus dem Großteil der Daten so gewählt, dass einige wenige extreme Ausreißer die Diagramme nicht verzerren; alle Punkte außerhalb dieses Bereichs werden in einer Anmerkung im Diagramm aufgeführt (oder mit dem Befehl `pass` können `ylim` die Begrenzungen überschrieben werden).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "cell-25",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-25-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-25-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-25-2.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-25-3.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-25-4.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "plot_characterization_comparison(\n",
        "    old_props=backend.properties().to_dict(),\n",
        "    new_props=backend_updated.properties().to_dict(),\n",
        "    plots=[\"readout\", \"rb_1q\", \"rb_2q\", \"t1\", \"t2\"],\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-26",
      "metadata": {},
      "source": [
        "Diese Diagramme erfordern eine sorgfältige Betrachtung, denn nicht jede Lücke zwischen den beiden Kurven bedeutet, dass das Gerät abgedriftet ist:\n",
        "\n",
        "* **Auslesung und Einzel-Qubit-Fehler** : Die Messwerte stimmen bei den meisten Qubits mit den angegebenen Werten überein, während der angegebene Wert für einige wenige Qubits weit von der Messkurve abweicht. Genau diese punktuellen Unstimmigkeiten sollen durch diesen Arbeitsablauf aufgefangen werden.\n",
        "* **$T_1$** : Die beiden Datensätze verteilen sich umeinander herum, ohne dass ein systematischer Versatz erkennbar ist, was mit den natürlichen Schwankungen von „ $T_1$ “ im Zeitverlauf übereinstimmt.\n",
        "* **Zwei-Qubit-Fehler** : Die gemessenen Werte liegen systematisch *über* den angegebenen Werten. Dies ist zu erwarten, da die angegebenen Werte an isolierten Gates gemessen werden, während beim Experiment zur Schichttreue viele Gates gleichzeitig betrieben werden und daher Übersprechen auftritt. Die geschichteten Zahlen sind für tiefe Schaltkreise relevanter, lassen sich jedoch nicht direkt mit den veröffentlichten Kalibrierungsdaten vergleichen.\n",
        "* **$T_2$** : Die gemessenen Werte liegen bei den meisten Qubits deutlich *unter* den angegebenen Werten. Auch hier spielt die Methodik eine große Rolle, wie im nächsten Abschnitt erläutert wird.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-27",
      "metadata": {},
      "source": [
        "<span id=\"inspect-individual-experiment-results\" />\n",
        "\n",
        "#### Einzelne Versuchsergebnisse überprüfen\n",
        "\n",
        "Sie können die Rohdaten der einzelnen Charakterisierungsversuche auch über die Eigenschaft `experiment_data` einsehen, die die zugrunde liegenden [Qiskit-Experiments](https://qiskit-community.github.io/qiskit-experiments/) -Objekte `ExperimentData` zurückgibt. Das folgende Beispiel zeigt beispielsweise die gemessene Abklingkurve von „ $T_1$ “ für ein einzelnes Qubit. Dies ist nützlich, um die Qualität einer Anpassung zu überprüfen, bevor man sich auf den daraus resultierenden Wert verlässt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "cell-28",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "156 figures available, e.g. T1_Q0_c78ef792.svg\n"
          ]
        },
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-28-1.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "t1_data = characterizer.experiment_data[\"t1\"]\n",
        "\n",
        "# Each qubit has its own fit figure\n",
        "n_figs = len(t1_data.figure_names)\n",
        "print(f\"{n_figs} figures available, e.g. {t1_data.figure_names[0]}\")\n",
        "\n",
        "# Show the T1 decay curve of the first qubit\n",
        "t1_data.figure(0)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-29",
      "metadata": {},
      "source": [
        "<span id=\"measure-t2-with-a-dynamical-decoupling-train\" />\n",
        "\n",
        "#### T2 -Messung mit einer dynamischen Entkopplungsfolge\n",
        "\n",
        "Standardmäßig wendet das Experiment „ $T_2$ “ ein einzelnes Hahn-Echo an und misst alle Qubits parallel, was – wie die obige Vergleichsgrafik gezeigt hat – zu deutlich niedrigeren Werten für „ $T_2$ “ führen kann, als vom Backend gemeldet werden. Eine Hypothese betrifft die Anzahl der Echos: Die gemeldeten Werte könnten unter Berücksichtigung der dynamischen Entkopplung kalibriert sein, wodurch niederfrequente Störgeräusche unterdrückt werden. Um dies zu testen, führen Sie eine Charakterisierung ausschließlich mit „ $T_2$ “ durch, wobei Sie den Wert auf einen höheren Wert einstellen `t2_num_echoes` , wodurch eine Folge von Echoimpulsen im CPMG-Stil angewendet wird. Die Verzögerungen entsprechen in beiden Fällen der gesamten Zeit der freien Entwicklung, sodass die angepassten Werte für „ $T_2$ “ direkt mit den Ergebnissen aus der Ein-Echo-Messung vergleichbar sind.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "cell-30",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Building T2 experiments\n",
            "T2 (Hahn) experiment submitted: ['d9b96s6g26ic73dflcn0']\n",
            "Updating T2\n"
          ]
        }
      ],
      "source": [
        "# Run a T2-only characterization using a CPMG-style train of 8 echoes\n",
        "characterizer_dd = BackendCharacterization(backend)\n",
        "backend_updated_dd = characterizer_dd.run_and_update(\n",
        "    experiments=[\"t2\"], t2_num_echoes=8\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "cell-31",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/tutorials/refresh-backend-properties-with-real-time-benchmarking/extracted-outputs/cell-31-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Median T2 — reported: 142 us | single echo: 53 us | 8-echo CPMG: 56 us\n"
          ]
        }
      ],
      "source": [
        "# Compare the multi-echo T2 against the backend-reported values\n",
        "plot_characterization_comparison(\n",
        "    old_props=backend.properties().to_dict(),\n",
        "    new_props=backend_updated_dd.properties().to_dict(),\n",
        "    plots=[\"t2\"],\n",
        "    title_prefix=\"8-echo CPMG\",\n",
        ")\n",
        "\n",
        "# Compare medians across the reported values, the single-echo run,\n",
        "# and the 8-echo run\n",
        "reported_t2s = [\n",
        "    prop[\"value\"]\n",
        "    for qubit in backend.properties().to_dict()[\"qubits\"]\n",
        "    for prop in qubit\n",
        "    if prop[\"name\"] == \"T2\"\n",
        "]\n",
        "t2_reported = np.median(reported_t2s)\n",
        "t2_single = np.median(list(error_maps[\"t2_map\"].values())) * 1e6\n",
        "t2_dd = (\n",
        "    np.median(list(characterizer_dd.analyze_results()[\"t2_map\"].values()))\n",
        "    * 1e6\n",
        ")\n",
        "print(\n",
        "    f\"Median T2 — reported: {t2_reported:.0f} us | \"\n",
        "    f\"single echo: {t2_single:.0f} us | 8-echo CPMG: {t2_dd:.0f} us\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-32",
      "metadata": {},
      "source": [
        "In diesem Durchlauf hatten die zusätzlichen Echos kaum Einfluss auf das Ergebnis: Der Medianwert für 8 Echos (56 µs) liegt nahe am Medianwert für ein einzelnes Echo (53 µs), und beide liegen weit unter dem angegebenen Medianwert (142 µs). Die Anzahl der Echos allein erklärt diese Diskrepanz nicht; es spielen noch weitere methodische Unterschiede eine Rolle, wie beispielsweise Einzelheiten des Kalibrierungsverfahrens, die parallele statt isolierte Messung aller Qubits und so weiter.\n",
        "\n",
        "Die praktische Erkenntnis daraus ist, dass man Vergleiche von „ $T_2$ “ (und „layered two-qubit error“) zwischen verschiedenen Methoden mit Vorsicht betrachten sollte. Die aktualisierten Werte stellen eine in sich konsistente Momentaufnahme unter Bedingungen dar, die einer realen Arbeitslast nahekommen, wodurch sie sich gut dafür eignen, Qubits miteinander zu vergleichen oder die Entwicklung eines Geräts im Zeitverlauf zu verfolgen. Eine Abweichung gegenüber den gemeldeten Kalibrierungsdaten ist jedoch nicht automatisch ein Hinweis auf eine Drift.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-33",
      "metadata": {},
      "source": [
        "<span id=\"steps-1–4-compressed-into-a-single-call\" />\n",
        "\n",
        "### Die Schritte 1–4 in einem einzigen Aufruf zusammengefasst\n",
        "\n",
        "Im Alltag benötigt man die Zwischenergebnisse nur selten. Die Methode `run_and_update` verknüpft alle oben durchgeführten Schritte (Erstellen, Übermitteln, Anpassen und Aktualisieren) zu einem einzigen Aufruf, der das aktualisierte Backend zurückgibt. Es akzeptiert dieselbe `experiments` Liste (und leitet Optionen wie weiter `t2_num_echoes`) und kann ebenfalls in einen `Batch` oder Kontext `Session` eingebettet werden.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Die folgende Zelle wird erst zurückgegeben, wenn alle Aufträge und die Nachbearbeitung abgeschlossen sind.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "cell-34",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Building readout experiments\n",
            "Building 1Q RB experiments\n",
            "Building 2Q RB experiments\n",
            "Building T1 experiments\n",
            "Building T2 experiments\n",
            "Layered two-qubit RB submitted: ['d9b7oqnu62qs738otat0', 'd9b7p76g26ic73dfjolg', 'd9b7pnm6hjac73ffb57g', 'd9b7q4fu62qs738otce0']\n",
            "Readout job submitted: d9b7q4mg26ic73dfjprg\n",
            "T1 experiment submitted: ['d9b7q57u62qs738otcfg']\n",
            "T2 (Hahn) experiment submitted: ['d9b7q5m6hjac73ffb5pg']\n",
            "Single-qubit RB submitted: ['d9b7r4e6hjac73ffb71g', 'd9b7reu6hjac73ffb7d0']\n",
            "Updating readout error\n",
            "Updating single-qubit X error\n",
            "Updating single-qubit SX error\n",
            "Updating two-qubit error\n",
            "Updating T1\n",
            "Updating T2\n"
          ]
        }
      ],
      "source": [
        "# Initialize a fresh characterizer\n",
        "characterizer = BackendCharacterization(backend)\n",
        "\n",
        "# Run all of the experiments and update the backend in a single call\n",
        "backend_updated = characterizer.run_and_update(experiments=experiments)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-35",
      "metadata": {},
      "source": [
        "Das aktualisierte Objekt `backend_updated` kann nun überall dort verwendet werden, wo Backend-Eigenschaften in Ihren Workflow einfließen. Probieren Sie diesen Vorgang in Verbindung mit dem Tutorial [„Echtzeit-Benchmarking zur Qubit-Auswahl“](/docs/tutorials/real-time-benchmarking-for-qubit-selection) aus, um beim Transpiling einer Schaltung die leistungsstärksten Qubits auszuwählen. Da das Gerät ständig abweicht, sollten Sie die Eigenschaften kurz vor der tatsächlichen Ausführung Ihrer Arbeitslast aktualisieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-36",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "Wenn Sie diese Arbeit interessant fanden, könnten Sie auch an folgenden Materialien interessiert sein:\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Verwenden Sie die aktualisierten Eigenschaften, um im Tutorial [„Echtzeit-Benchmarking für die Qubit-Auswahl“](/docs/tutorials/real-time-benchmarking-for-qubit-selection) bessere Qubits auszuwählen\n",
        "  * Erfahren Sie, wie die gemeldeten Kalibrierungsdaten im [QPU](/docs/guides/qpu-information) -Informationsleitfaden dargestellt werden\n",
        "  * Entdecken Sie die einzelnen Charakterisierungsexperimente in der [Dokumentation zu Qiskit-Experimenten](https://qiskit-community.github.io/qiskit-experiments/)\n",
        "  * Weitere Benchmarks auf Geräteebene finden Sie im [Qiskit Device Benchmarking-Repository](https://github.com/qiskit-community/qiskit-device-benchmarking)\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}