Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ToF routine for qblox #728

Merged
merged 5 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions src/qibolab/instruments/qblox/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,17 @@ class DemodulatedAcquisition:
It is advisable to have a power level at least higher than 5mV.
"""

scope: dict
"""Data returned by scope qblox acquisition."""
bins: dict
"""Binned acquisition data returned by qblox."""
duration: int
"""Duration of the readout pulse."""

@property
def raw(self):
return self.scope["acquisition"]["scope"]

@property
def integration(self):
return self.bins["integration"]
Expand All @@ -115,16 +121,14 @@ def shots_q(self):
return np.array(self.integration["path1"]) / self.duration

@property
def averaged_i(self):
"""I-component after demodulating and integrating every shot waveform
and then averaging over shots."""
return np.mean(self.shots_i)
def raw_i(self):
"""Average of the raw i waveforms for every readout pulse."""
return np.array(self.raw["path0"]["data"][0 : self.duration])

@property
def averaged_q(self):
"""Q-component after demodulating and integrating every shot waveform
and then averaging over shots."""
return np.mean(self.shots_q)
def raw_q(self):
"""Average of the raw q waveforms for every readout pulse."""
return np.array(self.raw["path1"]["data"][0 : self.duration])

@property
def classified(self):
Expand Down
19 changes: 9 additions & 10 deletions src/qibolab/instruments/qblox/cluster_qrm_rf.py
Original file line number Diff line number Diff line change
Expand Up @@ -977,14 +977,14 @@ def acquire(self):
for port in self._output_ports_keys:
for sequencer in self._sequencers[port]:
# Store scope acquisition data on 'scope_acquisition' acquisition of the default sequencer
# TODO: Maybe this store_scope can be done only if needed to optimize the process!
if sequencer.number == self.DEFAULT_SEQUENCERS[port]:
self.device.store_scope_acquisition(
sequencer.number, "scope_acquisition"
)
scope = self.device.get_acquisitions(sequencer.number)[
"scope_acquisition"
]

if not hardware_demod_enabled: # Software Demodulation
if len(sequencer.pulses.ro_pulses) == 1:
pulse = sequencer.pulses.ro_pulses[0]
Expand All @@ -1003,19 +1003,18 @@ def acquire(self):
bins = results[pulse.serial]["acquisition"]["bins"]
acquisitions[pulse.qubit] = acquisitions[
pulse.serial
] = DemodulatedAcquisition(bins, duration)

] = DemodulatedAcquisition(scope, bins, duration)
# Provide Scope Data for verification (assuming memory reseet is being done)
if len(sequencer.pulses.ro_pulses) == 1:
pulse = sequencer.pulses.ro_pulses[0]
frequency = self.get_if(pulse)
acquisitions[pulse.serial].averaged = AveragedAcquisition(
scope, duration, frequency
)
# if len(sequencer.pulses.ro_pulses) == 1:
# pulse = sequencer.pulses.ro_pulses[0]
# frequency = self.get_if(pulse)
# acquisitions[pulse.serial].averaged = AveragedAcquisition(
# scope, duration, frequency
# )
PiergiorgioButtarini marked this conversation as resolved.
Show resolved Hide resolved

# grab only the data required by the platform
# TODO: to be updated once the functionality of ExecutionResults is extended
return {key: acquisition.data for key, acquisition in acquisitions.items()}
return {key: acquisition for key, acquisition in acquisitions.items()}
PiergiorgioButtarini marked this conversation as resolved.
Show resolved Hide resolved

def disconnect(self):
"""Stops all sequencers, disconnect all the outputs from the AWG paths
Expand Down
17 changes: 8 additions & 9 deletions src/qibolab/instruments/qblox/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,25 +189,24 @@ def _execute_pulse_sequence(
and not module_pulses[name].ro_pulses.is_empty
):
results = module.acquire()
existing_keys = set(acquisition_results.keys()) & set(results.keys())
for key, value in results.items():
if key in existing_keys:
acquisition_results[key].update(value)
else:
acquisition_results[key] = value

acquisition_results[key] = value
# TODO: move to QRM_RF.acquire()
shape = tuple(len(sweeper.values) for sweeper in reversed(sweepers))
shots_shape = (nshots,) + shape
for ro_pulse in sequence.ro_pulses:
if options.acquisition_type is AcquisitionType.DISCRIMINATION:
_res = acquisition_results[ro_pulse.serial][2]
_res = acquisition_results[ro_pulse.serial].classified
_res = np.reshape(_res, shots_shape)
if options.averaging_mode is not AveragingMode.SINGLESHOT:
_res = np.mean(_res, axis=0)
elif options.acquisition_type is AcquisitionType.RAW:
i_raw = acquisition_results[ro_pulse.serial].raw_i
q_raw = acquisition_results[ro_pulse.serial].raw_q
_res = i_raw + 1j * q_raw
else:
PiergiorgioButtarini marked this conversation as resolved.
Show resolved Hide resolved
ires = acquisition_results[ro_pulse.serial][0]
qres = acquisition_results[ro_pulse.serial][1]
ires = acquisition_results[ro_pulse.serial].shots_i
qres = acquisition_results[ro_pulse.serial].shots_q
_res = ires + 1j * qres
if options.averaging_mode is AveragingMode.SINGLESHOT:
_res = np.reshape(_res, shots_shape)
Expand Down