Skip to content
Michael Walsh edited this page Oct 17, 2019 · 23 revisions

Welcome to the CommandCenter wiki!

This document is meant to help you understand how to operate CommandCenter, develop new functionality and learn how some of the underlying code works.

There is a slack team dedicated to providing help and discussion with any aspect of the codebase. Feel free to request access: commandcenter-dev.slack.com

Suggested Order to Read

Using CommandCenter

Hopefully the use is quite intuitive, but you can find a short guide walking you through the various menus and controls. This won't cover use of a particular module. For that, you should reference the wiki page for that module.

While MATLAB is not super OS-dependent for most of its functionality, the graphics engine can be. As such, the GUI only displays well on a Windows. Everything works on other OS's, but it will be difficult to interact with the user interface (UI/GUI).

Background/Terminology

CommandCenter is designed to be a modular framework for robust and quick development. This section is certainly not necessary for using CommandCenter - it is intended for those interested in developing. As such, there are a few underlying components that will be referenced frequently (familiarity with OOP concepts will significantly help):

MATLAB (OOP) concepts

  • Package: a folder that begins with a "+" is interpreted as a package which gives everything in that folder its own namespace. For example, a function foo inside a folder called +Modules will need to be referenced via its package name Modules.foo. Packages can be nested.
  • Class Folders: a folder that begins with an "@" is interpreted as a class folder. While this may seem similar to a package, they are fundamentally different. A class folder must have the classdef file inside. All other function files are class methods. This is a convenient way to split a very long classdef file into multiple files.
  • Class Property: classes can define a set of properties (optionally with attributes declared) that can be thought of as variables associated with that class.
  • Inheritance: a class may inherit properties and methods from other classes (called the superclasses). This is a very important fundamental concept of OOP and building module frameworks.
  • Abstract classes: classes that are designed to be inherited (e.g. superclasses) have the additional ability to define "abstract" properties and/or methods. If a subclass inherits such a superclass it must explicitly define those abstract components.
  • Event/Property Listeners: Event and listeners are an important aspect of CommandCenter. Managers will frequently setup listeners to various events defined by handle objects or different types of modules.

Unique to this codebase

  • Module: at its most basic form, a module is a class that is meant to provide control over some aspect of an experiment (e.g. a laser, camera and database/filesystem).
    • Prefs: a module can define a set of prefs (which are class properties) that get saved between MATLAB sessions. This is a way to provide persistent memory from reloading modules to rebooting the computer. The way they are used is entirely up to the module.
    • Settings: the graphical interface provides two parts to the settings panel. The first part is shared with all modules of a given type (e.g. turning a source on/off) and enforced by the abstract superclass. The rest is dedicated to custom settings declared by the module. These are some set of the module's properties. For the most part, these are exactly the set of prefs.
  • Manager: a manager is a class that has the responsibility of providing the link between modules and the CommandCenter graphical interface.

Basic Code Structure and Launching

The entry function to launch the GUI is CommandCenter.m which is a GUIDE application that uses CommandCenter.fig as the template. Virtually all functionality is immediately passed off to the various manager classes upon executing CommandCenter_OpeningFcn(...) with the exception of a few "File" menu callbacks.

Below is a block diagram outlining the architecture of the code. Each block can be roughly mapped to a class instance. Any block directly above another block indicates that the above block has a handle to the lower one. Very generally, the orientation also indicates the flow of data - starting with data being generated at the very bottom "Driver Modules" and propagating up to, for example, the "Database Manager". The logger sits along the side and is accessible to any instance in the stack. The "CommandCenter" block should be thought of as the entry point or opening function of the software, and is described below.

CommandCenter structure

The Opening Function

