Skip to content

Commit

Permalink
Merge pull request #36 from KCL-BMEIS/34_new_acq_settings
Browse files Browse the repository at this point in the history
#34 - implementing new channel settings
  • Loading branch information
crnbaker authored Oct 13, 2023
2 parents 61b2089 + 8142231 commit dedc279
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 6 deletions.
2 changes: 2 additions & 0 deletions src/example_scripts/continuous_averaging_fifo_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ExternalTriggerMode,
TriggerSettings,
AcquisitionSettings,
InputImpedance,
)


Expand Down Expand Up @@ -56,6 +57,7 @@ def continuous_averaging_multi_fifo_example(
enabled_channels=[0],
vertical_ranges_in_mv=[200],
vertical_offsets_in_percent=[0],
input_impedances=[InputImpedance.ONE_MEGA_OHM],
timestamping_enabled=True,
number_of_averages=num_averages,
)
Expand Down
2 changes: 2 additions & 0 deletions src/example_scripts/continuous_multi_fifo_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ExternalTriggerMode,
TriggerSettings,
AcquisitionSettings,
InputImpedance,
)


Expand Down Expand Up @@ -56,6 +57,7 @@ def continuous_multi_fifo_example(
enabled_channels=[0],
vertical_ranges_in_mv=[200],
vertical_offsets_in_percent=[0],
input_impedances=[InputImpedance.ONE_MEGA_OHM],
timestamping_enabled=True,
batch_size=batch_size,
)
Expand Down
2 changes: 2 additions & 0 deletions src/example_scripts/finite_multi_fifo_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
ExternalTriggerMode,
TriggerSettings,
AcquisitionSettings,
InputImpedance,
)


Expand Down Expand Up @@ -54,6 +55,7 @@ def finite_multi_fifo_example(
enabled_channels=[0],
vertical_ranges_in_mv=[200],
vertical_offsets_in_percent=[0],
input_impedances=[InputImpedance.ONE_MEGA_OHM],
timestamping_enabled=True,
batch_size=batch_size,
)
Expand Down
2 changes: 2 additions & 0 deletions src/example_scripts/standard_single_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
ExternalTriggerMode,
TriggerSettings,
AcquisitionSettings,
InputImpedance,
)


Expand Down Expand Up @@ -54,6 +55,7 @@ def standard_single_mode_example(
enabled_channels=[0],
vertical_ranges_in_mv=[200],
vertical_offsets_in_percent=[0],
input_impedances=[InputImpedance.ONE_MEGA_OHM],
timestamping_enabled=True,
)

Expand Down
6 changes: 4 additions & 2 deletions src/example_scripts/star_hub_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
ExternalTriggerMode,
AcquisitionMode,
AcquisitionSettings,
InputImpedance,
)


Expand Down Expand Up @@ -67,8 +68,9 @@ def connect_to_star_hub_example(
pre_trigger_length_in_samples=0,
timeout_in_ms=1000,
enabled_channels=[0, 8], # at least 1 channel from each child card must be enabled
vertical_ranges_in_mv=[200],
vertical_offsets_in_percent=[0],
vertical_ranges_in_mv=[200, 200],
vertical_offsets_in_percent=[0, 0],
input_impedances=[InputImpedance.ONE_MEGA_OHM, InputImpedance.ONE_MEGA_OHM],
timestamping_enabled=True,
batch_size=5,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,27 @@ def configure_acquisition(self, settings: AcquisitionSettings) -> None:
)
self.set_timeout_in_ms(settings.timeout_in_ms)
self.set_enabled_channels(settings.enabled_channels)
for channel, v_range, v_offset in zip(
self.channels, settings.vertical_ranges_in_mv, settings.vertical_offsets_in_percent

# Apply channel dependent settings
for channel, v_range, v_offset, impedance in zip(
self.channels,
settings.vertical_ranges_in_mv,
settings.vertical_offsets_in_percent,
settings.input_impedances,
):
cast(SpectrumDigitiserChannel, channel).set_vertical_range_in_mv(v_range)
cast(SpectrumDigitiserChannel, channel).set_vertical_offset_in_percent(v_offset)
cast(SpectrumDigitiserChannel, channel).set_input_impedance(impedance)

# Only some hardware has software programmable input coupling, so coupling can be None
if settings.input_couplings is not None:
for channel, coupling in zip(self.channels, settings.input_couplings):
cast(SpectrumDigitiserChannel, channel).set_input_coupling(coupling)

# Only some hardware has software programmable input paths, so it can be None
if settings.input_paths is not None:
for channel, path in zip(self.channels, settings.input_paths):
cast(SpectrumDigitiserChannel, channel).set_input_path(path)

# Write the configuration to the card
self.write_to_spectrum_device_register(SPC_M2CMD, M2CMD_CARD_WRITESETUP)
Expand Down
44 changes: 43 additions & 1 deletion src/spectrumdevice/devices/digitiser/digitiser_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@
)
from spectrumdevice.exceptions import SpectrumCardIsNotADigitiser
from spectrumdevice.settings.card_dependent_properties import CardType
from spectrumdevice.settings.channel import VERTICAL_OFFSET_COMMANDS, VERTICAL_RANGE_COMMANDS
from spectrumdevice.settings.channel import (
INPUT_IMPEDANCE_COMMANDS,
InputImpedance,
VERTICAL_OFFSET_COMMANDS,
VERTICAL_RANGE_COMMANDS,
InputCoupling,
INPUT_COUPLING_COMMANDS,
InputPath,
INPUT_PATH_COMMANDS,
)


