Counter implementation with labscript

18 views
Skip to first unread message

Alex M.

unread,
Mar 18, 2026, 6:04:59 PM (5 days ago) Mar 18
to the labscript suite
Hello all,

We are interested in using counters on the NI-PCIe-6361 DAQ to count rising edges of TTL pulses from a single photon counting module, and were wondering if there was a way to acquire this data through labscript similar to how analog inputs are structured.

I've read through the documentation and have seen that NI DAQs with counters can be used for wait monitors, but haven't seen any methods or classes one can use to directly acquire data from such a counter with labscript, and then use lyse to analyze this data later.

Has anyone tried this before, or can recommend how to accomplish it?

best,

Alexander

Chris Billington

unread,
Mar 18, 2026, 6:37:52 PM (5 days ago) Mar 18
to labscri...@googlegroups.com
Hi Alex,

Indeed, this functionality doesn't currently exist. The use of counters for wait monitors is fairly specific to wait monitors, and not on top of any more general labscript counter functionality. To implement counters for other purposes "properly" in labscript, changes in several places would be needed, including (I think):

* Modify labscript/inputs.py to add a CounterInput class similar to AnalogInput
* Modify labscript_devices/NI_DAQmx/models/get_capabilities.py to introspect counter capabilities - right now it counts how many counter inputs there are, it's possible this is sufficient information for basic counter usage, but I'm not sure. If more info is needed, then after adding introspection for it to the script, one would then need to run the script on a system with simulated devices of all supported models added in NI MAX to introspect their capabilities and save to the capabilities.json file. One would then need to re-run labscript_devices/NI_DAQmx/models/generate_subclasses.py to regenerate all the subclasses for the specific models, that pass set these capabilities as keyword arguments.
* Modify labscript_devices/NI_DAQmx/labscript_devices.py to allow CounterInput child devices, and to write their acquisition details to a table in the HDF5 file during compilation, similar to how analog acquisition details are currently saved. If additional capabilities were added to capabilities.json via get_capabilities.py, then arguments for the additional capabilities would need to be added as instantiation arguments to the NI_DAQmx labscript device class (the generated subclasses automatically pass in anything in the capabilities dict as instantiation arguments).
* Modify labscript_devices/NI_DAQmx/blacs_workers.py to read this table and configure counter inputs using the NI DAQmx API during transition_to_buffered, and to save the results to the HDF5 file during transition_to_manual. This would likely require defining an additional worker class for the acquisition, similar to how the NI_DAQmxAcquisitionWorker class acquires analog input data in a separate worker process. 
* Modify labscript_devices/NI_DAQmx/blacs_tabs.py to create the new worker, similar to how it currently does for the analog acquisition worker.
* Presumably add some methods to lyse.Run() to extract these acquisition traces

So pretty involved!

An alternative hack if you just want it working for yourself is to set up the counter acquisition as an entirely separate program that configures the acquisition and for it to start on a trigger or whatnot, as you would using the NI DAQmx API if you were not using labscript at all. Then just use labscript to deliver the trigger at the desired time with a Trigger object. You might then use a labscript FunctionRunner object to read the acquired data from that other program (over a socket, over zmq, or even reading from a file on disk written by the acquisition program) and save it to the HDF5 file at the end of a shot.

Regards,

Chris

--
You received this message because you are subscribed to the Google Groups "the labscript suite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to labscriptsuit...@googlegroups.com.
To view this discussion, visit https://groups.google.com/d/msgid/labscriptsuite/170c9ee4-4362-468e-9d58-870c0ce7a9cen%40googlegroups.com.

Chris Timossi

unread,
Mar 19, 2026, 12:52:29 AM (4 days ago) Mar 19
to labscri...@googlegroups.com, labscri...@googlegroups.com
Alex,

I put something together using a counter on our PXIe-6363 for our photon counter. I’m new to Labscript and there’s a lot of Claude code but it works for our purpose. 


Chris Timossi

On Mar 18, 2026, at 3:37 PM, Chris Billington <chrisjbi...@gmail.com> wrote:



Philip Starkey

unread,
Mar 19, 2026, 11:00:20 AM (4 days ago) Mar 19
to the labscript suite
Hi Alex,

What timing specs do you need and are you only interested in the number of pulses or do you need to acquire any timing information related to them as well?

I ask because, as a potential left field idea, you could probably push a raspberry pi pico 2350 to count pulses at 50 Mhz with some clever PIO programming (and maybe higher with overclocking) if all you needed was the total count. 

Cheers,
Phil

Alex M.

unread,
Mar 21, 2026, 2:40:55 PM (2 days ago) Mar 21
to labscri...@googlegroups.com
Hello Chris,

Thanks for linking this code! I looked through your repo and it seems that this might work very well for our purposes. I have a few questions though.

Just to make sure I understand the way this wrapper works, you use the physical connection of the prawnblaster to your PXI3-6363 (PFI12) as the clock terminal from which the arm trigger is sent to the counter responsible for receiving the TTL pulses from your photon counter. You use the first sample clock edge, since it is effectively the same as the master pseudoclock edge because these are synchronized. Finally, I understand this to be a passive process, in the sense that it is a purely clock driven process, and that there is no method that one calls in the experiment logic to command an acquisition.

I see that you specify the ctr1 channel, which on the PXIe-6361 corresponds to the CTR1A according to the NI pinout. Is there any reason why you choose the CTR1A and  not the CTR1Z or  CTR1B, which correspond to PFI4 and PFI11 respectively?

Also, in your connection table, you specify the acquisition rate of the 6363 to be 100 (Hz I presume?) and then the counter sample rate to also be 100 Khz. Is the latter just the rate at which the data from the counter is updated in blacs, and the former the actual sample rate of the counter?

Thanks again for providing this code!

best,

Alex


Alex M.

unread,
Mar 21, 2026, 2:42:31 PM (2 days ago) Mar 21
to labscri...@googlegroups.com
Hello Phil,

I think for now we are interested in just the number of pulses, and won't need to clock higher than 25 Mhz, given our maximum frequency for TTL pulses from our spcm is about 22 Mhz.

--
You received this message because you are subscribed to the Google Groups "the labscript suite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to labscriptsuit...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages