Hi Apoorva,
To clear up when which code runs:
- Shots are "compiled" by runmanager, and then "run" by BLACS.
- generate_code runs when your shot is compiled by runmanager. No communication with hardware should occur here. Of course, if you write code here that communicates with hardware, it will run, but that is not the intended role of this function. generate_code() should process any instructions the user has added in their labscript code, converting them to the low-level instructions that need to be programmed into the device, and then save those instructions to the shot file.
- The code that actually communicates with hardware should be put in the BLACS worker class for the device. There are three relevant methods. init(), which runs when BLACS starts up or when the BLACS tab in question is restarted, transition_to_buffered(), which runs at the start of each shot, and transition_to_manual(), which runs at the end of each shot. The job of transition_to_buffered() is to read the shot file (which is given to it as a function argument), and obtain the instructions which were saved by generate_code(). It then should communicate with the hardware and use those instructions to set up the device so that it is ready for the shot to begin. transition_to_manual() should do any communication with the hardware that is needed at the end of the shot, such as reading acquired data, and writing it to the shot file as well.
If the same shot file is repeated many times, then it is only compiled once, but these two functions in BLACS will run multiple times as copies of the shot file are made and transition_to_buffered() and transition_to_manual() are called multiple times.
If you haven't already, reading our
paper might help you get a better idea of how things fit together. A lot has changed since then, but the basic layout (as depicted in the flowcharts) of how the data flows between programs is the same now as it was then.
When you say you have an IntermediateDevice, do you mean that you made a subclass of IntermediateDevice, and overrode its generate_code() method? Firstly, since your device sounds like it does not have a parent device giving it clocking signals, or child devices with different outputs, I would subclass Device. Secondly, you will need to make several classes: a "labscript device" class, a "BLACS tab" class, and a "BLACS worker" class. The labscript device class is for interacting with your labscript code and saving instructions to the shot file (in generate_code()). The BLACS tab is about creating a graphical interface in BLACS for the device, and for you this will be mostly empty. The BLACS worker is for actually communicating with the device each shot.
I'll create an example of the files and classes you would need to do this, which will hopefully be instructive and might serve as a reference to others as well. Other examples exist, but are less minimal.
As for repeating a fixed number of times, there is currently no way to configure this in BLACS, but the way I would do it is to create a global in runmanager called "repeat_number" or similar, and set it to range(N) where N is the number of desired repeats. Runmanager will then treat this as a parameter to be iterated over, and will create N shots when you click the "engage" button.
I hope that clears up some things!
-Chris