diff --git a/src/spectrumdevice/devices/abstract_device/abstract_spectrum_card.py b/src/spectrumdevice/devices/abstract_device/abstract_spectrum_card.py index 5076fce..80bac9e 100644 --- a/src/spectrumdevice/devices/abstract_device/abstract_spectrum_card.py +++ b/src/spectrumdevice/devices/abstract_device/abstract_spectrum_card.py @@ -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: diff --git a/src/spectrumdevice/devices/mocks/__init__.py b/src/spectrumdevice/devices/mocks/__init__.py index a4c8766..b9e7355 100644 --- a/src/spectrumdevice/devices/mocks/__init__.py +++ b/src/spectrumdevice/devices/mocks/__init__.py @@ -8,15 +8,9 @@ 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 ( @@ -24,7 +18,7 @@ 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__) @@ -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 @@ -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) @@ -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 @@ -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 diff --git a/src/spectrumdevice/devices/mocks/mock_abstract_devices.py b/src/spectrumdevice/devices/mocks/mock_abstract_devices.py index 4a90991..863f9f3 100644 --- a/src/spectrumdevice/devices/mocks/mock_abstract_devices.py +++ b/src/spectrumdevice/devices/mocks/mock_abstract_devices.py @@ -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 @@ -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 @@ -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, @@ -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,