Streamer#
- class nistreamer.streamer.NIStreamer[source]#
Represents the whole streamer
- add_ao_card(max_name, samp_rate, nickname=None, proxy_class=<class 'nistreamer.card.AOCardProxy'>)[source]#
Add an analog output card.
- Parameters:
max_name (
str) – name of the card as shown in NI MAXsamp_rate (
float) – sample rate in Hznickname (
Optional[str]) – human-readable name (e.g. “Fast AO card”; used for visualizations)proxy_class (
Optional[Type[BaseCardProxy]]) – custom subclass ofBaseCardProxyto use for the device proxy.
- Returns:
proxy_classinstance representing this card.- Raises:
KeyError – if a card with the same name already exists.
- add_do_card(max_name, samp_rate, nickname=None, proxy_class=<class 'nistreamer.card.DOCardProxy'>)[source]#
Add a digital output card.
- Parameters:
max_name (
str) – name of the card as shown in NI MAXsamp_rate (
float) – sample rate in Hznickname (
Optional[str]) – human-readable name (e.g. “Fast DO card”; used for visualizations)proxy_class (
Optional[Type[BaseCardProxy]]) – custom subclass ofBaseCardProxyto use for the device proxy.
- Returns:
proxy_classinstance representing this card.- Raises:
KeyError – if a card with the same name already exists.
- property chunksize_ms: float#
Streaming chunk size in milliseconds.
Chunk size is the main unit of streaming - all signal samples within a single chunk are computed, stored in memory, and transferred to the hardware in one operation together, at the same time as the previous chunk is playing.
Optimal chunk size depends on the tradeoff. Larger size reduces the risk of buffer underflow at the cost of increased overhead - memory allocation and the initial chunk compute will take longer. The default value is 150 ms.
Notes
If chunk size exceeds the total sequence duration, no streaming actually happens - all samples are computed before generation starts. This could be used to eliminate the risk of underflows if sequence is sufficiently short. However, in-stream looping feature will be disabled, and trying to pre-sample a long waveform can overfill RAM.
- property starts_last: str | None#
Specifies which card starts last.
- Format:
dev_name: str- this card waits for all others to start first;None(default) - each threads starts its task independently.
Typically, this is needed when start trigger or shared sample clock are used for hardware synchronisation. The card-provider of the signal should call
ni_task.start()last, otherwise some “consumer” cards could start later and miss the signal.
- property ref_clk_provider: Tuple[str, str] | None#
Specifies which card exports its 10 MHz reference clock signal during the run.
- Format:
(card_name: str, term_name: str)- card card_name exports to terminal term_nameNone- no card exports
Notes
(1) NIStreamer uses run-based static reference clock export - signal is statically exported during
init_stream()and then automatically undone duringclose_stream()calls.This export is static instead of being tied to NI tasks. As a result, any card supporting 10MHz export can serve as the provider. It does not have to be active (get some instructions) or even be registered in the streamer.
(2) If this mechanism is not sufficient, you can manually do a static export from any card by calling
share_10mhz_ref(). However, such export will not be undone automatically - you should manually callunshare_10mhz_ref()orreset_dev().Forgetting to undo manual export is very easy and dangerous - the exporter card will continue silently feeding the signal until the system is power-cycled. That can lead to physical double-driving and very confusing mis-triggering or mis-clocking errors. So only choose the manual export over the automatic method (1) if absolutely necessary.
- got_instructions()[source]#
Returns
Trueif there are some instructions in the edit cache, otherwiseFalse.- Return type:
bool
- last_instr_end_time()[source]#
Returns the last instruction end time or
Noneif the edit cache is empty.- Return type:
Optional[float]
- compile(stop_time=None)[source]#
Compiles the full pulse sequence from instructions in the current edit cache.
- Parameters:
stop_time (
Optional[float]) – IfNone(default), the compiled sequence stops at the last instruction end. Specifying a later stop time extends the sequence duration.- Return type:
float- Returns:
The actual compiled stop time.
- Raises:
ValueError – if provided
stop_timeis below the last instruction end.
Notes
The actual stop times may vary between cards due to clock grid mismatch and extra ticks on the final closing edges. The returned value is the shortest run time across all cards.
If explicit
stop_timeis provided, the additional time at the sequence end will be filled according to the usual rules:Constant values after finite-duration instructions.
Continued waveforms after “go-this” instructions.
- validate_compile_cache()[source]#
Verifies that compile cache is up-to-date with the current edit cache.
- Returns:
Noneif compile cache is up-to-date with the current edit cache.- Raises:
ValueError – If compile cache does not match edit cache (typical reason - users forgot to re-compile after adding more instructions).
- init_stream()[source]#
Context-based stream initialization.
This function should only be used in the
withcontext. The returned object is aStreamHandleinstance providing full stream control.Examples
>>> strmr = NIStreamer() >>> # ... add cards/channels, add instructions, compile ... >>> with strmr.init_stream() as stream_handle: >>> stream_handle.launch(instream_reps=10) >>> # Do some other logic while waiting ... >>> stream_handle.wait_until_finished()
- Raises:
ValueError – if stream initialization fails due to invalid settings.
See also
StreamHandlefor more details about stream controls;run()- a more basic way of launching stream.
- run(nreps=1)[source]#
Runs pulse sequence generation.
This method will block and only return after all
nrepsiterations have been generated. But it can be interrupted withKeyboardInterrupt- generation will stop between repetitions.- Parameters:
nreps (
Optional[int]) – the number of times to play the sequence. Plays once by default.- Raises:
ValueError – if stream initialization fails due to invalid settings.
RuntimeError – if generation fails during streaming (underflow, timeout, overvoltage).
Notes
This method implements basic repeating by stopping and re-starting the stream every time. As a result, there is a fluctuating time gap between subsequent repetitions.
Repeating with no gap and rigid timing between iterations is possible with so-called in-stream looping. It is only accessible through the context-based interface. See
init_stream()andStreamHandlefor more details.See also
init_stream()andStreamHandlefor full stream control.
- close_stream()[source]#
Closes the stream.
You typically do not need to use this method since context manager will automatically close the stream whenever exiting the context.
There is a small chance that a rapid succession of
KeyboardInterruptsignals disrupts__exit__()logic and prevents automatic stream shutdown. But even then, the next call toinitwill automatically close it.So this method is mostly exposed for completeness.
- add_reset_instr(reset_time=None)[source]#
Helper method - adds a “go-reset-value” instruction on each channel.
- Parameters:
reset_time (
Optional[float]) – the time at which to add the reset instruction (the same for all channels). IfNone, the latest last instruction end time from across all channels is used.- Raises:
ValueError – if requested
reset_timeis below the last instruction end time.