qiskit/tools/qcvv/tomography.py
def tomography_set(meas_qubits,
                   meas_basis='Pauli',
                   prep_qubits=None,
                   prep_basis=None):
    """
    Generate a dictionary of tomography experiment configurations.

    This returns a data structure that is used by other tomography functions
    to generate state and process tomography circuits, and extract tomography
    data from results after execution on a backend.

    Quantum State Tomography:
        Be default it will return a set for performing Quantum State
        Tomography where individual qubits are measured in the Pauli basis.
        A custom measurement basis may also be used by defining a user
        `tomography_basis` and passing this in for the `meas_basis` argument.

    Quantum Process Tomography:
        A quantum process tomography set is created by specifying a preparation
        basis along with a measurement basis. The preparation basis may be a
        user defined `tomography_basis`, or one of the two built in basis 'SIC'
        or 'Pauli'.
        - SIC: Is a minimal symmetric informationally complete preparation
               basis for 4 states for each qubit (4 ^ number of qubits total
               preparation states). These correspond to the |0> state and the 3
               other vertices of a tetrahedron on the Bloch-sphere.
        - Pauli: Is a tomographically overcomplete preparation basis of the six
                 eigenstates of the 3 Pauli operators (6 ^ number of qubits
                 total preparation states).

    Args:
        meas_qubits (list): The qubits being measured.
        meas_basis (tomography_basis or str): The qubit measurement basis.
            The default value is 'Pauli'.
        prep_qubits (list or None): The qubits being prepared. If None then
            meas_qubits will be used for process tomography experiments.
        prep_basis (tomography_basis or None): The optional qubit preparation
            basis. If no basis is specified state tomography will be performed
            instead of process tomography. A built in basis may be specified by
            'SIC' or 'Pauli'  (SIC basis recommended for > 2 qubits).

    Returns:
        dict: A dict of tomography configurations that can be parsed by
        `create_tomography_circuits` and `tomography_data` functions
        for implementing quantum tomography experiments. This output contains
        fields "qubits", "meas_basis", "circuits". It may also optionally
        contain a field "prep_basis" for process tomography experiments.
        ```
        {
            'qubits': qubits (list[ints]),
            'meas_basis': meas_basis (tomography_basis),
            'circuit_labels': (list[string]),
            'circuits': (list[dict])  # prep and meas configurations
            # optionally for process tomography experiments:
            'prep_basis': prep_basis (tomography_basis)
        }
        ```
    Raises:
        QiskitError: if the Qubits argument is not a list.
    """
    if not isinstance(meas_qubits, list):
        raise QiskitError('Qubits argument must be a list')
    num_of_qubits = len(meas_qubits)

    if prep_qubits is None:
        prep_qubits = meas_qubits
    if not isinstance(prep_qubits, list):
        raise QiskitError('prep_qubits argument must be a list')
    if len(prep_qubits) != len(meas_qubits):
        raise QiskitError('meas_qubits and prep_qubitsare different length')

    if isinstance(meas_basis, str):
        if meas_basis.lower() == 'pauli':
            meas_basis = PAULI_BASIS

    if isinstance(prep_basis, str):
        if prep_basis.lower() == 'pauli':
            prep_basis = PAULI_BASIS
        elif prep_basis.lower() == 'sic':
            prep_basis = SIC_BASIS

    circuits = []
    circuit_labels = []

    # add meas basis configs
    if prep_basis is None:
        # State Tomography
        for meas_product in product(meas_basis.keys(), repeat=num_of_qubits):
            meas = dict(zip(meas_qubits, meas_product))
            circuits.append({'meas': meas})
            # Make label
            label = '_meas_'
            for qubit, op in meas.items():
                label += '%s(%d)' % (op[0], qubit)
            circuit_labels.append(label)
        return {'qubits': meas_qubits,
                'circuits': circuits,
                'circuit_labels': circuit_labels,
                'meas_basis': meas_basis}

    # Process Tomography
    num_of_s = len(list(prep_basis.values())[0])
    plst_single = [(b, s)
                   for b in prep_basis.keys()
                   for s in range(num_of_s)]
    for plst_product in product(plst_single, repeat=num_of_qubits):
        for meas_product in product(meas_basis.keys(),
                                    repeat=num_of_qubits):
            prep = dict(zip(prep_qubits, plst_product))
            meas = dict(zip(meas_qubits, meas_product))
            circuits.append({'prep': prep, 'meas': meas})
            # Make label
            label = '_prep_'
            for qubit, op in prep.items():
                label += '%s%d(%d)' % (op[0], op[1], qubit)
            label += '_meas_'
            for qubit, op in meas.items():
                label += '%s(%d)' % (op[0], qubit)
            circuit_labels.append(label)
    return {'qubits': meas_qubits,
            'circuits': circuits,
            'circuit_labels': circuit_labels,
            'prep_basis': prep_basis,
            'meas_basis': meas_basis}
