"""
Dummies
=======
This module gathers different 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
import numpy as np
[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
[docs]
@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"""
[docs]
@kernel
def _set_frequency(self, frequency):
self.frequency = frequency
self.experiment.log.info(self.identifier + ": Set frequency to {0:.0f} MHz", [frequency / 1e6])
[docs]
@kernel
def _set_amplitude(self, amplitude):
self.amplitude = amplitude
self.experiment.log.info(self.identifier + ": Set amplitude to {0:.3f}", [amplitude])
[docs]
@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))]
[docs]
@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 = ""):
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 = ""):
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
[docs]
class DummyCore:
"""A ARTIQ sim dummy core device that works with Atomiq."""
def __init__(self, _dmgr) -> None:
pass
[docs]
def run(self, k_function, k_args, k_kwargs) -> int:
return 0
[docs]
def get_rtio_counter_mu(self) -> int:
return 0
[docs]
def reset(self) -> None:
pass
[docs]
def break_realtime(self) -> None:
pass
[docs]
def seconds_to_mu(self, seconds) -> np.int64:
return np.int64(seconds)
[docs]
def mu_to_seconds(self, mu) -> float:
return float(mu)