Loading CHANGELOG.rst +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ Merged branches and closed issues * Qblox Backend - Support for append bin mode (#184, !180). * Updated existing schedules to make use of the acquisition index (#180, !180). * Added a function to extract acquisition metadata from a schedule (#179, !180). * Qblox ICCs - Compensated integration time for Qblox QRM IC component (!199). 0.4.0 InstrumentCoordinator and improvements to backends (2021-08-06) --------------------------------------------------------------------- Loading quantify_scheduler/instrument_coordinator/components/qblox.py +49 −6 Original line number Diff line number Diff line Loading @@ -358,6 +358,9 @@ class PulsarQRMComponent(PulsarInstrumentCoordinatorComponent): f"sequencer{seq_idx}_integration_length_acq", settings.integration_length_acq, ) self._acquisition_manager.integration_length_acq = ( settings.integration_length_acq ) self.instrument.set(f"sequencer{seq_idx}_demod_en_acq", settings.nco_en) Loading Loading @@ -482,6 +485,7 @@ class _QRMAcquisitionManager: self.acquisition_metadata: AcquisitionMetadata = acquisition_metadata self.scope_mode_sequencer: Optional[str] = None self.integration_length_acq: Optional[int] = None self.seq_name_to_idx_map = { f"seq{idx}": idx for idx in range(number_of_sequencers) } Loading @@ -504,7 +508,7 @@ class _QRMAcquisitionManager: protocol_to_function_mapping = { "weighted_integrated_complex": self._get_integration_data, "ssb_integration_complex": self._get_integration_data, "ssb_integration_complex": self._get_integration_amplitude_data, "trace": self._get_scope_data, # NB thresholded protocol is still missing since there is nothing in # the acquisition library for it yet. Loading Loading @@ -540,8 +544,8 @@ class _QRMAcquisitionManager: formatted_acquisitions[ AcquisitionIndexing(acq_channel=acq_channel, acq_index=acq_idx) ] = ( np.array(i_vals[acq_idx::acq_stride]), np.array(q_vals[acq_idx::acq_stride]), i_vals[acq_idx::acq_stride], q_vals[acq_idx::acq_stride], ) return formatted_acquisitions Loading Loading @@ -632,7 +636,7 @@ class _QRMAcquisitionManager: def _get_integration_data( self, acquisitions: dict, acq_channel: int = 0 ) -> Tuple[float, float]: ) -> Tuple[np.ndarray, np.ndarray]: """ Retrieves the integrated acquisition data associated with an `acq_channel`. Loading @@ -640,6 +644,8 @@ class _QRMAcquisitionManager: ---------- acquisitions The acquisitions dict as returned by the sequencer. acq_channel The `acq_channel` from which to get the data. Returns ------- Loading @@ -652,12 +658,49 @@ class _QRMAcquisitionManager: bin_data = self._get_bin_data(acquisitions, acq_channel) i_data, q_data = ( bin_data["integration"]["path0"], bin_data["integration"]["path1"], np.array(bin_data["integration"]["path0"]), np.array(bin_data["integration"]["path1"]), ) return i_data, q_data def _get_integration_amplitude_data( self, acquisitions: dict, acq_channel: int = 0 ) -> Tuple[np.ndarray, np.ndarray]: """ Gets the integration data but normalized to the integration time (number of samples summed). The return value is thus the amplitude of the demodulated signal directly and has volt units (i.e. same units as a single sample of the integrated signal). Parameters ---------- acquisitions The acquisitions dict as returned by the sequencer. acq_channel The `acq_channel` from which to get the data. Returns ------- data_i Array containing I-quadrature data. data_q Array containing I-quadrature data. """ if self.integration_length_acq is None: raise RuntimeError( "Retrieving data failed. Expected the integration length to be defined," " but it is `None`." ) compensated_data_i, compensated_data_q = self._get_integration_data( acquisitions=acquisitions, acq_channel=acq_channel ) compensated_data_i, compensated_data_q = ( compensated_data_i / self.integration_length_acq, compensated_data_q / self.integration_length_acq, ) return compensated_data_i, compensated_data_q def _get_threshold_data( self, acquisitions: dict, acq_channel: int = 0, acq_index: int = 0 ) -> float: Loading tests/scheduler/instrument_coordinator/components/test_qblox.py +4 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ import json import tempfile from pathlib import Path import numpy as np import pytest from pulsar_qcm import pulsar_qcm from pulsar_qrm import pulsar_qrm Loading Loading @@ -524,7 +526,8 @@ def test_get_integration_data(make_qrm, mock_acquisition_data): qrm: qblox.PulsarQRMComponent = make_qrm("qrm0", "1234") acq_manager = qblox._QRMAcquisitionManager(qrm, qrm._number_of_sequencers, {}, None) data = acq_manager._get_integration_data(mock_acquisition_data, acq_channel=0) assert data == ([0.0] * 10, [0.0] * 10) np.testing.assert_array_equal(data[0], np.array([0.0] * 10)) np.testing.assert_array_equal(data[1], np.array([0.0] * 10)) def test_get_scope_channel_and_index(make_qrm): Loading Loading
CHANGELOG.rst +1 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,7 @@ Merged branches and closed issues * Qblox Backend - Support for append bin mode (#184, !180). * Updated existing schedules to make use of the acquisition index (#180, !180). * Added a function to extract acquisition metadata from a schedule (#179, !180). * Qblox ICCs - Compensated integration time for Qblox QRM IC component (!199). 0.4.0 InstrumentCoordinator and improvements to backends (2021-08-06) --------------------------------------------------------------------- Loading
quantify_scheduler/instrument_coordinator/components/qblox.py +49 −6 Original line number Diff line number Diff line Loading @@ -358,6 +358,9 @@ class PulsarQRMComponent(PulsarInstrumentCoordinatorComponent): f"sequencer{seq_idx}_integration_length_acq", settings.integration_length_acq, ) self._acquisition_manager.integration_length_acq = ( settings.integration_length_acq ) self.instrument.set(f"sequencer{seq_idx}_demod_en_acq", settings.nco_en) Loading Loading @@ -482,6 +485,7 @@ class _QRMAcquisitionManager: self.acquisition_metadata: AcquisitionMetadata = acquisition_metadata self.scope_mode_sequencer: Optional[str] = None self.integration_length_acq: Optional[int] = None self.seq_name_to_idx_map = { f"seq{idx}": idx for idx in range(number_of_sequencers) } Loading @@ -504,7 +508,7 @@ class _QRMAcquisitionManager: protocol_to_function_mapping = { "weighted_integrated_complex": self._get_integration_data, "ssb_integration_complex": self._get_integration_data, "ssb_integration_complex": self._get_integration_amplitude_data, "trace": self._get_scope_data, # NB thresholded protocol is still missing since there is nothing in # the acquisition library for it yet. Loading Loading @@ -540,8 +544,8 @@ class _QRMAcquisitionManager: formatted_acquisitions[ AcquisitionIndexing(acq_channel=acq_channel, acq_index=acq_idx) ] = ( np.array(i_vals[acq_idx::acq_stride]), np.array(q_vals[acq_idx::acq_stride]), i_vals[acq_idx::acq_stride], q_vals[acq_idx::acq_stride], ) return formatted_acquisitions Loading Loading @@ -632,7 +636,7 @@ class _QRMAcquisitionManager: def _get_integration_data( self, acquisitions: dict, acq_channel: int = 0 ) -> Tuple[float, float]: ) -> Tuple[np.ndarray, np.ndarray]: """ Retrieves the integrated acquisition data associated with an `acq_channel`. Loading @@ -640,6 +644,8 @@ class _QRMAcquisitionManager: ---------- acquisitions The acquisitions dict as returned by the sequencer. acq_channel The `acq_channel` from which to get the data. Returns ------- Loading @@ -652,12 +658,49 @@ class _QRMAcquisitionManager: bin_data = self._get_bin_data(acquisitions, acq_channel) i_data, q_data = ( bin_data["integration"]["path0"], bin_data["integration"]["path1"], np.array(bin_data["integration"]["path0"]), np.array(bin_data["integration"]["path1"]), ) return i_data, q_data def _get_integration_amplitude_data( self, acquisitions: dict, acq_channel: int = 0 ) -> Tuple[np.ndarray, np.ndarray]: """ Gets the integration data but normalized to the integration time (number of samples summed). The return value is thus the amplitude of the demodulated signal directly and has volt units (i.e. same units as a single sample of the integrated signal). Parameters ---------- acquisitions The acquisitions dict as returned by the sequencer. acq_channel The `acq_channel` from which to get the data. Returns ------- data_i Array containing I-quadrature data. data_q Array containing I-quadrature data. """ if self.integration_length_acq is None: raise RuntimeError( "Retrieving data failed. Expected the integration length to be defined," " but it is `None`." ) compensated_data_i, compensated_data_q = self._get_integration_data( acquisitions=acquisitions, acq_channel=acq_channel ) compensated_data_i, compensated_data_q = ( compensated_data_i / self.integration_length_acq, compensated_data_q / self.integration_length_acq, ) return compensated_data_i, compensated_data_q def _get_threshold_data( self, acquisitions: dict, acq_channel: int = 0, acq_index: int = 0 ) -> float: Loading
tests/scheduler/instrument_coordinator/components/test_qblox.py +4 −1 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ import json import tempfile from pathlib import Path import numpy as np import pytest from pulsar_qcm import pulsar_qcm from pulsar_qrm import pulsar_qrm Loading Loading @@ -524,7 +526,8 @@ def test_get_integration_data(make_qrm, mock_acquisition_data): qrm: qblox.PulsarQRMComponent = make_qrm("qrm0", "1234") acq_manager = qblox._QRMAcquisitionManager(qrm, qrm._number_of_sequencers, {}, None) data = acq_manager._get_integration_data(mock_acquisition_data, acq_channel=0) assert data == ([0.0] * 10, [0.0] * 10) np.testing.assert_array_equal(data[0], np.array([0.0] * 10)) np.testing.assert_array_equal(data[1], np.array([0.0] * 10)) def test_get_scope_channel_and_index(make_qrm): Loading