"""
Dummies
=======
This module gathers differnt dummy components that mimic hardware but do nothing. They are mainly used for debugging
atomiq
"""
from __future__ import annotations
from atomiq.components.primitives import Component, Parametrizable, Measurable, Switchable
from atomiq.components.electronics.adc import ADC
from atomiq.components.electronics.voltagesource import DAC
from atomiq.components.electronics.rfsource import RFSource
from artiq.experiment import kernel, portable
from artiq.language.core import now_mu
from artiq.language.types import TFloat, TArray, TInt32, TStr, TBool
[docs]
class DummyADC(ADC):
kernel_invariants = {"return_value"}
def __init__(self, return_value: TFloat, *args, **kwargs):
ADC.__init__(self, *args, **kwargs)
self.return_value = return_value
@kernel
def _measure(self, target_arr: TArray(TFloat)) -> TArray(TFloat):
for i in range(self.num_chan):
target_arr[i] = self.return_value
return target_arr
[docs]
class DummyRFSource(RFSource):
"""A dummy RFSource used for debugging
"""
@kernel
def _set_frequency(self, frequency):
self.frequency = frequency
self.experiment.log.info(self.identifier + ": Set frequency to {0:.0f} MHz", [frequency/1e6])
@kernel
def _set_amplitude(self, amplitude):
self.amplitude = amplitude
self.experiment.log.info(self.identifier + ": Set amplitude to {0:.3f}", [amplitude])
@kernel
def _set_phase(self, phase):
self.phase = phase
self.experiment.log.info(self.identifier + ": Set phase to {0}/pi", [phase/3.14])
[docs]
class DummyDAC(DAC):
def __init__(self, *args, **kwargs):
DAC.__init__(self, *args, **kwargs)
self.values = [0.0]*self.num_chan
[docs]
@kernel
def set_channel_voltage(self, channel: TInt32, voltage: TFloat):
self.values[channel] = voltage
[docs]
@kernel
def update(self):
self.experiment.log.info("time: {0}", [self.experiment.core.mu_to_seconds(now_mu())])
self.experiment.log.info(self.identifier + ": Setting output voltages {0}", [self.values])
[docs]
class DummyActor(Component, Parametrizable):
def __init__(self, *args, **kwargs):
Component.__init__(self, *args, **kwargs)
Parametrizable.__init__(self, ["amplitude"])
self.amplitude = 0.0
[docs]
@kernel
def set_amplitude(self, amp: TFloat):
self.amplitude = amp
self.experiment.log.info("DummyActor("+self.identifier+"): setting amplitude {0}", [amp])
[docs]
class DummyMonitor(Component, Measurable):
def __init__(self, dummy_actor: DummyActor, *args, **kwargs):
Component.__init__(self, *args, **kwargs)
Measurable.__init__(self, ["voltage"])
self.dummy_actor = dummy_actor
[docs]
@kernel
def get_voltage(self) -> TFloat:
return 0.2*self.dummy_actor.amplitude
[docs]
class DummySwitch(Component, Switchable):
def __init__(self, channels, *args, **kwargs):
Component.__init__(self, *args, **kwargs)
Switchable.__init__(self, channels)
self.states = [0 for _ in range(len(channels))]
@portable
def _get_channel_index(self, channel: TStr) -> TInt32:
for i in range(len(self.channels)):
if self.channels[i] == channel:
return i
return -1
[docs]
@kernel
def on(self, channel: TStr = "") -> None:
if channel == "":
channel = self.channels[0]
self.states[self._get_channel_index(channel)] = 1
self.experiment.log.info("DummySwitch("+self.identifier+"): switching on channel {}", [channel,])
[docs]
@kernel
def off(self, channel: TStr = "") -> None:
if channel == "":
channel = self.channels[0]
self.states[self._get_channel_index(channel)] = 0
self.experiment.log.info("DummySwitch("+self.identifier+"): switching off channel {}", [channel,])
[docs]
@kernel
def is_on(self, channel: TStr = "") -> TBool:
if channel == "":
channel = self.channels[0]
state = self.states[self._get_channel_index(channel)]
if state == 1:
self.experiment.log.info(
"DummySwitch("+self.identifier+"): pretending {} is on",
[channel,],
)
return True
else:
self.experiment.log.info(
"DummySwitch("+self.identifier+"): pretending {} is off",
[channel,],
)
return False