Skip to content

Commit

Permalink
#35 - fixed batched acquisitions for star hubs
Browse files Browse the repository at this point in the history
  • Loading branch information
crnbaker committed Oct 13, 2023
1 parent ee81d9b commit 6366c25
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 50 deletions.
43 changes: 0 additions & 43 deletions src/example_scripts/connect_to_star_hub.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/example_scripts/finite_multi_fifo_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def finite_multi_fifo_example(
vertical_ranges_in_mv=[200],
vertical_offsets_in_percent=[0],
timestamping_enabled=True,
batch_size=5,
batch_size=batch_size,
)

# Apply settings
Expand Down
95 changes: 95 additions & 0 deletions src/example_scripts/star_hub_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from matplotlib.pyplot import figure, title, plot, show

from spectrumdevice.devices.mocks import MockSpectrumDigitiserCard, MockSpectrumDigitiserStarHub
from spectrumdevice.devices.digitiser import SpectrumDigitiserCard
from spectrumdevice.devices.digitiser import SpectrumDigitiserStarHub
from spectrumdevice.settings import ModelNumber, TriggerSettings, TriggerSource, ExternalTriggerMode, AcquisitionMode, \
AcquisitionSettings


def connect_to_star_hub_example(
mock_mode: bool, num_cards: int, master_card_index: int, ip_address: str
) -> SpectrumDigitiserStarHub:

if not mock_mode:
child_cards = []
for n in range(num_cards):
# Connect to each card in the hub.
child_cards.append(SpectrumDigitiserCard(device_number=n, ip_address=ip_address))
# Connect to the hub itself
return SpectrumDigitiserStarHub(device_number=0, child_cards=child_cards, master_card_index=master_card_index)
else:
mock_child_cards = []
for n in range(num_cards):
# Create a mock device for each card in the hub
mock_child_cards.append(
MockSpectrumDigitiserCard(
device_number=n,
model=ModelNumber.TYP_M2P5966_X4,
mock_source_frame_rate_hz=10.0, # Mock devices need to be provided with a mock source frame rate
num_modules=2, # (For real devices, this and num_channels_per_module are read from the hardware).
num_channels_per_module=4,
)
)
# Create a mock hub containing the above devices
return MockSpectrumDigitiserStarHub(
device_number=0, child_cards=mock_child_cards, master_card_index=master_card_index
)


if __name__ == "__main__":

num_measurements = 5

hub = connect_to_star_hub_example(mock_mode=False, num_cards=2, master_card_index=1, ip_address="169.254.13.35")

print(f"{hub} contains {len(hub.channels)} channels in total:")
for channel in hub.channels:
print(channel)

# Trigger settings
trigger_settings = TriggerSettings(
trigger_sources=[TriggerSource.SPC_TMASK_EXT0],
external_trigger_mode=ExternalTriggerMode.SPC_TM_POS,
external_trigger_level_in_mv=1000,
)

# Acquisition settings
acquisition_settings = AcquisitionSettings(
acquisition_mode=AcquisitionMode.SPC_REC_FIFO_MULTI,
sample_rate_in_hz=40000000,
acquisition_length_in_samples=400,
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],
timestamping_enabled=True,
batch_size=5,
)

# Apply settings
hub.configure_trigger(trigger_settings)
hub.configure_acquisition(acquisition_settings)

# Execute acquisition
measurements = hub.execute_finite_fifo_acquisition(num_measurements)

# Plot waveforms
for n, measurement in enumerate(measurements):
figure()
title(f"Measurement {n}")
for wfm in measurement.waveforms:
plot(wfm)

ts_format = "%Y-%m-%d %H:%M:%S.%f"
print(f"Completed {len(measurements)} measurements each containing {len(measurements[0].waveforms)} waveforms.")
print(f"Waveforms had the following shape: {measurements[0].waveforms[0].shape}")
print(f"and the following timestamps:")
for measurement in measurements:
print(measurement.timestamp.strftime(ts_format) if measurement.timestamp else "Timestamping disabled")

hub.reset()
hub.disconnect()

