You are viewing unmaintained documentation for an older version of OpenSesame. Click here to view the current documentation. Your version of OpenSesame: Language:

OpenSesame 3.0.0 will bring amazing new features! Curious? Take it for a test spin, and help us iron out the kinks.

Source-code architecture

Overview

About this page

This page is intended to provide (potential) developers with an idea of OpenSesame’s source-code architecture. This is an informal and incomplete description of the most important characteristics of the architecture. If you have questions that are not answered here, please refer to the source code, or ask questions in the ‘OpenSesame-dev’ section of the forum.

General description of the architecture

The source-code architecture of OpenSesame is highly modular, and the various levels of abstraction are separated across three different Python packages, each of which contains several sub-packages (see Figure 1). At the highest level, openexp deals with input (keyboard responses, etc.) and output (display presentation, etc.). The libopensesame package implements the OpenSesame runtime, i.e. the functionality required to execute experiments. Finally, the libqtopensesame package implements the graphical user interface (GUI).

UML class diagram

/contribute/img/architecture/uml-class-diagram.png

Figure 1. A schematic depiction of the source-code architecture. This diagram is a sketch that conveys some general principles, and not a complete UML class diagram.

The openexp package

The openexp package (yellow in Figure 1) implements input and output in a way that is not tied to a specific mechanism. For example, whenever something needs to be shown on the display, an instance of canvas is created, as shown in Listing 1:

from openexp.canvas import canvas
# `exp` must be an instance of `libopensesame.experiment.experiment`.
my_canvas = canvas(exp)
# Will print something like:
# <openexp._canvas.xpyriment.xpyriment instance at 0x3ae1f80>
print my_canvas

Listing 1. The canvas class is a factory that produces a back-end specific canvas object.

The canvas class is a factory that produces a back-end-specific canvas object, based on the canvas_backend property of the experiment object. For example, if the xpyriment back-end is used, my_canvas (in the example above) will become an instance of openexp._canvas.xpyriment.xpyriment. All openexp._canvas.[backend].[backend] classes are adapters that implement the same interface and map this onto functions that are specific to the underlying library. The interface specified in openexp._canvas.legacy.legacy is the reference interface, which all other back-ends must implement.

The same principle is also used for the keyboard, mouse, sampler, and synth classes.

The libopensesame package

The libopensesame package (blue in Figure 1) implements the runtime of OpenSesame. It provides all the functionality that is required to execute an experiment, but is not concerned with the GUI.

An experiment consists of several items, such as sketchpads, sequences, and loops. Items may execute other items. For example, a sequence executes one or more other items in a sequential order. In this way, by hopping from item to item, the progression of the experiment is determined.

All items are derived from the item class, which provides the basic functionality that is common to all items. A special type of item is the experiment item. The experiment item embeds all other items in its items attribute (a dict where item names are keys and item objects are values), stores experimental variables, and implements functionality for pre-experiment initialization and post-experiment clean-up. All other items have an experiment attribute, which points towards the experiment item.

from libopensesame.experiment import experiment

# A very basic experiment in OpenSesame script
exp_str = u'''
set start my_sketchpad
define sketchpad my_sketchpad
	draw textline 0 0 "Dummy text"
'''
# Parse the OpenSesame script into an experiment object
exp = experiment(string=exp_str)
# Calling the `experiment.run()` method will launch the full experiment
exp.run()
# Access the `my_sketchpad` item
my_sketchpad = exp.items[u'my_sketchpad']
print my_sketchpad
# The item in turn contains a reference to the `experiment` object
print my_sketchpad.experiment

Listing 2. You can parse and execute an experiment with a few lines of code.

The four most important item methods are:

  • prepare() implements the item’s prepare phase.
  • run() implements the item’s run phase.
  • from_string() parses an OpenSesame script into an item.
  • to_string() generates an OpenSesame script from an item.

The libqtopensesame package

The libqtopensesame package (green in Figure 1) implements the OpenSesame GUI. It is the most complicated and largest part of OpenSesame. The main application window is implemented in qtopensesame.

Items

The libqtopensesame.items sub-package is the GUI counterpart of libopensesame. At the heart of this package is the qtitem class, which provides the basic GUI functionality that is common to all items. Every item class from libopensesame has a counterpart in libqtopensesame.items, in which the runtime functionality is extended with GUI functionality. Basically, what an item does is implemented in libopensesame, while its GUI controls are implemented in libtopensesame.items.

The four most important qtitem methods are:

  • apply_edit_changes() updates the item based on changes in the GUI.
  • edit_widget() updates the GUI based on the status of the item.
  • init_edit_widget() constructs the item’s GUI controls.

Runners

The [runner name]_runner classes, all of which are derived from base_runner, provide the functionality required for running an experiment. Essentially, an instance of libopensesame.experiment.experiment is created based on the active instance of libqtopensesame.items.experiment.experiment in the GUI. The experiment is executed and any exceptions that occur during execution are passed as osexceptions back to the GUI.

UI classes

The libqtopensesame.ui sub-package contains various auto-generated modules that implement parts of the user interface. All modules are generated directly from the .ui files located in /resources/ui.

Linked list of packages and modules

Click on the links below to view the relevant source-code files on GitHub.