diff --git a/interrogate_badge.svg b/interrogate_badge.svg index 52c20d08f..c8d6a2861 100644 --- a/interrogate_badge.svg +++ b/interrogate_badge.svg @@ -1,5 +1,5 @@ - interrogate: 98.6% + interrogate: 98.3% @@ -12,8 +12,8 @@ interrogate interrogate - 98.6% - 98.6% + 98.3% + 98.3% diff --git a/src/qililab/constants.py b/src/qililab/constants.py index 126de1741..91bd5b546 100644 --- a/src/qililab/constants.py +++ b/src/qililab/constants.py @@ -219,17 +219,18 @@ class RESULTSDATAFRAME: SOFTWARE_AVG_INDEX = "software_avg_index" SEQUENCE_INDEX = "sequence_index" LOOP_INDEX = "loop_index_" - QUBIT_INDEX = "qubit_index" RESULTS_INDEX = "results_index" - BINS_INDEX = "bins_index" + SEQUENCER = "sequencer" + BIN = "bin" + CIRCUIT = "circuit" SCOPE_INDEX = "scope_index" - ACQUISITION_INDEX = "acquisition_index" P0 = "p0" P1 = "p1" I = "i" # noqa: E741 Q = "q" AMPLITUDE = "amplitude" PHASE = "phase" + BINARY_CLASSIFICATION = "binary_classification" UNITS = {"frequency": "Hz"} diff --git a/src/qililab/result/acquisition.py b/src/qililab/result/acquisition.py index 03d8140f0..48d6b2694 100644 --- a/src/qililab/result/acquisition.py +++ b/src/qililab/result/acquisition.py @@ -15,7 +15,7 @@ class Acquisition: Args: pulse_length (int): Duration (in ns) of the pulse. i_values: (NDArray[numpy.float32]): I data normalized - q_values: (NDArray[numpy.float32]): I data normalize + q_values: (NDArray[numpy.float32]): Q data normalize amplitude_values: (NDArray[numpy.float32]): amplitude values from I/Q normalized phase_values: (NDArray[numpy.float32]): phase values from I/Q normalized @@ -48,7 +48,6 @@ def _create_acquisition(self) -> pd.DataFrame: amplitude, phase. For multiple values you may need to redefine this method. """ - return pd.DataFrame( { RESULTSDATAFRAME.I: self.i_values, diff --git a/src/qililab/result/acquisitions.py b/src/qililab/result/acquisitions.py index e572e7130..aa8f559b9 100644 --- a/src/qililab/result/acquisitions.py +++ b/src/qililab/result/acquisitions.py @@ -6,7 +6,7 @@ from qililab.constants import RESULTSDATAFRAME from qililab.result.acquisition import Acquisition -from qililab.utils.dataframe_manipulation import concatenate_creating_new_name_index +from qililab.utils.dataframe_manipulation import concatenate_creating_new_concatenation_index_name @dataclass @@ -21,13 +21,11 @@ class Acquisitions: data_dataframe_indices: set[str] = field(init=False, default_factory=set) def acquisitions(self) -> pd.DataFrame: - """return the acquisitions with a structure - I, Q, Amplitude, Phase - """ + """return the acquisitions with a structure: qubit_index, bin, I, Q, Amplitude, Phase""" acquisition_list = [acquisition.acquisition for acquisition in self._acquisitions] - return concatenate_creating_new_name_index( - dataframe_list=acquisition_list, new_index_name=RESULTSDATAFRAME.ACQUISITION_INDEX + return concatenate_creating_new_concatenation_index_name( + dataframe_list=acquisition_list, new_concatenation_index_name=RESULTSDATAFRAME.SEQUENCER ) def probabilities(self) -> dict[str, float]: diff --git a/src/qililab/result/qblox_results/bins_data.py b/src/qililab/result/qblox_results/bins_data.py index 4887155b0..3ae02e098 100644 --- a/src/qililab/result/qblox_results/bins_data.py +++ b/src/qililab/result/qblox_results/bins_data.py @@ -24,13 +24,13 @@ def __post_init__(self): self.path1 = [value for value in self.path1 if not np.isnan(value)] integration: QbloxIntegrationData - threshold: list + binary_classification: list avg_cnt: list def __post_init__(self): """Remove nan values.""" # FIXME: Since we cannot do ascending loops in Qpysequence, we need to # use always a number of bins = num_loops + 1. Thus the first bin is always a nan. - self.threshold = [value for value in self.threshold if not np.isnan(value)] + self.binary_classification = [value for value in self.binary_classification if not np.isnan(value)] self.avg_cnt = [value for value in self.avg_cnt if not np.isnan(value)] def __len__(self) -> int: @@ -39,4 +39,4 @@ def __len__(self) -> int: Returns: int: Length of the QbloxIntegrationData. """ - return len(self.threshold) + return len(self.binary_classification) diff --git a/src/qililab/result/qblox_results/qblox_bins_acquisition.py b/src/qililab/result/qblox_results/qblox_bins_acquisition.py index 1481d0dae..03dc9455c 100644 --- a/src/qililab/result/qblox_results/qblox_bins_acquisition.py +++ b/src/qililab/result/qblox_results/qblox_bins_acquisition.py @@ -2,6 +2,8 @@ from dataclasses import dataclass +import numpy as np +import numpy.typing as npt import pandas as pd from qililab.constants import RESULTSDATAFRAME @@ -10,13 +12,31 @@ @dataclass class QbloxBinAcquisition(Acquisition): - """Qblox Bin Acquisition normalized""" + """Qblox Bin Acquisition normalized + Args: + binary_classification_values (NDArray[np.float32]): Thresholded values in case of + """ + + binary_classification_values: npt.NDArray[np.float32] + + def __post_init__(self): + """Create acquisitions""" + super().__post_init__() + self.data_dataframe_indices.add(RESULTSDATAFRAME.BINARY_CLASSIFICATION) def _create_acquisition(self) -> pd.DataFrame: """transposes each of the acquired results arrays so that we have for each value - a structure with i, q, amplitude, phase. + a structure with: bin, i, q, amplitude, phase. """ - acquisition_dataframe = super()._create_acquisition() - acquisition_dataframe.index.rename(RESULTSDATAFRAME.BINS_INDEX, inplace=True) + acquisition_dataframe = pd.DataFrame( + { + RESULTSDATAFRAME.I: self.i_values, + RESULTSDATAFRAME.Q: self.q_values, + RESULTSDATAFRAME.AMPLITUDE: self.amplitude_values, + RESULTSDATAFRAME.PHASE: self.phase_values, + RESULTSDATAFRAME.BINARY_CLASSIFICATION: self.binary_classification_values, + } + ) + acquisition_dataframe.index.rename(RESULTSDATAFRAME.BIN, inplace=True) acquisition_dataframe.reset_index(inplace=True) return acquisition_dataframe diff --git a/src/qililab/result/qblox_results/qblox_bins_acquisitions.py b/src/qililab/result/qblox_results/qblox_bins_acquisitions.py index 9d0b49749..08fde5d9f 100644 --- a/src/qililab/result/qblox_results/qblox_bins_acquisitions.py +++ b/src/qililab/result/qblox_results/qblox_bins_acquisitions.py @@ -32,7 +32,13 @@ def _build_bin_acquisition(self, bins_data: BinsData, integration_length: int): """build a bin acquisition""" i_values = np.array(bins_data.integration.path0, dtype=np.float32) q_values = np.array(bins_data.integration.path1, dtype=np.float32) - return QbloxBinAcquisition(integration_length=integration_length, i_values=i_values, q_values=q_values) + binary_classification_values = np.array(bins_data.binary_classification, dtype=np.float32) + return QbloxBinAcquisition( + integration_length=integration_length, + i_values=i_values, + q_values=q_values, + binary_classification_values=binary_classification_values, + ) def counts(self) -> Counts: """Return the counts of measurements in each state. @@ -46,9 +52,9 @@ def counts(self) -> Counts: # TODO: Add limitations to check we are doing single-shot for multi qubit? counts_object = Counts(n_qubits=len(self.bins)) for bin_idx in range(num_bins): - # The threshold inside of a qblox bin is the name they use for already classified data as a value between - # 0 and 1, not the value used in the comparator to perform such classification. - measurement_as_list = [int(bins_data.threshold[bin_idx]) for bins_data in self.bins] + # The binary_classification inside of a qblox bin is the name they use for already classified data as a + # value between 0 and 1, and threshold is the value used in the comparator to perform such classification. + measurement_as_list = [int(bins_data.binary_classification[bin_idx]) for bins_data in self.bins] measurement = "".join(str(bit) for bit in measurement_as_list) counts_object.add_measurement(state=measurement) return counts_object diff --git a/src/qililab/result/qblox_results/qblox_result.py b/src/qililab/result/qblox_results/qblox_result.py index ee2497204..260cb4dba 100644 --- a/src/qililab/result/qblox_results/qblox_result.py +++ b/src/qililab/result/qblox_results/qblox_result.py @@ -26,7 +26,7 @@ class QbloxResult(Result): - integration: integration data. - path_0: input path 0 integration result bin list. - path_1: input path 1 integration result bin list. - - threshold: threshold result bin list. + - binary_classification: thresholded result bin list. - valid: list of valid indications per bin. - avg_cnt: list of number of averages per bin. Args: diff --git a/src/qililab/result/results.py b/src/qililab/result/results.py index ef6a14561..9d0c9897d 100644 --- a/src/qililab/result/results.py +++ b/src/qililab/result/results.py @@ -1,5 +1,4 @@ """Results class.""" -from collections import Counter from copy import deepcopy from dataclasses import dataclass, field @@ -11,7 +10,10 @@ from qililab.result.qblox_results.qblox_result import QbloxResult from qililab.result.result import Result from qililab.utils import coordinate_decompose -from qililab.utils.dataframe_manipulation import concatenate_creating_new_name_index +from qililab.utils.dataframe_manipulation import ( + concatenate_creating_new_concatenation_index_name, + concatenate_creating_new_index_name_and_concatenation_index_name, +) from qililab.utils.factory import Factory from qililab.utils.loop import Loop from qililab.utils.util_loops import compute_ranges_from_loops, compute_shapes_from_loops @@ -91,7 +93,10 @@ def to_dataframe(self) -> pd.DataFrame: """ result_dataframes = [result.to_dataframe() for result in self.results] - return concatenate_creating_new_name_index(dataframe_list=result_dataframes, new_index_name="result_index") + return concatenate_creating_new_concatenation_index_name( + dataframe_list=result_dataframes, + new_concatenation_index_name=RESULTSDATAFRAME.CIRCUIT, + ) def _build_empty_result_dataframe(self): """Builds an empty result dataframe, with the minimal number of columns and nans as values""" @@ -110,8 +115,10 @@ def _concatenate_acquisition_dataframes(self): result.acquisitions().reset_index(drop=True) if result is not None else self._build_empty_result_dataframe() for result in self.results ] - return concatenate_creating_new_name_index( - dataframe_list=result_acquisition_list, new_index_name=RESULTSDATAFRAME.RESULTS_INDEX + return concatenate_creating_new_index_name_and_concatenation_index_name( + dataframe_list=result_acquisition_list, + new_index_name=RESULTSDATAFRAME.RESULTS_INDEX, + new_concatenation_index_name=RESULTSDATAFRAME.CIRCUIT, ) def _generate_new_acquisition_column_names(self): @@ -191,7 +198,11 @@ def acquisitions(self, mean: bool = False) -> pd.DataFrame: expanded_acquisition_df = self._add_meaningful_acquisition_indices( result_acquisition_dataframe=result_acquisition_df ) - return self._process_acquisition_dataframe_if_needed(result_dataframe=expanded_acquisition_df, mean=mean) + processed_acquisition_df = self._process_acquisition_dataframe_if_needed( + result_dataframe=expanded_acquisition_df, mean=mean + ) + + return processed_acquisition_df.drop(columns=[RESULTSDATAFRAME.RESULTS_INDEX]) def _fill_missing_values(self): """Fill with None the missing values.""" diff --git a/src/qililab/utils/dataframe_manipulation.py b/src/qililab/utils/dataframe_manipulation.py index 6ceb7961c..d05ab3083 100644 --- a/src/qililab/utils/dataframe_manipulation.py +++ b/src/qililab/utils/dataframe_manipulation.py @@ -1,20 +1,29 @@ """Utilities for usual dataframe manipulation""" +import pandas as pd -import pandas as pd +def concatenate_creating_new_index_name(dataframe_list: list[pd.DataFrame], new_index_name: str) -> pd.DataFrame: + """Concatenates an ordered list of dataframes into a single one, adding a new named column copying the index of + the final concatenated dataframe. + The result dataframe will have as columns the union of the original dataframes plus the new column with a copy + of the final index. -def concatenate_creating_new_name_index(dataframe_list: list[pd.DataFrame], new_index_name: str) -> pd.DataFrame: - """Concatenates an ordered list of dataframes into a single one, adding a new named column containing the index of - the dataframe the data came from in the original list. - The result dataframe will have as columns the union of the original dataframes plus the new column with the - indices. The index structure of the dataframes will not be considered when creating the new one (as opposed to when normally using a dataframe, where you would get a multiindex if previous index was structured). + Example: + new_index_name (copy of left index) + v + df0 df1 |NEW' BIN Q I A Phase + | BIN Q I A Phase | BIN Q I A Phase 0 | 0 ' 0 1 1 1 0 ] df0 + 0 | 0 1 1 1 0 + 0 | 0 0 0 0 0 = 1 | 1 ' 1 1 1 1 0 ] + 1 | 1 1 1 1 0 1 | 1 0 0 0 0 2 | 2 ' 0 0 0 0 0 ] df1 + 3 | 3 ' 1 0 0 0 0 ] + Args: - dataframe_list: list of dataframes to concatenate - new_index_name: name to be given to the new column containing the indices + dataframe_list (list[df]): list of dataframes to concatenate + new_index_name (str): name to be given to the new column containing the copy of the final index Returns: pd.Dataframe: the new dataframe @@ -23,3 +32,74 @@ def concatenate_creating_new_name_index(dataframe_list: list[pd.DataFrame], new_ concatenated_df.index.rename(new_index_name, inplace=True) concatenated_df.reset_index(inplace=True) return concatenated_df + + +def concatenate_creating_new_concatenation_index_name( + dataframe_list: list[pd.DataFrame], new_concatenation_index_name: str +) -> pd.DataFrame: + """Concatenates an ordered list of dataframes into a single one, adding a new named colum containing the position + from the concatenation_list. + + The result dataframe will have as columns the union of the original dataframes plus the new column that tells you + from which element of the concatenation_list it came. + + Example: + new_concatenation_index_name (position of concatenation) + v + df0 df1 |NEW' BIN Q I A Phase + | BIN Q I A Phase | BIN Q I A Phase 0 | 0 ' 0 1 1 1 0 ] df0 + 0 | 0 1 1 1 0 + 0 | 0 0 0 0 0 = 1 | 0 ' 1 1 1 1 0 ] + 1 | 1 1 1 1 0 1 | 1 0 0 0 0 2 | 1 ' 0 0 0 0 0 ] df1 + 3 | 1 ' 1 0 0 0 0 ] + + Args: + dataframe_list (list[df]): list of dataframes to concatenate + new_concatenation_index_name (str): name of the new column containing the position from the concatenation_list. + + Returns: + pd.Dataframe: the new dataframe + """ + for index, dataframe in enumerate(dataframe_list): + dataframe[new_concatenation_index_name] = index + col = dataframe.pop(new_concatenation_index_name) + dataframe.insert(0, col.name, col) + + return pd.concat(dataframe_list, ignore_index=True) + + +def concatenate_creating_new_index_name_and_concatenation_index_name( + dataframe_list: list[pd.DataFrame], new_index_name: str, new_concatenation_index_name: str +) -> pd.DataFrame: + """Concatenates an ordered list of dataframes into a single one, adding two new named columns, one that copies + the index of the final concatenated dataframe and another that contains the position from the concatenation_list. + + The result dataframe will have as columns the union of the original dataframes plus the two new columns of the + "concatenate_creating_new_index_name", "concatenate_creating_new_concatenation_index_name" functions defined above. + + The index structure of the dataframes will not be considered when creating the new one (as opposed to when + normally using a dataframe, where you would get a multiindex if previous index was structured). + + Example: new_index_name + v new_concatenation_index_name + v v + df0 df1 |NEW1 NEW2' BIN Q I A Phase + | BIN Q I A Phase | BIN Q I A Phase 0 | 0 0 ' 0 1 1 1 0 ] df0 + 0 | 0 1 1 1 0 + 0 | 0 0 0 0 0 = 1 | 1 0 ' 1 1 1 1 0 ] + 1 | 1 1 1 1 0 1 | 1 0 0 0 0 2 | 2 1 ' 0 0 0 0 0 ] df1 + 3 | 3 1 ' 1 0 0 0 0 ] + + Args: + dataframe_list (list[df]): list of dataframes to concatenate + new_index_name (str): name to be given to the new column containing the copy of the final index + new_concatenation_index_name (str): name of the new column containing the position from the concatenation_list. + Returns: + pd.Dataframe: the new dataframe + """ + dataframe_list = [ + concatenate_creating_new_concatenation_index_name( + dataframe_list=dataframe_list, + new_concatenation_index_name=new_concatenation_index_name, + ) + ] + + return concatenate_creating_new_index_name(dataframe_list=dataframe_list, new_index_name=new_index_name) diff --git a/tests/data.py b/tests/data.py index 981f4fb81..9182797b9 100644 --- a/tests/data.py +++ b/tests/data.py @@ -756,7 +756,7 @@ class FluxQubitSimulator: }, "bins": { "integration": {"path0": [-0.08875841551660968], "path1": [-0.4252879595139228]}, - "threshold": [0.48046875], + "binary_classification": [1], "avg_cnt": [1024], }, } @@ -773,7 +773,7 @@ class FluxQubitSimulator: }, "bins": { "integration": {"path0": [-0.14089025097703958], "path1": [-0.3594594414081583]}, - "threshold": [0.4599609375], + "binary_classification": [0], "avg_cnt": [1024], }, } @@ -807,7 +807,7 @@ class FluxQubitSimulator: }, "bins": { "integration": {"path0": [-0.08875841551660968], "path1": [-0.4252879595139228]}, - "threshold": [0.48046875], + "binary_classification": [1.0], "avg_cnt": [1024], }, } @@ -824,7 +824,7 @@ class FluxQubitSimulator: }, "bins": { "integration": {"path0": [-0.14089025097703958], "path1": [-0.3594594414081583]}, - "threshold": [0.4599609375], + "binary_classification": [0], "avg_cnt": [1024], }, } @@ -841,8 +841,9 @@ class FluxQubitSimulator: { RUNCARD.ALIAS: "rs_1", LOOP.PARAMETER: NODE.FREQUENCY, - LOOP.VALUES: np.arange(start=7342000000, stop=7352000000, step=100000), + LOOP.VALUES: (np.arange(start=7342000000, stop=7352000000, step=100000)).tolist(), LOOP.LOOP: None, + LOOP.CHANNEL_ID: None, } ], EXPERIMENT.RESULTS: [], diff --git a/tests/unit/execution/test_execution_manager.py b/tests/unit/execution/test_execution_manager.py index 7ec6a11a3..0f1178924 100644 --- a/tests/unit/execution/test_execution_manager.py +++ b/tests/unit/execution/test_execution_manager.py @@ -294,7 +294,7 @@ def test_execute_method_with_keyboard_interrupt( }, "bins": { "integration": {"path0": [1, 2, 3], "path1": [4, 5, 6]}, - "threshold": [1, 1, 1], + "binary_classification": [1, 1, 1], "avg_cnt": [1000, 1000, 1000], }, }, diff --git a/tests/unit/experiment/test_qblox_result.py b/tests/unit/experiment/test_qblox_result.py index 2605cb5d9..0b439d7f0 100644 --- a/tests/unit/experiment/test_qblox_result.py +++ b/tests/unit/experiment/test_qblox_result.py @@ -1,4 +1,4 @@ -""" Test Results """ +""" Test Result""" import numpy as np import pandas as pd @@ -66,7 +66,7 @@ def fixture_dummy_qrm(qrm_sequence: Sequence) -> DummyPulsar: @pytest.fixture(name="qblox_result_noscope") -def fixture_qblox_result_noscope(dummy_qrm: DummyPulsar): +def fixture_qblox_result_noscope(dummy_qrm: DummyPulsar) -> QbloxResult: """fixture_qblox_result_noscope Args: @@ -78,9 +78,25 @@ def fixture_qblox_result_noscope(dummy_qrm: DummyPulsar): acquisition = dummy_qrm.get_acquisitions(0)["single"]["acquisition"] return QbloxResult(integration_lengths=[1000], qblox_raw_results=[acquisition]) + # TODO: Modify dummy_qrm to to get better examples of acquisitions (the one below is the top one modified) + # acquisition = { + # "scope": { + # "path0": {"data": [], "out-of-range": False, "avg_cnt": 0}, + # "path1": {"data": [], "out-of-range": False, "avg_cnt": 0}, + # }, + # "bins": { + # "integration": {"path0": [1000.0, 19, 20], "path1": [-1.3504188124071826e-15, 0.000000, 1.0]}, + # "binary_classification": [1.0, 1.0, 1.0], + # "avg_cnt": [1, 1, 0], + # }, + # } + # return QbloxResult( + # integration_lengths=[1000, 1000, 1000], qblox_raw_results=[acquisition, acquisition, acquisition] + # ) + @pytest.fixture(name="qblox_result_scope") -def fixture_qblox_result_scope(dummy_qrm: DummyPulsar): +def fixture_qblox_result_scope(dummy_qrm: DummyPulsar) -> QbloxResult: """fixture_qblox_result_scope Args: @@ -92,10 +108,11 @@ def fixture_qblox_result_scope(dummy_qrm: DummyPulsar): dummy_qrm.store_scope_acquisition(0, "single") acquisition = dummy_qrm.get_acquisitions(0)["single"]["acquisition"] return QbloxResult(integration_lengths=[1000], qblox_raw_results=[acquisition]) + # return QbloxResult(integration_lengths=[1000, 1000], qblox_raw_results=[acquisition, acquisition]) @pytest.fixture(name="qblox_asymmetric_bins_result") -def fixture_qblox_asymmetric_bins_result(): +def fixture_qblox_asymmetric_bins_result() -> QbloxResult: qblox_raw_results = [ { "scope": { @@ -104,7 +121,7 @@ def fixture_qblox_asymmetric_bins_result(): }, "bins": { "integration": {"path0": [0.0, 0.0], "path1": [0.0, 0.0]}, - "threshold": [0.0, 1.0], + "binary_classification": [0.0, 1.0], "avg_cnt": [1, 1], }, }, @@ -115,7 +132,7 @@ def fixture_qblox_asymmetric_bins_result(): }, "bins": { "integration": {"path0": [0.0, 0.0, 0.0], "path1": [0.0, 0.0, 0.0]}, - "threshold": [1.0, 0.0, 1.0], + "binary_classification": [1.0, 0.1, 1.0], "avg_cnt": [1, 1, 1], }, }, @@ -124,7 +141,7 @@ def fixture_qblox_asymmetric_bins_result(): class TestsQbloxResult: - """Test `QbloxResults` functionalities.""" + """Test `QbloxResult` functionalities.""" def test_qblox_result_instantiation(self, qblox_result_scope: QbloxResult): """Tests the instantiation of a QbloxResult object. @@ -169,17 +186,19 @@ def test_qblox_result_acquisitions(self, qblox_result_noscope: QbloxResult): """ acquisitions = qblox_result_noscope.acquisitions() assert acquisitions.keys().tolist() == [ - RESULTSDATAFRAME.ACQUISITION_INDEX, - RESULTSDATAFRAME.BINS_INDEX, + RESULTSDATAFRAME.SEQUENCER, + RESULTSDATAFRAME.BIN, "i", "q", "amplitude", "phase", + "binary_classification", ] assert np.isclose(acquisitions["i"].iloc[0], 1.0, 1e-10) assert np.isclose(acquisitions["q"].iloc[0], 0.0, 1e-10) assert np.isclose(acquisitions["amplitude"].iloc[0], 0.0, 1e-10) assert np.isclose(acquisitions["phase"].iloc[0], 0.0, 1e-10) + assert np.isclose(acquisitions["binary_classification"].iloc[0], 1.0, 0.1) def test_qblox_result_acquisitions_scope(self, qblox_result_scope: QbloxResult): """Tests that the default acquisitions_scope method of QbloxResult returns the scope as it is. diff --git a/tests/unit/experiment/test_results.py b/tests/unit/experiment/test_results.py index 9a16b3fe9..3cc14cd33 100644 --- a/tests/unit/experiment/test_results.py +++ b/tests/unit/experiment/test_results.py @@ -10,17 +10,18 @@ class TestsResults: """Test `Results` functionalities.""" - @pytest.mark.parametrize("results_dict", [results_one_loops, results_two_loops]) + @pytest.mark.parametrize("results_dict", [results_one_loops, results_two_loops, results_one_loops_empty]) def test_from_dict_method(self, results_dict: dict): """Tests from_dict() serialization of results gives out a valid Results instance.""" results = Results.from_dict(results_dict) assert isinstance(results, Results) - @pytest.mark.parametrize("results_dict", [results_one_loops, results_two_loops]) + @pytest.mark.parametrize("results_dict", [results_one_loops, results_two_loops, results_one_loops_empty]) def test_to_dict_method(self, results_dict: dict): """Tests to_dict() serialization of results gives the intended dictionary.""" results = Results.from_dict(results_dict) results_final = results.to_dict() + assert isinstance(results_final, dict) assert results_final == results_dict @pytest.mark.parametrize("results_dict", [results_one_loops, results_two_loops, results_one_loops_empty]) diff --git a/tests/unit/instruments/qblox/test_qblox_qrm.py b/tests/unit/instruments/qblox/test_qblox_qrm.py index 3180aa87e..a7c9a4d72 100644 --- a/tests/unit/instruments/qblox/test_qblox_qrm.py +++ b/tests/unit/instruments/qblox/test_qblox_qrm.py @@ -437,7 +437,7 @@ def test_get_acquisitions_method(self, qrm: QbloxQRM): }, "bins": { "integration": {"path0": [1, 1, 1, 1], "path1": [0, 0, 0, 0]}, - "threshold": [0.5, 0.5, 0.5, 0.5], + "binary_classification": [1.0, 1.0, 1.0, 1.0], "avg_cnt": [1000, 1000, 1000, 1000], }, }, diff --git a/tests/utils.py b/tests/utils.py index c75a5e4bb..99bab74a7 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -26,7 +26,7 @@ def mock_instruments(mock_rs: MagicMock, mock_pulsar: MagicMock, mock_keithley: }, "bins": { "integration": {"path0": [-0.08875841551660968], "path1": [-0.4252879595139228]}, - "threshold": [0.48046875], + "binary_classification": [1], "avg_cnt": [1024], }, },