{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "cell-00",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Atualizar as propriedades do backend com análises comparativas em tempo real\"\n",
        "description: \"Execute experimentos rápidos de caracterização para medir as propriedades da QPU em tempo real e atualizar um backend com dados atualizados sobre erros de T1 (Q-textura), T2, leitura e portas.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore CPMG dephase ylim */}\n",
        "\n",
        "<span id=\"refresh-backend-properties-with-real-time-benchmarking\" />\n",
        "\n",
        "# Atualizar as propriedades do backend com análises comparativas em tempo real\n",
        "\n",
        "Estimativa de tempo de *uso: 3 minutos no ibm\\_kingston (OBSERVAÇÃO: trata-se apenas de uma estimativa. (O tempo de execução pode variar.)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-01",
      "metadata": {},
      "source": [
        "<span id=\"learning-outcomes\" />\n",
        "\n",
        "## Resultados do aprendizado\n",
        "\n",
        "* Por que as propriedades informadas por uma QPU podem ficar desatualizadas em relação ao comportamento atual do dispositivo e quando vale a pena medi-las novamente por conta própria\n",
        "* O que cada um dos cinco experimentos padrão de caracterização (readout, benchmarking aleatório de qubit único, benchmarking aleatório em camadas de dois qubits, $T_1$ e $T_2$ ) mede\n",
        "* Como executar o conjunto completo de caracterizações em uma única chamada ou passo a passo e obter um objeto de backend com propriedades atualizadas\n",
        "* Como comparar as propriedades medidas com as relatadas e por que algumas diferenças refletem a metodologia de medição, e não a deriva do dispositivo\n",
        "\n",
        "<span id=\"prerequisites\" />\n",
        "\n",
        "## Pré-requisitos\n",
        "\n",
        "* O fluxo de trabalho do [Qiskit Patterns](/docs/guides/intro-to-patterns)\n",
        "* [Qiskit Runtime modos de execução](/docs/guides/execution-modes), em especial o modo em lote\n",
        "* Como explorar [informações sobre a QPU](/docs/guides/qpu-information), como propriedades do backend e dados de calibração\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-02",
      "metadata": {},
      "source": [
        "<span id=\"background\" />\n",
        "\n",
        "## Segundo plano\n",
        "\n",
        "Cada QPU do IBM Quantum® relata um conjunto de propriedades que descrevem o desempenho atual de cada um de seus qubits: tempos de relaxamento ( $T_1$ ), tempos de coerência ( $T_2$ ), erros de leitura e erros em portas de um e dois qubits. Esses números têm importância na prática. O transpiler os utiliza para determinar em quais qubits físicos seu circuito deve ser executado; as técnicas de mitigação de erros dependem deles; e você pode usá-los para avaliar se um dispositivo está funcionando bem o suficiente para um experimento.\n",
        "\n",
        "As propriedades relatadas são resultado de procedimentos de calibração que geralmente são executados cerca de uma vez por dia. Os qubits supercondutores, no entanto, podem sofrer desvio em escalas de tempo mais curtas, e defeitos transitórios (os chamados sistemas de dois níveis) podem degradar temporariamente um qubit que parecia estar em excelentes condições no momento da calibração. Além disso, muitas vezes um trabalho é transpilado bem antes de ser efetivamente executado; portanto, as decisões baseadas nas propriedades relatadas podem se basear em informações desatualizadas. O tutorial [“Teste de desempenho em tempo real para seleção de qubits”](/docs/tutorials/real-time-benchmarking-for-qubit-selection) mostra o quanto essas propriedades podem variar de um dia para outro e constrói manualmente um fluxo de trabalho completo de caracterização a partir de [experimentos](https://qiskit-community.github.io/qiskit-experiments/) individuais do Qiskit.\n",
        "\n",
        "Este tutorial mostra a versão simplificada desse fluxo de trabalho, utilizando o utilitário `BackendCharacterization` do [Qiskit Device Benchmarking](https://github.com/qiskit-community/qiskit-device-benchmarking), que reúne a construção do experimento, o envio da tarefa e o ajuste de curvas em poucas chamadas. Você gasta cerca de 70 segundos de tempo da QPU e recebe um objeto backend cujas propriedades refletem *o estado* atual do dispositivo, pronto para ser comparado com os valores relatados ou repassado para ferramentas posteriores.\n",
        "\n",
        "<span id=\"the-characterization-experiments\" />\n",
        "\n",
        "### Os experimentos de caracterização\n",
        "\n",
        "O pacote inclui cinco propriedades, cada uma com um experimento padrão:\n",
        "\n",
        "* **Erro de leitura** (`readout`): Cada qubit é preparado em um estado de $|0\\rangle$ ou $|1\\rangle$ e medido imediatamente. A probabilidade de se obter um resultado errado na leitura do estado corresponde ao erro de preparação e medição do estado (SPAM).\n",
        "* **Erro de porta de qubit único** (`rb_1q`): O benchmarking aleatório (RB) executa sequências de portas de Clifford aleatórias de qubit único que, idealmente, se combinam para formar a identidade. A forma como a probabilidade de sobrevivência diminui com o comprimento da sequência resulta no erro médio por gate, independentemente dos erros do SPAM.\n",
        "* **Erro de porta de dois qubits** (`rb_2q`): O mesmo conceito de RB aplicado a camadas completas de portas de dois qubits não sobrepostas executadas simultaneamente, como em um experimento [de fidelidade de camada](https://arxiv.org/abs/2311.05933). Como muitas portas operam simultaneamente, as taxas de erro resultantes incluem efeitos de interferência cruzada e se aproximam mais do que um circuito complexo realmente apresenta.\n",
        "* **$T_1$** (`t1`): Cada qubit é excitado e medido após atrasos crescentes. O decaimento da população do estado excitado determina o tempo de relaxamento.\n",
        "* **$T_2$** (`t2`): Um experimento de eco de Hahn coloca cada qubit em uma superposição, aplica um pulso de eco na metade do atraso e mede a rapidez com que a coerência de fase é perdida. Por padrão, é utilizado um único eco; uma variante com múltiplos ecos (no estilo CPMG) é demonstrada no final deste tutorial.\n",
        "\n",
        "<span id=\"what-refreshing-does-and-does-not-do\" />\n",
        "\n",
        "### O que a atualização faz e o que não faz\n",
        "\n",
        "Tenha em mente três pontos ao utilizar este fluxo de trabalho:\n",
        "\n",
        "* As propriedades atualizadas estão disponíveis apenas no objeto de backend que é retornado a você. Nada muda no próprio dispositivo nem nos dados de calibração que o IBM Quantum reporta a outros usuários.\n",
        "* Os valores medidos representam um instantâneo obtido por meio de uma metodologia específica. Alguns deles, notadamente os erros em camadas de dois qubits e os valores da função de $T_2$ de eco único paralelo, são medidos de maneira diferente dos dados de calibração relatados; portanto, parte de qualquer discrepância observada é de natureza metodológica, e não resultado de desvio. Este tutorial mostra onde isso acontece.\n",
        "* A própria caracterização consome tempo de processamento da QPU (cerca de 70 segundos para o conjunto completo de testes em um processador Heron r2 ), o que é o preço a pagar por informações atualizadas.\n",
        "\n",
        "O fluxo de trabalho segue as quatro etapas de um padrão do Qiskit:\n",
        "\n",
        "* **Etapa 1: Mapeie as entradas clássicas para um problema quântico.** Escolha o dispositivo e o conjunto de propriedades a serem medidas.\n",
        "* **Etapa 2: Otimizar o problema para execução em hardware quântico.** O utilitário constrói os circuitos experimentais diretamente nas portas nativas do dispositivo e os paraleliza por todo o chip.\n",
        "* **Etapa 3: Execute usando o comando `Qiskit primitives`.** Os experimentos são executados como tarefas do Sampler dentro de um lote.\n",
        "* **Etapa 4: Realizar o pós-processamento e apresentar o resultado no formato clássico desejado.** Inserir os dados de medição em mapas de erros por qubit, atualizar o backend e comparar as propriedades medidas com as relatadas.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-03",
      "metadata": {},
      "source": [
        "<span id=\"requirements\" />\n",
        "\n",
        "## Requisitos\n",
        "\n",
        "Antes de iniciar este tutorial, certifique-se de que os seguintes itens estejam instalados:\n",
        "\n",
        "* Qiskit SDK v2.0 ou versão posterior, com suporte [à visualização](/docs/api/qiskit/visualization)\n",
        "* Qiskit Runtime v0.40 ou posterior (`pip install qiskit-ibm-runtime`)\n",
        "* Avaliação de desempenho de dispositivos com o Qiskit, que também instala [o Qiskit Experiments](https://qiskit-community.github.io/qiskit-experiments/) (`pip install git+https://github.com/qiskit-community/qiskit-device-benchmarking.git`)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-04",
      "metadata": {},
      "source": [
        "<span id=\"setup\" />\n",
        "\n",
        "## Instalação\n",
        "\n",
        "Importe as bibliotecas necessárias.\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": [
        "O conjunto de ferramentas de caracterização configura vários experimentos, envia múltiplas tarefas e realiza o ajuste dos resultados, o que pode levar alguns minutos no total. Ative o registro de log no nível INFO para que cada etapa exiba seu andamento à medida que ocorre.\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",
        "## Exemplo de simulador em pequena escala\n",
        "\n",
        "Este tutorial não inclui um exemplo de simulador. O fluxo de trabalho mede as imperfeições físicas de um dispositivo específico: a rapidez com que seus qubits relaxam e perdem a fase, e a frequência com que suas portas lógicas e a leitura falham. Um simulador ideal não apresenta nenhuma dessas imperfeições; portanto, não há nada a ser caracterizado. Você poderia associar um modelo de ruído sintético a um backend falso, mas, nesse caso, os experimentos recuperariam apenas os números que você mesmo inserisse. Por esse motivo, passamos diretamente ao hardware, dividido nas quatro etapas de um padrão do Qiskit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-09",
      "metadata": {},
      "source": [
        "<span id=\"large-scale-hardware-example\" />\n",
        "\n",
        "## Exemplo de hardware em grande escala\n",
        "\n",
        "<span id=\"step-1-map-classical-inputs-to-a-quantum-problem\" />\n",
        "\n",
        "### Etapa 1: Mapeamento de entradas clássicas para um problema quântico\n",
        "\n",
        "Nesse fluxo de trabalho, o “problema” é o próprio dispositivo: as entradas clássicas são a QPU que se deseja caracterizar e a lista de propriedades a serem medidas, e os experimentos quânticos são os circuitos de caracterização gerados a partir delas.\n",
        "\n",
        "Primeiro, selecione um backend. Este tutorial utiliza o Heron `ibm_kingston`, um processador de r2 de 156 qubits; você pode substituí-lo por qualquer dispositivo da IBM Quantum ao qual tenha acesso (ou escolher um com `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": [
        "Em seguida, escolha quais propriedades medir. Você pode ser aprovado em qualquer subconjunto dos seguintes experimentos:\n",
        "\n",
        "* `readout`: Experimento SPAM (preparação e medição de estados)\n",
        "* `rb_1q`: avaliação comparativa aleatória de qubits isolados\n",
        "* `rb_2q`: avaliação comparativa aleatória simultânea de dois qubits a partir de um experimento de fidelidade em camadas\n",
        "* `t2`: $T_2$ Experimento de eco de Hahn (um único eco por padrão)\n",
        "* `t1`: Experimento de relaxamento “ $T_1$ ”\n",
        "\n",
        "Execute o conjunto completo de testes para obter uma visão geral do dispositivo; remova itens da lista se você estiver interessado apenas em algumas propriedades e quiser economizar tempo de processamento da QPU.\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",
        "### Etapa 2: Otimizar o problema para execução em hardware quântico\n",
        "\n",
        "Na maioria dos tutoriais, é aqui que você faria a transpilagem dos seus circuitos. Aqui, isso `BackendCharacterization` é feito internamente. Ele constrói os circuitos experimentais diretamente nas portas nativas do dispositivo, executa os experimentos de qubit único em todos os qubits em paralelo e programa os testes de desempenho de dois qubits em camadas disjuntas do mapa de acoplamento, de modo que todo o dispositivo seja coberto com apenas algumas tarefas. Devido a essa paralelização, todo o conjunto de testes consome apenas cerca de 70 segundos de tempo da QPU.\n",
        "\n",
        "Inicialize a classe que gerencia o fluxo de trabalho:\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",
        "### Etapa 3: Executar usando Qiskit primitives\n",
        "\n",
        "O método `run_experiments` cria os circuitos e os envia como tarefas [do Sampler](/docs/guides/get-started-with-sampler). Execute-o dentro de um contexto [`Batch`](/docs/guides/run-jobs-batch) para que as tarefas sejam agendadas juntas na QPU, e o método retorne assim que todas as tarefas tiverem sido enviadas. (Você também pode executá-lo fora de um arquivo em lote ou dentro de um `Session`.)\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Você pode receber um aviso informando que um backend está sendo passado enquanto um gerenciador de contexto de sessão está aberto. Isso é esperado e pode ser ignorado sem problemas.\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": [
        "O método retorna os trabalhos enviados como um dicionário cujas entradas são organizadas por experimento, o que é útil para acompanhá-los no [painel do IBM Quantum Platform ou para depuração.](/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",
        "### Etapa 4: Realizar o pós-processamento e apresentar o resultado no formato clássico desejado\n",
        "\n",
        "<span id=\"analyze-the-results\" />\n",
        "\n",
        "#### Analise os resultados\n",
        "\n",
        "O método `analyze_results` aguarda a conclusão dos trabalhos e realiza o ajuste dos dados de medição: decaimentos exponenciais para $T_1$ e $T_2$, decaimentos de probabilidade de sobrevivência para os experimentos RB e matrizes de atribuição para a leitura dos resultados. Ela retorna um dicionário de *mapas de erros*, com uma entrada para cada propriedade medida, sendo que cada uma mapeia um qubit (ou par de qubits) para seu valor medido.\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": [
        "Os mapas abrangem o erro de leitura, os erros de qubit único e `x` de porta `sx` , os erros de dois qubits em camadas (`lf_error_map`, provenientes do experimento de fidelidade em camadas) e os tempos de $T_1$ e e $T_2$, expressos em segundos.\n",
        "\n",
        "<span id=\"update-the-backend-properties\" />\n",
        "\n",
        "#### Atualizar as propriedades do backend\n",
        "\n",
        "O método `update_backend` grava os valores medidos nas propriedades de uma cópia do backend e a retorna. O objeto `backend` original mantém os dados de calibração relatados, para que possamos comparar os dois, conforme mostrado a seguir. Lembre-se de que essa atualização é estritamente local, restrita à sua sessão do Python; ela não altera nada no dispositivo nem para outros usuários.\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",
        "#### Compare as propriedades medidas com as relatadas\n",
        "\n",
        "Por fim, represente graficamente as propriedades medidas em tempo real em relação aos valores informados pelo backend. Em cada painel, os qubits (ou pares de qubits) são classificados de acordo com o valor medido; assim, a curva de medição é suave por definição, e a dispersão dos valores relatados em torno dela mostra onde os dois resultados divergem. É apresentado um único gráfico para o RB de um único qubit, pois o mesmo erro medido por porta é atribuído tanto à porta quanto `x` à porta `sx` . Os limites dos eixos são escolhidos com base na maior parte dos dados, de modo que alguns outliers extremos não comprimam os gráficos; quaisquer pontos fora desse intervalo são contabilizados em uma anotação no gráfico (ou utilize a opção `pass` para `ylim` substituir os limites).\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": [
        "Esses gráficos exigem uma leitura cuidadosa, pois nem toda diferença entre as duas curvas significa que o dispositivo sofreu desvio:\n",
        "\n",
        "* **Leitura e erros em qubits individuais** : os valores medidos correspondem aos relatados para a maioria dos qubits, enquanto o valor relatado para alguns qubits está muito distante da curva medida. Essas divergências pontuais são exatamente o tipo de desvio que esse fluxo de trabalho foi projetado para detectar.\n",
        "* **$T_1$** : Os dois conjuntos de dados se distribuem entre si sem nenhum desvio sistemático, o que é consistente com a ideia de que o $T_1$ flutua naturalmente ao longo do tempo.\n",
        "* **Erros de dois qubits** : os valores medidos estão sistematicamente *acima* dos valores relatados. Isso é esperado, pois os valores relatados são medidos em portas isoladas, enquanto o experimento de fidelidade de camada opera várias portas simultaneamente e, portanto, inclui interferência cruzada. Os números por camadas são mais relevantes para circuitos profundos, mas não são diretamente comparáveis aos dados de calibração divulgados.\n",
        "* **$T_2$** e: Os valores medidos estão bem *abaixo* dos valores relatados para a maioria dos qubits. Mais uma vez, a metodologia desempenha um papel importante, conforme analisado na próxima seção.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-27",
      "metadata": {},
      "source": [
        "<span id=\"inspect-individual-experiment-results\" />\n",
        "\n",
        "#### Analisar os resultados de cada experimento\n",
        "\n",
        "Você também pode examinar os resultados brutos dos experimentos de caracterização individuais por meio da propriedade `experiment_data` , que retorna os objetos `ExperimentData` [`Qiskit Experiments`](https://qiskit-community.github.io/qiskit-experiments/) subjacentes. Por exemplo, a figura a seguir mostra a curva de decaimento medido $T_1$ de um único qubit, o que é útil para verificar a qualidade de um ajuste antes de confiar no valor obtido.\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",
        "#### Medir o “ T2 ” com uma sequência de desacoplamento dinâmico\n",
        "\n",
        "Por padrão, o experimento “ $T_2$ ” aplica um único eco de Hahn e mede todos os qubits em paralelo, o que, como mostrou o gráfico comparativo acima, pode resultar em valores de “ $T_2$ ” visivelmente menores do que os relatados pelo backend. Uma hipótese diz respeito ao número de ecos: os valores relatados podem ser calibrados por meio do desacoplamento dinâmico, que suprime o ruído de baixa frequência. Para testar isso, execute uma caracterização apenas com a função “ $T_2$ ” com o parâmetro definido `t2_num_echoes` para um valor maior, o que aplica uma sequência de pulsos de eco no estilo CPMG. Os atrasos representam o tempo total de evolução livre em ambos os casos; portanto, os valores ajustados de “ $T_2$ ” são diretamente comparáveis aos resultados de eco único.\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": [
        "Nesta execução, os ecos adicionais quase não alteraram o resultado: a mediana dos 8 ecos (56 µs) é próxima daquela do eco único (53 µs), e ambas permanecem bem abaixo da mediana relatada (142 µs). O número de ecos, por si só, não explica essa diferença; há outras diferenças metodológicas envolvidas, como detalhes do procedimento de calibração, a medição de todos os qubits em paralelo, em vez de isoladamente, e assim por diante.\n",
        "\n",
        "A lição prática é que devemos tratar com cautela as comparações entre metodologias no que diz respeito à função de medição de probabilidade ( $T_2$ ) e aos erros em camadas de dois qubits. Os valores atualizados constituem um instantâneo internamente consistente obtido em condições próximas às de uma carga de trabalho real, o que os torna ideais para comparar qubits entre si ou acompanhar a evolução de um dispositivo ao longo do tempo. No entanto, uma discrepância em relação aos dados de calibração relatados não é, por si só, indício de desvio.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-33",
      "metadata": {},
      "source": [
        "<span id=\"steps-1–4-compressed-into-a-single-call\" />\n",
        "\n",
        "### Etapas 1 a 4 reunidas em uma única chamada\n",
        "\n",
        "No dia a dia, raramente é necessário consultar os resultados intermediários. O método `run_and_update` agrupa todas as etapas que você realizou acima (compilação, envio, ajuste e atualização) em uma única chamada que retorna o backend atualizado. Ele aceita a mesma `experiments` lista (e repassa opções como `t2_num_echoes`), e também pode ser envolvido em um `Session` contexto ou `Batch` .\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  A célula a seguir não retorna até que todos os trabalhos e o pós-processamento estejam concluídos.\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": [
        "O objeto `backend_updated` atualizado já está pronto para ser usado em qualquer lugar em que as propriedades do backend sejam incorporadas ao seu fluxo de trabalho. Experimente esse processo em conjunto com o tutorial [“Avaliação comparativa em tempo real para seleção de qubits”](/docs/tutorials/real-time-benchmarking-for-qubit-selection) para escolher os qubits com melhor desempenho ao compilar um circuito. Como o dispositivo fica se desviando, atualize as propriedades próximo ao momento em que você realmente executar sua carga de trabalho.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cell-36",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "Se você achou este trabalho interessante, talvez se interesse pelo material a seguir:\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Use as propriedades atualizadas para selecionar qubits melhores no tutorial “[Avaliação comparativa em tempo real para seleção de qubits](/docs/tutorials/real-time-benchmarking-for-qubit-selection) ”\n",
        "  * Saiba como os dados de calibração relatados são apresentados no guia [de informações do](/docs/guides/qpu-information) QPU\n",
        "  * Explore os experimentos de caracterização individuais na [documentação](https://qiskit-community.github.io/qiskit-experiments/) do Qiskit Experiments\n",
        "  * Confira outros testes de desempenho em nível de dispositivo no [repositório](https://github.com/qiskit-community/qiskit-device-benchmarking) 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
}