class SpectrumDigitiserChannel(AbstractSpectrumChannel, SpectrumDigitiserChannelInterface):
Expand Down Expand Up @@ -79,3 +88,36 @@ def set_vertical_offset_in_percent(self, offset: int) -> None:
"""
self._parent_device.write_to_spectrum_device_register(VERTICAL_OFFSET_COMMANDS[self._number], offset)
self._vertical_offset_in_percent = offset

@property
def input_impedance(self) -> InputImpedance:
"""The current input impedance setting of the channel (50 Ohm or 1 MOhm)"""
impedance_binary_value = self._parent_device.read_spectrum_device_register(
INPUT_IMPEDANCE_COMMANDS[self._number]
)
return InputImpedance(impedance_binary_value)

def set_input_impedance(self, input_impedance: InputImpedance) -> None:
self._parent_device.write_to_spectrum_device_register(
INPUT_IMPEDANCE_COMMANDS[self._number], input_impedance.value
)

@property
def input_coupling(self) -> InputCoupling:
"""The coupling (AC or DC) setting of the channel. Only available on some hardware."""
coupling_binary_value = self._parent_device.read_spectrum_device_register(INPUT_COUPLING_COMMANDS[self._number])
return InputCoupling(coupling_binary_value)

def set_input_coupling(self, input_coupling: InputCoupling) -> None:
self._parent_device.write_to_spectrum_device_register(
INPUT_COUPLING_COMMANDS[self._number], input_coupling.value
)

@property
def input_path(self) -> InputPath:
"""The input path setting of the channel. Only available on some hardware."""
path_binary_value = self._parent_device.read_spectrum_device_register(INPUT_PATH_COMMANDS[self._number])
return InputPath(path_binary_value)

def set_input_path(self, input_path: InputPath) -> None:
self._parent_device.write_to_spectrum_device_register(INPUT_PATH_COMMANDS[self._number], input_path.value)
28 changes: 28 additions & 0 deletions src/spectrumdevice/devices/digitiser/digitiser_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from spectrumdevice.devices.abstract_device import SpectrumChannelInterface, SpectrumDeviceInterface
from spectrumdevice.settings import AcquisitionMode, AcquisitionSettings
from spectrumdevice import Measurement
from spectrumdevice.settings.channel import InputImpedance, InputCoupling, InputPath


class SpectrumDigitiserChannelInterface(SpectrumChannelInterface, ABC):
Expand Down Expand Up @@ -42,6 +43,33 @@ def set_vertical_offset_in_percent(self, offset: int) -> None:
def convert_raw_waveform_to_voltage_waveform(self, raw_waveform: ndarray) -> ndarray:
raise NotImplementedError()

@property
@abstractmethod
def input_impedance(self) -> InputImpedance:
raise NotImplementedError()

@abstractmethod
def set_input_impedance(self, input_impedance: InputImpedance) -> None:
raise NotImplementedError()

@property
@abstractmethod
def input_coupling(self) -> InputCoupling:
raise NotImplementedError()

@abstractmethod
def set_input_coupling(self, input_coupling: InputCoupling) -> None:
raise NotImplementedError()

@property
@abstractmethod
def input_path(self) -> InputPath:
raise NotImplementedError()

@abstractmethod
def set_input_path(self, input_path: InputPath) -> None:
raise NotImplementedError()


class SpectrumDigitiserInterface(SpectrumDeviceInterface, ABC):
"""Defines the public interface for control of all Spectrum digitiser devices, be they StarHub composite devices
Expand Down
7 changes: 7 additions & 0 deletions src/spectrumdevice/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from spectrumdevice.settings.card_dependent_properties import ModelNumber
from spectrumdevice.settings.card_features import CardFeature, AdvancedCardFeature
from spectrumdevice.settings.channel import InputImpedance, InputCoupling, InputPath
from spectrumdevice.settings.device_modes import AcquisitionMode, ClockMode
from spectrumdevice.settings.io_lines import IOLineMode, AvailableIOModes
from spectrumdevice.settings.transfer_buffer import (
Expand Down Expand Up @@ -76,6 +77,8 @@ class AcquisitionSettings:
"""The voltage range to apply to each enabled channel in mW."""
vertical_offsets_in_percent: List[int]
"""The DC offset to apply to each enabled channel as percentages of their vertical ranges."""
input_impedances: List[InputImpedance]
"""The input impedance settings to apply to each channel"""
timestamping_enabled: bool
"""If True, Measurements will include the time at which the acquisition was triggered. Increases latency by ~10 ms.
"""
Expand All @@ -84,6 +87,10 @@ class AcquisitionSettings:
SpectrumDigitiserCard.get_waveforms()."""
number_of_averages: int = 1
"""If an averaging AcquisitionMode is selected, this defines the number of averages."""
input_couplings: Optional[List[InputCoupling]] = None
"""The coupling (AC or DC) to apply to each channel. Only available on some hardware, so default is None."""
input_paths: Optional[List[InputPath]] = None
"""The input path (HF or Buffered) to apply to each channel. Only available on some hardware, so default is None."""


class SpectrumRegisterLength(Enum):
Expand Down
123 changes: 123 additions & 0 deletions src/spectrumdevice/settings/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@
SPCM_STOPLVL_HOLDLAST,
SPCM_STOPLVL_LOW,
SPCM_STOPLVL_ZERO,
SPC_50OHM0,
SPC_50OHM1,
SPC_50OHM10,
SPC_50OHM11,
SPC_50OHM12,
SPC_50OHM13,
SPC_50OHM14,
SPC_50OHM15,
SPC_50OHM2,
SPC_50OHM3,
SPC_50OHM4,
SPC_50OHM5,
SPC_50OHM6,
SPC_50OHM7,
SPC_50OHM8,
SPC_50OHM9,
SPC_AMP0,
SPC_AMP1,
SPC_AMP2,
Expand Down Expand Up @@ -93,6 +109,38 @@
CHANNEL13,
CHANNEL14,
CHANNEL15,
SPC_ACDC0,
SPC_ACDC1,
SPC_ACDC2,
SPC_ACDC3,
SPC_ACDC4,
SPC_ACDC5,
SPC_ACDC6,
SPC_ACDC7,
SPC_ACDC8,
SPC_ACDC9,
SPC_ACDC10,
SPC_ACDC11,
SPC_ACDC12,
SPC_ACDC13,
SPC_ACDC14,
SPC_ACDC15,
SPC_PATH0,
SPC_PATH1,
SPC_PATH2,
SPC_PATH3,
SPC_PATH4,
SPC_PATH5,
SPC_PATH6,
SPC_PATH7,
SPC_PATH8,
SPC_PATH9,
SPC_PATH10,
SPC_PATH11,
SPC_PATH12,
SPC_PATH13,
SPC_PATH14,
SPC_PATH15,
)

VERTICAL_RANGE_COMMANDS = (
Expand Down Expand Up @@ -219,3 +267,78 @@ class SpectrumChannelName(Enum):
CHANNEL13 = CHANNEL13
CHANNEL14 = CHANNEL14
CHANNEL15 = CHANNEL15


class InputImpedance(Enum):
FIFTY_OHM = 1
ONE_MEGA_OHM = 0


INPUT_IMPEDANCE_COMMANDS = (
SPC_50OHM0,
SPC_50OHM1,
SPC_50OHM2,
SPC_50OHM3,
SPC_50OHM4,
SPC_50OHM5,
SPC_50OHM6,
SPC_50OHM7,
SPC_50OHM8,
SPC_50OHM9,
SPC_50OHM10,
SPC_50OHM11,
SPC_50OHM12,
SPC_50OHM13,
SPC_50OHM14,
SPC_50OHM15,
)


class InputCoupling(Enum):
AC = 1
DC = 0


INPUT_COUPLING_COMMANDS = (
SPC_ACDC0,
SPC_ACDC1,
SPC_ACDC2,
SPC_ACDC3,
SPC_ACDC4,
SPC_ACDC5,
SPC_ACDC6,
SPC_ACDC7,
SPC_ACDC8,
SPC_ACDC9,
SPC_ACDC10,
SPC_ACDC11,
SPC_ACDC12,
SPC_ACDC13,
SPC_ACDC14,
SPC_ACDC15,
)


class InputPath(Enum):
BUFFERED_INPUTS = 0
HF_INPUT_WITH_FIXED_50_OHM_TERMINATION = 1


INPUT_PATH_COMMANDS = (
SPC_PATH0,
SPC_PATH1,
SPC_PATH2,
SPC_PATH3,
SPC_PATH4,
SPC_PATH5,
SPC_PATH6,
SPC_PATH7,
SPC_PATH8,
SPC_PATH9,
SPC_PATH10,
SPC_PATH11,
SPC_PATH12,
SPC_PATH13,
SPC_PATH14,
SPC_PATH15,
)
2 changes: 1 addition & 1 deletion src/tests/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SpectrumTestMode(Enum):
MOCK_DEVICE_TEST_FRAME_RATE_HZ = 10.0

# Trigger source to use for integration tests. Has no effect in SpectrumTestMode.MOCK_HARDWARE
INTEGRATION_TEST_TRIGGER_SOURCE = TriggerSource.SPC_TMASK_EXT0
INTEGRATION_TEST_TRIGGER_SOURCE = TriggerSource.SPC_TMASK_SOFTWARE


if SINGLE_CARD_TEST_MODE == SpectrumTestMode.REAL_HARDWARE and not SPECTRUM_DRIVERS_FOUND:
Expand Down
Loading

0 comments on commit dedc279

Please sign in to comment.