Source code for qiskit.assembler.disassemble

# -*- coding: utf-8 -*-

# This code is part of Qiskit.
#
# (C) Copyright IBM 2017, 2019.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Disassemble function for a qobj into a list of circuits and its config"""

import collections

from qiskit.circuit.classicalregister import ClassicalRegister
from qiskit.circuit.instruction import Instruction
from qiskit.circuit.quantumcircuit import QuantumCircuit
from qiskit.circuit.quantumregister import QuantumRegister


def _experiments_to_circuits(qobj):
    """Return a list of QuantumCircuit object(s) from a qobj.

    Args:
        qobj (Qobj): The Qobj object to convert to QuantumCircuits

    Returns:
        list: A list of QuantumCircuit objects from the qobj
    """
    if qobj.experiments:
        circuits = []
        for x in qobj.experiments:
            quantum_registers = [QuantumRegister(i[1], name=i[0])
                                 for i in x.header.qreg_sizes]
            classical_registers = [ClassicalRegister(i[1], name=i[0])
                                   for i in x.header.creg_sizes]
            circuit = QuantumCircuit(*quantum_registers,
                                     *classical_registers,
                                     name=x.header.name)
            qreg_dict = collections.OrderedDict()
            creg_dict = collections.OrderedDict()
            for reg in quantum_registers:
                qreg_dict[reg.name] = reg
            for reg in classical_registers:
                creg_dict[reg.name] = reg
            conditional = {}
            for i in x.instructions:
                name = i.name
                qubits = []
                params = getattr(i, 'params', [])
                try:
                    for qubit in i.qubits:
                        qubit_label = x.header.qubit_labels[qubit]
                        qubits.append(
                            qreg_dict[qubit_label[0]][qubit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                clbits = []
                try:
                    for clbit in i.memory:
                        clbit_label = x.header.clbit_labels[clbit]
                        clbits.append(
                            creg_dict[clbit_label[0]][clbit_label[1]])
                except Exception:  # pylint: disable=broad-except
                    pass
                if hasattr(circuit, name):
                    instr_method = getattr(circuit, name)
                    if i.name in ['snapshot']:
                        _inst = instr_method(
                            i.label,
                            snapshot_type=i.snapshot_type,
                            qubits=qubits,
                            params=params)
                    elif i.name == 'initialize':
                        _inst = instr_method(params, qubits)
                    else:
                        _inst = instr_method(*params, *qubits, *clbits)
                elif name == 'bfunc':
                    conditional['value'] = int(i.val, 16)
                    full_bit_size = sum([creg_dict[x].size for x in creg_dict])
                    mask_map = {}
                    raw_map = {}
                    raw = []

                    for creg in creg_dict:
                        size = creg_dict[creg].size
                        reg_raw = [1] * size
                        if not raw:
                            raw = reg_raw
                        else:
                            for pos, val in enumerate(raw):
                                if val == 1:
                                    raw[pos] = 0
                            raw = reg_raw + raw
                        mask = [0] * (full_bit_size - len(raw)) + raw
                        raw_map[creg] = mask
                        mask_map[int("".join(str(x) for x in mask), 2)] = creg
                    creg = mask_map[int(i.mask, 16)]
                    conditional['register'] = creg_dict[creg]
                    val = int(i.val, 16)
                    mask = raw_map[creg]
                    for j in reversed(mask):
                        if j == 0:
                            val = val >> 1
                        else:
                            conditional['value'] = val
                            break
                else:
                    _inst = temp_opaque_instruction = Instruction(
                        name=name, num_qubits=len(qubits),
                        num_clbits=len(clbits), params=params)
                    circuit.append(temp_opaque_instruction, qubits, clbits)
                if conditional and name != 'bfunc':
                    _inst.c_if(conditional['register'], conditional['value'])
                    conditional = {}
            circuits.append(circuit)
        return circuits
    return None


[docs]def disassemble(qobj): """Disassemble a qobj and return the circuits, run_config, and user header. Args: qobj (Qobj): The input qobj object to disassemble Returns: tuple: (circuits, run_config, user_qobj_header): * circuits (list): A list of quantum circuits * run_config (dict): The dict of the run config * user_qobj_header (dict): The dict of any user headers in the qobj """ run_config = qobj.config.to_dict() user_qobj_header = qobj.header.to_dict() circuits = _experiments_to_circuits(qobj) return circuits, run_config, user_qobj_header