Repository: Qiskit/qiskit

Issue:
QuantumInstance.execute returns the calibration circuits results
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues -->

### Information

- **Qiskit Terra version**: 0.18.3
- **Python version**: 3.8.6
- **Operating system**: MacOSX 10.15.7

### What is the current behavior?

When QuantumInstance class uses measurement error mitigation, the `execute` command returns the results of the calibration circuits in addition to the requested circuits. This causes an error in the CircuitSample.sample_circuits command and as a result alters the first iteration of the VQE optimization.

### Steps to reproduce the problem

```
from qiskit import Aer, QuantumCircuit
from qiskit.ignis.mitigation import CompleteMeasFitter
from qiskit.opflow import CircuitSampler, CircuitStateFn
from qiskit.utils import QuantumInstance

qc = QuantumCircuit(1)
qc.x(0)

qc_meas = qc.copy()
qc_meas.measure_all()

backend = Aer.get_backend('aer_simulator')
for idx, is_use_mitigation in enumerate([False, True]):
    if is_use_mitigation:
        quantum_instance = QuantumInstance(backend, measurement_error_mitigation_cls=CompleteMeasFitter)
    else:
        quantum_instance = QuantumInstance(backend)

    counts = quantum_instance.execute(qc_meas).get_counts()
    print(counts)

    circuit_sampler = CircuitSampler(quantum_instance)
    sampling = circuit_sampler.sample_circuits(circuit_sfns=[CircuitStateFn(qc)])
    print(sampling)
```

### What is the expected behavior?

Should return just the result of the input circuit.

### Suggested solutions
It seems like there is a mechanism to skip result in line 641 in utils/quantum_instance.py file. 
I think it can be utilised to skip the calibration results as well.



Discussion:

Resolving patch:
diff --git a/qiskit/utils/quantum_instance.py b/qiskit/utils/quantum_instance.py
--- a/qiskit/utils/quantum_instance.py
+++ b/qiskit/utils/quantum_instance.py
@@ -511,6 +511,8 @@ def _find_save_state(data):
                 self.maybe_refresh_cals_matrix(timestamp) or meas_error_mitigation_fitter is None
             )
 
+            cal_circuits = None
+            prepended_calibration_circuits: int = 0
             if build_cals_matrix:
                 if circuit_job:
                     logger.info("Updating to also run measurement error mitigation.")
@@ -558,6 +560,7 @@ def _find_save_state(data):
                         self._time_taken += result.time_taken
                     else:
                         circuits[0:0] = cal_circuits
+                        prepended_calibration_circuits = len(cal_circuits)
                         result = run_circuits(
                             circuits,
                             self._backend,
@@ -685,7 +688,8 @@ def _find_save_state(data):
                     num_param_variations = len(self._run_config.parameterizations[0][0])
                     num_circuits = num_circuit_templates * num_param_variations
                 else:
-                    num_circuits = len(circuits)
+                    input_circuits = circuits[prepended_calibration_circuits:]
+                    num_circuits = len(input_circuits)
                 skip_num_circuits = len(result.results) - num_circuits
                 #  remove the calibration counts from result object to assure the length of
                 #  ExperimentalResult is equal length to input circuits
@@ -710,6 +714,12 @@ def _find_save_state(data):
                         tmp_result, self._meas_error_mitigation_method
                     )
                     for i, n in enumerate(c_idx):
+                        # convert counts to integer and remove 0 values
+                        tmp_result.results[i].data.counts = {
+                            k: round(v)
+                            for k, v in tmp_result.results[i].data.counts.items()
+                            if round(v) != 0
+                        }
                         result.results[n] = tmp_result.results[i]
 
         else:


Test patch:
diff --git a/test/python/algorithms/test_measure_error_mitigation.py b/test/python/algorithms/test_measure_error_mitigation.py
--- a/test/python/algorithms/test_measure_error_mitigation.py
+++ b/test/python/algorithms/test_measure_error_mitigation.py
@@ -182,13 +182,33 @@ def _get_operator(self, weight_matrix):
     def test_measurement_error_mitigation_qaoa(self):
         """measurement error mitigation test with QAOA"""
         algorithm_globals.random_seed = 167