def tomography_set(meas_qubits,
                   meas_basis='Pauli',
                   prep_qubits=None,
                   prep_basis=None):
    """
    Generate a dictionary of tomography experiment configurations.

    This returns a data structure that is used by other tomography functions
    to generate state and process tomography circuits, and extract tomography
    data from results after execution on a backend.

    Quantum State Tomography:
        Be default it will return a set for performing Quantum State
        Tomography where individual qubits are measured in the Pauli basis.
        A custom measurement basis may also be used by defining a user
        `tomography_basis` and passing this in for the `meas_basis` argument.

    Quantum Process Tomography:
        A quantum process tomography set is created by specifying a preparation
        basis along with a measurement basis. The preparation basis may be a
        user defined `tomography_basis`, or one of the two built in basis 'SIC'
        or 'Pauli'.
        - SIC: Is a minimal symmetric informationally complete preparation
               basis for 4 states for each qubit (4 ^ number of qubits total
               preparation states). These correspond to the |0> state and the 3
               other vertices of a tetrahedron on the Bloch-sphere.
        - Pauli: Is a tomographically overcomplete preparation basis of the six
                 eigenstates of the 3 Pauli operators (6 ^ number of qubits
                 total preparation states).

    Args:
        meas_qubits (list): The qubits being measured.
        meas_basis (tomography_basis or str): The qubit measurement basis.
            The default value is 'Pauli'.
        prep_qubits (list or None): The qubits being prepared. If None then
            meas_qubits will be used for process tomography experiments.
        prep_basis (tomography_basis or None): The optional qubit preparation
            basis. If no basis is specified state tomography will be performed
            instead of process tomography. A built in basis may be specified by
            'SIC' or 'Pauli'  (SIC basis recommended for > 2 qubits).

    Returns:
        dict: A dict of tomography configurations that can be parsed by
        `create_tomography_circuits` and `tomography_data` functions
        for implementing quantum tomography experiments. This output contains
        fields "qubits", "meas_basis", "circuits". It may also optionally
        contain a field "prep_basis" for process tomography experiments.
        ```
        {
            'qubits': qubits (list[ints]),
            'meas_basis': meas_basis (tomography_basis),
            'circuit_labels': (list[string]),
            'circuits': (list[dict])  # prep and meas configurations
            # optionally for process tomography experiments:
            'prep_basis': prep_basis (tomography_basis)
        }
        ```
    Raises:
        QiskitError: if the Qubits argument is not a list.
    """
    if not isinstance(meas_qubits, list):
        raise QiskitError('Qubits argument must be a list')
    num_of_qubits = len(meas_qubits)

    if prep_qubits is None:
        prep_qubits = meas_qubits
    if not isinstance(prep_qubits, list):
        raise QiskitError('prep_qubits argument must be a list')
    if len(prep_qubits) != len(meas_qubits):
        raise QiskitError('meas_qubits and prep_qubitsare different length')

    if isinstance(meas_basis, str):
        if meas_basis.lower() == 'pauli':
            meas_basis = PAULI_BASIS

    if isinstance(prep_basis, str):
        if prep_basis.lower() == 'pauli':
            prep_basis = PAULI_BASIS
        elif prep_basis.lower() == 'sic':
            prep_basis = SIC_BASIS

    circuits = []
    circuit_labels = []

    # add meas basis configs
    if prep_basis is None:
        # State Tomography
        for meas_product in product(meas_basis.keys(), repeat=num_of_qubits):
            meas = dict(zip(meas_qubits, meas_product))
            circuits.append({'meas': meas})
            # Make label
            label = '_meas_'
            for qubit, op in meas.items():
                label += '%s(%d)' % (op[0], qubit)
            circuit_labels.append(label)
        return {'qubits': meas_qubits,
                'circuits': circuits,
                'circuit_labels': circuit_labels,
                'meas_basis': meas_basis}

    # Process Tomography
    num_of_s = len(list(prep_basis.values())[0])
    plst_single = [(b, s)
                   for b in prep_basis.keys()
                   for s in range(num_of_s)]
    for plst_product in product(plst_single, repeat=num_of_qubits):
        for meas_product in product(meas_basis.keys(),
                                    repeat=num_of_qubits):
            prep = dict(zip(prep_qubits, plst_product))
            meas = dict(zip(meas_qubits, meas_product))
            circuits.append({'prep': prep, 'meas': meas})
            # Make label
            label = '_prep_'
            for qubit, op in prep.items():
                label += '%s%d(%d)' % (op[0], op[1], qubit)
            label += '_meas_'
            for qubit, op in meas.items():
                label += '%s(%d)' % (op[0], qubit)
            circuit_labels.append(label)
    return {'qubits': meas_qubits,
            'circuits': circuits,
            'circuit_labels': circuit_labels,
            'prep_basis': prep_basis,
            'meas_basis': meas_basis}
