Executing a sequence ==================== The function :func:`~caqtus.experiment_control.sequence_execution.run_sequence` is the entry point for running a sequence. Initialization -------------- When the sequence is being prepared, a :class:`~caqtus.shot_compilation.DeviceCompiler` is created for each instrument in use. It is in charge of converting shot parameters into instrument-specific instructions. To do so, it can use the :class:`~caqtus.device.DeviceConfiguration` entered by the user. The result of the compiler :meth:`~caqtus.shot_compilation.DeviceCompiler.compile_initialization_parameters` method is used to instantiate an associated :class:`~caqtus.device.Device` object. This device object is in charge of managing the connection to the instrument. Each device is then initialized by entering its context manager (i.e. its method :meth:`~caqtus.device.Device.__enter__` is called). Run --- The shot parameters are iterated over according to the sequence :class:`~caqtus.types.iteration.IterationConfiguration`. For each shot, its parameters are passed to the device compilers :meth:`~caqtus.shot_compilation.DeviceCompiler.compile_shot_parameters` method. The resulting instructions are then passed to the method :meth:`~caqtus.device.DeviceController.run_shot` of the :class:`~caqtus.device.DeviceController` object associated with the device. The controller manages the device during the shot. Unlike the devices, controllers can interact with each other for synchronization or data exchange. The controller first sends the instructions for the shot to the device and waits for all devices to be ready. The shot is then triggered and the controllers can react to data generated by the devices while waiting for the shot to finish. Shutdown -------- If no error occurs either during shot compilation or execution, the sequence terminates successfully. If an error occurs while compiling a shot, the currently running shot will finish properly, but no shot will be scheduled after it. If an error occurs inside the :meth:`~caqtus.device.DeviceController.run_shot` method of a controller, the shot is aborted in the middle of its execution. It is unfortunately not possible to let the other devices go to the end of the shot, since there are not guarantee to be able to terminate if they are waiting for the device that crashed. Because of this, the :meth:`~caqtus.device.DeviceController.run_shot` method of the other controllers are cancelled as soon as possible. In the end of the sequence, whether it is successful or not, each device is closed by exiting its context manager (i.e. its method :meth:`~caqtus.device.Device.__exit__` is called).