Acquire#

Acquisition components are sources of data in vortex, such as a digitizer card. Each component provides a similar API.

Overview#

An acquisition component is first initialized with a call to initialize(), supplying a matching configuration object. Initialization brings the component into a state where multiple acquisitions can be subsequently performed. Once the component is initialized, a preparation step is required for some acquisitions. Tasks performed during preparation are those that required to start each acquisition, such as arming the digitizer. This is performed by calling prepare(). After the preparation step, some acquisitions permit the queuing (or “preloading”) of blocks for a buffered asynchronous operation.

The acquisition begins producing data with a call to start(). Data is received synchronously with next() or asynchronously with next_async(). Both methods accept an id argument, which is provided only for user bookkeeping and logging. A call to stop() requests that the acquisition complete. Note that asynchronously queued blocks may continue to complete after stop() is called. When used with the Engine, the user is only responsible for calling initialize(). The engine will call prepare(), start(), and stop() at the appropriate time.

Some components support preloading, in which next() or next_async() may be called prior to start(). These components queue the provided buffers for immediate acquisition once start() is called. Each component states below whether or not preloading is supported. Preloading is primarily a feature of the Engine, which is controlled with the preload parameter on a per-component basis when calling EngineConfig.add_acquisition().

Components#

vortex provides components for simulated and physical acquisitions.

Null#

class vortex.acquire.NullAcquisition#

Perform no acquisition.

This class is provided as an engine placeholder for testing or mocking. The only necessary configuration is the expected output shape.

Note

This component supports preloading with the engine.

initialize(config)#

Initialize the acquisition using the supplied configuration. Present for API uniformity but calling is necessary only if the configuration is accessed elsewhere.

Parameters

config (NullAcquisitionConfig) – New configuration to apply.

prepare()#

Prepare to imminently start the acquisition. Present for API uniformity, but calling is unnecessary.

start()#

Start the acquisition. Present for API uniformity, but calling is unnecessary.

stop()#

Stop the acquisition. Present for API uniformity, but calling is unnecessary.

next(buffer, id=0)#

Acquire the next buffer. Always successfully acquires buffer.shape[0] records.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire.

  • id (int) – Number to associate with the buffer for logging purposes.

Returns

int – The number of records acquired. The number of records is always matches buffer.shape[0].

next_async(buffer, callback, id=0)#

Acquire the next buffer asynchronously and execute the callback when complete.

Caution

The callback is executed in the calling thread before this method returns.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire.

  • callback (Callable[[int, Exception], None]) – Callback to execute when buffer is filled. The callback receives two arguments, the number of records acquired and any exception which occurred during the acquisition. The number of records is always buffer.shape[0], and the exception is always None.

  • id (int) – Number to associate with the buffer for logging purposes.

property config: NullAcquisitionConfig#

Copy of the active configuration.

class vortex.acquire.NullAcquisitionConfig#

Configuration object for NullAcquisition.

property shape: List[int[3]]#

Required shape of output buffers. Returns a list of [records_per_block, samples_per_record, channels_per_sample]. Read-only.

property samples_per_record: int#

Number of samples per record.

property records_per_block: int#

Number of records in each acquired buffer or block.

property channels_per_sample: int#

Number of channels that comprise each sample.

validate()#

Check the configuration for errors.

Raises

RuntimeError – If the configuration is invalid.

copy()#

Create a copy of this configuration.

Returns

NullAcquisitionConfig – The copy.

File#

class vortex.acquire.FileAcquisition#

Acquire data from a file.

Data is read from the file and returned in the requested shape. The file is read as raw bytes with no datatype or alignment considerations. File looping for infinite acquisitions is possible. This class is intended primarily for testing or offline post-processing.

Note

This component supports preloading with the engine.

__init__(logger=None)#

Create a new object with optional logging.

Parameters

logger (vortex.Logger) – Logger to receive status messages. Logging is disabled if not provided.

initialize(config)#

Initialize the acquisition using the supplied configuration.

Parameters

