# 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

### Overview

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](https://www.mathworks.com/help/matlab/matlab_oop/scoping-classes-with-packages.html) are used to keep things neat and avoid namespace issues. A [model/view](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) ([also see](https://www.mathworks.com/matlabcentral/fileexchange/40294-model-view-control-pattern-using-guide)) 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](https://github.com/tenss/ScanImageAPI_Examples). 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.

### Components

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.
