Code overview
An understanding of how the code is organized and what the classes do are only necessary for users who wish to modify the code. This documentation assumes a good understanding of MATLAB and object-oriented programming.

Finding your way around


All code is in the code directory. tests contains unit-testing code. The SETTINGS directory will be used to store your rig settings once BakingTray has been run for the first time. It is suggested that you keep backups of these in SETTINGS_BACKUP, or anywhere else of your choosing. The two settings directories are excluded from version control. The ChangeLog.txt file lists the major modifications made to the software. BakingTray is highly modular so it's very easy to run the software with different hardware by adding classes.

The code directory

Packages are used to keep things neat and avoid namespace issues. A model/view (also see) paradigm is used to separate the logic from the GUIs. In this framework the BT class is the "model" which controls acquisition. An instance of BT can be created at the command-line and a full acquisition can be set up and run purely using this class without the GUI. This is like the hSI object, if you're familiar with the ScanImage API. The BakingTray.m function starts the API and then builds the GUI. This is how you will typically be starting BakingTray. The resources directory contains a small number of helper functions. The components directory contains code used to drive hardware (laser, motion, and cutting) and interact with other software (scanning). The recipe class handles creation, reading, and processing of sample-specific preferences. e.g. Things like the number of tiles, the sample name, the image resolution, etc. The logger component is used to build detailed log files of the actions undertaken during acquisition. The detailed logs are stored in each section's directory. This is used for debugging in scenarios where an unattended acquisition stops seemingly random. The BakingTray package contains the GUIs and other functions directly involved in acquisition.


The BT class is responsible for controlling all the hardware on the microscope. Methods in BakingTray perform tasks such as moving the sample using the X/Y stage, raising the X/Y stage, starting and stopping the vibrotome, and performing the cutting cycle.
The goal of the software is to maintain flexibility so BT contains no hardware-specific commands of any sort. These commands are stored in "glue" or "bridge" classes that provide a consistent interface between the BakingTray class and the physical hardware. e.g. the BSC201 class interfaces between the ThorLabs BSC201 linear actuator controller and BakingTray. To enforce consistency, the BSC201_APT class inherits the abstract class linearcontroller that declares all methods that BSC201_APT should define. linearcontroller also contains extensive documentation as to how those methods should behave. To avoid duplication, BSC201_APT does not contain documentation on methods declared in linnearcontroller. Exactly the same system applies to the C891 class that controls the PI stages responsible for X and Y motion.
BakingTray might brings together the following classes in composite class:
  • X stage -- C891 class that inherits linearcontroller. The instance of the C891 class will have an instance of V551 that inherits linearstage attached to it at C891.attachedStage to form a composite object.
  • Y stage -- C891 class that inherits linearcontroller. The instance of the C891 class will have an instance of V551 that inherits linearstage attached to it at C891.attachedStage.
  • Z stage -- BSC201_APT class that inherits linearcontroller. The instance of the BSC201_APT class will have an instance of DRV014 that inherits linearstage attached to it at BSC201_APT.attachedStage.
  • Scanner - An instance of SIBT that inherits scanner.
Classes for each component type sit in their own sub-directories grouped by type. Each of these directories contains a buildComponent.m function that is responsible for making a functioning object from any of the classes in that directory.

The GUIs

Each component has a "view" class that controls a GUI. Let's take the maitai laser: The maitai class inherits laser and can interact with a GUI that is built by the class laser_view.
When laser_view is run, it incorporates an instance of the maitai object (or whatever laser you are using) and attaches listeners to the hidden GUI properties defined in the laser class. Any new class you build to control a piece of hardware must update these properties. Look in the associated abstract class for your component to see what needs to be updated.
Once set up, the following sort of thing happens. Say that the user runs at the command line:
>> hBT.laser.setWavelength(880)
This changes the value of the hidden hBT.laser.targetWavelength property so that field in the GUI will automatically change and the laser wavelength tracked by the GUI until the laser stops tuning.