Generate a dictionary of tomography experiment configurations.

    This returns a data structure that is used by other tomography functions
    to generate state and process tomography circuits, and extract tomography
    data from results after execution on a backend.

    Quantum State Tomography:
        Be default it will return a set for performing Quantum State
        Tomography where individual qubits are measured in the Pauli basis.
        A custom measurement basis may also be used by defining a user
        `tomography_basis` and passing this in for the `meas_basis` argument.

    Quantum Process Tomography:
        A quantum process tomography set is created by specifying a preparation
        basis along with a measurement basis. The preparation basis may be a
        user defined `tomography_basis`, or one of the two built in basis 'SIC'
        or 'Pauli'.
        - SIC: Is a minimal symmetric informationally complete preparation
               basis for 4 states for each qubit (4 ^ number of qubits total
               preparation states). These correspond to the |0> state and the 3
               other vertices of a tetrahedron on the Bloch-sphere.
        - Pauli: Is a tomographically overcomplete preparation basis of the six
                 eigenstates of the 3 Pauli operators (6 ^ number of qubits
                 total preparation states).

    Args:
        meas_qubits (list): The qubits being measured.
        meas_basis (tomography_basis or str): The qubit measurement basis.
            The default value is 'Pauli'.
        prep_qubits (list or None): The qubits being prepared. If None then
            meas_qubits will be used for process tomography experiments.
        prep_basis (tomography_basis or None): The optional qubit preparation
            basis. If no basis is specified state tomography will be performed
            instead of process tomography. A built in basis may be specified by
            'SIC' or 'Pauli'  (SIC basis recommended for > 2 qubits).

    Returns:
        dict: A dict of tomography configurations that can be parsed by
        `create_tomography_circuits` and `tomography_data` functions
        for implementing quantum tomography experiments. This output contains
        fields "qubits", "meas_basis", "circuits". It may also optionally
        contain a field "prep_basis" for process tomography experiments.
        ```
        {
            'qubits': qubits (list[ints]),
            'meas_basis': meas_basis (tomography_basis),
            'circuit_labels': (list[string]),
            'circuits': (list[dict])  # prep and meas configurations
            # optionally for process tomography experiments:
            'prep_basis': prep_basis (tomography_basis)
        }
        ```
    Raises:
        QiskitError: if the Qubits argument is not a list.