+        backend = Aer.get_backend("aer_simulator")
+        w = rx.adjacency_matrix(
+            rx.undirected_gnp_random_graph(5, 0.5, seed=algorithm_globals.random_seed)
+        )
+        qubit_op, _ = self._get_operator(w)
+        initial_point = np.asarray([0.0, 0.0])
+
+        # Compute first without noise
+        quantum_instance = QuantumInstance(
+            backend=backend,
+            seed_simulator=algorithm_globals.random_seed,
+            seed_transpiler=algorithm_globals.random_seed,
+        )
+        qaoa = QAOA(
+            optimizer=COBYLA(maxiter=3),
+            quantum_instance=quantum_instance,
+            initial_point=initial_point,
+        )
+        result = qaoa.compute_minimum_eigenvalue(operator=qubit_op)
+        ref_eigenvalue = result.eigenvalue.real
 
+        # compute with noise
         # build noise model
         noise_model = noise.NoiseModel()
         read_err = noise.errors.readout_error.ReadoutError([[0.9, 0.1], [0.25, 0.75]])
         noise_model.add_all_qubit_readout_error(read_err)
 
-        backend = Aer.get_backend("aer_simulator")
         quantum_instance = QuantumInstance(
             backend=backend,
             seed_simulator=algorithm_globals.random_seed,
@@ -196,17 +216,14 @@ def test_measurement_error_mitigation_qaoa(self):
             noise_model=noise_model,
             measurement_error_mitigation_cls=CompleteMeasFitter,
         )
-        w = rx.adjacency_matrix(
-            rx.undirected_gnp_random_graph(5, 0.5, seed=algorithm_globals.random_seed)
-        )
-        qubit_op, _ = self._get_operator(w)
+
         qaoa = QAOA(
-            optimizer=COBYLA(maxiter=1),
+            optimizer=COBYLA(maxiter=3),
             quantum_instance=quantum_instance,
-            initial_point=np.asarray([0.0, 0.0]),
+            initial_point=initial_point,
         )
         result = qaoa.compute_minimum_eigenvalue(operator=qubit_op)
-        self.assertAlmostEqual(result.eigenvalue.real, 3.49, delta=0.05)
+        self.assertAlmostEqual(result.eigenvalue.real, ref_eigenvalue, delta=0.05)
 
     @unittest.skipUnless(HAS_AER, "qiskit-aer is required for this test")
     @unittest.skipUnless(HAS_IGNIS, "qiskit-ignis is required to run this test")
@@ -313,6 +330,43 @@ def test_measurement_error_mitigation_with_vqe_ignis(self, config):
         quantum_instance.reset_execution_results()
         self.assertAlmostEqual(result.eigenvalue.real, -1.86, delta=0.05)
 
+    @unittest.skipUnless(HAS_AER, "qiskit-aer is required for this test")
+    @unittest.skipUnless(HAS_IGNIS, "qiskit-ignis is required to run this test")
+    def test_callibration_results(self):
+        """check that results counts are the same with/without error mitigation"""
+        algorithm_globals.random_seed = 1679
+        np.random.seed(algorithm_globals.random_seed)
+        qc = QuantumCircuit(1)
+        qc.x(0)
+
+        qc_meas = qc.copy()
+        qc_meas.measure_all()
+        backend = Aer.get_backend("aer_simulator")
+
+        counts_array = [None, None]
+        for idx, is_use_mitigation in enumerate([True, False]):
+            if is_use_mitigation:
+                quantum_instance = QuantumInstance(
+                    backend,
+                    seed_simulator=algorithm_globals.random_seed,
+                    seed_transpiler=algorithm_globals.random_seed,
+                    shots=1024,
+                    measurement_error_mitigation_cls=CompleteMeasFitter_IG,
+                )
+                with self.assertWarnsRegex(DeprecationWarning, r".*ignis.*"):
+                    counts_array[idx] = quantum_instance.execute(qc_meas).get_counts()
+            else:
+                quantum_instance = QuantumInstance(
+                    backend,
+                    seed_simulator=algorithm_globals.random_seed,
+                    seed_transpiler=algorithm_globals.random_seed,
+                    shots=1024,
+                )
+                counts_array[idx] = quantum_instance.execute(qc_meas).get_counts()
+        self.assertEqual(
+            counts_array[0], counts_array[1], msg="Counts different with/without fitter."
+        )
+
 
 if __name__ == "__main__":
     unittest.main()