The structure of Stytra

We developed Stytra using the Python programming language. We endeavored to follow best practices in software engineering: separation of user interface and data processing code, modularity and consistent programming interfaces.

In Stytra, new experiments can be designed using very simple Python syntax, allowing even beginners in programming to develop their own stimulation paradigms. Once defined, the experiment is controlled through a graphical user interface which can be used with no knowledge of Python.

At the core of the Stytra package lies the Experiment object, which links all components that may be used in an experiment: stimulus presentation, camera, animal tracking, metadata and logging. This organization enables composing different experimental paradigms with full code reuse. Improvement of different modules (e.g. the user interface, plotting or tracking) is therefore reflected in all experimental setups, and support for a new piece of hardware or tracking function can be added with minimal effort and interference with other parts of the project. Online image processing is organized along a sequence of steps: first, images are acquired from the camera, then the image is filtered and tracked, and the tracking results are saved. Acquisition, tracking and data saving occur in separate processes (depicted in blue, purple, and green in the diagram below).

dataflow diagram

This approach improves the reliability and the performance of online behavioral tracking, and exploits the advantages of multi-core processors. After processing, streaming numerical data (such as tracking results and dynamic parameters of stimuli) is passed into data accumulators in the main thread, and a user-selected subset can be plotted in real time and saved in one of the several supported formats. Moreover, for every experimental session all changeable properties impacting the execution of the experiment are recorded and saved. Finally, as the software package is version-controlled, the version (commit hash) of the software in use is saved as well, ensuring the complete reproducibility of every experiment.

dataflow class diagram

Basic classes

The Experiment object binds all the different components required to run an experiment. The most basic Experiment object performs the presentation of a succession of stimuli, saving the experiment metadata and the stimulation log. For experiments including video tracking, the TrackingExperiment object augments the basic Experiment with features such as camera frame acquisitions and online image analysis. The image analysis pipeline can be one of the zebrafish specific pipelines supplied with Stytra, or a custom tracking pipeline. The Experiment is linked to the user interface for controlling the running of stimulation protocols, inserting metadata, controlling parameters, and calibrating the stimulus display. For details of the user interface, please see the user interface section of the documentation.

In general, the users do not need to define new types of Experiment objects for every new experimental paradigm. Instead, paradigms are implemented by defining a Protocol object which contains the stimulus sequence (as described below) and a configuration dictionary with information about the camera, tracking pipeline, and triggering. The appropriate Experiment object can be automatically instantiated from the configuration dictionary using the Stytra constructor. Alternatively, an Experiment can be instantiated and run from the experiment script, as described in the documentation examples. Ideally, the provided Experiment objects should cover most of the requirements of zebrafish behavioral experiments, and redefining the Experiment is required only if one needs to modify the graphical user interface (GUI), add more nodes in the data pipeline (screens or cameras) or implement more specific customizations. A more detailed depiction of the connections and versions of different objects is depicted in above. For examples of how to create a Protocol and run experiments in Stytra, see Create a new protocol.