config (FileAcquisitionConfig) – New configuration to apply.

prepare()#

Prepare to imminently start the acquisition. Present for API uniformity, but calling is unnecessary.

start()#

Start the acquisition, and open the source file.

stop()#

Stop the acquisition, and close the source file.

next(buffer, id=0)#

Acquire the buffer and return the number of acquired records.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire, with shape that matches self.config.shape.

  • id (int) – Number to associate with the buffer for logging purposes.

Returns

int – The number of records acquired. If the number acquired is less than the number requested, the acquisition is complete.

Raises

RuntimeError – If the acquisition fails.

next_async(buffer, callback, id=0)#

Acquire the buffer asynchronously and execute the callback when complete.

Caution

The callback may be executed in the calling thread before this method returns if an error occurs while queueing the background acquisition.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to fill with data according to the shape of the buffer, which must match self.config.shape.

  • callback (Callable[[int, Exception], None]) – Callback to execute when buffer is filled. The callback receives two arguments, the number of records acquired and any exception which occurred during the acquisition. If the number of records acquired is less than the number requested, the acquisition is complete.

  • id (int) – Number to associate with the buffer for logging purposes.

property config: FileAcquisitionConfig#

Copy of the active configuration.

class vortex.acquire.FileAcquisitionConfig#

Base: NullAcquisitionConfig

Configuration object for FileAcquisition.

property path: str#

Path to file that backs the acquisition.

property loop: bool#

Loop the file to provide an infinite acquisition. Otherwise, the acquisition ends when the end of file is reached.

copy()#

Return a copy of this configuration.

Returns

FileAcquisitionConfig – The copy.

AlazarTech#

Host#

class vortex.acquire.AlazarAcquisition#

Acquire data using an AlazarTech digitizer.

Once prepare() is called, the acquisition may be started and stopped as many times as necessary.

Note

This component supports preloading with the engine.

__init__(logger=None)#

Create a new object with optional logging.

Parameters

logger (vortex.Logger) – Logger to receive status messages. Logging is disabled if not provided.

initialize(config)#

Initialize the acquisition using the supplied configuration. The Alazar card is fully configured when this method returns.

Parameters

config (AlazarConfig) – New configuration to apply.

prepare()#

Prepare to imminently start the acquisition. The Alazar card is armed for capture.

start()#

Start the acquisition.

stop()#

Stop the acquisition.

Caution

Asynchronously acquired buffers that completed before the acquisition was stopped may continue to result after this method returns.

next(buffer, id=0)#

Acquire the buffer and return the number of acquired records.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire, with shape that matches self.config.shape.

  • id (int) – Number to associate with the buffer for logging purposes.

Returns

int – The number of records acquired. If the number acquired is less than the number requested, the acquisition is complete.

Raises

RuntimeError – If the acquisition fails.

next_async(buffer, callback, id=0)#

Acquire the buffer asynchronously and execute the callback when complete.

Caution

The callback may be executed in the calling thread before this method returns if an error occurs while queueing the background acquisition.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire, with shape that matches self.config.shape.

  • callback (Callable[[int, Exception], None]) – Callback to execute when buffer is filled. The callback receives two arguments, the number of records acquired and any exception which occurred during the acquisition. If the number of records acquired is less than the number requested, the acquisition is complete.

  • id (int) – Number to associate with the buffer for logging purposes.

property config: AlazarConfig#

Copy of the active configuration.

class vortex.acquire.AlazarConfig#

Base: NullAcquisitionConfig

Configuration object for AlazarAcquisition.

property device: AlazarDevice#

Alazar device for acquisition. Defaults to AlazarDevice().

property clock: InternalClock | ExternalClock#

Internal or external clock configuration. Defaults to InternalClock().

property trigger: SingleExternalTrigger | DualExternalTrigger#

Single or dual trigger configuration. Defaults to SingleExternalTrigger().

property inputs: List[Input]#

List of input configurations for each channel acquire. Default is empty.

