from typing import Optional, List, Tuple, Union, Dict, Set
from numbers import Real
import itertools
from qupulse.expressions import Expression
from qupulse.utils.types import MeasurementWindow
from qupulse.pulses.parameters import Parameter
MeasurementDeclaration = Tuple[str, Union[Expression, str, Real], Union[Expression, str, Real]]
[docs]class MeasurementDefiner:
def __init__(self, measurements: Optional[List[MeasurementDeclaration]]):
if measurements is None:
self._measurement_windows = []
else:
self._measurement_windows = [(name,
begin if isinstance(begin, Expression) else Expression(begin),
length if isinstance(length, Expression) else Expression(length))
for name, begin, length in measurements]
for _, _, length in self._measurement_windows:
if (length < 0) is True:
raise ValueError('Measurement window length may not be negative')
[docs] def get_measurement_windows(self,
parameters: Dict[str, Real],
measurement_mapping: Dict[str, Optional[str]]) -> List[MeasurementWindow]:
"""Calculate measurement windows with the given parameter set and rename them woth the measurement mapping"""
def get_val(v):
return v.evaluate_numeric(**parameters)
resulting_windows = [(measurement_mapping[name], get_val(begin), get_val(length))
for name, begin, length in self._measurement_windows
if measurement_mapping[name] is not None]
for _, begin, length in resulting_windows:
if begin < 0 or length < 0:
raise ValueError('Measurement window with negative begin or length: {}, {}'.format(begin, length))
return resulting_windows
[docs] def insert_measurement_instruction(self,
instruction_block,
parameters: Dict[str, Parameter],
measurement_mapping: Dict[str, Optional[str]]):
parameters = {k: parameters[k].get_value()
for k in self.measurement_parameters}
measurements = self.get_measurement_windows(parameters, measurement_mapping)
if measurements:
instruction_block.add_instruction_meas(measurements)
@property
def measurement_parameters(self) -> Set[str]:
return set(var
for _, begin, length in self._measurement_windows
for var in itertools.chain(begin.variables, length.variables))
@property
def measurement_declarations(self) -> List[MeasurementDeclaration]:
return [(name,
begin.original_expression,
length.original_expression)
for name, begin, length in self._measurement_windows]
@property
def measurement_names(self) -> Set[str]:
return {name for name, *_ in self._measurement_windows}