show()
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def configure_acquisition(self, settings: AcquisitionSettings) -> None:
if settings.batch_size > 1 and settings.acquisition_mode == AcquisitionMode.SPC_REC_STD_SINGLE:
raise ValueError("In standard single mode, only 1 acquisition can be downloaded at a time.")
self._acquisition_mode = settings.acquisition_mode
self._batch_size = settings.batch_size
self.set_batch_size(settings.batch_size)
self.set_acquisition_mode(settings.acquisition_mode)
self.set_sample_rate_in_hz(settings.sample_rate_in_hz)
self.set_acquisition_length_in_samples(settings.acquisition_length_in_samples)
Expand Down Expand Up @@ -101,14 +101,14 @@ def execute_finite_fifo_acquisition(self, num_measurements: int) -> List[Measure
timestamp attribute, which (if timestamping was enabled in acquisition settings) contains the time at
which the acquisition was triggered.
"""
if (num_measurements % self._batch_size) != 0:
if (num_measurements % self.batch_size) != 0:
raise ValueError(
"Number of measurements in a finite FIFO acquisition must be a multiple of the "
" batch size configured using AbstractSpectrumDigitiser.configure_acquisition()."
)
self.execute_continuous_fifo_acquisition()
measurements = []
for _ in range(num_measurements // self._batch_size):
for _ in range(num_measurements // self.batch_size):
measurements += [
Measurement(waveforms=frame, timestamp=self.get_timestamp()) for frame in self.get_waveforms()
]
Expand Down
8 changes: 8 additions & 0 deletions src/spectrumdevice/devices/digitiser/digitiser_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self, device_number: int = 0, ip_address: Optional[str] = None):
raise SpectrumCardIsNotADigitiser(self.type)
self._acquisition_mode = self.acquisition_mode
self._timestamper: Optional[Timestamper] = None
self._batch_size = 1

def _init_channels(self) -> Sequence[SpectrumDigitiserChannelInterface]:
num_modules = self.read_spectrum_device_register(SPC_MIINST_MODULES)
Expand Down Expand Up @@ -249,6 +250,13 @@ def set_acquisition_mode(self, mode: AcquisitionMode) -> None:
mode (`AcquisitionMode`): The desired acquisition mode."""
self.write_to_spectrum_device_register(SPC_CARDMODE, mode.value)

@property
def batch_size(self) -> int:
return self._batch_size

def set_batch_size(self, batch_size: int) -> None:
self._batch_size = batch_size

def define_transfer_buffer(self, buffer: Optional[Sequence[TransferBuffer]] = None) -> None:
"""Create or provide a `TransferBuffer` object for receiving acquired samples from the device.
Expand Down
9 changes: 9 additions & 0 deletions src/spectrumdevice/devices/digitiser/digitiser_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,12 @@ def acquisition_mode(self) -> AcquisitionMode:
@abstractmethod
def set_acquisition_mode(self, mode: AcquisitionMode) -> None:
raise NotImplementedError()

@property
@abstractmethod
def batch_size(self) -> int:
raise NotImplementedError()

@abstractmethod
def set_batch_size(self, batch_size: int) -> None:
raise NotImplementedError()
13 changes: 12 additions & 1 deletion src/spectrumdevice/devices/digitiser/digitiser_star_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def _get_waveforms(digitiser_card: SpectrumDigitiserCard) -> None:
thread.join()

waveform_sets_all_cards_ordered = []
for n in range(self._batch_size):
for n in range(self.batch_size):
waveforms_in_this_batch = []
for card in self._child_cards:
waveforms_in_this_batch += card_ids_and_waveform_sets[str(card)][n]
Expand Down Expand Up @@ -178,3 +178,14 @@ def set_acquisition_mode(self, mode: AcquisitionMode) -> None:
mode (`AcquisitionMode`): The desired acquisition mode."""
for d in self._child_cards:
cast(SpectrumDigitiserCard, d).set_acquisition_mode(mode)

@property
def batch_size(self) -> int:
batch_sizes = []
for d in self._child_cards:
batch_sizes.append(cast(SpectrumDigitiserCard, d).batch_size)
return check_settings_constant_across_devices(batch_sizes, __name__)

def set_batch_size(self, batch_size: int) -> None:
for d in self._child_cards:
cast(SpectrumDigitiserCard, d).set_batch_size(batch_size)
4 changes: 2 additions & 2 deletions src/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
from numpy import array, concatenate

from example_scripts.connect_to_star_hub import star_hub_example
from example_scripts.star_hub_example import connect_to_star_hub_example
from example_scripts.continuous_averaging_fifo_mode import continuous_averaging_multi_fifo_example
from example_scripts.continuous_multi_fifo_mode import continuous_multi_fifo_example
from example_scripts.finite_multi_fifo_mode import finite_multi_fifo_example
Expand Down Expand Up @@ -110,7 +110,7 @@ def setUp(self) -> None:
self._star_hub_mock_mode = STAR_HUB_TEST_MODE == SpectrumTestMode.MOCK_HARDWARE

def test_star_hub(self) -> None:
hub = star_hub_example(
hub = connect_to_star_hub_example(
mock_mode=self._star_hub_mock_mode,
num_cards=NUM_CARDS_IN_STAR_HUB,
master_card_index=STAR_HUB_MASTER_CARD_INDEX,
Expand Down

0 comments on commit 6366c25

Please sign in to comment.