Skip to content
3 changes: 3 additions & 0 deletions ReleaseNotes.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## pending/current ##

- Hardware:
- Add a `measure_program` method to the DAC interface. This method is used by the QCoDeS integration.

- Pulse Templates:
- `MappingPulseTemplate`:
- `allow_partial_parameter_mapping` is now True as a default. The default can be changed with the class variable `MappingPulseTemplate.ALLOW_PARTIAL_PARAMETER_MAPPING`.
Expand Down
31 changes: 30 additions & 1 deletion qupulse/hardware/dacs/alazar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, Any, Optional, Tuple
from typing import Dict, Any, Optional, Tuple, List, Iterable
from collections import defaultdict

import numpy as np
Expand Down Expand Up @@ -146,3 +146,32 @@ def register_mask_for_channel(self, mask_id: str, hw_channel: int, mask_type='au
raise NotImplementedError('Currently only can do cross buffer mask')
self._mask_prototypes[mask_id] = (hw_channel, mask_type)

def measure_program(self, channels: Iterable[str]) -> Dict[str, np.ndarray]:
"""
Get all measurements at once and write them in a dictionary.
"""

scanline_data = self.__card.extractNextScanline()

scanline_definition = scanline_data.definition
operation_definitions = {operation.identifier: operation
for operation in scanline_definition.operations}
mask_definitions = {mask.identifier: mask
for mask in scanline_definition.masks}

def get_input_range(operation_id: str):
# currently does not work for ComputeMomentDefinition :(
mask_id = operation_definitions[operation_id].maskID

hw_channel = int(mask_definitions[mask_id].channel)

# This fails if new changes have been applied to the card in the meantime
# It is better than self.config.inputConfiguration but still
return self.__card.scanConfiguration.inputConfiguration[hw_channel].inputRange

data = {}
for op_name in channels:
input_range = get_input_range(op_name)
data[op_name] = scanline_data.operationResults[op_name].getAsVoltage(input_range)

return data
10 changes: 6 additions & 4 deletions qupulse/hardware/dacs/dac_base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from abc import ABCMeta, abstractmethod
from typing import Dict, Tuple

import numpy
from typing import Dict, Tuple, Iterable

__all__ = ['DAC']

Expand All @@ -17,7 +15,7 @@ def register_measurement_windows(self, program_name: str, windows: Dict[str, Tup
@abstractmethod
def register_operations(self, program_name: str, operations) -> None:
""""""

@abstractmethod
def arm_program(self, program_name: str) -> None:
""""""
Expand All @@ -32,3 +30,7 @@ def clear(self) -> None:

Caution: This affects all programs and waveforms on the AWG, not only those uploaded using qupulse!
"""

@abstractmethod
def measure_program(self, channels: Iterable[str]) -> Dict[str, 'numpy.ndarray']:
"""Get the last measurement's results of the specified operations/channels"""
6 changes: 6 additions & 0 deletions tests/hardware/dummy_devices.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from typing import Tuple, Set, Dict
from collections import deque


from qupulse.hardware.awgs.base import AWG, ProgramOverwriteException
from qupulse.hardware.dacs import DAC
Expand All @@ -7,6 +9,7 @@ class DummyDAC(DAC):
def __init__(self):
self._measurement_windows = dict()
self._operations = dict()
self.measured_data = deque([])

self._armed_program = None

Expand Down Expand Up @@ -35,6 +38,9 @@ def clear(self) -> None:
self._operations = dict()
self._armed_program = None

def measure_program(self, channels):
return self.measured_data.pop()


class DummyAWG(AWG):
"""Dummy AWG for debugging purposes."""
Expand Down