property options: List[AuxIOTriggerOut | AuxIOClockOut | AuxIOPacerOut | OCTIgnoreBadClock]#

List of acquisition options. Default is empty.

property resampling: numpy.ndarray[int]#

Zero-based index of samples to keep in each record. All other samples are removed from the record. This can be used to perform resampling with nearest-neighbor interpolation. Number of samples to keep must match the number of samples per record. Set to an empty array ([]) to disable resampling. Disabled by default.

property acquire_timeout: datetime.timedelta#

Timeout for the acquisition of each block. Defaults to timedelta(seconds=1).

property stop_on_error: bool#

Automatically stop the acquisition when an error occurs. Default is `True.

property channel_mask: int#

Bitmask of channels configured for acquisition. Read-only.

property samples_per_second: int#

Number of samples per second for internally-clocked acquisitions. Read-only.

Raises

RuntimeError – if samples_per_second_is_known is False.

property samples_per_second_is_known: bool#

True if samples_per_second is specified in the configuration (e.g., vortex.acquire.InternalClock) and False otherwise. Read-only.

property recommended_minimum_records_per_block: int#

Minimum recommended records per block for the configured Alazar digitizer. Read-only.

property bytes_per_multisample: int#
copy()#

Create a copy of this configuration.

Returns

AlazarConfig – The copy.

Host with On-board FFT#

class vortex.acquire.AlazarFFTAcquisition#

Base: AlazarAcquisition

Acquire data using an AlazarTech digitizer with the on-board FPGA configured for FFT computation.

This class may be used to simultaneously acquire the raw and FFT data using the include_time_domain option. In this case, both the raw and FFT data are combined into a single record.

Note

This component supports preloading with the engine.

initialize(config)#

Initialize the acquisition using the supplied configuration. The Alazar card is fully configured when this method returns.

Parameters

config (AlazarFFTConfig) – New configuration to apply.

property config: AlazarFFTConfig#

Copy of the active configuration.

class vortex.acquire.AlazarFFTConfig#

Base: AlazarConfig

Configuration object for AlazarFFTAcquisition.

property fft_length: int#

Length of on-board FFT to perform. Records are zero-padded to reach this length. Must be larger than samples per record and must be a power of 2.

property spectral_filter: numpy.ndarray[numpy.complex64]#

Spectral filter to apply before the FFT. Must have the same length as FFT. Set to empty array ([]) to disable. Disabled by default.

property background: numpy.ndarray[numpy.uint16]#

Background record to subtract. Set to empty array([]) to disable. Disabled by default.

property include_time_domain: bool#

Append time domain data to the output FFT record. Requires a pointer cast to access since different data types are combined into single record. Defaults to False.

property samples_per_ascan: int#

Number of samples per the output A-scan, which may differ from samples per record depending on FFT settings. Read-only.

property ascans_per_block: int#

Number of A-scans per block which is identical to number of records per blocks. Provided for API consistency only.

property buffer_bytes_per_record: int#

The number of bytes required for each record buffer. Read-only.

copy()#

Create a copy of this configuration.

Returns

AlazarFFTConfig – The copy.

GPU#

class vortex.acquire.AlazarGPUAcquisition#

Base: AlazarAcquisition

Acquire data using an AlazarTech digitizer with extensions to deliver data directly to a CUDA-capable GPU.

Note

This component supports preloading with the engine.

Note

vortex will perform its own GPU data transfers as needed. AlazarAcquisition with vortex-managed GPU transfer gives comparable performance to AlazarGPUAcquisition.

initialize(config)#

Initialize the acquisition using the supplied configuration. The Alazar card is fully configured when this method returns.

Parameters

config (AlazarGPUConfig) – New configuration to apply.

next(buffer, id=0)#

Acquire the buffer and return the number of acquired records.

Parameters
Returns

int – The number of records acquired. If the number acquired is less than the number requested, the acquisition is complete.

Raises

RuntimeError – If the acquisition fails.

next_async(buffer, callback, id=0)#

Acquire the buffer asynchronously and execute the callback when complete.

Caution

The callback may be executed in the calling thread before this method returns if an error occurs while queueing the background acquisition.

Parameters
  • buffer (cupy.ndarray[cupy.uint16]) – The buffer to acquire, with shape that matches self.config.shape on GPU device self.config.gpu_device_index.

  • callback (Callable[[int, Exception], None]) – Callback to execute when buffer is filled. The callback receives two arguments, the number of records acquired and any exception which occurred during the acquisition. If the number of records acquired is less than the number requested, the acquisition is complete.

  • id (int) – Number to associate with the buffer for logging purposes.

property config: AlazarGPUConfig#

Copy of the active configuration.

class vortex.acquire.AlazarGPUConfig#

Base: AlazarConfig

Configuration object for AlazarGPUAcquisition.

property gpu_device_index: int#

Index of CUDA device for delivery of data. Defaults to index 0.

copy()#

Create a copy of this configuration.

Returns

AlazarGPUConfig – The copy.

Configuration#

An Alazar configuration is specified using a series of classes that encode configuration options. These options are shared by all Alazar acquisition classes.

See also

Consult the ATS-SDK documentation for fine details regarding this configuration. Most configuration classes below map to one or two ATS-SDK API calls.

class vortex.acquire.AlazarDevice#

Representation of an Alazar device identifier.

__init__(system_index=1, board_index=1)#

Create a new object.

Parameters
property system_index: int#

Index of Alazar system. The first system has index 1.

property board_index: int#

Index of board within Alazar system The first board has index 1.

class vortex.driver.alazar.Coupling#

Enumeration of coupling modes.

DC#
AC#
class vortex.driver.alazar.ClockEdge#

Enumeration of clock edges.

Rising#
Falling#
class vortex.driver.alazar.TriggerSlope#

Enumeration of trigger slopes.

Positive#
Negative#
vortex.driver.alazar.InfiniteAcquisition: int#

Value to indicate infinite acquisition.

vortex.driver.alazar.TriggerRangeTTL: int#

Trigger range value that indicates TTL.

Clock#
class vortex.acquire.InternalClock#

Configure an internal clock source.

__init__(samples_per_second=800_000_000)#

Create a new object.

Parameters

samples_per_second (int) – Value for samples_per_second.

property samples_per_second: int#

Number of samples per second to configure for the internal clock

class vortex.acquire.ExternalClock#

Configure an external clock source.

__init__(level_ratio=0.5, coupling=Coupling.AC, edge=ClockEdge.Rising, dual=False)#

Create a new object.

Parameters
property level_ratio: float#

Signal level threshold in range [0, 1] at which a clock edge is detected.

property coupling: Coupling#

Coupling for clock input.

property edge: ClockEdge#

Edge on which to trigger the clock.

property dual: bool#

Trigger on both rising and falling clock edges if True. Otherwise, trigger only on edge set by edge.

Trigger#
class vortex.acquire.SingleExternalTrigger#

Configure a single external trigger.

__init__(range_millivolts=2500, level_ratio=0.09, delay_samples=80, slope=TriggerSlope.Positive, coupling=DC)#

Create a new object.

Parameters
property range_millivolts: int#

Trigger input range, specified in millivolts.

property level_ratio: float#

Signal level threshold in range [0, 1] at which a trigger event is detected.

property delay_samples: int#

Number of samples to skip following a trigger event before acquiring a record. Non-negative.

property slope: TriggerSlope#

Polarity of trigger signal.

property coupling: Coupling#

Coupling for trigger input.

class vortex.acquire.DualExternalTrigger#

Configure a dual external trigger.

__init__(range_millivolts=2500, level_ratios=[0.09, 0.09], delay_samples=80, initial_slope=Positive, coupling=DC)#

Create a new object.

Parameters
property range_millivolts: int#

Trigger input range, specified in millivolts.

property level_ratios: List[float[2]]#

A pair of signal level thresholds in range [0, 1] at which trigger events are detected.

property delay_samples: int#

Number of samples to skip following a trigger event before acquiring a record. Non-negative.

property initial_slope: TriggerSlope#

Polarity of the initial trigger.

property coupling: Coupling#

Coupling for trigger input.

Input#
class vortex.acquire.Input#

Configure an input channel.

__init__(channel=Channel.B, range_millivolts=400, impedance_ohms=50, coupling=Coupling.DC)#

Create a new object.

Parameters
property channel: Channel#

Channel to receive this configuration.

property range_millivolts: int#

Channel input range, specified in millivolts.

property impedance_ohms: int#

Channel input impedance, specified in Ohms.

property coupling: Coupling#

Coupling for channel input.

property bytes_per_sample: int#

Number of bytes per sample acquired for this input. Read-only.

copy()#

Copy this object.

Returns

Input – The copy.

class vortex.driver.alazar.Channel#

Enumeration of input channels.

A#
B#
C#
D#
E#
F#
G#
H#
I#
J#
K#
L#
M#
N#
O#
P#
Options#

Although the Alazar configuration will accept multiple auxillary I/O options, only the last one will have effect.

class vortex.acquire.AuxIOTriggerOut#

Pass the trigger through the auxillary I/O port.

class vortex.acquire.AuxIOClockOut#

Pass the clock through the auxillary I/O port.

class vortex.acquire.AuxIOPacerOut#

Pass the clock through the auxillary I/O port after a divider.

__init__(divider=2)#

Create a new object.

Parameters

divider (int) – Value for divider.

property divider: int#

Divider for clock, with minimum value of 2. The clock frequency is divided by this value to determine the pacer frequency.

class vortex.acquire.OCTIgnoreBadClock#

Activate the OCT ignore bad clock feature.

__init__(good_seconds=4.95e-6, bad_seconds=4.95e-6)#

Create a new object

Parameters

See also

See the AlazarOCTIgnoreBadClock documentation for full details.

property good_seconds: float#

Good clock duration, specified in seconds.

property bad_seconds: float#

Bad clock duration, specified in seconds.

NI Vision#

IMAQ#

class vortex.acquire.ImaqAcquisition#

Acquire data using a NI IMAQ-compatible line-scan or area-scan camera. Each line or row of the acquire corresponds to a record. Each element of the line or row corresponds to a sample.

Caution

ImaqAcquisition does not support preloading. When registering ImaqAcquisition with an Engine, set preload=False.

__init__(logger=None)#

Create a new object with optional logging.

Parameters

logger (vortex.Logger) – Logger to receive status messages. Logging is disabled if not provided.

initialize(config)#

Initialize the acquisition using the supplied configuration. The Alazar card is fully configured when this method returns.

Parameters

config (ImaqAcquisitionConfig) – New configuration to apply.

prepare()#

Prepare to imminently start the acquisition. Present for API uniformity, but calling is unnecessary.

start()#

Start the acquisition.

stop()#

Stop the acquisition.

Caution

Asynchronously acquired buffers that completed before the acquisition was stopped may continue to result after this method returns.

next(buffer, id=0)#

Acquire the buffer and return the number of acquired records.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire, with shape that matches self.config.shape.

  • id (int) – Number to associate with the buffer for logging purposes.

Returns

int – The number of records acquired. If the number acquired is less than the number requested, the acquisition is complete.

Raises

RuntimeError – If the acquisition fails.

next_async(buffer, callback, id=0)#

Acquire the buffer asynchronously and execute the callback when complete.

Caution

The callback may be executed in the calling thread before this method returns if an error occurs while queueing the background acquisition.

Parameters
  • buffer (numpy.ndarray[numpy.uint16]) – The buffer to acquire, with shape that matches self.config.shape.

  • callback (Callable[[int, Exception], None]) – Callback to execute when buffer is filled. The callback receives two arguments, the number of records acquired and any exception which occurred during the acquisition. If the number of records acquired is less than the number requested, the acquisition is complete.

  • id (int) – Number to associate with the buffer for logging purposes.

property config: ImaqAcquisitionConfig#

Copy of the active configuration.

class vortex.acquire.ImaqAcquisitionConfig#

Base: NullAcquisitionConfig

Configuration object for ImaqAcquisition.

property device_name: str#

Name of IMAQ device to access. Defaults to "img0".

property offset: List[int[2]]#

Region of interest offset within acquisition window in (X, Y) format. The shape of the region of interest is set with records_per_block and samples_per_record. Prefer to use sample_offset and record_offset instead.

property sample_offset: int#

Number of samples to skip in the acquisition window. Defines the “left” offset of the region of interest. Defaults to 0.

property record_offset: int#

Number of records to skip in the acquisition window. Defines the “top” offset of the region of interest. Defaults to 0.

property line_trigger: Optional[LineTrigger]#

Configure a line input trigger. Set to None to disable. Disabled by default.

property frame_trigger: Optional[FrameTrigger]#

Configure a frame input trigger. Set to None to disable. Disabled by default.

property trigger_output: List[TriggerOutput]#

Configure multiple trigger outputs. Defaults to [TriggerOutput()].

property ring_size: int#

Number of buffers to allocate for the internal ring buffer. Recommended minimum is 10. Adjust as needed to avoid frame overruns. Defaults to 10.

property acquire_timeout: datetime.timedelta#

Timeout for the acquisition of a frame. Defaults to timedelta(seconds=1).

property stop_on_error: bool#

Automatically stop the acquisition on an error. Deafults to True.

property bypass_region_check: bool#

Do not check that the region of interest fits within the acquisition window. If the region of interest does not fit but this check is disabled, the acquired frame will be zero-padded to the requested size. Enabled by default.

copy()#

Create a copy of this configuration.

Returns

ImaqAcquisitionConfig – The copy.

Configuration#

See also

Consult the IMAQ documentation for fine details regarding this configuration. Most configuration classes below map to one or two IMAQ API calls.

class vortex.driver.imaq.Signal#

Enumeration of signal types.

NoSignal#
External#
RTSI#
IsoIn#
IsoOut#
Status#
ScaledEncoder#
SoftwareTrigger#
class vortex.driver.imaq.Polarity#

Enumeration of polarities.

Low#
High#
class vortex.driver.imaq.Source#

Enumeration of signal sources.

Disabled#
AcquisitionInProgress#
AcquisitionDone#
PixelClock#
Unasserted#
Asserted#
Hsync#
Vsync#
FrameStart#
FrameDone#
ScaledEncoder#
class vortex.driver.imaq.RegionOfInterest#

Representation of a rectangular region of interest within an image.

__init__(top, left, height, width, pixels_per_row=0)#

Create a new object.

Parameters
property top: int#
property left: int#
property height: int#
property width: int#
property pixels_per_row: int#

A value of 0 indicates that there are width pixels per row.

Trigger Input#
class vortex.acquire.LineTrigger#

Configure a line trigger.

__init__(line=0, skip=0, polarity=Polarity.High, signal=Signal.External)#

Create a new object.

Parameters
property line: int#

Index of input for the trigger.

property skip: int#

Number of samples to skip after the line trigger is received.

property polarity: Polarity#

Polarity of the trigger.

property signal: Signal#

Signal type of the trigger.

class vortex.acquire.FrameTrigger#

Configure a frame trigger.

__init__(line=0, polarity=Polarity.High, signal=Signal.External)#

Create a new object.

Parameters
property line: int#

Index of input for the trigger.

property polarity: vortex.driver.imaq.Polarity#

Polarity of the trigger.

property signal: vortex.driver.imaq.Signal#

Signal type of the trigger.

Trigger Output#
class vortex.acquire.TriggerOutput#

Configure a trigger output.

__init__(line=0, source=Source.Hsync, polarity=Polarity.High, signal=Signal.External)#

Create a new object.

Parameters
property line: int#

Index of the output for the trigger.

property source: Source#

Source of the trigger.

property polarity: Polarity#

Polarity of the trigger.

property signal: Signal#

Signal type of the trigger.