This function has the responsibility to:

  1. Build the GUI using MATLAB's GUIDE engine
  2. Instantiate and link the managers to the appropriate panels and callbacks.
  3. Instantiate the logging engine.
  4. If a unique key for this distribution hasn't been made, generate one (taking into account MATLAB's random seed generation).
    • This is a 258 bit random number encoded in base64 (ecluding characters that are not URL safe).
    • It is used exclusively to identify log files at the central logging server.
  5. Check that you are synced with the most recent git branches (and warn you if you aren't).
  6. Prepare the inactivity timer (initialized at 30 minutes).
  7. Assign the managers variable in the main workspace to the ManagerContainer.
  8. Reset the dbquit failsafe. See below for details.

Other relevant methods

  • inactivity(timerH) is called when the 30 minute timer discussed in the opening function is triggered. See the below for more details on this concept.
  • figure1_SizeChangeFcn(...) is responsible for keeping the correct positions of various panels as the user changes the figure size.
  • file_logger_Callback(...) is called when the user clicks the "Logger Visible" option in the File menu to toggle the logger's visibility.
  • git_pull_master_Callback(...) is the callback to the "Git Pull" File menu option.
  • figure1_CloseRequestFcn(...) cleans up everything that happened during CommandCenter's instantiation.
    • Deletes all managers (see managers to see what this entails).
    • Deletes any leftover modules (frequently drivers that weren't cleaned up). During module instantiation, the modules add themself to a master list, and remove themselves upon destruction (see modules).
    • Cleans up inactivity timer.
    • Sends new logs to the central logging server.
    • Disables the dbquit override.

Only the methods that have the bulk of the functionality directly in them are listed. The numerous other methods in CommandCenter.m are light wrappers to functionality that is described elsewhere (likely in managers).

Inactivity Monitor

The inactivity monitor is an extremely useful tool. It is capable of disengaging from servers or signaling the end of use for pieces of equipment that may have been left on either manually or due to the completion of a long experiment. The default setting (hard-coded in the the opening function) is 30 minutes of inactivity and. If you wish to change the timeout duration, it is best to adjust the value stored in the timeout property of the Manager Container.

This monitor is implemented as a MATLAB timer object. It can be accessed from the Manager Container's handles.inactivity_timer property. The state of inactivity can be checked by looking at the inactivity property of the Manager Container.

The two places this flag is adjusted are:

  1. The inactivity method (see other relevant methods) where it is set to true.
  2. The sandboxed_function method in the manager superclass (see managers for more details.) which sets it to false. This is also the method that resets the clock back to the timeout property of the Manager Container after each call. It is called on every action taken in CommandCenter that leads to interacting with a loaded module.

The actions taken by the inactivity monitor being triggered are:

  • Resetting the "quit debugging" failsafe.
  • Iterate through DB, Experiment, Sources, Stages, and Imaging manager's inactive methods.
  • Send new log messages to the central logging server.
  • Displaying a modal dialog to the user of all actions taken (including those returned by managers.)

Logger

Coming Soon

Quit Debugging Failsafe

As discussed briefly in the README, quitting in the middle of debugging can cause unexpected behavior. As such, there is a failsafe in place to prevent the user from accidentally doing this. The failsafe function is prepared in the opening function and all additional functionality is contained within the failsafe function.

The state of the failsafe is controlled by its filename:

  • Enabled --> "dbquit.m"
  • Disabled -> "dbquit_disabled.m"

Specifically, the opening function "enables" the dbquit failsafe by naming the failsafe function "dbquit.m" such that it overloads MATLAB's builtin dbquit (which is also called when pressing the "Quit Debugging" button in MATLAB).

The failsafe function will interrupt the typical dbquit operation with a modal dialog notifying the user of the situation and how to override it if absolutely necessary.

When overridden by the user, the failsafe function will rename itself to "dbquit_disabled.m" such that it is no longer shadowing the MATLAB builtin.

A triggered inactivity timer will reset this to be enabled again.

Folder Structure

I will outline some relevant files as well.

  CommandCenter
  ├── CommandCenter.m         # Entry function
  ├── +Base                   # Core files for CommandCenter functioning
  │   ├── QR                  # QR reader class
  │   │   └── ...
  │   ├── Manager.m           # Manager superclass
  │   ├── ManagerContainer.m
  │   ├── Module.m            # Module superclass
  │   ├── pref.m              # Pref superclass
  │   ├── pref_handler.m      # Mixin to enable class-based prefs
  │   ├── input.m             # Pref input superclass
  │   ├── SmartImage.m        # SmartImage class
  │   ├── SmartSample.m       # SmartSample class
  │   └── ...
  ├── +Modules                # Module abstract definitions
  │   ├── Database.m          # Database/saving module superclass
  │   ├── Driver.m            # Driver module superclass
  │   ├── Experiment.m        # Experiment module superclass
  │   ├── Imaging.m           # Imaging module superclass
  |   ├── Source.m            # Source module superclass
  |   ├── Stage.m             # Stage module superclass
  │   └── ...
  ├── +Prefs                  # Location of Pref classes
  │   ├── +Inputs             # Location of Input classes used by prefs
  │   │   └── ...
  │   └── ...
  ├── HelperFunctions         # Generic tools (e.g. plotting, analysis, etc.)
  │   ├── PulseSequence       # Classes for building PulseSequence tree
  │   │   └── ...
  │   ├── hwserver.m          # Client for Module Server*
  │   └── ...
  ├── Modules                 # Location of all implemented module classes
  │   ├── +Databases          # Database modules
  │   │   └── ...
  │   ├── +Drivers            # Driver modules
  │   │   └── ...
  │   ├── +Experiments        # Experiment modules
  │   │   └── ...
  │   ├── +Imaging            # Imaging modules
  │   │   └── ...
  │   ├── +Sources            # Source modules
  │   │   └── ...
  │   ├── +Stages             # Stage modules
  │   │   └── ...
  │   └── Managers            # Location of implemented manager classes
  │       └── ...
  ├── overload_builtin        # Overloaded functions for MATLAB version compatibility
  │   └── ...
  └── ...

*Module Server