Skip to content

Commit

Permalink
#26 - mock device param dict now created in MockAbstractSpectrumDevic…
Browse files Browse the repository at this point in the history
…e with option to pass a value for it. This means values can be preconfigured by child classes if necessary.
  • Loading branch information
crnbaker committed Jan 8, 2024
1 parent 758d47e commit 303e416
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __init__(self, device_number: int = 0, ip_address: Optional[str] = None, **k
"""
print("AbstractSpectrumCard", flush=True)
super().__init__(**kwargs)
super().__init__() # required for proper MRO resolution
if ip_address is not None:
self._visa_string = _create_visa_string_from_ip(ip_address, device_number)
else:
Expand Down
22 changes: 7 additions & 15 deletions src/spectrumdevice/devices/mocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,17 @@
from time import perf_counter, sleep
from typing import Any, List, Optional, Sequence

from spectrum_gmbh.regs import (
SPC_FNCTYPE,
SPC_MIINST_CHPERMODULE,
SPC_MIINST_MODULES,
SPC_PCITYP,
)
from spectrumdevice.devices.digitiser import SpectrumDigitiserCard
from spectrumdevice.devices.digitiser import SpectrumDigitiserStarHub
from spectrumdevice.devices.mocks.mock_abstract_devices import MockAbstractSpectrumDigitiser
from spectrumdevice.devices.mocks.mock_abstract_devices import MockAbstractSpectrumDigitiser, MockAbstractSpectrumDevice
from spectrumdevice.devices.mocks.mock_waveform_source import TRANSFER_CHUNK_COUNTER
from spectrumdevice.devices.mocks.timestamps import MockTimestamper
from spectrumdevice.exceptions import (
SpectrumNoTransferBufferDefined,
SpectrumSettingsMismatchError,
)
from spectrumdevice.settings import TransferBuffer
from spectrumdevice.settings.card_dependent_properties import CardType, ModelNumber
from spectrumdevice.settings.card_dependent_properties import CardType
from spectrumdevice.settings.device_modes import AcquisitionMode

logger = logging.getLogger(__name__)
Expand All @@ -40,7 +34,7 @@ class MockSpectrumDigitiserCard(MockAbstractSpectrumDigitiser, SpectrumDigitiser
samples. It also uses a MockTimestamper to generated timestamps for mock waveforms.
"""

def __init__(self, num_modules: int = 2, num_channels_per_module: int = 4, **kwargs: Any):
def __init__(self, **kwargs: Any):
"""
Args:
device_number (int): The index of the mock device to create. Used to create a name for the device which is
Expand All @@ -57,12 +51,10 @@ def __init__(self, num_modules: int = 2, num_channels_per_module: int = 4, **kwa
super().__init__(card_type=CardType.SPCM_TYPE_AI, **kwargs)
print("EVERYTHING INITIALISED", flush=True)
self._visa_string = "Mock_" + self._visa_string
self._param_dict[SPC_MIINST_MODULES] = num_modules
self._param_dict[SPC_MIINST_CHPERMODULE] = num_channels_per_module
self._param_dict[TRANSFER_CHUNK_COUNTER] = 0
self._connect(self._visa_string)
self._acquisition_mode = self.acquisition_mode
self._previous_transfer_chunk_count = 0
self._param_dict[TRANSFER_CHUNK_COUNTER] = 0

def enable_timestamping(self) -> None:
self._timestamper: MockTimestamper = MockTimestamper(self, self._handle)
Expand Down Expand Up @@ -143,7 +135,7 @@ def wait_for_acquisition_to_complete(self) -> None:
logger.warning("No acquisition in progress. Wait for acquisition to complete has no effect")


class MockSpectrumDigitiserStarHub(MockAbstractSpectrumDigitiser, SpectrumDigitiserStarHub):
class MockSpectrumDigitiserStarHub(MockAbstractSpectrumDevice, SpectrumDigitiserStarHub):
"""A mock spectrum StarHub, for testing software written to use the `SpectrumStarHub` class.
Overrides methods of `SpectrumStarHub` and `AbstractSpectrumDigitiser` that communicate with hardware with mocked
Expand All @@ -153,13 +145,13 @@ class MockSpectrumDigitiserStarHub(MockAbstractSpectrumDigitiser, SpectrumDigiti
def __init__(self, **kwargs: Any):
"""
Args:
child_cards (Sequence[`MockSpectrumDigitiserCard`]): A list of `MockSpectrumCard` objects defining the
child_cards (Sequence[`MockSpectrumDigitiserCard`]): A list of `MockSpectrumDigitiserCard` objects defining the
properties of the child cards located within the mock hub.
master_card_index (int): The position within child_cards where the master card (the card which controls the
clock) is located.
"""
super().__init__(**kwargs)
# self._visa_string = "Mock_" + self._visa_string
self._visa_string = "Mock_" + self._visa_string
self._connect(self._visa_string)
self._acquisition_mode = self.acquisition_mode

Expand Down
79 changes: 52 additions & 27 deletions src/spectrumdevice/devices/mocks/mock_abstract_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
SPCM_X3_AVAILMODES,
SPCM_XMODE_DISABLE,
SPC_CARDMODE,
SPC_FNCTYPE, SPC_MEMSIZE,
SPC_FNCTYPE,
SPC_MEMSIZE,
SPC_MIINST_MAXADCVALUE,
SPC_PCIEXTFEATURES,
SPC_PCIFEATURES,
SPC_PCITYP, SPC_SEGMENTSIZE,
SPC_PCITYP,
SPC_SEGMENTSIZE,
SPC_TIMEOUT,
SPC_MIINST_MODULES,
SPC_MIINST_CHPERMODULE,
)
from spectrumdevice.devices.abstract_device import AbstractSpectrumDevice
from spectrumdevice.devices.digitiser.abstract_spectrum_digitiser import AbstractSpectrumDigitiser
Expand All @@ -33,30 +37,12 @@


class MockAbstractSpectrumDevice(AbstractSpectrumDevice, ABC):
"""Overrides methods of `AbstractSpectrumDevice` that communicate with hardware with mocked implementations, allowing
software to be tested without Spectrum hardware connected or drivers installed, e.g. during CI. Instances of this
class cannot be constructed directly - instantiate `MockAbstractSpectrumDigitiser` and `MockSpectrumStarHub` objects instead,
which inherit from this class."""

def __init__(self, model: ModelNumber, card_type: CardType, mode: AcquisitionMode, **kwargs: Any) -> None:
print("MockAbstractSpectrumDevice", flush=True)
self._param_dict: Dict[int, int] = {
SPC_PCIFEATURES: SPCM_FEAT_MULTI,
SPC_PCIEXTFEATURES: SPCM_FEAT_EXTFW_SEGSTAT,
SPCM_X0_AVAILMODES: SPCM_XMODE_DISABLE,
SPCM_X1_AVAILMODES: SPCM_XMODE_DISABLE,
SPCM_X2_AVAILMODES: SPCM_XMODE_DISABLE,
SPCM_X3_AVAILMODES: SPCM_XMODE_DISABLE,
SPC_TIMEOUT: 1000,
SPC_SEGMENTSIZE: 1000,
SPC_MEMSIZE: 1000,
SPC_PCITYP: model.value,
SPC_FNCTYPE: card_type.value,
SPC_CARDMODE: mode.value
}
super().__init__() # required for proper MRO resolution
self._buffer_lock = Lock()
self._enabled_channels = [0]
def __init__(self, param_dict: Optional[Dict[int, int]] = None, **kwargs: Any):
if param_dict is None:
self._param_dict: Dict[int, int] = {}
else:
self._param_dict = param_dict
super().__init__(**kwargs) # required for proper MRO resolution

def write_to_spectrum_device_register(
self, spectrum_register: int, value: int, length: SpectrumRegisterLength = SpectrumRegisterLength.THIRTY_TWO
Expand Down Expand Up @@ -110,7 +96,45 @@ def read_spectrum_device_register(
raise SpectrumDeviceNotConnected("Mock device has been disconnected.")


class MockAbstractSpectrumDigitiser(MockAbstractSpectrumDevice, AbstractSpectrumDigitiser, ABC):
class MockAbstractSpectrumCard(MockAbstractSpectrumDevice, ABC):
"""Overrides methods of `AbstractSpectrumDevice` that communicate with hardware with mocked implementations, allowing
software to be tested without Spectrum hardware connected or drivers installed, e.g. during CI. Instances of this
class cannot be constructed directly - instantiate `MockAbstractSpectrumDigitiser` and `MockSpectrumStarHub` objects instead,
which inherit from this class."""

def __init__(
self,
model: ModelNumber,
card_type: CardType,
mode: AcquisitionMode,
num_modules: int,
num_channels_per_module: int,
**kwargs: Any,
) -> None:
print("MockAbstractSpectrumCard", flush=True)
param_dict: dict[int, int] = {}
param_dict[SPC_PCIFEATURES] = SPCM_FEAT_MULTI
param_dict[SPC_PCIEXTFEATURES] = SPCM_FEAT_EXTFW_SEGSTAT
param_dict[SPCM_X0_AVAILMODES] = SPCM_XMODE_DISABLE
param_dict[SPCM_X1_AVAILMODES] = SPCM_XMODE_DISABLE
param_dict[SPCM_X2_AVAILMODES] = SPCM_XMODE_DISABLE
param_dict[SPCM_X3_AVAILMODES] = SPCM_XMODE_DISABLE
param_dict[SPC_TIMEOUT] = 1000
param_dict[SPC_SEGMENTSIZE] = 1000
param_dict[SPC_MEMSIZE] = 1000
param_dict[SPC_PCITYP] = model.value
param_dict[SPC_FNCTYPE] = card_type.value
param_dict[SPC_CARDMODE] = mode.value
param_dict[SPC_MIINST_MODULES] = num_modules
param_dict[SPC_MIINST_CHPERMODULE] = num_channels_per_module
self._buffer_lock = Lock()
self._enabled_channels = [0]
super().__init__(
param_dict=param_dict, **kwargs
) # then call the rest of the inits after the params have been set


class MockAbstractSpectrumDigitiser(MockAbstractSpectrumCard, AbstractSpectrumDigitiser, ABC):
"""Overrides methods of `AbstractSpectrumDigitiser` that communicate with hardware with mocked implementations, allowing
software to be tested without Spectrum hardware connected or drivers installed, e.g. during CI. Instances of this
class cannot be constructed directly - instantiate `MockAbstractSpectrumDigitiser` and `MockSpectrumStarHub` objects instead,
Expand Down Expand Up @@ -142,6 +166,7 @@ def start(self) -> None:
notify_size = self.transfer_buffers[0].notify_size_in_pages # this will be 0 in STD_SINGLE_MODE
waveform_source = mock_waveform_source_factory(self.acquisition_mode, self._param_dict, notify_size)
amplitude = self.read_spectrum_device_register(SPC_MIINST_MAXADCVALUE)
print(f"STARTING WAVEFORM SOURCE WITH AMPLITUDE {amplitude}")
self._acquisition_stop_event.clear()
self._acquisition_thread = Thread(
target=waveform_source,
Expand Down

0 comments on commit 303e416

Please # to comment.